Performance 使用双缓冲画布的简单动画不平滑
我尝试开发一个简单的flash游戏,使用doublebuffer绘制动画 触发Event.ENTER\u帧时会发生重画 用于双缓冲的backbuffer类型为BitmapData 动画非常简单:我在backbuffer中绘制一个20x20像素的位图,增加x坐标,这样它就可以从画布的左侧平滑地移动到右侧。这基本上运作良好,但如果你仔细观察,你会发现这一运动中出现了重大的中断。这似乎与帧速率无关,因为其持续超过60。对于动画来说,平滑移动的中断是不可接受的,但我很确定我对双缓冲没有做错,所以我担心这可能是flash播放器的问题或其他什么。。。如果不是这样的话,我会松一口气的 请查看显示简单动画的swf: (顺便说一句,当运动基于两帧之间的时间时,动画的中断也不会消失——到目前为止,它的每帧恒定2像素。) 我上传了一个非常轻量级的flash builder项目,包括上面swf的全部源代码: 非常感谢您的帮助Performance 使用双缓冲画布的简单动画不平滑,performance,actionscript-3,flash,animation,doublebuffered,Performance,Actionscript 3,Flash,Animation,Doublebuffered,我尝试开发一个简单的flash游戏,使用doublebuffer绘制动画 触发Event.ENTER\u帧时会发生重画 用于双缓冲的backbuffer类型为BitmapData 动画非常简单:我在backbuffer中绘制一个20x20像素的位图,增加x坐标,这样它就可以从画布的左侧平滑地移动到右侧。这基本上运作良好,但如果你仔细观察,你会发现这一运动中出现了重大的中断。这似乎与帧速率无关,因为其持续超过60。对于动画来说,平滑移动的中断是不可接受的,但我很确定我对双缓冲没有做错,所以我担心这
谢谢你我在chrome上运行得非常顺利,但我知道你描述的效果。我在Firefox中的一个应用程序中体验到了这一点,但我使用的是显示列表,而不是位图数据。我的问题是因为显示对象移动不到一个像素,flash对此不满意。当我将对象缩放到0.99时,它就被修复了 你可以试着画出dT,看看它是否稳定。它应该是16.6666(或0.0166),因为您是以60fps的速度运行的。如果它是波动的,则会导致enter frame事件被推回
这可能也很有用:首先,您的backBuffer很好,您只需在更新前锁定(),然后在更新后解锁()。接下来,当您可以使用位图对象时,为什么要重画图形?因此,您可以原样保留GraphicsController.enterFrame(),添加
backBuffer.lock()
和backBuffer.unlock()
在方法代码的开头和结尾调用,并且在初始化阶段使用单个位图对象,该对象将在enterFrame调用期间自动更新。应用程序的enterFrame()中的所有其他内容都将变得无用
基本上我说的是,将画布从类型形状更改为类型位图,该位图将硬链接到GraphicsController的backBuffer,并将自动更新
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));
}
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();
}