代码之家  ›  专栏  ›  技术社区  ›  Jeffrey Kern

在游戏中渲染二维地图-裁剪和滚动

  •  1
  • Jeffrey Kern  · 技术社区  · 15 年前

    好啊。 我在Essense尝试对Nes硬件做出自己的解释,这样我就可以制作一个理想的类似于Nes游戏的游戏。我目前一直在研究如何调整如何将播放区域绘制到视频内存(后缓冲区)。

    后置缓冲器

    NES对名称表或backbuffer有限制。对于我的例子,backbuffer是256x240像素大,或者一个屏幕的大小。如果我把这个画到电视上,它会完全填满屏幕。现在,如果我把这个画到屏幕上,偏移量为x=5,整个图像就会被移动并环绕在屏幕上。

    例如。。。。。

    ORIGINAL, NO OFFSET:                      DRAWN WITH OFFSET OF X=5:
    ABCDEFGHIJK                               GHIJKABCDEF
    
    DRAWN WITH OFFSET OF X=-5:
    FGHIJKABCDE
    

    屏幕被分割成8 x 8像素的正方形,共32x30行和列。(256x240像素)。偏移量是以像素表示的,而不是以列表示的;因此从理论上讲,我可以将屏幕偏移5个像素,并且每列都将向右移动5个像素。

    级设计

    我的阶段由屏幕组成,包含以16x15行和列表示的数据,每个行和列以16x16像素表示。这是为了模拟有多少个NES游戏存储的级别数据-每个图块包含关于每个8x8块中应该包含哪些内容的信息。

    例如。:

    AA
    BC     with A,B,C,D representing what 8x8 graphic should go where
    

    级别设计也用这个来表示,每个数字都是一个不同的屏幕,没有任何意义,为空。

    -----
    -123-
    ---4-
    --54-
    -----
    

    字符位置 这很容易。我已经知道如何根据字符的绝对位置确定字符所基于的表、行和列。我还可以确定屏幕内的相对位置。

    有了这个信息,我可以很容易地知道哪些列在字符的左右两侧,如果有的话(如果字符在屏幕1的左侧,那么就不会有更多的左电平了)

    所以这是邓邓邓邓的问题 如何将级别绘制到屏幕上,以便它们从一个级别滚动到下一个级别。 一次画一个全屏是相对容易的,当角色到达边缘时,只需翻转到另一个屏幕。

    然而,我在概念上遇到的问题是,我需要将级别数据“流”到屏幕上。也就是说,字符向右移动24个像素。BG也需要移动。

    所以,我需要将backbuffer的滚动调整为24像素。然而,仅仅滚动一次就会导致屏幕被覆盖,覆盖水平的旧部分。所以,在滚动时,我需要确保将新的级别片段绘制到后台缓冲区。但在我能做到这一点之前,我需要弄清楚哪些瓷砖需要先画出来。如果这个人向左移动24个像素,我需要在后缓冲层上重新绘制瓷砖,并相应地更改偏移量。

    我们不要忘记,如果字符向右移动,并且没有更多的级别数据需要绘制,那么应该没有偏移,而是字符更靠近屏幕的一侧(而不是通过X轴居中于屏幕的中间)。

    基本上,我现在脑子里有很多不同的数字和价值观——试图把我的头脑集中在许多概念上,它们使我的大脑变成了“咕”。有人对我如何处理这个问题有什么看法吗?

    编辑:使用vb.net。C也适用(两者都有I程序)

    2 回复  |  直到 15 年前
        1
  •  3
  •   Bob Montgomery    15 年前

    NES的做法是使用4个名称表,每个名称表为256x240。当你从屏幕上滚动一个时,相邻的一个就会滚动。要使“worlds”大于512x480,请在屏幕外的位置更新名称表。

    一般来说,盒带在ROM中会有一个包含所有级别数据的巨大表,并且会用1或2个RAM变量跟踪整体位置。然后当游戏滚动时,它将更新RAM变量,使用这些变量查找级别数据表,并将新级别数据复制到屏幕外的名称表部分。

    所以实际上,您的缓冲区应该是512x480,而您只显示其中的256x240部分。

    你看过任何有大滚动世界的NES游戏的反汇编吗?我认为部分拆除的子宫内膜在某处…

    …是的,在 romhacking.net

    Metroid disassembly 不是很好的评论,但只要努力一点,就不应该太难弄明白。

    Another disassembly 这是更好的评价。

    编辑:在上面发布的第二个拆卸中,查看metroidgameengineepage.txt中的“Setuproom”例行程序和“Drawroom”例行程序;标签LEB4D中的例行程序显示了在一种情况下如何更新名称表。还可以查看“getnametable”例程上面的大量注释。一般来说,在整个文档中搜索“名称表”将获得更多信息。

    编辑编辑:也在romhacking.net;the memory map for SMB 可能有用。

        2
  •  0
  •   NoAlias    15 年前

    我将建立一个图像控件网格,并从数据库中加载级别,该数据库存储每个图片相对于级别的列和行。一旦代表游戏角色的图像到达屏幕右侧足够远(您必须将其位置存储在一些模块级变量中),您将加载下一列图像(同时将所有其他图像向左移动并删除第一列)。