Alternatif untuk Sistem Status Game?


30

Sejauh yang saya tahu, sebagian besar game memiliki semacam "sistem kondisi permainan" yang beralih di antara berbagai kondisi permainan; ini mungkin hal-hal seperti "Intro", "MainMenu", "CharacterSelect", "Memuat", dan "Game".

Di satu sisi, sangat masuk akal untuk memisahkan ini menjadi sistem negara. Lagi pula, mereka berbeda dan harus dalam pernyataan pergantian besar, yang jelas-jelas berantakan; dan mereka tentu saja diwakili dengan baik oleh sistem negara. Tetapi pada saat yang sama, saya melihat keadaan "Game" dan bertanya-tanya apakah ada yang salah dengan pendekatan sistem keadaan ini. Karena itu seperti gajah di dalam ruangan; BESAR dan jelas tetapi tidak ada yang mempertanyakan pendekatan sistem keadaan gim.

Sepertinya konyol bagi saya bahwa "Game" diletakkan pada level yang sama dengan "Menu Utama". Namun tidak ada cara untuk memecah keadaan "Game".

Apakah sistem keadaan permainan cara terbaik untuk pergi? Apakah ada teknik berbeda yang lebih baik untuk mengelola, "kondisi permainan"? Apakah saya boleh memiliki status intro yang menggambar film dan mendengarkan untuk masuk, dan kemudian memuat status yang memotong pada manajer sumber daya, dan kemudian keadaan permainan yang praktis melakukan segalanya ? Bukankah ini juga tampak tidak seimbang bagi Anda? Apakah saya melewatkan sesuatu?

Jawaban:


30

Saya pikir Anda hanya berdebat semantik di sini. Ini disebut Game State karena berperilaku seperti Mesin Negara Hingga , dengan sejumlah negara terbatas dan transisi di antara mereka. 'Game' di 'Game State System' mengacu pada sistem keseluruhan, dengan 'Memuat', 'MainMenu' dll menjadi status permainan. Ini bisa dengan mudah disebut 'adegan' atau 'layar' atau 'level'. Ini hanya semantik.

Saya tidak yakin bahwa FSM ketat berlaku lagi. Dalam implementasi saya, saya memanggil negara 'Layar' dan membiarkannya menjadi stackable - yaitu. layar dapat ditarik di atas layar lain, mengontrol apakah layar di bawahnya diperbarui atau digambar. Dengan cara ini, saya dapat memiliki beberapa layar aktif pada saat yang sama dengan logika mandiri dan kode khusus untuk layar itu, tanpa harus khawatir tentang layar lain.

Layar Jeda, misalnya, dapat dibuka di atas layar gameplay utama saya yang melarang pembaruan, tetapi memungkinkan menggambar di bawahnya sendiri. Layar inventaris karakter dapat memungkinkan gambar dan pembaruan - sehingga permainan terus dimainkan saat Anda bekerja di inventaris Anda.


inilah tepatnya yang harus dilakukan. Layar harus dapat memuat beberapa layar lain dalam arsitektur mirip pohon. Jadi program Anda berisi layar permainan, yang berisi layar menu jeda, yang berisi layar pengaturan audio dan layar pengaturan permainan. dll
Iain

1
Saya akan senang melihat contoh kode sumber untuk ini! (Lebih disukai dalam C ++ / C # / Java)
Zolomon

1
Sayangnya, saya hanya memiliki kode produksi saat ini, tetapi ada konsep serupa dalam sampel XNA Game State: creators.xna.com/en-GB/samples/gamestatemanagement
DrDeth

7

Tentu kondisi Game akan sangat besar, tetapi tidak ada alasan bahwa kondisi Game itu sendiri tidak dapat berisi mesin negara untuk mengelola datanya. Mesin status hierarkis bermanfaat.


4

Saya selalu suka menganggap setiap "keadaan" sebagai "adegan". Jadi video pembuka adalah adegan, hanya yang statis. Kredit adalah sebuah adegan. Menu adalah heboh. Satu-satunya perbedaan di antara mereka semua adalah tingkat interaktivitas dan logika permainan.


3

Saya punya masalah dengan itu juga, sebenarnya.

Katakanlah Anda memiliki Game.

Alih-alih membuat 'Game' menjadi status seperti 'Memuat', 'Menu Utama', dll. - IMO lebih baik membiarkan Game memiliki beberapa status:

"Memuat" - "menampilkan menu" - "dijeda" , dll.

Gim ini masih berjalan, tetapi ketika itu menampilkan menu utama itu akan berada dalam mode 'menu pertunjukan'.

Dan ketika Game tidak dalam keadaan tertentu, itu hanya berjalan.

Itu jauh lebih masuk akal, setidaknya bagi saya. :)


Saya setuju. Tidak ada yang ingin keluar dari Game-State hanya untuk memasuki Pause-State . Di sisi lain: Ini masih sistem negara .. hanya bersarang :)
bummzack

2

Program online (dalam arti tradisional online, yaitu. Terus berjalan dan menanggapi input, daripada makna yang terhubung ke internet) biasanya terdiri dari 3 hal:

  • pengumpulan dan penanganan input
  • memperbarui logika
  • keluaran

Secara umum, ketiganya terkait dan berubah pada saat yang sama. Misalnya, saat menampilkan layar splash Anda dapat memetakan semua kunci Anda ke perintah 'layar dekat' dan pembaruan mungkin memudar grafik secara perlahan dengan output hanya menunjukkan grafik itu. Tetapi ketika memainkan game, semua kunci bisa memetakan ke perintah yang berbeda dan pembaruan mengubah sifat banyak objek dalam game.

Ketika Anda melihatnya dengan cara ini, masuk akal untuk memisahkan Intro dari Character Creation dan dari Game yang tepat: masing-masing memiliki seperangkat aturan input, pembaruan, dan output sendiri. Mereka hampir seperti program mandiri yang berbagi beberapa data dan kode perpustakaan. Dan, dengan mengingat hal ini, biasanya masuk akal untuk memiliki hanya satu kondisi permainan, karena gameplaynya cukup homogen.

Tentu saja, jika Anda benar-benar memiliki jenis permainan yang berbeda (mis. Contoh RPG - Peta Dunia, Peta Kota, Cutscene, Combat), dengan input, pembaruan, dan keluaran yang berbeda, tidak ada alasan Anda tidak dapat memiliki banyak negara di sana juga bukan hanya 1 kondisi Game. Tapi itu tergantung pada gim Anda.


1

Saya melihatnya sebaliknya. 'Menu', 'Skor Tertinggi', "kredit" atau apa pun yang Anda miliki, dapat dianggap sebagai tingkat lain, dan kemudian keadaan itu tidak selalu lebih ringan daripada keadaan 'permainan' Anda (keadaan permainan kebetulan memiliki lebih banyak entitas pada umumnya, dan yang berbeda, tetapi pada akhirnya hanya tingkat lain di mana entitas menunjukkan perilaku yang lebih sulit dan 'peta' umumnya kurang rumit).
Membuat perubahan itu dalam pemikiran Anda pasti menarik Anda keluar dari sindrom "menu membosankan".


Saya akan mengatakan hal yang sama ... Semua menu saya, layar, apa pun, hanyalah level lain.
speeder

1

Dalam permainan saya, saya memiliki:

Execution Manager , yang menginisialisasi aplikasi (game), memuat sumber daya, melepaskan sumber daya saat keluar dari aplikasi, dll. Ini menginisialisasi Mesin Aplikasi, GameViewEngine, GameLogicEngine.

Game State Manager , yang berada di GameLogicEngine, dan bertanggung jawab untuk mengendalikan hal-hal yang terkait dengan loop utama game: deteksi tabrakan, perhitungan fisika, bacaan keyboard, operasi matematika, dll ...

Awalnya, saya cenderung hanya memiliki satu Game State Manager yang merupakan bagian dari GameLogicEngine saya. Namun, saya mengalami beberapa kesulitan dengan kontrol atas intialisasi subsistem utama (GameLogic, ApplicationEngine, ...). Itu bisa saja dilakukan, tetapi itu lebih berantakan, imo.

Sekarang segalanya terlihat lebih transparan bagi saya, dan saya senang dengan desainnya.


0

Ganti nama status 'Game' menjadi sesuatu seperti 'Gameplay'. Maka logika Anda tampak lebih baik; Anda berhenti bermain untuk masuk ke menu th: Anda keluar dari status Gameplay untuk pergi ke status MainMenu.

Juga, saya pikir hal-hal seperti jeda, yang akan mengharuskan permainan berada dalam kondisi yang sama seperti ketika Anda menjeda permainan, seharusnya tidak menjadi bagian yang terpisah. Negara bagian dan sarang anak, mungkin? Gameplay memiliki menu jeda.


0

Saya pikir ada metode bagus yang disebut tumpukan kondisi permainan. Saya belum melihat makalah atau artikel tentang itu tetapi sudah menyebar sedikit dengan suara. Pada dasarnya kondisi permainan paling atas pada tumpukan disebut pertama dan dapat melakukan apa pun yang diinginkan dengan input / render dll. Status permainan paling atas adalah satu-satunya yang diizinkan untuk mendorong atau mengubah status.

Di mesin saya, status permainan sebenarnya hanya daftar entitas permainan. Saya kemudian memiliki entitas yang berfungsi sebagai menu. Menu-negara saya baik menghentikan game (dengan tidak memperbarui item berikutnya pada tumpukan) tetapi membiarkan negara lain (s) mendorong model mereka ke renderer sehingga menu jeda saya (yang tidak mencakup seluruh layar) masih memiliki rendering game di belakang.

Saya harap itu memberikan gambaran tentang sistem yang sedikit berbeda yang tidak didasarkan pada mesin negara.


0

Apakah saya boleh memiliki status intro yang menggambar film dan mendengarkan untuk masuk, dan kemudian memuat status yang memotong pada manajer sumber daya, dan kemudian keadaan permainan yang praktis melakukan segalanya? Bukankah ini juga tampak tidak seimbang bagi Anda? Apakah saya melewatkan sesuatu?

Ini baik-baik saja. Atau setidaknya, ini merupakan peningkatan dari "memiliki saklar jelek besar tergantung pada keadaan permainan itu".

Saya ingin menunjukkan bahwa di sebagian besar gim, Anda akan memerlukan mesin negara berhingga untuk menangani entitas entitas sederhana. Contoh khas adalah musuh yang dalam kondisi Iddle, Attacking atau Dieing.

Jika Anda memiliki Mesin Status Hingga yang cukup abstrak, maka Anda dapat menggunakannya kembali untuk objek Game dan AI Anda; tiba-tiba Anda tidak "menginvestasikan" banyak upaya pada kondisi Game - alih-alih Anda menggunakan kembali kode yang Anda gunakan.

Self-plug Shameless kemudian terjadi: Saya telah mengimplementasikan Mesin Negara Hingga pada pustaka permainan Lua saya, MiddleClass (secara konkret, add-on yang disebut MindState). Inilah cara Anda melakukan Game State dengan itu .


0

Pendekatan yang berbeda untuk ini adalah dengan menggunakan konsep dari dunia pemrograman fungsional yang disebut Serikat Diskriminasi . Meskipun ini biasanya ditemukan dalam bahasa FP, Anda dapat meniru mereka menggunakan kelas .

Pada dasarnya, Serikat Diskriminasi adalah tipe yang selalu merupakan salah satu nkasus, dan data yang disimpan dapat bervariasi dengan setiap kasus.

Sebagai contoh:

type GameState =
  | Menu of MenuState
  | Playing of SimulationState

Di sini, GameStatetipe kami dapat berupa Menuatau Playing. Jika ya Menu, maka akan berisi MenuStateobjek. Jika ya Playing, maka akan berisi SimulationStateobjek.

Untuk memperbarui, kami akan matchpada keadaan, dan memanggil fungsi yang berbeda sesuai:

let update gameTime = 
  let nextState = 
    match gameState with
    | Menu menuState -> updateMenu gameTime menuState
    | Playing simulationState -> updateSimulation gameTime simulationState

  // Mutate the current state
  gameState <- nextState

Dan juga untuk rendering:

let render gameTime = 
  let nextState = 
    match gameState with
    | Menu menuState -> renderMenu menuState
    | Playing simulationState -> renderSimulation simulationState

Salah satu keuntungan dari pendekatan ini adalah bahwa Anda dapat menangani hal-hal lintas negara (seperti sumber daya) dengan lebih mudah tanpa global atau melewati objek "layanan".

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.