Pertanyaanku adalah:
Bagaimana saya bisa menangani keadaan gim dalam sistem entitas saya, tanpa menggunakan tumpukan benda keadaan gim di sekitar?
Jadi desain sistem entitas saya berarti bahwa ketika entitas perlu mendaftar untuk acara input misalnya, komponen input memanggil sistem input dan mengatakan "daftarkan entitas ini untuk input ini". Ini semua baik-baik saja dan baik, namun jika Anda menambahkan ke dalam konsep ini kondisi permainan (katakanlah layar jeda), itu menjadi masalah untuk diselesaikan jika suatu entitas berada dalam kondisi saat ini dan harus menerima input.
Saya dapat menambah komponen input / sistem sehingga dikatakan, "daftarkan entitas ini untuk input ini saat berada di status permainan ini", tetapi ini mengharuskan setiap entitas tahu di mana menyatakan akan digunakan, dan itu mungkin tidak jelas. Selain itu, menjaga daftar status permainan sekitar per input yang terdaftar (dan sistem lain yang menggunakan panggilan balik) kedengarannya tidak terlalu efisien.
Gagasan lain yang saya miliki adalah karena akan ada entitas yang mewakili kondisi permainan, tandai sebagai dinonaktifkan, lalu saat membuat acara masukan, periksa apakah entitas tersebut bukan turunan dari entitas kondisi permainan yang dinonaktifkan. Tampaknya mahal untuk melatih orang tua untuk setiap panggilan balik.
Gagasan lain adalah membuat semua sistem menyimpan data mereka dikunci melawan keadaan saat ini, sehingga ketika menghasilkan input, entitas target bahkan tidak akan menjadi kandidat. Namun ini benar-benar menyakiti kemampuan untuk memungkinkan komunikasi antara entitas di negara yang berbeda (tidak begitu menjadi masalah untuk layar jeda, tetapi berpikir memilih kunci di Oblivion / Skyrim).
Satu-satunya ide lain yang saya miliki adalah meminta semua komponen menangani perubahan keadaan dan berkomunikasi dengan sistem yang relevan untuk menonaktifkan apa pun yang telah mereka daftarkan, dan mengaktifkannya kembali ketika beralih kembali ke keadaan ini.
Yang kedua (tandai objek sebagai dinonaktifkan) dan sebagainya (masing-masing komponen berurusan dengan perubahan keadaan) tampak seperti yang terbaik dari ide-ide saya, tetapi tidak satu pun dari mereka yang menganggap saya sangat hebat.
Apakah ada orang lain yang punya ide lain tentang cara melakukan ini?
sunting Sementara saya berbicara tentang input secara khusus dalam pertanyaan ini, ini dapat berarti sistem apa pun yang mampu mengirim pesan / acara ke entitas, seperti tabrakan, acara pengatur waktu, dll ...
sumber
Jawaban:
Apa yang sering digunakan adalah perantara
Intent System
yang mengabstraksi input dan melacak konteks dan gamestate yang relevan.Sistem Intent akan berhenti mengirimkan input ketika simulasi dijeda misalnya. Ini juga menangani pemetaan antara peristiwa dan niat pengontrol (bergerak ke arah, menjalankan, menembak, memuat ulang ...).
Dengan cara ini, pelanggan Anda yang lain tidak bergantung pada gamepad / input tertentu (BUTTON_A, BUTTON_B vs BUTTON_X, BUTTON_O ...) tetapi mereka semua bereaksi terhadap maksud yang sama (IntentRun, IntentReload ...).
Keuntungan lain adalah bahwa sistem niat dapat menyadari adanya pengendali yang ditambahkan / dihapus, karena dapat mengirim maksud ke pelanggan apa pun bahkan di luar simulasi Anda dapat menangani maksud seperti itu
AddPlayer(controllerID)
.Berapa banyak informasi tentang status permainan yang Anda berikan ke sistem baik melalui acara / pesan atau langsung terserah Anda. Tetapi waktu yang diinvestasikan dalam sistem Intent biasanya sepadan.
Anda dapat mengelola Konteks Intent yang akan menghasilkan intents ketika mereka dilampirkan ke sistem.
Konteksnya dapat diprioritaskan, yaitu:
Dengan cara ini Anda dapat menambah dan menghapus konteks yang saat ini relevan.
Dan satu hal tentang seluruh sistem maksud adalah bahwa ia harus berjalan saat simulasi dijeda.
Salah satu cara yang sering digunakan untuk memainkan / menghentikan sementara simulasi permainan tanpa memutakhirkan pembaruan yang tidak terkait simulasi adalah dengan menggunakan rangkaian waktu yang berbeda. yaitu
GenericSystem::onTime(Long time, Long deltaTime, Long simTime, Long simDeltaTime)
.Dengan pendekatan ini, mesin Anda dapat dengan mudah memblokir kenaikan pada simTime gim yang pada gilirannya akan memblokir pembaruan pada animasi & mesin fisika yang relevan yang menggunakan
simTime and simDeltaTime
sementara memungkinkan pembaruan terus menerus dari efek pegas kamera Anda jika harus bergerak bahkan selama jeda, animasi dari efek pemuatan pada papan iklan dalam game virtual saat data sedang diunduh ...sumber
Bagaimana dengan membuat sistem acara global dan kemudian memiliki komponen pendengar acara untuk masing-masing entitas Anda? Setelah acara "Perubahan Status Game" Anda dapat bermain-main dengan komponen secara individual untuk setiap entitas tertentu.
Katakanlah Anda memiliki komponen input. Setelah komponen pendengar acara menerima acara perubahan kondisi permainan, itu mengubah nilai yang sangat spesifik untuk komponen input tertentu, sehingga tidak akan menerima panggilan input apa pun atau tidak akan membuat gerakan atau panggilan respons apa pun ke sistem atau pemiliknya.
Ini berfungsi untuk saya karena sebagian besar komponen saya ditulis (melalui Lua). Yaitu saya memiliki komponen input, yang dipicu sekali ketika tombol ditekan dan itu api dari gerakan + arah dan kemudian dipicu ketika kunci dilepaskan dan itu api dari arah + berhenti. Ada juga komponen pendengar acara yang menghubungi komponen input (jika permainan dijeda) untuk berhenti melakukan fungsi menembak dan berhenti jika perlu. Saya kemudian dapat dengan mudah menambahkan entitas lain dengan reaksi berbeda terhadap peristiwa yang sama dan penekanan tombol menggunakan skrip lain. Dengan cara ini Anda akan menyimpan interaksi antara entitas yang berbeda di negara bagian yang berbeda dan bahkan membuatnya lebih dapat disesuaikan. Terlebih lagi, beberapa entitas bahkan mungkin tidak memiliki komponen pendengar acara di dalamnya.
Apa yang baru saja saya jelaskan pada dasarnya adalah contoh praktis dari solusi keempat Anda.
sumber