Как я могу реализовать постоянное состояние для объектов, определенных на уровне?

17

Я разрабатываю 2D Metroidvania, который состоит из ряда взаимосвязанных уровней, которые могут быть пересмотрены.

Каждый уровень представлен файлом Tiled TMX, в котором я указал, где появляются различные объекты различных классов спрайтов (например, враги, пикапы, рычаги и т. Д.). При запуске новой игры, загрузке сохраненной игры или изменении уровня мой игровой цикл проходит через соответствующий файл TMX и генерирует все объекты на этом уровне.

Я обрабатываю изменения уровня следующим образом: если Playerобъект пересекается с Portalобъектом, change_map()вызывается метод, который загружает новую карту (ту, которая связана с пересекающимся порталом) и помещает игрока в соответствующую позицию на новой карте.

Некоторые из моих объектов имеют состояния, которые я хотел бы сохранять постоянными при смене уровня, сохранении и выходе из игры. Например, если игрок открывает дверь, а атрибут состояния двери установлен на «открыто», я бы хотел, чтобы дверь была открыта, когда игрок вернется. Я хочу что-то подобное для рычагов, которые могут быть установлены влево или вправо, и различных других объектов. Кроме того, у игрока иногда будут собираться предметы, которые я не хочу возрождать, когда игрок повторно посещает область.

Мой вопрос, таким образом, как я могу справиться с такой настойчивостью?

Я работаю в Python, хотя я думаю, что вы можете абстрагироваться от этого.

GoldenGremlin
источник

Ответы:

27

Я думаю, что недумание этой проблемы даст наилучшие результаты, поэтому я бы просто внедрил в вашу игру простую систему сохранения значений ключей, которую вы сохраняете вместе с другими сохраненными данными, а затем загружаете по требованию, когда вам требуется доступ к предыдущему состоянию.

Поток может выглядеть примерно так:

  1. Уровень загрузки из файла
  2. Перед размещением плитки / объекта проверьте, имеет ли он «постоянное» свойство.
    1. Если да: проверьте сохраненную пару ключ-значение для ключа, соответствующего свойству, и выберите подходящее значение.
    2. Если нет: поместите объект как обычно
  3. Когда игрок выходит из уровня / сохраняет игровой цикл через все объекты со свойством «persistent» и сохраняет их как пару ключ-значение.

Вот пример псевдокода, основанный на том, что я использую в своей простой 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, добавить такие свойства очень просто:

добавление собственности

Надеемся, что это даст вам представление о том, как реализовать постоянное состояние как можно проще!

Charanor
источник
Это очень полезно, хотя я изо всех сил пытаюсь понять, как именно применить это к моей ситуации. Я подумаю об этом еще немного.
GoldenGremlin
Я думаю, что мне трудно понять, как я могу заставить сохранение значений работать. Когда я сохраняю, я не буду перебирать тайлы в данных TMX. Скорее, я буду перебирать объекты спрайтов в моей группе all_sprites. Когда я загружаю карты, я использую свойства TMX объектов TMX в качестве параметров при создании экземпляров моих объектов-спрайтов, но после этого я не касаюсь этих свойств, поэтому они не отслеживают изменения в объектах-спрайтах.
GoldenGremlin
1
@dietestus Вы, вероятно, должны просто дать вашим объектам спрайта propertiesполе, которое вы изменяете, и использовать плитки propertiesтолько для указания того, какое свойство нужно изменить (но все данные хранятся в вашем спрайте). Вы также можете просто передать плитку своему спрайту, чтобы вы могли изменить плитку из спрайта :), если неясно, что я имею в виду, я могу
смоделировать
3
@dietestus Как только вы взаимодействуете с постоянным объектом (дверь, рычаг), вы сохраняете новое состояние на карте ключ-значение. Вам не нужно перебирать карты, когда вы сохраняете, у вас уже есть все на вашей карте.
Герр Дерб
1
@dietestus Да, вы есть :) это простой словарь, в котором ключи являются именами свойств, а значения (ну ... значения). Наличие нескольких объектов на одной плитке ничего не изменит, если у вас есть уникальные ключи.
Charanor