Jak mogę wdrożyć stan trwały dla obiektów zdefiniowanych na poziomie?

17

Opracowuję 2D Metroidvania, która składa się z szeregu powiązanych ze sobą poziomów, które można ponownie odwiedzić.

Każdy poziom jest reprezentowany przez kafelkowy plik TMX , w którym określiłem, gdzie pojawiają się różne obiekty różnych klas duszków (na przykład wrogowie, przetworniki, dźwignie itp.). Podczas uruchamiania nowej gry, ładowania zapisanej gry lub zmiany poziomu, moja pętla gry przechodzi przez odpowiedni plik TMX i generuje wszystkie obiekty na tym poziomie.

Obsługuję zmiany poziomów w następujący sposób: Jeśli Playerobiekt przecina Portalobiekt, change_map()wywoływana jest metoda, która ładuje nową mapę (powiązaną z przecinającym się portalem) i ustawia gracza w odpowiednim miejscu na nowej mapie.

Niektóre z moich przedmiotów mają stany, które chciałbym być trwałe przez zmiany poziomu i zapisywanie i kończenie gry. Na przykład, jeśli gracz odblokuje drzwi, a atrybut stanu drzwi jest ustawiony na „otwarte”, chciałbym, aby drzwi były otwarte, gdy gracz powróci. Chcę coś podobnego do dźwigni, które można ustawić w lewo lub w prawo, i różnych innych przedmiotów. Co więcej, gracz czasami zbiera przedmioty, których nie chcę odradzać, gdy gracz powróci na dany obszar.

Moje pytanie brzmi zatem, jak poradzić sobie z tego rodzaju wytrwałością?

Pracuję w Pythonie, choć myślę, że można od tego oderwać się.

GoldenGremlin
źródło

Odpowiedzi:

27

Myślę, że nie przemyślenie tego problemu da najlepsze wyniki, więc po prostu wdrożyłbym prosty system zapisywania kluczowych wartości w grze, który przechowujesz razem z innymi zapisanymi danymi, a następnie ładuję na żądanie, gdy potrzebujesz uzyskać dostęp do poprzedniego stanu.

Przepływ może wyglądać mniej więcej tak:

  1. Poziom ładowania z pliku
  2. Przed umieszczeniem kafelka / obiektu sprawdź, czy ma on właściwość „trwałą”.
    1. Jeśli tak: Sprawdź zapisaną parę klucz-wartość dla klucza pasującego do właściwości i pobierz odpowiednią wartość.
    2. Jeśli nie: Ustaw obiekt jak zwykle
  3. Kiedy gracz opuści poziom / zapisuje pętlę gry przez wszystkie obiekty z „trwałą” właściwością i zapisuje je jako parę klucz-wartość.

Oto przykład pseudokodu oparty na tym, czego używam w mojej prostej grze 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)

Następnie mogę po prostu sprawdzić stan za pomocą tej właściwości:

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

Jeśli używasz edytora map kafelkowych, takiego jak Tiled, dodawanie właściwości w ten sposób jest bardzo proste:

dodawanie własności

Mam nadzieję, że da to pomysł, jak wdrożyć stan trwały tak prosto, jak to możliwe!

Charanor
źródło
Jest to bardzo pomocne, choć staram się dokładnie zobaczyć, jak zastosować to w mojej sytuacji. Pomyślę o tym jeszcze trochę.
GoldenGremlin
Myślę, że mam problem z widzeniem, w jaki sposób mogę uzyskać zapisanie wartości do działania. Kiedy zapisuję, nie będę iterował po kafelkach danych TMX. Zamiast tego będę powtarzał obiekty sprite w mojej grupie all_sprites. Kiedy ładuję mapy, używam właściwości TMX obiektów TMX jako parametrów podczas tworzenia instancji moich obiektów sprite, ale potem nie dotykam tych właściwości, więc nie śledzą zmian w obiektach sprite.
GoldenGremlin
1
@dietestus Prawdopodobnie powinieneś po prostu nadać swoim obiektom propertiespole, które zmodyfikujesz, a zamiast tego użyć kafelków propertiesjako wskazania, którą właściwość chcesz zmodyfikować (ale wszystkie dane są przechowywane w twoim ikonce). Możesz także przekazać kafelek do swojego duszka, aby móc modyfikować kafelek z ikonki :) jeśli nie jest jasne, co mam na myśli, mogę
wykpić
3
@dietestus Gdy tylko wejdziesz w interakcję z trwałym bytem (drzwi, dźwignia), zapiszesz nowy stan na mapie klucz-wartość. Podczas zapisywania nie musisz powtarzać map, masz już wszystko na mapie.
Herr Derb
1
@dietestus Tak, jesteś :) to prosty słownik, w którym klucze są nazwami właściwości, a wartościami są (no cóż ... wartości). Posiadanie wielu obiektów na tym samym kafelku niczego nie zmieni, o ile masz unikalne klucze.
Charanor