Flex/Flash/AS3中的Vsync是什么?

9
我正在制作一个有许多移动物体(如子弹等)的2D射击游戏。
我使用BitmapData.copyPixels(...)将整个屏幕渲染到缓冲区:BitmapData。然后我从“缓冲区”复制到屏幕:BitmapData。帧率为60。
private var bitmap:Bitmap = new Bitmap();
private var buffer:Bitmap = new Bitmap();

private function start():void {
    addChild(bitmap);
}

private function onEnterFrame():void {
    // render into "buffer"
    // copy "buffer" -> "bitmap"
}

问题在于精灵被撕裂了:某些部分的精灵被水平移动了。
看起来像是关闭VSYNC的PC游戏。
有人解决了这个问题吗?
更新:问题不是关于性能,而是关于消除屏幕撕裂。
[!] 更新:我创建了另一个问题,在这里您可以尝试使用Flash方式或BitmapData+copyPixels()实现两种方法。

其他人说得没错,这种方法并不适合Flash Player...但我很惊讶,它根本不起作用...几个问题:-你尝试过锁定正在绘制的bitmapData吗?(如果没有,这可能会有很大帮助!)-你是否使用透明位图?(一般性能杀手)-你尝试过Stage::invalidate和在Event.RENDER上渲染而不是渲染吗?问候back2dos - back2dos
锁定/解锁没有帮助,因为将“缓冲区”->“位图”复制会产生单个事件,因此在两种情况下都是相同的单个通知。 我确实使用透明位图来进行抛射物 - 但是,问题不在于性能,而在于屏幕撕裂。 我尝试过: *在ENTER_EVENT中准备“缓冲区”+ stage.invalidate(),然后 *在RENDER事件中将“缓冲区”->“位图”复制 相同的结果(屏幕撕裂),但更高的CPU消耗(我猜是因为stage.invalidate()触发的事件)。 - oshyshko
屏幕撕裂与性能有关。这是解决撕裂的唯一方法。 - Kekoa
3
@Kekoa,我不能同意。性能与屏幕撕裂无关,因为我使用双缓冲技术。如果性能较差,我可能会获得更低的FPS,但不会出现屏幕撕裂。 - oshyshko
3个回答

7

我深有同感,因为我目前也在开发自己的游戏中。默认设置下,Flash渲染器会产生可怕的屏幕撕裂/垂直同步问题,无论你编写什么代码都是如此。

这就是我很高兴能找到最简单、最优雅的解决方案的原因,而不需要重新编写代码(这一点没有任何帮助,问题在于Flash播放器,而不是代码)。

只需在发布设置中启用硬件加速。有两个不同的选项:

级别1:直接;和级别2:GPU

在官方文档中了解更多信息:指定SWF文件的发布设置,并决定哪个选项最适合您的游戏。

目标市场在这里确实起到了作用,如果这是一个专业玩家的严肃游戏,您不需要担心可能存在的性能问题,因为大多数玩家都有GPU。

这篇文章并没有为我提供具体的解决方案,但引导我找到了正确的方向。但是,如果您的游戏将在浏览器窗口中运行,您可能还需要使用设置Wmode为直接或GPU的相同技术。


你知道是否有一个可以为此指定元数据标签属性的方法吗?(适用于FlashDevelop AS-only游戏,不需要FLAs)。类似这样的东西:[SWF(hardwareAcc="gpu")] 是否存在? - chamberlainpi
我所知道的另一个参数是wmode,它可以在嵌入Flash文件的html文件中设置。我相信一定有办法可以在没有Flash IDE的情况下实现这一点。 - Daniel Carvalho
结论是什么?这确实是Flash播放器的问题,我们无法做任何改进吗? - Huang F. Lei
嗯,是的和不是的。如果在Flash中不启用某种硬件加速,屏幕撕裂将会发生。如果启用它,Flash将会渲染得很好。 - Daniel Carvalho
即使使用了一些硬件加速渲染,仍然可能出现撕裂。我尝试在60fps下使用Context3D,并使用context.clear(随机颜色)进行测试。撕裂依然存在,但比之前明显改善了一点。 - ansiart
这篇关于编程的文章 http://active.tutsplus.com/tutorials/animation/quick-tip-fixing-v-sync-tearing-issues-in-flash/ 对我帮助很大。它告诉你在HTML中将wmode设置为direct。 - Frank

-4

你可能想要做的第一件事是停止将Flash Player视为DOS。Flash Player本身就是一个高度优化的2D游戏引擎,我真的不明白为什么你要通过复制大量位图切片来重新发明轮子。当然,你会遇到性能问题。

Flash Player不允许你同步任何垂直或水平空白,因为Flash Player根本没有这个概念。

如果你想要“更流畅”的动画,我个人认为你应该重新考虑你的方法。Flash Player肯定有这个能力,你只是采用了错误的方法。


2
奇怪的是,在内存中复制字节块(位图)应该比使用数学计算渲染更容易。Flash 中存在“cacheAsBitmap”的原因应该是有其道理的。另外,请查看此链接:http://aralbalkan.com/759 - oshyshko
你的Sprites(DisplayObject)根本不必是矢量图。Flash Player已经针对此进行了优化。当你开始使用位图在ActionScript中重新创建Flash Player已经非常擅长并且已经进行了优化的内容时,那么你就错过了重点。我认为你应该多读Tinic Uro博客:http://www.kaourantin.net - Luke
2
@Luke:如果你提供了一个实用的替代方案,而不仅仅是说原始方法是错误的,那么你的答案会更有用。在制作2D游戏的背景下,有几个在线资源建议使用位图和copyToPixels,所以这不是原帖作者在重新发明轮子。 - Kylotan

-5

不要将东西保存到BitmapData中,那会让你的应用程序崩溃,绝对会崩溃。BitmapData的性能并不是很好。

在Flash中制作所有游戏元素,使用Sprites(如果必须使用MovieClips),然后按照Flash的设计方式工作,作为一个矢量动画平台。它从未针对2D位图图形进行优化。 2D矢量图形效果良好,即使导入位图,它们移动起来也比渲染到BitmapData对象中要好。


如果我放弃使用缓冲并将位图作为本地Flash精灵(仍然是位图),那么它会解决VSYNC问题吗? - oshyshko
不,它不会。但是它看起来比你目前拥有的要好得多。正如我在回答你的问题时所说,Flash Player没有垂直同步的概念。当您将fps设置为60(这很荒谬,但这不是重点)时,Flash Player将尝试生成60 fps。实际上,它几乎永远无法做到这一点。 - Luke
1
我发现在某些情况下,使用Bitmapdata可以提高性能。 - Matt W
@Matt 但是你的整个应用程序每帧都渲染到一个BitmapData对象中?这真的是一个糟糕的想法。我并不是说BitmapData没有用处。 - Kekoa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接