【问题标题】:How do I retain proper background on a character-based graphics system?如何在基于字符的图形系统上保留适当的背景?
【发布时间】:2020-01-02 00:29:13
【问题描述】:

我感觉很复古,并决定在我的第一台计算机 (Commodore PET 4032) 上编写我最喜欢的 8 位计算机游戏 (Williams' Defender)。所有代码都是用 6502 汇编语言完成的。对于那些不熟悉 PET 的人来说,所有的图形都是基于角色的,要构建游戏,您可以在 40 列 x 25 行的屏幕上移动不同的角色。这是一项非常古老的技术——没有精灵,没有图形层,没有我们今天习惯的屏幕级别的 AND 功能等。

我希望游戏同时发射多个“激光束”,这些激光束在穿过屏幕时可能会相互叠加。现在,当光束沿着屏幕移动时,它们会将自身下方的内容存储在内存中,然后在它们移动时替换自身下方的内容,以将背景恢复到原始状态。当第二个激光器在第一个激光器的顶部移动时,问题就出现了。第一个激光器移动并替换原始背景,而不是将第二个激光器留在顶部,然后第二个激光器移动并留下第一个激光器的伪影。

是否有一种经典的“轻量级”算法或规则集允许多个对象相互移动,从而保留下面的原始正确事物?我尝试了不同的方法(在事物遍历时交换背景等),但似乎没有什么能给我想要的正确结果。

【问题讨论】:

  • gaming.stackexchange 上提问可能会更好。在 stackoverflow 上通常不允许对软件库的建议提出问题(我相信,部分原因是它们随着技术的进步和创建意见驱动的对话而变化如此之快)请提供minimal reproducible example 并仔细检查How to Ask跨度>
  • 如果您始终以正确的顺序绘制和取消绘制所有对象,您的方法将奏效。很多游戏都是这样做的。另一种经常使用的技术是将对象异或(异或)到屏幕上,然后再次对它们进行异或以取消绘制,但这可能效果不佳,具体取决于您的分辨率和颜色映射 - 它最适合黑白。否则汤米关于重绘背景的其他建议将是标准方法。

标签: graphics 6502 commodore


【解决方案1】:

可以选择让每个精灵保留其覆盖的任何内容的副本,并让它们以与您绘制它们的顺序相反的顺序擦除自己。这不会失败,但它假设您有时间进行完整的精灵绘制并擦除每一帧。

您还可以使用屏幕大小的“是背景”和“是精灵”标志的缓冲区。每次绘制精灵时,将其角色位置标记为“是精灵”。要擦除所有精灵,遍历屏幕大小的缓冲区,在没有标记为“是背景”的任何地方重新绘制背景。如果迭代整个 2000 个潜在插槽的成本太大,您可以保持更新位置的上限和下限。

如果您只有一个视频缓冲区,您还可以比较两个此类缓冲区之间的差异以显着减少闪烁:首先绘制新的精灵,无论它们应该去哪里,并在新缓冲区中记录它们。绘制完所有精灵后,在新缓冲区未标记为“is sprite”但旧缓冲区标记为的任何位置填充背景。

【讨论】:

  • 谢谢你,汤米。这些就是我一直在寻找的想法。我应该有足够的周期来处理你第一段中的那个。
【解决方案2】:

我建议:

  • 维护一个游戏状态模型,让您可以随时重绘整个屏幕。这将包括所有可移动元素的位置和其他状态
  • 在帧之间更新游戏状态时,累积所有需要重绘的单元格的掩码,因为其中的某些内容发生了更改或移动。
  • 从上到下按深度顺序遍历游戏元素,重绘每个元素在已更改单元格掩码中的部分
  • 从更改的单元格掩码中删除您绘制的任何单元格,这样它就不会被更深的元素重写。
  • 背景将是最后一个,并将重绘所有剩余的单元格,为下一帧留下一个空蒙版。

此过程可避免因取消在单帧中绘制的任何内容而导致的任何闪烁。

可以将各种索引结构添加到更改的单元格掩码中,以避免不必要的绘图工作。此处适合进行何种优化取决于您的游戏。例如,如果背景大部分是静态的,那么在更新期间将每个更改的单元格的坐标添加到列表中会很有用,然后只在背景重绘期间检查这些单元格。或者您可以根据所有可移动元素的先前位置来执行此操作……最多 2 个。

如果大部分场景在每一帧中都发生了变化,那么您可以跳过蒙版累积,直接从全屏蒙版开始……尽管我认为 PET 可能不足以应付此类游戏。

【讨论】:

    【解决方案3】:

    由于从未为 Pet 编程过,我无法就您可以尝试什么提供任何具体建议,但我可以建议将当前屏幕背景的副本保存在大约 1k 的 RAM 中。这样,您可以在删除写入该图块的最后一个“精灵”时使用该数据来恢复您的背景。不幸的是,这还要求您将代码和对象数据的组合保持在 31k 以下,除非您将其编程为盒式磁带。只是一些想法,对于它们的价值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      • 1970-01-01
      • 2013-03-31
      • 2020-07-09
      • 1970-01-01
      相关资源
      最近更新 更多