Apakah saya, dan bagaimana, memisahkan masalah input dan objek game?

20

Mungkin di setiap game pengembang harus berurusan dengan input, entah itu kejadian keyboard dan mouse sederhana, acara sentuh atau sesuatu sebagai input accelerometer. Input ini secara langsung dari efek tidak langsung objek dalam permainan. Terkadang input yang sama dapat mempengaruhi objek yang berbeda. Sekarang saya sudah memikirkan bagaimana membuat model ini. Cara saya melihatnya ada dua pendekatan yang berbeda.

  • Biarkan objek game itu sendiri yang menanganinya, berlangganan ke acara dan menyebutnya metode sendiri. Ini memiliki keuntungan membiarkan objek-objek permainan itu sendiri memutuskan input mana yang menyebabkan tindakan mana. Kelemahan tampaknya adalah bahwa kode input akan hancur dengan kode objek game "inti". Juga objek permainan tidak menyadari keadaan sisa permainan, dan kadang-kadang mungkin tidak bertindak berdasarkan masukan peristiwa. Ini sepertinya tidak benar.

  • Mintalah input-controller umum untuk mengurus semua input dan membuat keputusan tentang siapa yang akan menangani acara apa. Hal ini tampaknya memisahkan masalah dengan lebih baik, tetapi secara ketat memasangkan kelas input-controller ke objek-game. Entah bagaimana perlu tahu siapa yang ingin menerima acara mana dan di negara mana. Ini sepertinya juga tidak benar.

Strategi apa yang Anda gunakan untuk menangani ini?

Robert Massa
sumber

Jawaban:

7

Saya sarankan memisahkan acara input dari objek game sehingga Anda dapat dengan cepat mengubah / meningkatkan metodologi input tanpa harus mengedit dan men-debug 10 kelas objek. Contohnya adalah beralih dari kontrol hanya keyboard ke keyboard + mouse, atau hanya menetapkan kembali tombol.

Alih-alih menyambungkan erat input ke objek game individual, panggil hanya satu metode per sinyal input unik pada objek game, dan biarkan ia memutuskan cara untuk menjalankannya.

Gunakan pengontrol input untuk melacak status input:

Up press event   -> dir = up
Down press event -> dir = down

Setiap kali kondisi input berubah, evaluasi apakah objek game siap dimodifikasi:

set dir  ->  if gamestate != paused && battlemode == false
             ->  character.changeDir(dir);

Terapkan metode umum pada objek game Anda, yang dapat dipanggil oleh pengontrol input, atau objek game lainnya, sesuai kebutuhan:

changeDir (dir)
setSpeed (walk/run)
Edwardian
sumber
7

Saya merekomendasikan pendekatan MVC. Dalam MVC objek game hanya perlu khawatir tentang pemodelan sistem game, dan menyediakan antarmuka tingkat tinggi seperti move_left. Kemudian memiliki objek pengontrol yang khawatir tentang memetakan input ke panggilan model. Tidak hanya memungkinkan untuk perubahan kontrol yang mudah, ia memberikan antarmuka yang baik untuk AI mereka hanyalah pengontrol lain.

Dalam opsi kedua Anda, saya akan membagi pengontrol input menjadi dua bagian, yang menangani sentuhan perangkat yang sebenarnya, keyboard, accel, apa pun yang Anda bisa melemparnya, memetakannya ke dalam set input umum. Kemudian miliki bagian kedua yang memetakan input umum ke input spesifik game. Ucapkan keyboard panah atas peta untuk input1 kemudian menyentuh bagian atas layar sentuh juga memetakan ke input1 juga sekarang Anda menulis bagian kedua yang memetakan input 1 untuk melompat. Sekarang Anda dapat memetakan perangkat IO apa pun serta playback yang disimpan atau input AI ke sistem input generik ini dan memiliki bagian spesifik gim kecil yang memuat apa yang input1 artinya bagi model.

stonemetal
sumber
5
Ada banyak diskusi di tempat lain di situs ini tentang mengapa MVC umumnya bukan pola yang sesuai untuk game; apa yang dijelaskan stonemetal bahkan bukan MVC, itu hanya abstraksi; dan "Gunakan MVC" bukan jawaban, karena MVC adalah deskripsi seluruh kelas arsitektur dan bukan cara khusus untuk memisahkan masalah (atau satu-satunya cara untuk melakukannya).
2
MVC harus memberinya A) artikel wikipedia untuk membaca B) sejumlah variasi tentang cara mendekati solusi yang telah terbukti bekerja C) Saya menyebutkan cara saya akan mengaturnya di mana model memperlihatkan antarmuka tingkat tinggi bahwa controller memetakan input level rendah (nyata atau sintetis) ke aksi level tinggi dan secara langsung memanipulasi model daripada beberapa sistem acara.
stonemetal
1

Saya akan menyarankan untuk membuat permainan Anda ( Model ) mendefinisikan daftar kemungkinan peristiwa input (diimplementasikan sebagai enum atau objek dengan antarmuka dasar yang sama). Hal-hal seperti MovingRightStarted, MovingRightStopped, FiredWeapon1, Escape, dll ...

Gim ini mendefinisikan struktur data (misalnya a queue) yang dapat diisi oleh kode input Anda ( Pengontrol ) dengan acara masukan.

Kemudian game Anda dapat polling struktur data untuk mendapatkan acara input.

Dengan cara ini, Anda bisa mencolokkan berbagai jenis pengontrol untuk memberi makan model:

  • Hanya keyboard
  • Keyboard + Mouse
  • Joystick
  • Layar sentuh
  • Kecerdasan buatan

Anda hanya perlu mendorong mereka untuk memasukkan acara ke model.

Splo
sumber
Saya pikir saya mengerti apa yang Anda maksud, kecuali untuk Anda pilihan queuesebagai datatype untuk menyimpan ini. Bisakah Anda menjelaskan mengapa?
Robert Massa
Nah antara 2 input polling acara dari model, controller mungkin telah mendorong beberapa event aksi, dan penting untuk menjaga urutan input pengguna. Itu sebabnya saya memilih struktur data FIFO. Sebenarnya Anda mungkin juga perlu menentukan kapan input itu terjadi.
Splo