Cara terbaik untuk mengelola acara dalam game?

13

Saya sedang mengerjakan game di mana beberapa peristiwa dalam game perlu terjadi sesekali. Contoh yang bagus akan menjadi tutorial. Anda memulai permainan, dan pada beberapa titik dalam permainan terjadi suatu peristiwa:

  • Anda menghadapi musuh pertama Anda, permainan berhenti dan Anda menerima penjelasan tentang cara membunuhnya.
  • Anda membunuh musuh pertama, Anda menerima pesan "pekerjaan bagus".
  • Anda mendapatkan item baru, menu dengan popup statistik item.
  • dll.

Gim yang sedang saya kerjakan adalah gim puzzle yang aturan mainnya hampir sama, jadi sepertinya tidak efisien untuk melakukan hardcode semua peristiwa ini di tingkat yang berbeda.

Haruskah saya mendefinisikan peristiwa ini dalam sumber eksternal, seperti XML? Kemudian, tulis penerjemah yang membaca XML dan tetapkan persyaratan acara untuk level tersebut? Saya tidak yakin bagaimana saya bisa mendefinisikan suatu peristiwa yang harus terjadi ketika Anda membunuh dua musuh misalnya.

Untuk lebih jelasnya, saya tidak mencari bahasa pemrograman terbaik atau bahasa scripting untuk melakukan ini, tetapi lebih pada metode terbaik untuk menangani ini.

Terima kasih!


Sunting: Contoh kedua karena pertanyaan saya cukup sulit untuk dipahami:

Masalah yang saya alami adalah untuk menempatkan beberapa tindakan ekstra dalam permainan dalam prosedur yang selalu hampir sama. Seperti pertarungan RPG, setiap orang mendapat giliran, memilih skill, dll - selalu sama. Tapi bagaimana jika ada kasus di mana saya ingin menampilkan cutscene di suatu tempat di antara keduanya. Modyfing seluruh struktur permainan untuk lulus dalam kelas pertempuran yang diubah dengan cutscene termasuk tampaknya sangat tidak efisien. Saya bertanya-tanya bagaimana biasanya ini dilakukan.

omgnoseat
sumber
8
Jangan mencoba menyamaratakan banyak hal, tutorial misalnya sangat spesifik dan datang dengan banyak pemicu / acara yang berbeda. Tidak ada yang salah dengan hardcoding / scripting.
Maik Semder
1
@Maik Jika Anda memasukkannya ke dalam jawaban Id +1 itu .. Sederhana dan terpecahkan lebih baik daripada cantik setiap hari.
James
Contoh kedua Anda membuatnya jauh lebih jelas bahwa sistem pesan abstrak akan menjadi kemenangan besar. Untuk tutorial, Anda hanya dapat melakukan hard-code karena hanya terjadi sekali saja di awal, tetapi untuk acara yang sedang berlangsung yang dapat terjadi kapan saja selama seluruh permainan, nah itu berbeda.
jhocking
Masih agak kabur, sebutkan setidaknya 3 pemicu untuk 3 cutscene berbeda. sangat sulit dijawab secara umum. Pada dasarnya Anda harus menemukan pola umum untuk memahami cara menerapkannya dengan terbaik.
Maik Semder
Apa yang kamu inginkan? Anda ingin menjeda tindakan dan melakukan tindakan tambahan, lalu membatalkan jeda tindakan?
user712092

Jawaban:

7

Ini sangat tergantung pada bagaimana acara sebenarnya dikomunikasikan antar objek dalam game Anda. Misalnya, jika Anda menggunakan sistem pesan pusat maka Anda bisa memiliki modul tutorial yang mendengarkan pesan tertentu dan membuat popup tutorial setiap kali mendengar pesan tertentu. Kemudian Anda dapat mengatur pesan apa yang harus didengarkan, beserta sembulan yang ditampilkan, dalam file XML atau sesuatu yang diuraikan oleh modul tutorial. Dengan memiliki objek tutorial terpisah yang memantau keadaan gim dan menampilkan sembulan tutorial saat memperhatikan hal-hal di gim, Anda dapat mengubah objek tutorial sesuka hati tanpa perlu mengubah apa pun tentang gim Anda. (Apakah ini pola Pengamat? Saya tidak terbiasa dengan semua pola desain.)

Secara keseluruhan meskipun itu tergantung pada kompleksitas tutorial Anda jika itu layak dikhawatirkan. Hard-coding peristiwa dalam kode Anda dan / atau tingkat tidak tampak seperti masalah besar bagi saya hanya beberapa popup tutorial. Saya ingin tahu apa sebenarnya yang ada dalam pikiran Anda yang membuat Anda berpikir itu tidak efisien, karena semua yang harus Anda lakukan setiap pemicu hanya mengirim pesan ke modul tutorial, seperti TutorialModule.show ("1st_kill");

jhocking
sumber
Saya pikir karena ini permainan puzzle logikanya ada di satu lokasi untuk beberapa level dan semacamnya, membuat pemeriksaan untuk kita melakukan tutorial untuk ini menjadi sesuatu yang berlangsung di seluruh. Jujur jika itu adalah permainan puzzle, saya tidak berpikir ini akan mengambil hit besar untuk itu bahkan jika itu bukan kode tercantik, dan pada akhirnya kode hari yang bekerja dalam permainan yang dikirimkan selalu-selalu- 100% lebih baik daripada kode cantik yang tidak pernah melihat cahaya hari;)
James
Tidak pernah memikirkan sesuatu seperti pola pengamat, terdengar seperti solusi yang bagus. Saya akan mencobanya, terima kasih :)
omgnoseat
7

Inilah batasan desain yang saya pahami:

  1. Kode gameplay inti tidak peduli dengan persyaratan level dan tidak boleh digabungkan dengan kode yang berhubungan dengannya.

  2. Pada saat yang sama, itu adalah kode gameplay inti yang tahu kapan peristiwa spesifik yang memenuhi persyaratan tersebut terjadi (mendapatkan item, membunuh musuh, dll.)

  3. Level yang berbeda memiliki serangkaian persyaratan yang berbeda dan mereka perlu dijelaskan di suatu tempat.

Mengingat itu, saya kemungkinan akan melakukan sesuatu seperti ini: Pertama, buat kelas yang mewakili tingkat permainan. Ini akan merangkum sekumpulan persyaratan spesifik yang dimiliki suatu level. Ini memiliki metode yang dapat dipanggil ketika peristiwa permainan terjadi.

Berikan kode gameplay inti referensi ke objek level saat ini. Ketika peristiwa gameplay terjadi, itu akan memberitahu tingkat dengan memanggil metode di atasnya: enemyKilled, itemPickedUp, dll

Secara internal, Levelperlu beberapa hal:

  • Negara untuk melacak peristiwa yang sudah terjadi. Dengan cara ini dapat membedakan musuh pertama yang terbunuh dari yang lain, dan tahu kapan pertama kali Anda mengambil item yang diberikan.
  • Daftar LevelRequirementobjek yang menggambarkan kumpulan tujuan spesifik yang Anda butuhkan untuk level itu.

Saat Anda memasuki level, Anda akan membuatnya Leveldengan hakLevelRequirement s , mengatur kode gameplay, dan memberinya level itu.

Setiap kali terjadi pertandingan, gameplay meneruskannya Level. Yang pada gilirannya menghitung data agregat (jumlah total musuh yang terbunuh, musuh jenis itu yang terbunuh, dll.) Ia kemudian berjalan melalui objek-objek kebutuhannya, memberikan masing-masing data agregat. Suatu persyaratan menguji untuk melihat apakah telah terpenuhi, dan jika demikian memunculkan perilaku apa pun yang dihasilkan sesuai (menampilkan teks tutorial, dll.)

LevelRequirement pada dasarnya membutuhkan dua hal:

  1. Deskripsi tes untuk mengetahui apakah persyaratan telah dipenuhi. Ini bisa saja berfungsi jika bahasa Anda membuatnya mudah, jika tidak, Anda bisa memodelkannya dalam data. (Yaitu memiliki RequirementTypeenum dengan hal-hal seperti FIRST_KILLdan kemudian besar switchpada yang tahu cara memeriksa setiap jenis.)
  2. Suatu tindakan untuk dilakukan ketika persyaratan terpenuhi.

Masih ada pertanyaan di mana seperangkat persyaratan tersebut dijelaskan. Anda dapat melakukan sesuatu seperti XML atau format file teks lainnya. Itu berguna jika:

  1. Non-programmer akan menjadi level authoring.
  2. Anda ingin dapat mengubah persyaratan tanpa kompilasi ulang dan / atau memulai kembali.

Jika tidak ada yang seperti itu, saya mungkin akan langsung membangunnya dalam kode. Simpler selalu lebih baik.

banyak sekali
sumber
3 poin pertama adalah deskripsi yang sangat dekat dari metode yang saya gunakan sekarang, mengesankan! Ya hal yang paling saya perjuangkan adalah di mana menggambarkan persyaratan, dan bagaimana menerjemahkannya ke permainan (karena kemungkinan besar itu akan menjadi sesuatu yang eksternal). Terima kasih atas penjelasan mendalamnya :)
omgnoseat
5

Saya pikir Anda perlu tahu cara membuat acara ini dan sisa posting adalah tentang hal itu, Jika Anda hanya ingin menyimpan acara ini maka gunakan beberapa basis data relasional atau uraikan dengan teks dan gunakan bahasa scripting (dia akan melakukan parsing dan mengevaluasi untuk Kamu). :)

Yang Anda inginkan adalah mengenali peristiwa yang terjadi (1) dan kemudian melakukan beberapa tindakan yang diminta oleh peristiwa ini (pesan cetak, periksa penekanan tombol ...) (2). Anda juga ingin membuat acara ini hanya terjadi sekali (3).

Pada dasarnya Anda ingin memeriksa kondisi dan kemudian menjadwalkan beberapa perilaku.

Cara mengenali acara (1)

  • Anda ingin mengenali peristiwa seperti "musuh pertama yang dijumpai" ini, "item baru didapat"
  • jika bagian generik terjadi, " musuh bertemu ", " item diperoleh " Anda memeriksa bagian tertentu " pertama ...", " item baru didapat"

Terbuat dari apa acara

Dalam pandangan yang lebih umum, setiap peristiwa semacam itu terbuat dari:

  • prasyarat , Anda memeriksanya
  • tindakan yang akan dilakukan ketika prasyarat terpenuhi (katakan "" Kamu membunuh musuh pertama! ", katakan" "buat kombo dengan menekan tombol A dan B", katakan "tekan 'enter' untuk melanjutkan", perlu-kunci "enter")

Cara menyimpan acara ini

Dalam beberapa struktur data:

  • memiliki daftar prasyarat (string atau kode jika Anda menulisnya dalam bahasa tingkat tinggi)
  • memiliki daftar tindakan (mungkin berupa string, Mesin gempa menggunakan string untuk acara)

Anda juga dapat menyimpannya di basis data relasional, meskipun sepertinya tidak perlu, jika Anda ingin membuat game ini dalam jumlah besar, Anda mungkin perlu membuatnya.

Anda kemudian harus mengurai string / hal-hal ini. Atau Anda dapat menggunakan beberapa bahasa skrip seperti Python atau LUA atau bahasa seperti LISP, mereka semua dapat menguraikan dan menjalankannya untuk Anda. :)

Bagaimana cara menggunakan acara ini di loop game (2)

Anda akan membutuhkan dua struktur data ini:

  • antrian acara (acara yang dijadwalkan akan dijalankan ada di sini)
  • antrian tindakan (tindakan terjadwal, acara menyiratkan tindakan mana yang dilakukan)

Algoritma:

  • Jika Anda mengenali beberapa acara 's prasyarat terpenuhi Anda menempatkannya dalam antrian acara
  • (3) Maka Anda harus memastikan acara ini terjadi hanya sekali jika Anda mau :) (misalnya dengan array boolean has_this_event_happened ["musuh pertama kali ditemui"])
  • (jika antrian tindakan kosong, maka) Jika ada kejadian dalam antrian acara Anda memasukkan tindakannya ke antrian tindakan dan menghapusnya dari antrian acara
  • Jika ada tindakan dalam tindakan antrian, Anda mulai melakukan apa yang diminta
  • Jika tindakan tersebut dilakukan, Anda menghapusnya dari antrian tindakan

Cara membuat tindakan ini sendiri (2)

Anda membuat daftar objek, yang memiliki fungsi "pembaruan". Mereka kadang-kadang disebut entitas (dalam mesin Gempa) atau aktor (dalam mesin Unreal).

  1. Anda mulai objek-objek ini ketika mereka diminta untuk mulai dalam antrian tindakan.
  2. objek ini dapat digunakan untuk hal-hal lain seperti beberapa timer lainnya. Dalam Quake, entitas ini digunakan untuk seluruh logika game, saya sarankan Anda untuk membaca beberapa materi tentang itu .

Aksi "katakan sesuatu"

  1. Anda mencetak sesuatu di layar
  2. Anda ingin pesan ini muncul selama beberapa detik
  3. di "perbarui":
    • buat variabel remove_me_after dan kurangi dengan waktu yang berlalu
    • ketika variabel 0 Anda menghapus tindakan ini dari antrian tindakan
    • Anda juga menghapus objek ini (atau menjadwalkannya untuk dihapus ...)

Tindakan "memerlukan kunci"

  1. Itu tergantung pada bagaimana Anda ingin membuatnya, tetapi saya pikir Anda membuat pesan
  2. di "perbarui" ":
    • Anda cukup memeriksa acara penekanan tombol yang diinginkan
    • Anda mungkin perlu beberapa array / antrian untuk mengadakan acara penekanan tombol
    • maka Anda dapat menghapusnya dari antrian tindakan dan menghapus objek

Metode apa yang harus dipelajari

pengguna712092
sumber
-1 benar, atau dia hanya memanggil fungsi, serius, OP hanya ingin kotak pesan ketika kondisi tertentu terpenuhi
Maik Semder
Itu tulisan yang sangat bagus, tetapi tidak persis apa yang saya cari. Saya memang kesulitan menjelaskan apa yang saya inginkan. Saya menambahkan penjelasan kedua: Masalah yang saya hadapi adalah menempatkan beberapa tindakan ekstra dalam permainan dalam prosedur yang selalu hampir sama. Seperti pertarungan RPG, setiap orang mendapat giliran, memilih skill, dll - selalu sama. Tetapi bagaimana jika ada kasus di mana saya akan menampilkan cut-scene di suatu tempat di antara keduanya. Modyfing seluruh struktur permainan untuk lulus dalam kelas pertempuran yang diubah dengan cutene termasuk tampaknya sangat tidak efisien. Saya bertanya-tanya bagaimana ini biasanya dilakukan?
omgnoseat