Bagaimana saya bisa menerapkan status persisten untuk objek yang didefinisikan dalam level?

17

Saya sedang mengembangkan Metroidvania 2D yang terdiri dari serangkaian level yang saling berhubungan yang dapat ditinjau kembali.

Setiap level diwakili oleh file TMX Tiled di mana saya telah menentukan di mana berbagai objek dari berbagai kelas sprite muncul (misalnya, musuh, pickup, tuas, dll.). Saat memulai gim baru, memuat gim yang disimpan, atau mengubah level, loop gim saya berjalan melalui file TMX yang sesuai dan menghasilkan semua objek di level itu.

Saya menangani perubahan level dengan cara berikut: Jika Playerobjek memotong suatu Portalobjek, sebuah change_map()metode disebut yang memuat peta baru (yang terkait dengan portal berpotongan) dan menempatkan pemain pada posisi yang sesuai di peta baru.

Beberapa objek saya memiliki status yang ingin saya gigih melalui perubahan level dan menyimpan serta keluar dari game. Misalnya, jika pemain membuka kunci pintu dan atribut status pintu diatur ke "terbuka," Saya ingin pintu terbuka ketika pemain kembali. Saya ingin sesuatu yang serupa untuk tuas, yang dapat diatur ke kiri atau kanan, dan berbagai objek lainnya. Selanjutnya, pemain kadang-kadang akan mengumpulkan item yang saya tidak ingin respawn ketika pemain mengunjungi kembali daerah tersebut.

Pertanyaan saya adalah bagaimana saya bisa mengatasi kegigihan seperti ini?

Saya bekerja di Python, meskipun saya pikir Anda bisa abstrak jauh dari itu.

GoldenGremlin
sumber

Jawaban:

27

Saya pikir tidak terlalu memikirkan masalah ini akan memberikan hasil terbaik jadi saya hanya akan menerapkan sistem penghematan kunci-nilai sederhana ke dalam gim yang Anda simpan di sepanjang data simpanan Anda yang lain dan kemudian memuat sesuai permintaan saat Anda perlu mengakses keadaan sebelumnya.

Alirannya bisa terlihat seperti ini:

  1. Muat level dari file
  2. Sebelum menempatkan ubin / objek periksa apakah memiliki properti "persisten".
    1. Jika ya: Periksa pasangan nilai kunci yang disimpan untuk mencari kunci yang cocok dengan properti dan ambil nilai yang tepat.
    2. Jika tidak: Tempatkan objek seperti biasa
  3. Ketika pemain keluar dari level / menyimpan loop game melalui semua objek dengan properti "persisten" dan menyimpannya sebagai pasangan nilai kunci.

Berikut adalah contoh pseudo-kode berdasarkan apa yang saya gunakan untuk game 2D sederhana saya:

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)

Maka saya bisa memeriksa status menggunakan properti ini:

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

Jika Anda menggunakan editor peta ubin seperti Ubin menambahkan properti seperti ini sangat mudah:

menambahkan properti

Semoga ini akan memberi Anda ide tentang bagaimana menerapkan keadaan persisten sesederhana mungkin!

Charanor
sumber
Ini sangat membantu, meskipun saya berjuang untuk melihat bagaimana menerapkannya pada situasi saya. Saya akan memikirkannya lagi.
GoldenGremlin
Saya pikir saya mengalami kesulitan melihat bagaimana saya bisa mendapatkan penghematan nilai untuk bekerja. Saat saya menyimpan, saya tidak akan mengulangi ubin di data TMX. Sebaliknya, saya akan mengulangi objek sprite di grup all_sprites saya. Ketika saya memuat peta, saya menggunakan properti TMX dari objek TMX sebagai parameter ketika membuat instance objek sprite saya, tapi setelah itu saya tidak menyentuh properti itu, jadi mereka tidak melacak perubahan pada objek sprite.
GoldenGremlin
1
@dietestus Anda mungkin hanya perlu memberikan objek sprite objek propertiesAnda yang Anda ubah dan hanya menggunakan ubin propertiessebagai indikasi properti apa yang akan dimodifikasi (tetapi semua data disimpan dalam sprite Anda). Anda juga bisa meneruskan ubin ke sprite Anda sehingga Anda dapat memodifikasi ubin dari sprite :) jika tidak jelas apa yang saya maksud saya bisa membuat beberapa pseudocode lagi
Charanor
3
@dietestus Segera setelah Anda berinteraksi dengan entitas yang gigih (pintu, tuas), Anda menyimpan status baru ke peta nilai kunci. Anda tidak perlu mengulangi peta saat Anda menyimpan, Anda sudah memiliki semua yang ada di peta Anda.
Herr Derb
1
@dietestus Ya Anda :) :) ini adalah kamus sederhana di mana kuncinya adalah nama properti dan nilainya (well ... values). Memiliki banyak objek pada ubin yang sama tidak akan mengubah apa pun selama Anda memiliki kunci unik.
Charanor