首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AS3闪电战比移动闪电战慢。为什么?

AS3闪电战比移动闪电战慢。为什么?
EN

Stack Overflow用户
提问于 2013-08-30 17:27:48
回答 1查看 1.5K关注 0票数 0

我试着遵循Lee的闪电战教程系列以及Rex Van der spuy的“闪光灯高级游戏设计”的技巧。

我是一个开发人员,致力于一个网上虚拟世界制造的闪光灯。我做了一个电话应用程序(类似于手机在大盗窃罪汽车游戏)。不管怎么说,当一个消息被发送时,我们想要播放这个疯狂的动画,一个信封在周围飞来飞去,在周围闪烁着火花。这是一个滞后(特别是在旧电脑),所以我认为这将是一个很好的机会使用闪电战。然而,闪电战动画的播放速度实际上比常规电影慢!这到底是怎么回事?闪电战只对移动设备更好,在计算机上更慢吗?也许我做错了什么。这是我的代码:

//这部分发生在电话IT初始化时

代码语言:javascript
复制
//**                
//---------------- Blitting stuff ----------------------------------
// add this bitmap stage to the display list so we can see it
            _bitmapStage = new BitmapData(550, 400, true, 0xD6D6D6);


        _phoneItself.addChild(new Bitmap(_bitmapStage));

        var _spritesheetClass:Class = getDefinitionByName("ESpritesheet_1") as Class;
        _spritesheet = new _spritesheetClass() as BitmapData;

        _envelopeBlit = new BlitSprite(_spritesheet, BlitConfig.envelopeAnimAry , _bitmapStage);
        _envelopeBlit.x = -100;
        _envelopeBlit.y = 0;

        _envelopePlayTimer = new Timer(5, 0);
        _envelopePlayTimer.addEventListener(TimerEvent.TIMER, onEnterTimerFrame);
        _envelopeBlit.addEventListener("ENV_ANIM_DONE", onEnvAnimFinished);

// a "BlitSprite“是我做的一个类。看起来是这样的:

代码语言:javascript
复制
package com.fs.util_j.blit_utils
{
    import flash.display.BitmapData;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.geom.Point;
    import flash.geom.Rectangle;

    public class BlitSprite extends EventDispatcher
    {

        private var _fullSpriteSheet:BitmapData;
        private var _rects:Array;
        private var _bitmapStage:BitmapData;

        private var pos:Point = new Point ();
        public var x:Number = 0;
        public var y:Number = 0;

        public var _animIndex:

int =0,私有变量_count:int = 0;

代码语言:javascript
复制
    public var animate:Boolean = true;
    private var _whiteTransparent:BitmapData;
    private var _envelopeAnimAry:Array;
    private var _model:Object;



    public function BlitSprite(fullSpriteSheet:BitmapData, envelopeAnimAry:Array, bitmapStage:BitmapData, model:Object = null) 
    {
        _fullSpriteSheet = fullSpriteSheet;
        _envelopeAnimAry = envelopeAnimAry;
            _bitmapStage = bitmapStage;
            _model= model;

            init();
        }

        private function init():void
        {
//          _whiteTransparent = new BitmapData(100, 100, true, 0x80FFffFF);

            this.addEventListener("ENV_ANIM_DONE", onEvnAnimDone);

        }       

        protected function onEvnAnimDone(event:Event):void
        {

        }       

        public function render():void
        {

//          pos.x = x - _rects[_animIndex].width*.5;
//          pos.y = y - _rects[_animIndex].width*.5;

//          if (_count % 1 == 0 && animate == true)
//          {

//              trace("rendering");

                if (_animIndex == (_envelopeAnimAry.length - 1) )
                {
//                  _animIndex = 0;
                    dispatchEvent(new Event("ENV_ANIM_DONE", true));
                    animate = false;
//                  trace("!!!!animate over " + _model.animOver);

//                  if (_model != null)
//                  {
//                      _model.animOver = true;
//                  }

//                  trace("!!!!animate over " + _model.animOver);

                }

                else 
                {
                    _animIndex++;
                }


                pos.x = x + _envelopeAnimAry[_animIndex][1];
                pos.y = y + _envelopeAnimAry[_animIndex][2];


                _bitmapStage.copyPixels(_fullSpriteSheet, _envelopeAnimAry[_animIndex][0], pos, null, null, true);

        }



    }
}




// THIS PART HAPPENS WHEN PHONE'S SEND BUTTON IS CLICKED


                _envelopeBlit.animate = true;
                _envelopeBlit._animIndex = 0;
                _darkSquare.visible = true;
                _envelopePlayTimer.addEventListener(TimerEvent.TIMER, onEnterTimerFrame);
                _envelopePlayTimer.start();

它还使用BlitConfig,它存储有关TexturePacker所吐出的spritesheet的信息。

代码语言:javascript
复制
    package com.fs.pack.phone.configuration
    {
        import flash.geom.Rectangle;

        public final class BlitConfig
        {




            public static var _sending_message_real_20001:Rectangle = new Rectangle(300,1020,144,102);
            public static var _sending_message_real_20002:Rectangle = new Rectangle(452,1012,144,102);
            public static var _sending_message_real_20003:Rectangle = new Rectangle(852,852,146,102);
            public static var _sending_message_real_20004:Rectangle = new Rectangle(2,1018,146,102);
            public static var _sending_message_real_20005:Rectangle = new Rectangle(702,822,148,102);
.
.
.
public static var _sending_message_real_20139:Rectangle = new Rectangle(932,144,1,1);

    public static var envelopeAnimAry:Array = [

                // rectangle, x offset, y offset
            [ _sending_message_real_20001, 184,155],
            [ _sending_message_real_20002, 184,155],
            [ _sending_message_real_20003, 183,155],
            [ _sending_message_real_20004, 183,155],
.
.
.
[ _sending_message_real_20139, 0,0]
        ]



        public function BlitConfig()
        {
        }


    }
}
EN

回答 1

Stack Overflow用户

发布于 2013-08-30 17:53:52

编辑:知道这不是移动的,我下面的答案是不相关的。不过,我会把它留在那里,以防将来有人在闪电战中遇到麻烦。

关于这个特定的问题,你每5ms运行一次计时器。首先,计时器准确的最低范围是>15 is,所以这永远不是一个可行的解决方案。对于任何与在舞台上显示时间有关的计时器,都不应该比单个帧做得更少。(1000/stage.framerate.~40 app的30 app应用程序)

对于闪电战,目标是减少计算和渲染。按照你现在设置的方式,看起来你每隔5毫秒就会闪动一次。这实际上是MovieClip渲染频率的8倍以上。你应该减少你的blit频率。只有当一个改变实际上已经超出了翻译的范围时,才能这样做。这样做的频率比这要高,其原因是速度太慢(同样,创建位图也很慢)。

通常,您不希望在AIR for Mobile应用程序中使用blit (我假设您是这样做的,因为您提到了正在初始化的电话)。我不确定使用其他/本机SDK是否可以这样做,但要避免在空气中使用。

本质上,这取决于闪电战是如何运作的。闪电战采取屏幕截图,并显示在舞台上,而不是实际的对象。总的来说,这是很棒的。这意味着您的显示对象,特别是渲染速度慢的向量,必须少得多地呈现。这是特别好的动画,因为一个对象倾向于重新呈现每一次它是以任何方式,但不是一个位图。

然而,在移动平台上,创建位图非常缓慢。我从来没有研究过SDK是如何创建位图的,但是它并没有高效地创建位图(它常常让我怀疑它是否做到了逐像素)。在台式机上,这通常是好的。有足够的CPU和大量的RAM来使这种情况迅速发生。然而,在手机上,这种奢侈目前并不存在。因此,当您创建和创建位图时,运行该进程需要一段时间。

这个问题在高分辨率屏幕上更加严重。我在今年1月至5月开发了一个应用程序,在GPU加速环境中有选择地使用闪存来使用过滤器。在iPad 2上,闪电战使我的应用程序从30 app到24 app。没什么大不了的,用户不会注意到的。然而,在带有视网膜显示器的iPad 3上,它下降到10 iPad。当你想到它的时候,这是有意义的,因为视网膜iPads的像素是非视网膜iPads的4倍。

如果你真的想在手机上使用闪电战,我建议以下几点:

  1. 使用GPU渲染模式。没有它,你就没有机会。请注意,至少在空气前3.7中,GPU模式不支持过滤器.我不知道情况是否仍然如此。不过,您应该避免在移动设备上使用过滤器,因为它们呈现速度非常慢。
  2. 确保测试发布模式应用程序。根据构建设置,调试模式和发布模式应用程序之间的差别可能很大,特别是在iOS上。我刚刚开发的一个应用程序从2到3秒,在调试模式下创建了一个新的Flex View,在iPhone 4上用不到一个框架(~40 on )来完成它。
  3. 少用闪电战。只有在绝对必要的情况下才能做
  4. 寻找简化显示列表的方法。有一个有40个子对象的对象很容易创建一个按钮。相反,寻找方法将其简化为更少的对象和更少的过滤器(即使删除筛选器需要添加另一个对象)。我不相信这将有助于实际的闪电战过程,但它应该有助于渲染对象的第一。

因此,一般来说,在移动设备上使用闪存,因为位图创建是缓慢的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18538415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档