Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   API приложений и сред (http://www.flasher.ru/forum/forumdisplay.php?f=61)
-   -   [Starling] Имитация вращения барабана в слот-машинах (http://www.flasher.ru/forum/showthread.php?t=207747)

alexandrratush 05.05.2014 14:40

Имитация вращения барабана в слот-машинах
 
Здравствуйте! Возник вопрос в создании барабана слот-машины.
Starling я недавно начал использовать, поэтому возникли некие трудности.
Выставил количество кадров 60. При данной реализации, когда крутиться барабан, fps падает до 30. Это нормально или нет?

Вся проблема в применении фильтра BlurFilter. Без него все нормально проходит.
Подскажите как правильно применить фильтр в конкретной задаче.

Рут класс:
Код AS3:

package {
        import starling.display.Sprite;
        import starling.text.TextField;
        import starling.display.Quad;
        import starling.display.Image;
        import starling.textures.Texture;
        import starling.textures.TextureAtlas;
        import flash.display.Bitmap;
        import starling.events.Event;
        import starling.events.TouchEvent;
        import starling.events.Touch;
        import flash.geom.Point;
        import starling.events.TouchPhase;
 
        public class View extends Sprite {
                [Embed(source="assets/atlas.xml", mimeType="application/octet-stream")]
                private var AnimData:Class;
 
                [Embed(source="assets/atlas.png")]
                private var AnimTexture:Class;
 
                private var _slotMachines:SlotMachines;
 
                public function View() {
                        addEventListener(Event.ADDED_TO_STAGE, onAdded);
 
                        var texture:Texture = Texture.fromBitmap(new AnimTexture() as Bitmap);
                        var atlasXML:XML = new XML(new AnimData());
                        var textureAtlas:TextureAtlas = new TextureAtlas(texture, atlasXML);
 
                        //
                        _slotMachines = new SlotMachines(textureAtlas);
                        addChild(_slotMachines);
                }
 
                private function onAdded(e:Event):void {
                        stage.addEventListener(TouchEvent.TOUCH, onTouch);
                }
 
                private function onTouch(e:TouchEvent):void {
                        var touch:Touch = e.getTouch(stage, TouchPhase.BEGAN);
                        if (touch == null) return;
 
                        if (!_slotMachines.isRun) {
                                _slotMachines.run();
                        } else {
                                _slotMachines.stop();
                        }
                }
 
        }
}

Барабан:
Код AS3:

package {
        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 com.greensock.BlitMask;
        import com.greensock.TweenMax;
        import flash.geom.Rectangle;
 
        public class SlotMachines extends Sprite {
 
                /** Атлас изображений */
                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:BlurFilter = new BlurFilter(0, 5);
 
 
                public function SlotMachines(textureAtlas:TextureAtlas) {
                        _textureAtlas = textureAtlas;
                        _assetsManager = new Assets(_textureAtlas);
 
                        // Отрисовка машины
                        draw();
                }
 
                /** Запуск машины */
                public function run():void {
                        var slotItem:SlotItem;
                        var image:Image;
                        var ty:Number;
 
                        // Включаем флаг
                        _isRun = true;
 
                        // Цикл по всем столбцам
                        for each (slotItem in _slotsVector) {
 
                                // Добавляем по 3 картинки
                                addNewImages(slotItem);
 
                                // Смещение по У для Твина
                                ty = slotItem.height / 2;
 
                                // Применяем фильтр
                                slotItem.filter = _blur;
 
                              TweenMax.to(slotItem, .05, {y:ty, repeat:1000, yoyo:true});
                        }
                }
 
                /** Остановка машины */
                public function stop():void {
                        var slotItem:SlotItem;
 
                        // В каждом столбце удаляем фильтр, сбрасываем позицию и удаляем эллементы
                        for each (slotItem in _slotsVector) {
                                slotItem.filter = null;
                                slotItem.y = 0;
                                slotItem.reset();
                        }
 
                        TweenMax.killAll();
 
                        // Выключаем флаг
                        _isRun = false;
                }
 
                /** Отрисовка машины */
                private function draw():void {
                        var slotItem:SlotItem;
                        var tx:int;
 
                        _slotsVector = new Vector.<SlotItem>;
 
                        // Создаем столбцы
                        for (var i:int = 0; i < _numSlots; i++) {
                                slotItem = new SlotItem();
 
                                // Добавляем по 3 картинки
                                addNewImages(slotItem);
 
                                // Смещение каждого столбца
                                slotItem.x = (slotItem.width + 5) * tx;
 
                                // Добавляем столбец
                                _slotsVector.push(slotItem);
                                addChild(slotItem);
 
                                tx ++;
                        }
 
                        // Размеры для маски
                        var _w:Number = (slotItem.width + 5) * tx;
                        var _h:Number = slotItem.height;
 
                        // Маска
                        this.clipRect = new Rectangle(0, 0, _w, _h);
                }
 
                /** Добавление новых (3) изображений */
                private function addNewImages(slotItem:SlotItem):void {
                        var image:Image;
 
                        for (var j:int = 0; j < 3; j++) {
                                image = new Image(_assetsManager.getTexture("s" + randRange(1, 9)));
                                slotItem.add(image);
                        }
                }
 
                public function get isRun():Boolean {
                        return _isRun;
                }
 
                private function randRange(minNum:Number, maxNum:Number):Number {
            return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);
        }
 
        }
}

Столбец в барабане:
Код AS3:

package  {
        import starling.display.Sprite;
        import starling.display.Image;
 
        public class SlotItem extends Sprite {
 
                /** Вектор всех изображений */
                private var _itemsVector:Vector.<Image>;
 
 
                public function SlotItem() {
                        _itemsVector = new Vector.<Image>;
                }
 
                /** Добавление новой картинки */
                public function add(image:Image):void {
                        var len:int = _itemsVector.length;
 
                        // Если уже есть 3 картинки, то распределяем их вверх от 0 координаты
                        if (len >= 3) {
                                image.y = image.height * (3 - len - 1);
                        } else {
                                image.y = image.height * len;
                        }
 
                        // Добавляем
                        _itemsVector.push(image);
                        addChild(image);
                }
 
                /** Остановка и сброс */
                public function reset():void {
                        var len:int = _itemsVector.length;
                        var image:Image;
 
                        // Первые 3 картинки удаляем
                        for (var j:int = 0; j < 3; j++) {
                                image = _itemsVector[i];
 
                                removeChild(image);
                                _itemsVector.splice(i, 1);
                        }
 
                        // Остальные сдвигаем вниз
                        for (var i:int = 2; i >= 0; i--) {
                                image = _itemsVector[i];
 
                                image.y = image.height * i;
                        }
                }
 
        }
}

P.S. Не очень уверен в правильной реализации самого вращения барабана, но лучше ничего не придумал и не нашел пока.
Если есть готовые решение, или может кто готов поделиться своими наработками, буду очень признателен.:)
Спасибо!

morgenshtern 05.05.2014 14:54

зачем вам BlurFilter? Делайте 5 столбцов, их копии, все это двигаете сверху вниз, перемещая копии и столбцы туда сюда. Никаких проседаний фпс быть не должно, писал недавно это на старлинге.

Группируйте столбцы картинок в спрайты и TweenMaxом двигайте сразу весь столбец. Вообще у меня на TweenMax (TweenNano я пробовал) действительно подтормаживало, я от него в самом начале отказался в пользу ентерфрейма. Вращение конечно получилось фпс-зависимое. Но фпс не падает, даже в моменты замены всей сотни элементов по всем барабанам и копиям.

В Texture.fromBitmap отключите generateMipMaps кстати.
А векторам всегда ставьте длину - они у адоба текут до сих пор...

alexandrratush 05.05.2014 16:30

Вложений: 1
Цитата:

зачем вам BlurFilter? Делайте 5 столбцов, их копии, все это двигаете сверху вниз, перемещая копии и столбцы туда сюда.
Так и сделал, BlurFilter добавил чтобы реалистичнее было. :)
Странно, но когда выложил флешку на свой тестовый сервер, то fps стал проседать всего на 5-10 единиц. Это нормально? Где тогда правильно?:(
Скрин:
Вложение 30847

Сборку производил в СS6.
В трейс выводит
Код:

[Starling] Initialization complete.
[Starling] Display Driver: Software (Embedded)


alexandrratush 05.05.2014 16:41

Цитата:

даже в моменты замены всей сотни элементов по всем барабанам и копиям.
Так много? У меня всего по 6 элементов в каждом столбце при вращении. А потом удаляются ненужные 3.

Вот ссылка на тестовую версию, посмотрите http://alextest.esy.es/test/baraban/

P.S. Это будет и на мобильных платформах, поэтому на что стоит обратить внимание? На FPS или DRW?

morgenshtern 05.05.2014 17:42

У меня большое поле)

Не нужно блюр. И так элементы двигаются) Каждый фильтр - это отрисовка. Если очень хочется - заблюрте в фотошопе текстуры, и подсовывайте в момент вращения.

Внимание обратить на все) DRW должно стремится к 1, 80 не приемлемо. 20 еще терпимо. Старайтесь организовывать сцену так, что бы текстуры из разных атласов не перемешивались. Т.е. например худ - один атлас. Элементы игры - второй атлас под худом.
Так же, динамические тексты добавляют отрисовку, старайтесь их тоже размещать поверх остальных картинок (если тексты нельзя заменить на спрайты, разумеется).
Кнопки с лейблами из feathers из коробки тоже добавляют отрисовки.

Цитата:

Display Driver: Software
видимо потому и быстрее, что ГПУ тормозит из-за кол-ва отрисовок) Поставьте принудительно хардварный.


Цитата:

Вот ссылка на тестовую версию
не похоже на вращение) Посмотрите как в других слотах сделано. Сначала барабаны чуть приподнять, потом по одному, ускоряя, вращать, потом начинать стопить по одному слева на право с эффектом легкого отскока. Через твинНано + события на окончание твина делается.

Astraport 05.05.2014 19:30

А filter.cache() делаете?

caseyryan 05.05.2014 19:59

А почему бы анимацию вращения заранее не отрендерить, а потом собрать старлинговские мувиклипы из кадров? Смысл делать ее реальную вообще?

alexandrratush 05.05.2014 20:01

Цитата:

не похоже на вращение)
да, я еще не доделал все, только вращение сейчас ковыряю. :)

Цитата:

А filter.cache() делаете?
Получается у меня столбцы барабана под маской, и когда я так делаю, то все невидимое очищается.

Zebestov 05.05.2014 20:14

Для начала SlotItem я бы реализовал не как Sprite с кучей дочерних Image, а как QuadBatch.

BuKT 05.05.2014 20:45

А по-моему тут проблема совсем не в движке, а в архитектуре (?).
Почему бы не пре-рендер? Запечь уже заблюренные элементы в текстуру и их крутить, не мучаясь с рантайм блюром.


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

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