Saya telah berjuang dengan cara mengimplementasikan skrip di mesin game saya. Saya hanya memiliki beberapa persyaratan: Ini harus intuitif, saya tidak ingin menulis bahasa kustom, parser dan interpreter, dan saya tidak ingin menggunakan threading. (Saya yakin ada solusi yang lebih sederhana; Saya tidak perlu kerumitan banyak untaian logika permainan.) Berikut ini contoh skrip, dengan Python (alias pseudocode):
def dramatic_scene(actors):
alice = actors["alice"]
bob = actors["bob"]
alice.walk_to(bob)
if bob.can_see(alice):
bob.say("Hello again!")
else:
alice.say("Excuse me, Bob?")
Sepenggal kisah mendongeng itu menimbulkan masalah implementasi. Saya tidak bisa hanya mengevaluasi seluruh metode sekaligus, karena walk_to
membutuhkan waktu permainan. Jika kembali segera, Alice akan mulai berjalan ke Bob, dan (dalam bingkai yang sama) menyapa (atau disambut). Tetapi jika walk_to
ada panggilan pemblokiran yang kembali ketika dia mencapai Bob, maka permainan saya macet, karena itu memblokir alur eksekusi yang sama yang akan membuat Alice berjalan.
Saya mempertimbangkan untuk membuat setiap fungsi sebagai tindakan - alice.walk_to(bob)
akan mendorong suatu objek ke antrian, yang akan muncul setelah Alice mencapai Bob, di mana pun dia berada. Itu lebih rusak: if
cabang dievaluasi segera, jadi Bob mungkin menyapa Alice bahkan jika punggungnya berbalik padanya.
Bagaimana mesin / orang lain menangani skrip tanpa membuat utas? Saya mulai mencari di area non-game-dev, seperti rantai animasi jQuery, untuk mencari ide. Sepertinya harus ada beberapa pola yang baik untuk masalah seperti ini.
Jawaban:
Cara sesuatu seperti Panda melakukan ini adalah dengan callback. Alih-alih memblokir itu akan menjadi sesuatu seperti
Memiliki panggilan balik yang lengkap memungkinkan Anda untuk menghubungkan peristiwa semacam ini sedalam yang Anda inginkan.
EDIT: Contoh JavaScript karena memiliki sintaks yang lebih baik untuk gaya ini:
sumber
Istilah yang ingin Anda cari di sini adalah " coroutines " (dan biasanya kata kunci bahasa atau nama fungsinya
yield
).Implementasi akan tergantung pertama-tama pada bahasa Anda. Untuk gim Anda ingin implementasinya seberat mungkin (lebih ringan dari benang atau bahkan serat). Halaman Wikipedia (tertaut) memiliki beberapa tautan ke berbagai implementasi khusus bahasa.
Saya mendengar Lua memiliki dukungan bawaan untuk coroutine. Begitu juga GameMonkey.
UnrealScript mengimplementasikan ini dengan apa yang disebutnya "status" dan "fungsi laten".
Jika Anda menggunakan C # Anda bisa melihat posting blog ini oleh Nick Gravelyn.
Selain itu, ide "rantai animasi", meskipun bukan hal yang sama, adalah solusi yang bisa diterapkan untuk masalah yang sama. Nick Gravelyn juga memiliki implementasi C # ini .
sumber
yield return walk_to();
di skrip Anda.tidak akan berulir cerdas.
Sebagian besar mesin gim bekerja sebagai serangkaian tahap modular dengan hal-hal di memori yang mendorong setiap tahap. Untuk 'walk to example' Anda, Anda biasanya memiliki tahap AI di mana karakter Anda berjalan dalam keadaan di mana mereka tidak harus mencari musuh untuk dibunuh, tahap animasi di mana mereka harus menjalankan animasi X, tahap fisika (atau tahap simulasi) di mana posisi aktualnya diperbarui, dll.
dalam contoh Anda di atas, 'alice' adalah aktor yang terdiri dari potongan-potongan yang hidup di banyak tahapan ini, jadi aktor yang menghalangi. untuk membuat banyak keputusan.
Sebagai gantinya, fungsi 'start_walk_to' mungkin akan melakukan sesuatu seperti:
Kemudian, loop utama Anda menjalankan tanda ai, tanda fisika, tanda animasi, dan tanda cutscene, dan cutscene memperbarui status untuk setiap subsistem di mesin Anda. Sistem cutscene pasti harus melacak apa yang masing-masing cutscene lakukan, dan sistem yang didorong coroutine untuk sesuatu yang linier dan deterministik seperti custscene mungkin masuk akal.
Alasan untuk modularitas ini adalah bahwa hal itu hanya membuat hal-hal bagus dan sederhana, dan untuk beberapa sistem (seperti fisika dan AI), Anda perlu mengetahui keadaan segalanya pada saat yang sama untuk menyelesaikan sesuatu dengan benar dan menjaga permainan dalam keadaan konsisten .
semoga ini membantu!
sumber