代码之家  ›  专栏  ›  技术社区  ›  Dynite

在二维滚动条中表示级别的最佳方法是什么?

  •  15
  • Dynite  · 技术社区  · 15 年前

    我没有游戏编程知识,经常想知道二维游戏(如Mario和Sonic等)中的级别是如何存储的。

    “存储”与数据(地面、平台、按钮、电梯等)的存储方式相同。

    也就是说,很明显,马里奥的一个关卡并不是从左向右移动的非常宽的图像。

    12 回复  |  直到 15 年前
        1
  •  22
  •   Martin Harris    15 年前

    由于ROM黑客场景,超级马里奥世界的文件格式(我可以想象这个时代最流行的游戏)是众所周知的,并且基本上被完全理解。还有一些文档会详细描述这一切。不幸的是,因为这意味着去不到合法的网站,我不能从工作中为你提供任何链接,但如果你谷歌的.mwl文件扩展名和一个名为“月球魔法”的编辑应用程序,它可能会为你指明正确的方向。

    不过,基本原则相当简单。首先,你需要你的图形,所以你可以用一个单独的图像,以一个确定的大小为景观瓷砖-较小的是更节省内存,较大的给你更多的细节,所以假设我们的是32 x 32像素。所以最后会出现这样的情况(代表不同瓷砖的字符):

        ! " £ $ %
        ^ & * ( )
    

    你可以为关卡的“样式”设置一个标题,所以火世界、冰世界、洞穴世界等。这可以节省你在不使用的瓷砖中加载的时间。

    接下来,您需要一个级别文件,它首先由要加载的图块集和表示每个图形的数字组成,如下所示:

       fireworld.img
       2 2 2 2 2 2 2 2
       3 3 2 2 2 2 3 3
       3 3 3 3 3 3 3 3
    

    与上面的瓷砖集合并(取决于瓷砖的编号方式)

       " " " " " " " "
       £ £ " " " " £ £
       £ £ £ £ £ £ £ £
    

    很明显,您需要在这上面分层更多的信息:哪些瓷砖是实心的,哪些是致命的等等。这可以在图像级别(3总是实心的)上完成,或者为了更灵活但更大的文件,可以在地图级别上完成。位标志可以做到,第一个数字是实的,第二个数字是致命的:

       fireworld.img
       200 200 200 200 200 200 200 200
       310 310 200 200 200 200 310 310
       310 310 310 310 310 310 310 310
    

    除此之外,您还需要在级别文件后面添加一个起点和终点(几个坐标)和敌人(他们使用的图形,他们使用的人工智能程序,他们从哪里开始)。

    完成所有这些之后,您就可以研究压缩了。有很多方法可以节省空间,很明显,现在它与16位和8位擦除中的效果没有多大关系,但即使如此,我们上面的格式也是非常浪费的。

    和往常一样,这些只是基本原则。您的结果可能会有所不同…

        2
  •  8
  •   Meep3D    15 年前

    不是很相关,但你知道马里奥的云和灌木丛是同一个精灵,只是颜色改变了?当时的记忆真的很昂贵!

    不可能真正知道它们是如何存储的,但可能使用对象网格方法,在这里+那里使用一些节省内存的技巧。实现必然会因游戏而异,而且几乎完全取决于开发人员——实际上没有任何标准方法。


    更新:我认为将整个级别表示为(非常宽的)网格是最好的方法。在每个网格框中,您将放置一个具有属性(产卵、地面、墙壁、胸部、坏蛋、刺等)的精灵。然后,引擎将在正确的位置绘制sprite,但也具有与之关联的属性。如果你把10块地板放在一排,你就必须对引擎进行编码,以识别连接,以及在哪里放置正确的端件等。显然,任何不是网格的东西都是天空!

    如何对这些信息进行编码几乎取决于你自己,而且既然记忆不再是一件大事,那么效率就没有那么重要了。只要列出一个对象代码,x,y就可以了。

        3
  •  4
  •   Kawa    15 年前

    所有声称马里奥游戏将其等级存储在某种二维数组结构中的人都是 方式 关:除了前两个GB马里奥游戏(可能是第三个),超级马里奥游戏是 基于对象 .

    每个级别分为多个屏幕,每个级别的总大小相同。每个屏幕都包含对象的可变长度列表,每个对象都具有类型、位置和(取决于类型)其他属性。在一个级别的开始,第一个或两个屏幕被解释并转换为用于绘制屏幕和进行交互的常规二维数组结构。当水平仪滚动过去时,这张地图会快速重建,丢弃超出范围的部分。

    这就是为什么如果你后退,敌人可以重新出现的原因,尤其是在SMW的一个森林级别,在那里你可以使用斗篷来回跳跃三个屏幕从一个毛虫到另一个。顺便说一句,因为你从来不碰地板,所以会有很多生命。

    当然,这个系统的细节在游戏之间是不同的。

    除此之外,马丁·哈里斯是完全正确的。

        4
  •  3
  •   rix0rrr    15 年前

    对于大多数2d游戏,我认为级别存储起来就像一张位图。

    工作原理如下:

    • 首先,你有很多固定的瓷砖,比如说16x16像素。这些瓷砖就像拼图游戏的碎片。你可以用各种方法把它们组合在一起形成一个层次。例如,这里有一个tileset,虽然这看起来是一个自上而下的游戏,但原理是相同的: http://silveiraneto.net/wp-content/uploads/2009/04/free_tileset_version_9.png

    • 一旦你的牌集合被知道了,你就给每个牌一个数字。如果图块少于256个,则可以将此数字存储在一个字节中;如果图块多于256个,则可以将其存储在一个字或双字中。在这一点上,向这些数字添加一些语义也是有用的。举个例子,1-100块代表“障碍”,你不能穿过。这将在以后派上用场。

    • 现在是时候定义地图了。我们只需把拼图块放在一个大网格上就可以做到这一点!我们为地图定义最大尺寸。对于侧滚,假设地图宽1000块,高50块。你可以随心所欲地选择。现在可以将内存(和磁盘)中的映射表示为 width * height 数字。网格中的每个“单元格”都包含一个数字,该数字表示应在该位置绘制的图块。

    现在绘制地图很容易:

    for (y = 0; y < height; y++) {
       for (x = 0; x < width; x++) {
          draw_tile(x * 16, y * 16, map[y][x]);
       }
    } 
    

    其他东西也一样。还记得我们将瓷砖1-100定义为障碍物吗?我们可以使用地图来检测玩家是否可以移动到某个位置:

    bool moveable(int x, int y) {
       return map[y / 16][x / 16] > 100;
    }
    

    这是瓷砖地图最基本的解释。通过扩展这个简单的概念,您可以做更多有趣的事情。以下是一些想法:

    我敢肯定大多数二维游戏都使用了一些不同的平铺游戏地图技术。

        5
  •  1
  •   chaos    15 年前

    AS stored data structures .

    问得太宽泛,回答得太宽泛。:)

        6
  •  1
  •   Nick Van Brunt    15 年前

    我已经使用Lua脚本为 Physle games .它们的加载速度不如二进制格式快,但它使调试和与其他工具集成更加容易。通常情况下,装载水平也不是速度真正起作用的地方。

        7
  •  0
  •   MiffTheFox    15 年前

    这太宽泛了。

    游戏级存储因引擎而异。

        8
  •  0
  •   foobarfuzzbizz    15 年前

    通常是游戏解析的某种自定义文件格式。

    XML和纯文本文件一样是一种可能性。但是,尝试打开一个游戏的级别文件,你很可能会看到乱码的文本。您需要找到关于游戏使用的特殊文件格式的文档。

    看看你的游戏修改网站,你会发现更多。

        9
  •  0
  •   Reto Meier    15 年前

    在你提到的马里奥和音速游戏(可能是旧的和二维的)的例子中,可能有一些神秘的压缩和优化格式,以绕过它们的控制台的存储和处理限制。

        10
  •  0
  •   Jon Mitchell    15 年前

    我不知道像马里奥这样的东西是如何存储它的级别的,我自己也从来没有这样做过,但这就是我将要采用的方法。

    我将创建一个可以基于XML的简单文件格式。在这一点上,我可能已经定义了游戏区域大小和其他元数据,比如名称和时间限制。然后,我会有一个对象列表,显示在游戏区域中,带有X/Y坐标和对象类型,例如,玩家开始位置、关卡退出等)我甚至可能有一个区域存储游戏中发生事件的时间。

    然后,游戏引擎必须解释文件,并在屏幕上呈现相应的项目。我可以想象存储数据是一件容易的事情,你用它来做什么会很棘手。

    希望有帮助。

        11
  •  0
  •   AakashM    15 年前

    我们尊敬的一位领导人发表了一篇有点关联的博文 Why are the Microsoft Office file formats so complicated? (And some workarounds)

        12
  •  0
  •   Alex Mcp    15 年前

    我经常看到使用的数组,其值以地形/填充类型为键。下面是Tony PA关于基于Flash Tile的游戏创建的一个非常好的教程:

    Game Map storage

    然后级别创建者扫描并创建文件。在Kongregate上查找允许用户级创建的游戏;它们存储了一个完整的级别,当您链接到游戏时,这些级别作为post变量提交。这是一个不经常被编码的透明过程,因此很容易学习(有许多游戏类型可以做到这一点)。