模仿老派雪碧闪烁(理论和概念)

Jef*_*ern 20 graphics xna animation sprite

我正在尝试开发一个老式的NES风格的视频游戏,精灵闪烁和图形减速.我一直在想我应该用什么类型的逻辑来启用这样的效果.

如果我想要老式的NES风格,我必须考虑以下限制:

  • 屏幕上一次不超过64个精灵
  • 每条扫描线不超过8个精灵,或者Y轴上的每条线都不超过8个精灵
  • 如果屏幕上有太多动作,系统将图像冻结一帧以让处理器赶上动作

从我读过的内容来看,如果屏幕上有超过64个精灵,开发人员只会绘制高优先级精灵而忽略低优先级精灵.它们也可以交替,在奇数编号的相对帧上绘制每个偶数编号的精灵.

扫描线问题很有意思.从我的测试来看,通过像NES那样逐个像素地绘制精灵,不可能在XBOX 360 XNA框架上获得良好的速度.这就是为什么在老式游戏中,如果在一条线上有太多的精灵,如果它们被减半,就会出现一些.对于这个项目的所有目的,我将扫描线设置为8像素高,并通过Y定位将每个扫描线的精灵分组在一起.

为了澄清,我将以8x8像素,而不是1x1的批量绘制精灵到屏幕.

所以,愚蠢的我需要提出一个解决方案....

  • 一次在屏幕上显示64个精灵
  • 每个'scanline'有8个精灵
  • 可以根据优先级绘制精灵
  • 每帧可以间隔精灵
  • 模拟减速

这是我目前的理论

首先,我提出的一个基本想法是解决精灵优先级问题.假设0-255(0为低)之间的值,我可以分配精灵优先级,例如:

  • 0到63低
  • 63至127为中等
  • 128到191很高
  • 192到255是最大的

在我的数据文件中,我可以将每个精灵分配为特定优先级.创建父对象时,精灵将在其指定范围之间随机分配一个数字.然后我会按照从高到低的顺序绘制精灵,最终目标是绘制每个精灵.

现在,当一个精灵被绘制在一个帧中时,我会在其初始优先级内随机生成一个新的优先级值.但是,如果没有在帧中绘制精灵,我可以将32添加到其当前优先级.例如,如果该系统可只画出精灵下降到135的优先级,具有45°的初始优先级的子画面然后可以后不被抽的3帧绘制(45 + 32 + 32 + 32 = 141)

理论上,这将允许精灵交替帧,允许优先级,并将精灵限制为每个屏幕64个.

现在,有趣的问题是我如何将精灵限制为每个扫描线只有8个?

我想如果我将精灵高优先级排序为低优先级,则循环遍历循环直到我达到64个精灵.但是,我不应该只列出列表中的前64个精灵.

在绘制每个精灵之前,我可以通过计数器变量检查在它的相应扫描线中绘制了多少个精灵.例如:

  • 0到7之间的Y值属于扫描线0,scanlineCount [0] = 0
  • 8到15之间的Y值属于Scanline 1,scanlineCount [1] = 0
  • 等等

我可以为每个绘制的帧重置每条扫描线的值.在向下精灵列表的同时,如果在该扫描线中绘制了精灵,则向扫描线的相应计数器添加1.如果它等于8,则不绘制该精灵并转到具有下一个最低优先级的精灵.

慢一点

我需要做的最后一件事是模拟减速.我最初的想法是,如果我每帧绘制64个精灵并且还需要绘制更多的精灵,我可以将渲染暂停16ms左右.然而,在我玩过的NES游戏中,如果没有任何精灵闪烁,有时会减速,而即使有一些精灵闪烁,游戏也会漂亮地移动.

也许为每个在屏幕上使用精灵的对象赋予一个值(比如上面的优先级值),如果所有对象的组合值都超过阈值,那么引入减速?

结论...

我写的所有内容听起来是否合法且可行,或者它是一个白日梦吗?我可以用这个游戏编程理论思考哪些改进?

Dan*_*ath 3

首先,我喜欢这个主意。在制作复古游戏时,如果忽略复杂性限制,情况就不一样了。通过编写一个强制执行的框架是一个主意。

我只能说,如果您将引擎抽象为开源“复古游戏”图形引擎,那确实很酷,我一定会加入!

  • 对于最高优先级的精灵,也许优先级队列可以简化这部分,因为您可以只取出 64 个最高优先级的精灵。

  • 随着减速,也许在引擎中你可以有一个limitValue. 每个精灵作为一个适当的limitUse。将所有变量加起来limitUse,如果低于limitValue,则不会减慢速度。现在,其中slowDelay = f(limitUseTotal - limitValue)f 是一个函数,它将多余的精灵数量转换为计算出的减速值。这是您建议的总体想法还是我误读了?