如何避免在类蠕虫游戏中每帧复制关卡 Surface?
Posted
技术标签:
【中文标题】如何避免在类蠕虫游戏中每帧复制关卡 Surface?【英文标题】:How to avoid copying the level Surface every frame in worms-like game? 【发布时间】:2012-05-13 00:23:22 【问题描述】:我正在开发一款具有可破坏地形的游戏(例如在游戏 Worms 或 Scorched Earth 中)并通过遮罩使用像素完美碰撞检测。
关卡是一个单一的表面,现在它的工作方式是我每帧创建一个副本,绘制所有需要在其上绘制的精灵,然后将可见区域blit到显示表面。
有什么方法可以避免每帧复制整个关卡表面,并且仍然可以使用 pygame 中的像素完美碰撞工具?
我尝试首先对水平表面进行 blit,然后对屏幕上的每个精灵进行 blit(其 blit 坐标由相机调整,除了坐标是静态的玩家角色),但在这种情况下,碰撞检测系统会崩溃并且我似乎无法修复它。
更新
我已设法通过以下方式使其工作: 在绘制精灵时,我将它们的游戏世界坐标(基本上是相对于关卡位图原点的坐标)转换为屏幕坐标(相对于相机的坐标,这是关卡的当前可见区域)。
在碰撞检测阶段,我使用相对于水平面定位的坐标和边界框;所以就像上面一样。问题是相机的位置绑定到玩家的位置,这不是也不应该是静态值(我真的不知道我是如何设法这么长时间没有意识到这一点的)。
虽然这解决了我的问题,但下面的答案更全面地介绍了如何在这种情况下提高性能。 我也愿意接受使用其他库的建议,这些库可以使考验更容易或更快。我曾考虑过 pyglet 和 rabbyt,但看起来那里存在同样的问题。
【问题讨论】:
【参考方案1】:这是一个在图形加速器出现之前经常出现的问题,当时计算机速度很慢。您基本上希望最大限度地减少刷新屏幕所需的工作。你走在正确的轨道上,但我建议如下:
在屏幕外保留一份可用的背景副本,就像您正在做的那样 现在。
分配一个与屏幕大小相同的工作位图。
对于每个精灵,计算边界矩形(边界框) 它的新旧职位。
如果新旧边界框重叠,则合并为一个 更大的盒子。如果它们不重叠,请分开处理。
将所有边界框分组为重叠的集合。他们可能都 以一组结束(当精灵彼此靠近时),或 每个边界框可能单独在一个集合中(当精灵是 相距甚远)。
将背景复制到工作位图对应的区域 到每个边界框集。
将每个集合的精灵复制到新的工作位图中 位置(当然是正确的 z 顺序!)。
最后,将完成的离屏位图复制到显示表面, 通过设置边界框来设置边界框。
这种方法最大限度地减少了您必须进行的复制量,包括背景和精灵。如果精灵相对于显示区域较小,则节省的空间应该很大。最坏的情况是所有精灵都排列在对角线上,几乎没有相互重叠。在这种情况下,您可能希望切换到比框更通用的边界形状。以 QuickDraw Regions 为例:WikipediaDiscussionPatentSource。
现在,您可能认为将边界框分组为集合的工作是 O(n^2) 操作,您是对的。但它只随着精灵数量的平方增长。 16 个精灵意味着 256 次比较。这可能比单个 sprite blit 工作量少。
我专注于最小化像素复制工作。我必须管理员我不熟悉您的碰撞检测库的详细信息,但我明白了。希望这与我提出的算法兼容。
祝你好运。如果您完成游戏并在线发布,请在您的问题或评论中添加指向它的链接。
【讨论】:
以上是关于如何避免在类蠕虫游戏中每帧复制关卡 Surface?的主要内容,如果未能解决你的问题,请参考以下文章