Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   TweenMax. Как правильно сократить время анимации? (http://www.flasher.ru/forum/showthread.php?t=207772)

alexandrratush 07.05.2014 13:58

TweenMax. Как правильно сократить время анимации?
 
Здравствуйте! Не знал куда написать, проект пишется на Starling, но проблема как мне кажется его не касается здесь.
Есть 5 вращающихся барабанов слот-машины. Все они находятся в векторе.
Происходит запуск с помощью TweenMax, и каждый экземпляр анимации сохраняем в этом же барабане.
Остановку решил сделать уменьшив параметр repeat каждого экземпляра TweenMax.
Это все работает, если барабаны крутятся не более 6-7 секунд. Если больше, то они останавливаются одновременно.
Подскажите, почему так?

Запуск анимации, repeat:-1:
Код AS3:

// Цикл по всем столбцам
for each (slotItem in _slotsVector) {
    var d:Number = 0;
 
        // Смещение вниз У
        ty = slotItem.height - _clipRect.height;
        d += .2;
 
        // в каждом барабане сохраняем анимацию
        slotItem.tween = new TweenMax(slotItem, .05, {
                        y:ty,
                        repeat:-1,
                        delay:d,
                        onStart:onStartFunc,
                        onStartParams:[slotItem],
                        onComplete:onCompleteFunc,
                        onCompleteParams:[slotItem],
                        yoyo:true,
                        ease:Elastic.easeInOut }
                );
}

Остановка анимации каждого барабана:
Код AS3:

public function stop():void {
        var slotItem:SlotItem;
        var d:Number = 20;
 
        // Уменьшаем постепенно анимацию в каждом барабане
        for each (slotItem in _slotsVector) {
                slotItem.tween.repeat = d;
                d += 10;
        }
}


morgenshtern 07.05.2014 14:48

попробуйте прибивать твины и подрубать новые, похоже на баг твинМакса. Или попробуйте твинНано.

Я делал из последовательности твинов. Текущие стопим, новые запускаем (либо запускаем по окончанию предыдущих), причем обычно с другими параметрами изинга.

Как уже писал в другой ветке - сначала приподнимаем, потом начинаем вращать (двигать вниз, по окончанию перемещать вверх изменением y), как пришло время стопить - убираем твин перемещения, добавляем твин отскока. У меня это все y-координатно зависимо, и применяется последовательно к каждому столбцу, для реалистичности.

in4core 07.05.2014 15:00

alexandrratush, вот готовый движок именно барабана. Половина тебе тут не надо, лень просто отчищать, но суть поймешь, я делаю через интер фрейм, а остановку через макс.

Код AS3:

package pro.clonez.slots.views.drums 
{
        import com.greensock.easing.Back;
        import com.greensock.TweenMax;
        import com.in4core.utils.FastSoundManager;
        import flash.display.MovieClip;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.filters.BlurFilter;
        import pro.clonez.slots.interfaces.IReel;
        import pro.clonez.slots.models.ReelsModel;
 
        /**
        * ...
        * @author in4core progression lab
        */

 
        public final class SimpleReel extends Sprite implements IReel
        {
                private var _symbolClass:Class;
 
                private var _mini1:Sprite = new Sprite();
                private var _mini2:Sprite = new Sprite();
                private var _answer:Sprite = new Sprite();
 
                private var _isRunning:Boolean = false;
                private var _reelsModel:ReelsModel;
                private var _reelNum:int = -1;
 
                public static var bonusAccepted:Boolean = false;
 
                public function SimpleReel()
                {
                        super();
                }
 
                public function set reelNum(n:int):void
                {
                        this._reelNum = n;
                }
 
                public function initialize(symbolClass:Class , model:ReelsModel):void
                {
                        this._reelsModel = model;
                        this._symbolClass = symbolClass;
 
                        for (var i:int = 0; i < this._reelsModel.maxSymbolsOnDrum; i++)
                        {
                                var sy1:MovieClip = new this._symbolClass() as MovieClip;
                                var sy2:MovieClip = new this._symbolClass() as MovieClip;
                                var sy3:MovieClip = new this._symbolClass() as MovieClip;
 
                                sy1.gotoAndStop( random );
                                sy2.gotoAndStop( random );
                                sy3.gotoAndStop( random );
 
                                sy1.y = sy2.y = sy3.y = i * sy1.height;
 
                                this._mini1.addChild(sy1);
                                this._mini2.addChild(sy2);
                                this._answer.addChild(sy3);
                        }
 
                        this.addChild(this._mini1);
                        this.addChild(this._mini2);
                        this.addChild(this._answer);
 
                        initFirst();
                }
 
                private function initFirst():void
                {
                        revertSymbols();
 
                        this._mini1.y = 0;
                        this._mini2.y = -this._mini2.height;
                        this._answer.y = this._mini2.y;
                        randomizeSymbols(this._mini2);
                }
 
                public function startSpin():void
                {
                        initFirst();
 
                        this._isRunning = true;
                        this.addEventListener(Event.ENTER_FRAME , rollIt);
                }
 
                private function rollIt(e:Event):void
                {
                        if (this._mini1.y >= this._mini1.height)
                        {
                                this._mini1.y = this._mini2.y - this._mini1.height;
                        }
                        else if (this._mini2.y >= this._mini2.height)
                        {
                                this._mini2.y = this._mini1.y - this._mini2.height;
                        }
 
                        this._mini1.y += this._reelsModel.drumSpeed;
                        this._mini2.y += this._reelsModel.drumSpeed;
 
                }
 
                public function stopSpin(resultData:Array):void
                {
                        if (!bonusAccepted)
                        {
                                if (resultData.indexOf("12") != -1 || resultData.indexOf(13) != -1 )
                                {
                                        FastSoundManager.playSound("book" , false , 0.5 , 100);
                                }
                                else FastSoundManager.playSound("stopReel" , false , 0.5 , 100);
                        }
 
                        this._isRunning = false;
                        this.removeEventListener(Event.ENTER_FRAME , rollIt);
 
                        var count:int = this._reelsModel.maxSymbolsOnReel;
                        var firstClip:Sprite;
                        var secondClip:Sprite;
                        var symbol:MovieClip;
 
                        if (this._mini1.y > 0)
                        {
                                firstClip = this._mini2;
                                secondClip = this._mini1;
                        }
                        else
                        {
                                firstClip = this._mini1;
                                secondClip = this._mini2;
                        }
 
                        for (var i:int = 0; i < count; i++)
                        {
                                symbol = this._answer.getChildAt(i) as MovieClip;
                                symbol.gotoAndStop( resultData[i] );
                                toFSSymbols(symbol);
                        }
 
                        this._answer.y = secondClip.y - secondClip.height;
                        firstClip.y = this._answer.y - this._answer.height;
 
                        TweenMax.to(this._answer , this._reelsModel.tweenMaxStopTimeJump ,
                        { y:0 , ease:Back.easeOut  } );
                        TweenMax.to(firstClip, this._reelsModel.tweenMaxStopTimeJump ,
                        { y:-firstClip.height , ease:Back.easeOut  } );
                        TweenMax.to(secondClip , this._reelsModel.tweenMaxStopTimeJump ,
                        { y:secondClip.height, ease:Back.easeOut  } );
                }
 
                public function switchState(state:String):void
                {
                        if (state == "blur")
                        {
                                this._mini1.filters = this._mini2.filters = [new BlurFilter (0, this._reelsModel.maxBlur, 1)];
                        }
                        else if (state == "unblur")
                        {
                                this._mini1.filters = this._mini2.filters = [];
                                this._answer.filters = [new BlurFilter (0, this._reelsModel.maxBlur, 1)];
                                TweenMax.to(this._answer , this._reelsModel.tweenMaxStopTimeJump , { blurFilter: { blurY:0 } , ease:Back.easeOut }  );
                        }
                }
 
                public function changeF():void
                {
                        var count:int = this._reelsModel.maxSymbolsOnReel;
                        var symbol1:MovieClip;
                        var symbol2:MovieClip;
                        var symbol3:MovieClip;
 
                        for (var i:int = 0; i < count; i++)
                        {
                                symbol1 = this._answer.getChildAt(i) as MovieClip;
                                symbol2 = this._mini1.getChildAt(i) as MovieClip;
                                symbol3 = this._mini2.getChildAt(i) as MovieClip;
 
                                toFSSymbols(symbol1);
                                toFSSymbols(symbol2);
                                toFSSymbols(symbol3);
                        }
                }
 
                public function rechangeF():void
                {
                        var count:int = this._reelsModel.maxSymbolsOnReel;
                        var symbol1:MovieClip;
                        var symbol2:MovieClip;
                        var symbol3:MovieClip;
 
                        for (var i:int = 0; i < count; i++)
                        {
                                symbol1 = this._answer.getChildAt(i) as MovieClip;
                                symbol2 = this._mini1.getChildAt(i) as MovieClip;
                                symbol3 = this._mini2.getChildAt(i) as MovieClip;
 
                                toNormalSymbols(symbol1);
                                toNormalSymbols(symbol2);
                                toNormalSymbols(symbol3);
                        }
                }
 
 
                private function randomizeSymbols(o:Sprite):void
                {
                        var symbol:MovieClip;
 
                        for (var i:int = 0; i < o.numChildren; i++)
                        {
                                symbol = o.getChildAt(i) as MovieClip;
                                symbol.gotoAndStop(random);
                                toFSSymbols(symbol);
                        }
                }
 
                private function revertSymbols():void
                {
                        var count:int = this._reelsModel.maxSymbolsOnReel;
                        var symbol1:MovieClip;
                        var symbol2:MovieClip;
                        var symbol3:MovieClip;
                        var n:int = 0;
 
                        for (var i:int = 0; i < count; i++)
                        {
                                symbol1 = this._answer.getChildAt(i) as MovieClip;
                                symbol2 = this._mini1.getChildAt(i) as MovieClip;
                                symbol3 = this._mini2.getChildAt(i) as MovieClip;
                                n = symbol1.currentFrame;
                                symbol2.gotoAndStop (n);
 
                                toFSSymbols(symbol1);
                                toFSSymbols(symbol2);
                                toFSSymbols(symbol3);
                        }
                }
 
                public function get isRunning():Boolean
                {
                        return this._isRunning;
                }
 
                private function get random():int
                {
                        return Math.floor(Math.random() * (this._reelsModel.symbolsCount - 1) + 1);
                }
 
                private function toFSSymbols(o:MovieClip):void
                {
                        if (!bonusAccepted) return;
 
                        var d:MovieClip = o.getChildAt(0) as MovieClip;
                        d.gotoAndStop("f");
                }
 
                private function toNormalSymbols(o:MovieClip):void
                {
                        var d:MovieClip = o.getChildAt(0) as MovieClip;
                        d.gotoAndStop("simple");
                }
 
        }
 
}


ZackMercury 07.05.2014 16:14

Цитата:

интер
Enter - энтэ:
Inter - интэ:

alexandrratush 11.05.2014 15:04

Спасибо всем за ответы.
Вот решил вставить такой костыль с помощью setTimeout :)
Код AS3:

/** Остановка машины */
public function stop():void {
        var slotItem:SlotItem;
        var d:int = 1000;
 
        // Скоротить анимацию
        for each (slotItem in _slotsVector) {
                // Здесь баг твина, поэтому ставим костыль :)
                // Ниже строчка не сработает ((
                // slotItem.tween.repeat = d;
                slotItem.stopTween(d);
 
                d += 1000;
        }
 
        // Выключаем флаг
        _isRun = false;
}

Код AS3:

public function stopTween(d:int):void {
        _intervalId = setTimeout(delayedFunction, d);
}
 
private function delayedFunction():void {
        clearTimeout(_intervalId);
        tween.repeat = 5.0;
}

Таким образом каждому следующему Твину присваиваем repeat = 5.0 через 1 секунду.

in4core спасибо что поделились своим кодом, но я думаю что он был бы мне полезен еще только когда я начинал работу, а так сейчас я там нашел мало что полезного. Потому как моя реализация совсем непохожа на вашу. :)

in4core 11.05.2014 19:05

alexandrratush - творение показать не забудь :) интересно же, как ты с твинмаксом здесь делаешь infinite

alexandrratush 11.05.2014 20:53

Вот мой динозавр.
Сам барабан состоит из 2-х классов.
Пока работает, а там увидим что с ним будет. :D
Демо выложил на свой сервер.

Код AS3:

package {
        import com.greensock.easing.*;
        import com.greensock.TweenMax;
        import starling.display.Sprite;
        import starling.display.Image;
        import starling.textures.TextureAtlas;
        import starling.textures.Texture;       
        import starling.textures.RenderTexture;
        import starling.filters.BlurFilter;
        import starling.display.Quad;
        import flash.geom.Rectangle;
 
 
        public class SlotMachines extends Sprite {
 
                /** Количество картинок в каждом столбце (максимальное) */
                public static const SLOT_ICON_MAX:int = 9;
 
                /** Количество видимых частей картинок */
                public static const SLOT_ICON_VIEW:int = 3;
 
                /** Атлас изображений */
                private var _textureAtlas:TextureAtlas;
 
                /** Менеджер, который выдает нам отдельные картинки из атласа */
                private var _assetsManager:Assets;
 
                /** Количество столбцов в слот-машине */
                private var _numSlots:int = 5;
 
                /** Вектор всех столбцов */
                private var _slotsVector:Vector.<SlotItem>;
 
                /** Запущена ли машина */
                private var _isRun:Boolean;
 
                /** Фильтр размытия */
                private var _blur:MotionBlurFilter = new MotionBlurFilter(89.5, 2);
 
                /** Маска */
                private var _clipRect:Rectangle;
 
                /** Количество остановленых столбцов */
                private var _countStop:int;
 
                /** Блокировка запуска/остановки машины, пока не будет запущена/остановлена вся анимация */
                private var _blocking:Boolean = false;
 
 
                public function SlotMachines(textureAtlas:TextureAtlas) {
                        _textureAtlas = textureAtlas;
                        _assetsManager = new Assets(_textureAtlas);
 
                        // Отрисовка машины
                        draw();
                }
 
                /** Запуск машины */
                public function run():void {
                        if (_blocking) return;
 
                        var slotItem:SlotItem;
                        var image:Image;
                        var ty:Number;
                        var d:Number = 0;
 
                        // Включаем флаг
                        isRun = true;
 
                        // Количество запусков сбрасываем
                        _countStop = 0;
 
                        // Включаем блокировку (выключим, только когда все будет запущено)
                        _blocking = true;
 
                        // Цикл по всем столбцам
                        for each (slotItem in _slotsVector) {
 
                                // Добавляем картинки в столбец
                                addNewImages(slotItem, SLOT_ICON_MAX - SLOT_ICON_VIEW);
 
                                // Смещение вниз У для Твина каждого столбца
                                ty = slotItem.height - _clipRect.height;
 
                                // Задержка анимации
                                d += .2;
 
                                // Анимация
                                slotItem.tween = new TweenMax(slotItem, .1, {
                                                y:ty,
                                                repeat:-1,
                                                delay:d,
                                                onStart:onStartFunc,
                                                onStartParams:[slotItem],
                                                onComplete:onCompleteFunc,
                                                onCompleteParams:[slotItem],
                                                yoyo:true,
                                                ease:Linear.easeIn }
                                        );
                        }
                }
 
                /** Старт анимации столбца */
                private function onStartFunc(slotItem:SlotItem):void {
                        // Применяем фильтр
                        slotItem.filter = _blur;
 
                        // Добавляем один запуск и проверяем для разблокировки машины
                        if (++_countStop == _numSlots) {
                                _blocking = false;
                        }
                }
 
                /** Завершение анимации */
                private function onCompleteFunc(slotItem:SlotItem):void {
                        slotItem.filter = null;
                        slotItem.y = 0;
                        slotItem.reset();
 
                        // Отнимаем один запуск и проверяем для разблокировки машины
                        if (--_countStop == 0) {
                                _blocking = false;
                        }
                }
 
                /** Остановка машины */
                public function stop():void {
                        if (_blocking) return;
 
                        var slotItem:SlotItem;
                        var d:int = 1000;
 
                        // Выключаем флаг "запуска"
                        isRun = false;
 
                        // Включаем блокировку (выключим, только когда все будет остановлено)
                        _blocking = true;
 
                        // Скоротить анимацию
                        for each (slotItem in _slotsVector) {
                                // Здесь баг твина, поэтому ставим костыль :)
                                // Ниже строчка не сработает ((
                                // slotItem.tween.repeat = d;
                                slotItem.stopTween(d);
 
                                d += 1000;
                        }
                }
 
                /** Отрисовка машины */
                private function draw():void {
                        var slotItem:SlotItem;
                        var tx:int;
 
                        _slotsVector = new Vector.<SlotItem>(5, true);
 
                        // Создаем столбцы
                        for (var i:int = 0; i < _numSlots; i++) {
                                slotItem = new SlotItem();
 
                                // Добавляем картинки
                                addNewImages(slotItem, SLOT_ICON_VIEW);
 
                                // Смещение каждого столбца
                                slotItem.x = (slotItem.width + 5) * tx;
 
                                // Добавляем столбец
                                _slotsVector[i] = slotItem;
                                addChild(slotItem);
 
                                tx ++;
                        }
 
                        // Размеры для маски
                        var _w:Number = (slotItem.width + 5) * tx;
                        var _h:Number = slotItem.height;
 
                        // Маска
                        _clipRect = new Rectangle(0, 0, _w, _h);
                        this.clipRect = _clipRect;
                }
 
                /**
                * Добавление новых изображений в столбец
                * @param        slotItem        Столбец
                * @param        count                Количество добавлений
                */

                private function addNewImages(slotItem:SlotItem, count:int):void {
                        // TODO Нужно переделать, чтобы передавать массив с значениями названий картинок
                        // Сейчас выбираеться рандом
                        var image:Image;
 
                        for (var j:int = 0; j < count; j++) {
                                image = new Image(_assetsManager.getTexture("s" + randRange(1, 9)));
                                slotItem.add(image);
                        }
                }
 
                public function get isRun():Boolean { return _isRun; }
                public function set isRun(value:Boolean):void {
                        _isRun = value;
                }
 
                public function get blocking():Boolean { return _blocking; }
 
                private function randRange(minNum:Number, maxNum:Number):Number {
            return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);
        }
 
        }
}


Код AS3:

package  {
        import com.greensock.TweenMax;
        import flash.utils.clearTimeout;
        import flash.utils.setTimeout;
        import starling.display.Sprite;
        import starling.display.Image;
 
        public class SlotItem extends Sprite {
 
                /** Вектор всех изображений */
                private var _itemsVector:Vector.<Image>;
 
                private var _count:int = 0;
 
                private var _intervalId:uint;
 
                public var tween:TweenMax;
 
 
                public function SlotItem() {
                        _itemsVector = new Vector.<Image>;
                }
 
                public function stopTween(d:int):void {
                        _intervalId = setTimeout(delayedFunction, d);
                }
 
                private function delayedFunction():void {
                        clearTimeout(_intervalId);
                        tween.repeat = 5.0;
                }
 
                /** Добавление новой картинки */
                public function add(image:Image):void {
                        var len:int = _itemsVector.length;
 
                        // Если уже есть картинки, то распределяем их вверх от 0 координаты
                        if (len >= SlotMachines.SLOT_ICON_VIEW) {
                                image.y = image.height * (SlotMachines.SLOT_ICON_VIEW - len - 1);
                        } else {
                                image.y = image.height * len;
                        }
 
                        // Добавляем
                        _itemsVector.push(image);
                        addChild(image);
                }
 
                /** Остановка и сброс */
                public function reset():void {
                        var i:int
                        var len:int = _itemsVector.length;
                        var image:Image;
                        var deleteImageCount:int = SlotMachines.SLOT_ICON_MAX - SlotMachines.SLOT_ICON_VIEW;
                        var imageCount:int = SlotMachines.SLOT_ICON_VIEW;
 
                        // Первые картинки удаляем
                        for (i = 0; i < deleteImageCount; i++) {
                                image = _itemsVector[0];
 
                                removeChild(image);
                                _itemsVector.splice(0, 1);
                        }
 
                        // Разворачиваем
                        _itemsVector = _itemsVector.reverse();
 
                        // Остальные сдвигаем вниз
                        for (i = 0; i < imageCount; i++) {
                                image = _itemsVector[i];
                                image.y = image.height * i;
                        }
                }
 
        }
}


samana 11.05.2014 20:59

Они так быстро крутятся и так мгновенно останавливаются, что можно было бы вместо реальной прокрутки просто запускать анимацию вращения (набор картинок), а при остановке выводить заранее выбранное, случайное положение. Но если конечно у вас в планах изменить скорость вращения на более плавную, то я конечно не прав)

alexandrratush 11.05.2014 21:07

samana главное что заказчику нравится. :D
А скорость изменить не составит проблемы, да и допилить остановку тоже можно.

in4core 11.05.2014 22:30

Цитата:

samana главное что заказчику нравится.
А ну походу дела у вас так проект то простенький, раз то, что в демо, нравится заказчику.
Я то вел разговор о novomatic / novoline слотах , как минимум.


Часовой пояс GMT +4, время: 19:25.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.