行。 我正在尝试对NES硬件进行自己的解释,因此我可以制作一款理想上类似于NES游戏的游戏。我目前不知道如何调整如何将播放区域绘制到视频内存(后台缓冲区)。
后备缓冲
NES对名称表或后备缓冲区有限制。对于我的例子,后备缓冲区大256x240像素,或一个屏幕的大小。如果我把它画到电视上,它会完美地填满屏幕。现在,如果我将这个偏移X = 5绘制到屏幕上,整个图像将被移动并且会在屏幕上环绕。
例如......
ORIGINAL, NO OFFSET: DRAWN WITH OFFSET OF X=5:
ABCDEFGHIJK GHIJKABCDEF
DRAWN WITH OFFSET OF X=-5:
FGHIJKABCDE
屏幕分为8x8像素的正方形,总共32x30行和列。 (256x240像素)。偏移量以像素表示 - 而不是列;所以在理论上,我可以将屏幕偏移5个像素,每列将向右移动5个像素。
级别设计
我的舞台由屏幕组成,包含以16x15行和列表示的数据,每行16x16像素。这是为了模拟有多少NES游戏存储的关卡数据 - 每个关卡都包含每个8x8块应该包含的信息。
E.g:
AA
BC with A,B,C,D representing what 8x8 graphic should go where
关卡设计也由此表示,每个数字都是不同的屏幕,而且 - 没有任何意义,null。
-----
-123-
---4-
--54-
-----
字符放置 这很简单。我已经知道如何根据它们的绝对定位确定我的字符所在的表,行和列。我还可以确定屏幕内的相对位置。
通过这些信息,我可以很容易地找出角色左侧和右侧的哪些列(如果有的话)(如果角色位于屏幕1的左侧,则不再是级别)
所以这里的问题是DUN DUN DUN 如何将我的关卡绘制到屏幕上,以便它们从一个滚动到下一个。 一次绘制一个完整的屏幕相对容易,当角色到达边缘时,只需翻转到另一个屏幕。
然而,我在概念上遇到的问题是我需要将关卡数据“流式传输”到屏幕上。那就是说,角色向右移动24个像素。 BG也需要移动。
所以,我需要将后备缓冲区的滚动调整24像素。然而,仅仅单独滚动将导致屏幕翻转,覆盖水平的旧部分。因此,在滚动时我需要确保将新的层次绘制到后台缓冲区。但在我能做到之前,我需要弄清楚哪些瓷砖需要先画出来。如果这个人向左移动了24个像素,我需要将碎片重新绘制到后备缓冲区并相应地更改偏移量。
让我们不要忘记,如果角色向右移动并且没有更多的水平数据被绘制,则应该没有偏移,而是角色更接近屏幕的一侧(而不是在中间位于通过X轴屏幕。)
基本上,我现在脑子里已经有很多不同的数字和价值观 - 试图围绕很多概念,他们让我的大脑变成了粘性物质。任何人都对我如何处理这个问题有任何看法?
编辑:使用VB.Net。 C#也适用(我同时编程)
答案 0 :(得分:3)
NES的方式是使用4个名称表,每个256x240。当您从屏幕上滚动一个时,相邻的一个将滚动。要使“worlds”大于512x480,您可以在屏幕外的位置更新名称表。
通常,磁带盒在ROM中会有一个包含所有级别数据的巨型表,并使用1或2个RAM变量跟踪整个位置。然后当游戏滚动时,它将更新RAM变量,使用它们查找关卡数据表并将新关卡数据复制到屏幕外名称表的部分。
所以实际上你的后台缓冲区应该是512x480,而你只显示256x240的部分。
您是否看过任何具有大型滚动世界的NES游戏的反汇编?我认为Metroid的部分拆解就在某处......
...是的,在romhacking.net
找到了一些文档Metroid disassembly;不是真的很好评论,但只要付出一点努力,就不应该太难理解。
Another disassembly评论更好。
编辑:在上面发布的第二个反汇编中,查看“SetupRoom”例程中的MetroidGameEnginePage.txt和“DrawRoom”例程;标签LEB4D的例程也显示了在一种情况下如何更新名称表。另请参阅“GetNameTable”例程上面的广泛注释。通常,在整个文档中搜索“名称表”可以获得更多信息。
编辑编辑:也在romhacking.net; memory map for SMB可能有用。
答案 1 :(得分:0)
我会设置一个图像控件网格,并从数据库加载级别,该数据库存储每个图片相对于关卡的列和行。一旦代表游戏角色的图像远离右侧(您必须将其位置存储在屏幕的某些模块级别变量中),您将加载下一列图像(同时将所有其他图像转移到离开并删除第一列。)