【问题标题】:Do I need to redraw all objects on a canvas every frame?我是否需要每帧重绘画布上的所有对象?
【发布时间】:2012-06-07 15:27:44
【问题描述】:

我正在设置一个游戏循环。循环设置为以 50 FPS 更新。目前,该应用程序所做的唯一操作是在响应触摸事件时绘制屏幕坐标。最初我将绘图功能设置为仅绘制新的触摸事件。这导致文本闪烁。多个触摸事件在不同时间闪烁,这让我认为 Canvas 在幕后使用了多个页面。为了解决这个问题,我列出了发生的每个触摸事件,并在每次绘制调用时重新绘制整个列表。

如果我错了,请纠正我,lockCanvas()/unlockCanvasAndPost() 调用本质上是一个后缓冲交换。阅读有关锁定和解锁的文档听起来好像有必要在调用之间重绘整个场景,除非您使用 lockCanvas(Rect dirty)。在这种情况下,脏矩形区域需要重绘,而外部区域被保留。

unlockCanvas() 之间永远不会保留 Surface 的内容 和 lockCanvas(),因此,Surface 区域内的每个像素 必须写。此规则的唯一例外是当脏 指定了矩形,在这种情况下,非脏像素将是 保存。

我知道这听起来像是我已经回答了我自己的问题,但根据文档,Surface 永远不会在调用之间保留。然而,这并不能解释我的第一个实现的行为,即我会点击屏幕并且文本会开始闪烁。由于我只绘制了一次文本,这意味着闪烁是从交换到没有得到 drawText() 调用的“backbuffer”,以及没有被破坏但可能需要考虑的原始 Surface不可靠。

所以,问题是:我是否需要在每次绘制调用时重绘所有对象?如果是这样,我是否需要“清除”画布,或者至少也重新绘制背景图像?

【问题讨论】:

    标签: android canvas game-loop


    【解决方案1】:

    是的,除非您在定义要重绘的区域的地方进行脏重绘,否则画布上的每个点都会被破坏。

    【讨论】:

    • 感谢您的回复。关于整个过程是如何工作的,是否有更好的文档?我会认为,如果 Surface 在调用之间被破坏,那么当只有一个 drawText() 调用时,我会有一个 blip 而不是闪烁的文本。因此,要么 Surface 确实被破坏,但在相同的内存位置重新创建,这样“脏”内存看起来没有任何变化;或者,表面没有被破坏,但“应该”被认为是不可靠的,也许是因为其他一些函数可能会在锁定/解锁调用之间改变它。很高兴知道它是如何工作的。
    • 我不完全确定你想要做什么,但在我所有的手动画布绘图应用程序中,我从未见过任何闪烁。我相信双缓冲是自动处理的(我当然不必手动管理它)。每次调用 invalidate 时都会调用 onDraw 回调并重新绘制画布。我不能说 Surface * 实际上做了什么……我从来没有看过底层代码。
    • 此时我只是想更好地了解正在发生的事情。现在我通过清除画布并重绘所有内容来获得无闪烁动画。我只是好奇为什么我会从一次绘图调用中得到闪烁。我最初的假设是画布是持久的,所以理论上锁定/解锁我处理的是同一个 Surface。情况并非如此,因此锁定/解锁会带来不同的 Surface。这是我到目前为止收集到的。除了我自己的观察之外,我希望能找到关于这种行为的更好的文档。再次感谢您的帮助
    • 传递一个dirtyRect会破坏性能,因为它必须从前一个缓冲区复制内容。当然希望有办法关闭双缓冲..
    猜你喜欢
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    • 1970-01-01
    • 2017-03-19
    相关资源
    最近更新 更多