经典的侧面滚动器如何实现定时事件和动画触发器?

时间:2010-11-12 21:51:30

标签: graphics assembly

我一直对Snes的超级马里奥系列感到惊讶。我认为它主要是在Z80组装中制作的。但由于没有实时时钟,他们究竟如何管理所有那些定时的动画事件,而且没有实时时钟?

由于

4 个答案:

答案 0 :(得分:5)

要记住的一个重要概念是VSync速率。这是电视中的电子枪(或现代电视中的等效电子枪)完成绘制屏幕的频率,然后慢慢地移动到屏幕顶部。

因为这是以恒定速率发生的(NTSC为60次/秒,PAL为50次),大多数游戏都使用此作为计时器,代码大致相当于:

void main() {
    while(true) {
        updateGame();
        updateSprites();
        waitForVSync();
    }
}

显然,这是非常简化的,但这就是正在发生的事情。有些游戏太复杂了,花了太长时间而错过了VSync时期。在这种情况下,他们会等待第二个VSync,因此以30(/ 25)FPS运行。

有时,你会注意到NES游戏的速度减慢(例如)。这是当工作负载太重以至于在单个操作帧中缺少几个VSync周期时。

但是,是的,这就是老式控制台时机如何工作的要点(实际上,即使是许多新的游戏机和PC游戏也使用相同的系统,而不仅仅是旧游戏机!)

答案 1 :(得分:2)

旧硬件上使用的一种非常常见的技术是依赖于用于显示图形的相同计时硬件。旧硬件通过读取存储器中的像素值并将其输出到端口上,以及一些“同步”信号来控制扫描电子枪,从而将数据从其图形端口(复合视频或更常见的RF)中流出。电视。

好的一点是,垂直同步信号,即使枪从屏幕底部摆动到顶部的垂直同步信号,通常连接到控制台CPU上的硬件中断,就在那一刻,这种情况恰好发生在每秒29.97次(几乎30fps),此时根本没有数据通过视频发送,因为光束需要一段时间才能“飞回”到屏幕顶部。当时在视频内存中所做的更改将是无闪烁的!

答案 2 :(得分:2)

游戏,然后就像现在一样,通常运行一个固定的时间步循环(参见Mike Carons的回答)。最初,这主要是为了方便;您的渲染无论如何都要同步到显示刷新率以避免撕裂,也可以每帧执行一次基于时间的处理。

如今,大多数游戏仍然以离散步长推进时间,这是一些基本速率的倍数,通常为50/60 Hz或类似100 Hz - 有些游戏仍然具有基于VSync的时序,但大多数只是使用常规计时器现在。现在我们使用固定时间步骤的原因略有不同:首先,游戏通常至少有一定数量的物理模拟正在进行,而且很难通过可变时间步长稳定地进行物理模拟 - 特别是在游戏这样的实时应用程序中通过使用更精确的集成方法等,不能轻易地为其投入更多的计算能力。其次,如果您有任何类型的联网多人游戏模式,您需要确保游戏与所有玩家保持同步。如果每个人都在不同的计时器上并以不同的速率处理事件,则几乎不可能管理(和调试)。强制每个人使用一个共同的时间步长使问题几个数量级更容易管理,因为你可以安全地假设两个开始处于相同状态并获得相同输入的玩家在5秒后仍将处于相同的状态,即使玩家可以看到不同的东西或拥有不同的机器,所有这些都会影响游戏运行的实际帧速率(因此也会影响游戏处理事件的速度)。

答案 3 :(得分:0)

Z80支持许多硬件中断 - 其中一个可能连接到周期性定时器(例如,每10ms)。一些早期的游戏控制台有与电视扫描刷新相关的时间,所以这可能已被连接起来。我不知道SNES,所以我根据当代其他系统的运作方式进行推测。

维基百科称SNES是一个16位系统,因此它不是Z80,即8位。 实际上它说它是65c816

http://en.wikipedia.org/wiki/Super_Nintendo_Entertainment_System

(上面的链接讨论了视频同步中断,所以我可能在正确的界限上假设你对实时时钟是正确的)