|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
TweenMax. Как правильно сократить время анимации?
Здравствуйте! Не знал куда написать, проект пишется на Starling, но проблема как мне кажется его не касается здесь.
Есть 5 вращающихся барабанов слот-машины. Все они находятся в векторе. Происходит запуск с помощью TweenMax, и каждый экземпляр анимации сохраняем в этом же барабане. Остановку решил сделать уменьшив параметр repeat каждого экземпляра TweenMax. Это все работает, если барабаны крутятся не более 6-7 секунд. Если больше, то они останавливаются одновременно. Подскажите, почему так? Запуск анимации, repeat:-1: // Цикл по всем столбцам 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 } ); } |
|
|||||
Регистрация: Jul 2007
Сообщений: 159
|
попробуйте прибивать твины и подрубать новые, похоже на баг твинМакса. Или попробуйте твинНано.
Я делал из последовательности твинов. Текущие стопим, новые запускаем (либо запускаем по окончанию предыдущих), причем обычно с другими параметрами изинга. Как уже писал в другой ветке - сначала приподнимаем, потом начинаем вращать (двигать вниз, по окончанию перемещать вверх изменением y), как пришло время стопить - убираем твин перемещения, добавляем твин отскока. У меня это все y-координатно зависимо, и применяется последовательно к каждому столбцу, для реалистичности.
__________________
Думаю на as3. Готов к долгосрочному взаимовыгодному сотрудничеству в сфере геймдева. |
|
|||||
[+4 06.05.14]
|
alexandrratush, вот готовый движок именно барабана. Половина тебе тут не надо, лень просто отчищать, но суть поймешь, я делаю через интер фрейм, а остановку через макс.
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"); } } }
__________________
Марк Tween |
|
|||||
Спасибо всем за ответы.
Вот решил вставить такой костыль с помощью setTimeout /** Остановка машины */ 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; } public function stopTween(d:int):void { _intervalId = setTimeout(delayedFunction, d); } private function delayedFunction():void { clearTimeout(_intervalId); tween.repeat = 5.0; } in4core спасибо что поделились своим кодом, но я думаю что он был бы мне полезен еще только когда я начинал работу, а так сейчас я там нашел мало что полезного. Потому как моя реализация совсем непохожа на вашу. |
|
|||||
Вот мой динозавр.
Сам барабан состоит из 2-х классов. Пока работает, а там увидим что с ним будет. Демо выложил на свой сервер. 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); } } } 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 главное что заказчику нравится.
А скорость изменить не составит проблемы, да и допилить остановку тоже можно. |
|
|||||
[+4 06.05.14]
|
Цитата:
Я то вел разговор о novomatic / novoline слотах , как минимум.
__________________
Марк Tween |
Часовой пояс GMT +4, время: 07:12. |
|
« Предыдущая тема | Следующая тема » |
|
|