【问题标题】:Simple animation using doublebufferd canvas is not smooth使用双缓冲画布的简单动画不流畅
【发布时间】:2012-09-01 08:44:34
【问题描述】:

我尝试开发一个简单的 Flash 游戏,使用双缓冲区来绘制动画。

重绘发生在 Event.ENTER_FRAME 被触发时。

用于双缓冲的后缓冲是 BitmapData 类型。

动画非常简单:我在后台缓冲区中绘制了一个 20x20 像素的位图,随着 x 坐标的增加,它应该从我的画布的左侧平滑地移动到右侧。这基本上可以正常工作,但是如果您仔细观察,您会发现此运动存在重大中断。这似乎与帧速率无关,因为它一直超过 60。平滑移动的中断对于动画来说是不可接受的,但我很确定我在双缓冲方面没有做错任何事情,所以我我害怕这可能是 Flash 播放器的问题或什么的......如果不是这种情况,我会非常放心

请看一下显示简单动画的 swf:

https://dl.dropbox.com/u/55967135/test.swf

(顺便说一句,当移动基于两帧之间的时间时,动画的中断也不会消失 - 现在每帧恒定 2 个像素。)

我上传了一个非常轻量级的 flash builder 项目,包括上面 swf 的完整源代码: https://dl.dropbox.com/u/55967135/test.zip

    public function enterFrame():void               
      {

           // Calculate the time since the last frame  (NOT USED IN THE EXAMPL PROGRAM)                   
           var thisFrame : Date = new Date();               
           var dT : Number = (thisFrame.getTime() - lastFrame.getTime())/1000.0;               
           lastFrame = thisFrame;          

           // erase backBuffer
           backBuffer.fillRect(backBuffer.rect, 0xFFFFFFFF);


           // set new postion of the small testimage
           if (this.pos > 600 || this.pos < 0) {
                this.direction = !this.direction;
           }

           // increase / decrease vertical position
           if (this.direction) {
                this.pos += 2;
           } else {
                this.pos -= 2;
           }

           //trace(pos);
           // draw small test image at postion "offset"
           backBuffer.copyPixels(     this.testGraphic.bitmap.bitmapData, 
                                         this.testGraphic.bitmap.bitmapData.rect, 
                                         new Point(pos, 0.0));               
      }

enterFrame() 是我的 GraphicsController 类的一个方法,它处理双缓冲。它由应用程序的 enterFrame(event) 方法启动:

        public function enterFrame(event:Event):void
           {
                GraphicsController.Instance.enterFrame();     
                myCanvas.graphics.clear();
                myCanvas.graphics.beginBitmapFill(GraphicsController.Instance.backBuffer, null, false, false);                              
                myCanvas.graphics.drawRect(0, 0, this.width, this.height);                              
                myCanvas.graphics.endFill();
                stage.invalidate();
           }  

非常感谢您的帮助

谢谢

【问题讨论】:

    标签: performance actionscript-3 flash animation doublebuffered


    【解决方案1】:

    在 Chrome 上运行对我来说非常流畅,但我知道你描述的效果。我在 Firefox 中的一个应用程序中体验过它,但我使用的是显示列表而不是位图数据。我的问题是因为将显示对象移动了不到一个像素,而 flash 对此并不满意。一旦我将对象缩放到 0.99,它就被修复了。

    您可以尝试绘制 dT 并查看它是否稳定。它应该是 16.6666(或 0.0166),因为您以 60fps 的速度运行,如果它在波动,那么某些东西会导致输入帧事件被推回。

    这也可能有用:http://www.craftymind.com/2008/04/18/updated-elastic-racetrack-for-flash-9-and-avm2/

    【讨论】:

      【解决方案2】:

      首先,您的 backBuffer 没有问题,您只需在更新之前对其进行 lock(),然后在完成更新后对其进行 unlock()。接下来,当您可以使用 Bitmap 对象时,为什么要重绘图形?因此,您保留 GraphicsController.enterFrame() 原样,在方法代码的开头和结尾添加 backBuffer.lock();backBuffer.unlock(); 调用,并在初始化阶段使用单个 Bitmap 对象,该对象将在enterFrame 调用。应用程序的 enterFrame() 中的其他所有内容都将变得无用。

      基本上我所说的是将你的画布从 Shape 类型更改为 Bitmap 类型,该位图将硬链接到 GraphicsController 的 backBuffer 并将自动更新。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-27
        • 2019-07-15
        • 2013-11-30
        • 2019-07-23
        • 2020-04-01
        • 1970-01-01
        • 2016-09-07
        相关资源
        最近更新 更多