如何为级别中定义的对象实现持久状态?


17

我正在开发2D Metroidvania,它由一系列相互关联的关卡组成,可以重新访问。

每个级别都由Tiled TMX文件表示,在该文件中,我指定了生成不同sprite类的各种对象的位置(例如,敌人,拾取器,控制杆等)。开始新游戏,加载已保存的游戏或更改级别时,我的游戏循环遍历相应的TMX文件并生成该级别中的所有对象。

我通过以下方式处理级别更改:如果Player对象与对象相交Portalchange_map()则调用一种方法,该方法加载新地图(与相交的门户相关联的地图)并将玩家定位在新地图上的适当位置。

我的某些对象具有一些状态,希望通过更改级别以及保存和退出游戏来保持这些状态。例如,如果玩家解锁门,并且门的状态属性设置为“打开”,则我希望玩家返回时将门打开。我想要类似的东西,可以将其设置为左或右,以及其他各种对象。此外,玩家有时会收集一些我不想在玩家重新访问该区域时重生的物品。

因此,我的问题是如何处理这种持久性?

我正在使用Python,尽管我认为您可以从中抽象出来。

Answers:


27

我认为不要过分考虑这个问题会得到最好的结果,因此我将在您的游戏中实现一个简单的键值保存系统,将其与其他保存数据一起存储,然后在需要访问以前的状态时按需加载。

该流程可能如下所示:

  1. 文件加载级别
  2. 放置图块/对象之前,请检查其是否具有“持久”属性。
    1. 如果是,请执行以下操作:检查已保存的键值对是否存在与属性匹配的键,并获取适当的值。
    2. 如果否:按正常放置对象
  3. 当玩家退出关卡时/使用“永久”属性保存所有对象的游戏循环,并将它们另存为键值对。

这是一个基于我在简单2D游戏中使用的伪代码示例:

def load_map(map):
    for y in range(0, height):
        for x in range(0, width):
            tile = map[x, y]

            for property in tile.properties:
                if is_persistent(property.name):
                    // Name prefixed with "persistent" means that it's persistent
                    // so we load the value from out persistent storage
                    property.value = persistent_values[property.name]

def save_map(map):
    ... everything in load_map ...
    if (property.name.matches("persistent_*")):
        // Name prefixed with "persistent" means that it's persistent
        // so we save the value to persistent storage
        persistent_values[property.name] = property.value

def is_persistent(name):
    return name.matches("persistent_*") and persistent_values.contains(name)

然后,我可以使用此属性检查状态:

def draw():
    if properties["persistent_is_pressed"].value:
        draw_sprite(button_pressed)
    else:
        draw_sprite(button_unpressed)

def on_pressed():
    properties["persistent_is_pressed"].value = not properties["persistent_is_pressed"].value

如果您使用的是诸如Tiled之类的切片地图编辑器,则添加这样的属性非常容易:

增加财产

希望这会给您一个关于如何尽可能简单地实现持久状态的想法!


这非常有帮助,尽管我正在努力查看如何准确地将其应用于我的情况。我会再考虑一下。
GoldenGremlin

我想我很难看到如何保存这些值才能正常工作。保存时,我不会遍历TMX数据中的图块。相反,我将遍历all_sprites组中的sprite对象。加载地图时,在实例化Sprite对象时,将TMX对象的TMX属性用作参数,但是此后,我不再触摸这些属性,因此它们不会跟踪Sprite对象中的更改。
GoldenGremlin18年

1
@dietestus您应该只为Sprite对象提供一个properties您修改的字段,并且仅使用tile properties指示要修改的属性(但所有数据都存储在您的Sprite中)。您也可以将

3
@dietestus与持久性实体(门,杠杆)进行交互后,便立即将新状态保存到键值映射中。保存时无需迭代地图,地图中已经包含了所有内容。
Derb先生

1
@dietestus是的,您是:)这是一个简单的词典,其中的键是属性名称,值是(以及...值)。只要您具有唯一键,在同一图块上具有多个对象就不会更改任何内容。
Charanor
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.