Pertama, saya tidak mengacu pada manajemen adegan; Saya mendefinisikan keadaan permainan secara longgar sebagai segala bentuk keadaan dalam permainan yang memiliki implikasi tentang apakah input pengguna harus diaktifkan atau tidak, atau jika aktor tertentu harus dinonaktifkan sementara, dll.
Sebagai contoh konkret, katakanlah ini adalah permainan Battlechess klasik. Setelah saya bergerak untuk mengambil bagian pemain lain, urutan pertempuran pendek dimainkan. Selama urutan ini, pemain seharusnya tidak diizinkan untuk memindahkan potongan. Jadi bagaimana Anda melacak transisi negara semacam ini? Mesin negara terbatas? Cek boolean sederhana? Tampaknya yang terakhir hanya akan bekerja dengan baik untuk game dengan sedikit perubahan kondisi seperti ini.
Saya bisa memikirkan banyak cara langsung untuk menangani ini menggunakan mesin negara yang terbatas, tetapi saya juga bisa melihat mereka dengan cepat lepas kendali. Saya hanya ingin tahu apakah ada cara yang lebih elegan untuk melacak status / transisi game.
Jawaban:
Saya pernah menemukan sebuah artikel yang menyelesaikan masalah Anda dengan cukup elegan. Ini adalah implementasi FSM dasar, yang disebut dalam loop utama Anda. Saya telah menguraikan rundown dasar artikel di sisa jawaban ini.
Status permainan dasar Anda terlihat seperti ini:
Setiap kondisi permainan diwakili oleh implementasi antarmuka ini. Sebagai contoh Battlechess Anda, ini bisa berarti keadaan ini:
Negara dikelola di mesin negara Anda:
Perhatikan bahwa setiap negara membutuhkan penunjuk ke CGameEngine di beberapa titik, sehingga negara itu sendiri dapat memutuskan apakah negara baru harus dimasukkan. Artikel menyarankan untuk meneruskan CGameEngine sebagai parameter untuk HandleEvents, Pembaruan, dan Gambar.
Pada akhirnya, loop utama Anda hanya berurusan dengan engine keadaan:
sumber
Saya mulai dengan menangani hal semacam ini dengan cara sesederhana mungkin.
Lalu saya akan menambahkan cek terhadap bendera boolean di tempat-tempat yang relevan.
Jika nanti saya menemukan saya perlu lebih banyak kasus khusus dari ini - dan hanya itu - saya faktor ulang menjadi sesuatu yang lebih baik. Biasanya ada 3 pendekatan yang akan saya ambil:
enum { PRE_MOVE, MOVE, POST_MOVE }
dan tambahkan transisi di mana pun dibutuhkan. Lalu aku bisa mengecek terhadap enum ini di mana aku dulu mengecek bendera boolean. Ini adalah perubahan sederhana tetapi yang mengurangi jumlah hal yang harus Anda periksa, memungkinkan Anda untuk menggunakan pernyataan pergantian untuk mengelola perilaku secara efektif, dll.pieceSelectionManager->disable()
atau serupa di awal urutan, danpieceSelectionManager->enable()
. Pada dasarnya Anda masih memiliki bendera, tetapi sekarang disimpan lebih dekat ke objek yang mereka kontrol, dan Anda tidak perlu mempertahankan status tambahan apa pun dalam kode permainan Anda.Secara umum saya tidak perlu melangkah lebih jauh dari ini ketika datang ke substrat kasus khusus, jadi saya tidak berpikir ada risiko "cepat keluar dari tangan".
sumber
http://www.ai-junkie.com/architecture/state_driven/tut_state1.html adalah tutorial yang bagus untuk manajemen keadaan gim! Anda dapat menggunakannya baik untuk entitas game atau untuk sistem menu seperti di atas.
Dia mulai mengajar tentang Pola Desain Negara , dan kemudian menerapkan
State Machine
, dan terus mengembangkannya. Ini bacaan yang sangat bagus! Akan memberi Anda pemahaman yang kuat tentang bagaimana keseluruhan konsep bekerja dan bagaimana menerapkannya pada jenis masalah baru!sumber
Saya mencoba untuk tidak menggunakan mesin negara dan boolean untuk tujuan ini, karena keduanya tidak dapat diskalakan. Keduanya berubah menjadi berantakan ketika jumlah negara tumbuh.
Saya biasanya mendesain gameplay sebagai urutan tindakan dan konsekuensi, setiap kondisi permainan datang secara alami tanpa perlu mendefinisikannya secara terpisah.
Misalnya dalam kasus Anda dengan menonaktifkan input pemain: Anda memiliki beberapa handler input pengguna dan beberapa indikasi visual ingame bahwa input dinonaktifkan, Anda harus menjadikan mereka objek atau komponen satu, jadi untuk menonaktifkan input Anda cukup menonaktifkan seluruh objek, tidak perlu menyinkronkannya dalam beberapa mesin keadaan atau bereaksi terhadap beberapa indikator boolean.
sumber