Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Оптимизация эффекта "хвоста кометы" (http://www.flasher.ru/forum/showthread.php?t=205910)

PainKiller 29.12.2013 19:04

Оптимизация эффекта "хвоста кометы"
 
В общем ситуация такая, есть мобильный проект на Box2D, в нем есть шар - снаряд, который управляется физикой. Решил применить к нему вот этот эффект, естественно пример приведенный там, перевел на ООП, получился такой класс:
Код AS3:

/**
 * http://www.FreeActionScript.com
 **/

package effects
{
        import flash.display.Bitmap;
        import flash.display.BitmapData;
        import flash.display.DisplayObjectContainer;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
        import flash.filters.BlurFilter;
        import flash.geom.ColorTransform;
        import flash.geom.Point;
        import flash.geom.Rectangle;
        import game.*;
 
        public class BlittTrailer extends Sprite
        {
                // canvas bitmap data var
                private var canvasBitmapData:BitmapData;
 
                // canvas bitmap - this will be added to the display list
                private var canvas:Bitmap;
 
                // canvas rectangle - used to save canvas size
                private var canvasRect:Rectangle;
 
                // circle (trailer) bitmap data
                private var circleBitmapData:BitmapData;
 
                // circle rectangle - used to save canvas size
                private var circleRect:Rectangle;
 
                // color transformer - used to make cavas transparent
                private var colorTransform:ColorTransform;
 
                private var _parent:DisplayObjectContainer;
                private var _ball:BallActor;
 
                public function BlittTrailer(parent:DisplayObjectContainer, ball:BallActor)
                {
                        _parent = parent;
                        _ball = ball;
                        init();
                }
 
                public function init():void
                {
 
                        // create main canvas bitmap data
                        canvasBitmapData = new BitmapData(Main.screenX, Main.screenY, true, 0x333333);
                        canvas = new Bitmap(canvasBitmapData);
                        _parent.addChild(canvas);
                        canvasRect = canvasBitmapData.rect;
                        // create circle trailer bitmap data
                        circleBitmapData = new BitmapData(10, 10, true, 0xFFFFFF);
                        // draw CircleTrailer movieclip, linked from library, inside circle bitmap data
                        circleBitmapData.draw(new CircleTrailer());
                        // save circle rectangle size
                        circleRect = canvasBitmapData.rect;
                        // create ColorTransformer to modify alpha of bitmap
                        colorTransform = new ColorTransform();
                        // (make it 99% transparent)
                        colorTransform.alphaMultiplier = .99;
                }
 
                public function removeTrailer():void
                {
                        _parent.removeChild(canvas);
                }
 
                public function render():void
                {
                        // lock bitmap data to prevent display from updating while we modify it
                        canvasBitmapData.lock();
                        // change alpha
                        canvasBitmapData.colorTransform(canvasRect, colorTransform);
                        // draw circle
                        canvasBitmapData.copyPixels(circleBitmapData, circleRect, new Point(_ball.ball.x - 5, _ball.ball.y - 5), null, null, true);
                        // apply blur filter
                        canvasBitmapData.applyFilter(canvasBitmapData, canvasBitmapData.rect, new Point(0, 0), new BlurFilter(8, 8)); //3, 3
                        // unlock bitmap data
                        canvasBitmapData.unlock();
                        if (!_ball.ball.stage)
                                _parent.removeChild(canvas);
                }
 
        }
}

где _parent - контейнер где идет вся игра, _ball - шар к которому применяется спецэффект. Визуально все работает как надо, но повторяю проект мобильный и фпс при появлении на сцене такого снаряда падает в 2 раза. Как оптимизировать не знаю, буду рад любым идеям.

Добавлено через 41 секунду
И да - аппаратное ускорение пока не используется.

Добавлено через 14 минут
Сейчас попробовал включить
Код:

<renderMode>gpu</renderMode>
абсолютно ничем не помогло, только некоторые фильтры слетели(((

samana 29.12.2013 19:26

А битмпаДата сильно большая?
Первое, что врезалось в глаза, это постоянное создание фильтра blur. Лучше создайте его отдельно, а потом применяйте. И некоторые точки тоже можно создать и использовать по кругу.

PainKiller 29.12.2013 20:45

битмапДата 480 х 800, за подсказку с фильтром спасибо, не углядел, но ситуацию это не сильно изменило, фпс все равно около 10 - 15

Добавлено через 58 секунд
попробую уменьшить размер битмапдаты, может это выправит ситуацию

Akopalipsis 29.12.2013 20:54

Воспользуюсь моментом и задам вопрос, который меня волнует с того момента, как я впервые увидел вот эти эффекты от Starling - их в обычных проектах использовать можно?

in4core 29.12.2013 23:04

PainKiller сам писал такой эффект недавно, просто поиграться. Производительность на уровне, даже на очень слабых машинах, выдает макс фпс.
Вот как я делал его, просто костяк. Если будет нужно, буду на работе выкину фул вершн, с эффекторами и т.п. :

Код AS3:

package com.in4core.utils 
{
        import com.greensock.TweenMax;
        import flash.display.Bitmap;
        import flash.display.BitmapData;
        import flash.display.DisplayObject;
        import flash.display.Stage;
        import flash.events.MouseEvent;
        /**
        * ...
        * @author in4core progression lab
        */

        public final class FlexObject
        {
                static private var _flexBitmapData:BitmapData;
                static private var _stage:Stage;
 
                public function FlexObject()
                {
 
                }
 
 
                public static function setInParams(stage:Stage , lifeTime:int = 50):void
                {
                        _stage = stage;
                }
 
                public static function startFlex():void
                {
                        _stage.addEventListener(MouseEvent.MOUSE_MOVE , onMove);
                }
 
                static private function onMove(e:MouseEvent):void
                {
                        var bmp:Bitmap = getMouseFlexBitmap();
                        _stage.addChild(bmp);
                        bmp.x = e.localX - bmp.width / 2;
                        bmp.y = e.localY - bmp.height / 2;
 
                        var randX:Number = Math.random() * 160 - 80;
                        var randY:Number = Math.random() * 160 - 80;
 
                        TweenMax.to(bmp, 1 , { alpha:0 , x:bmp.x + randX , y:bmp.y + randY , scaleX:3 , scaleY:3, blurFilter: { blurX:4 , blurY:4 } ,  onComplete:removeTarget , onCompleteParams:[bmp] } );
                }
 
                static private function removeTarget(target:Bitmap):void
                {
                        _stage.removeChild(target);
                }
 
                public static function createFlex(obj:DisplayObject):void
                {
                        _flexBitmapData = new BitmapData(obj.width, obj.height, true, 0);
                        _flexBitmapData.draw(obj);
                }
 
                private static function getMouseFlexBitmap():Bitmap
                {
                        return new Bitmap(_flexBitmapData);
                }
        }
 
}


PainKiller 30.12.2013 10:25

Спасибо, попробую этот вариант + на работе пройдусь по проекту скаутом, о результатах отпишусь.

Добавлено через 2 часа 45 минут
К сожалению у меня нет возможности подрубиться к скауту с мобильного через вайфай, поэтому смотрел с настольного ПК, запуская приложение в айр дебаг лончере. Итог таков - ф-ция render выполняется за 60 мс, львиную нагрузку в ней выполняют
canvasBitmapData.colorTransform(canvasRect, colorTransform);
canvasBitmapData.applyFilter(canvasBitmapData, canvasBitmapData.rect, new Point(0, 0), new BlurFilter(8, 8));
колортрансформ вынес в ф-цию init, скорость функции render возросла до 8 мс, но при запуске на мобиле никакой разницы я не ощутил. Придется попробовать версию in4core, хотя че то я на нее смотрю и у меня сомнения берут, что она будет более производительной, твинить блер-фильтры это ресурсоемко.

in4core 30.12.2013 13:20

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

samana 30.12.2013 15:40

Цитата:

Сообщение от PainKiller (Сообщение 1156220)
колортрансформ вынес в ф-цию init, скорость функции render возросла до 8 мс

Но тогда эффект исчезновения уже не будет срабатывать.

PainKiller 30.12.2013 17:30

Цитата:

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

samana 30.12.2013 17:36

Именно после своих сомнений, я проверил и - не работает)
А как же оно может срабатывать, если строчка
Код AS3:

canvasBitmapData.colorTransform(canvasRect, colorTransform);

выполниться только один раз в методе init? Ведь надо постоянно применять colorTransform к canvasBitmapData.
Ну ладно, чудеса да и только.


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

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