Kemarin, saya sudah membaca presentasi dari GDC Canada tentang sistem entitas Attribute / Behavior dan saya pikir ini cukup bagus. Namun, saya tidak yakin bagaimana menggunakannya secara praktis, tidak hanya secara teori. Pertama-tama, saya akan segera menjelaskan kepada Anda bagaimana sistem ini bekerja.
Setiap entitas game (objek game) terdiri dari atribut (= data, yang dapat diakses oleh perilaku, tetapi juga oleh 'kode eksternal') dan perilaku (= logika, yang berisi OnUpdate()
dan OnMessage()
). Jadi, misalnya, dalam klon Breakout, setiap bata akan terdiri dari (misalnya!): PositionAttribute , ColorAttribute , HealthAttribute , RenderableBehaviour , HitBehaviour . Yang terakhir bisa terlihat seperti ini (itu hanya contoh tidak berfungsi yang ditulis dalam C #):
void OnMessage(Message m)
{
if (m is CollisionMessage) // CollisionMessage is inherited from Message
{
Entity otherEntity = m.CollidedWith; // Entity CollisionMessage.CollidedWith
if (otherEntity.Type = EntityType.Ball) // Collided with ball
{
int brickHealth = GetAttribute<int>(Attribute.Health); // owner's attribute
brickHealth -= otherEntity.GetAttribute<int>(Attribute.DamageImpact);
SetAttribute<int>(Attribute.Health, brickHealth); // owner's attribute
// If health is <= 0, "destroy" the brick
if (brickHealth <= 0)
SetAttribute<bool>(Attribute.Alive, false);
}
}
else if (m is AttributeChangedMessage) // Some attribute has been changed 'externally'
{
if (m.Attribute == Attribute.Health)
{
// If health is <= 0, "destroy" the brick
if (brickHealth <= 0)
SetAttribute<bool>(Attribute.Alive, false);
}
}
}
Jika Anda tertarik dengan sistem ini, Anda dapat membaca lebih lanjut di sini (.ppt).
Pertanyaan saya terkait dengan sistem ini, tetapi umumnya setiap sistem entitas berbasis komponen. Saya belum pernah melihat bagaimana semua ini benar-benar bekerja dalam permainan komputer nyata, karena saya tidak dapat menemukan contoh yang baik dan jika saya menemukannya, itu tidak didokumentasikan, tidak ada komentar dan jadi saya tidak memahaminya.
Jadi, apa yang ingin saya tanyakan? Cara mendesain perilaku (komponen). Saya sudah baca di sini, di GameDev SE, bahwa kesalahan paling umum adalah membuat banyak komponen dan hanya, "membuat semuanya menjadi komponen". Saya telah membaca bahwa itu disarankan untuk tidak melakukan rendering dalam komponen, tetapi melakukannya di luar itu (jadi alih-alih RenderableBehaviour , itu mungkin harus RenderableAttribute , dan jika suatu entitas memiliki RenderableAttribute diatur ke true, maka Renderer
(kelas tidak terkait dengan komponen, tetapi ke mesin itu sendiri) harus menariknya di layar?).
Tapi, bagaimana dengan perilaku / komponennya? Katakanlah saya punya level, dan di level, ada Entity button
, Entity doors
dan Entity player
. Ketika pemain bertabrakan dengan tombol (itu adalah tombol lantai, yang diubah oleh tekanan), itu ditekan. Ketika tombol ditekan, itu membuka pintu. Nah, sekarang bagaimana cara melakukannya?
Saya datang dengan sesuatu seperti ini: pemain mendapat CollisionBehaviour , yang memeriksa apakah pemain bertabrakan dengan sesuatu. Jika dia bertabrakan dengan sebuah tombol, itu akan mengirimkan CollisionMessage
ke button
entitas. Pesan akan berisi semua informasi yang diperlukan: siapa yang bertabrakan dengan tombol. Tombol telah mendapat ToggleableBehaviour , yang akan menerima CollisionMessage
. Ini akan memeriksa siapa yang bertabrakan dan jika bobot entitas itu cukup besar untuk beralih tombol, tombol akan beralih. Sekarang, ini mengatur ToggledAttribute dari tombol menjadi true. Baiklah, tapi bagaimana sekarang?
Haruskah tombol mengirim pesan lain ke semua objek lain untuk memberi tahu mereka bahwa itu telah di-toggle? Saya pikir jika saya melakukan semuanya seperti ini, saya akan memiliki ribuan pesan dan itu akan menjadi sangat berantakan. Jadi mungkin ini lebih baik: pintu-pintu terus-menerus memeriksa apakah tombol yang tertaut padanya ditekan atau tidak, dan mengubah OpenedAttribute - nya sesuai. Tetapi kemudian itu berarti bahwa metode pintu OnUpdate()
akan terus melakukan sesuatu (apakah ini benar-benar masalah?).
Dan masalah kedua: bagaimana jika saya memiliki lebih banyak jenis tombol. Satu ditekan oleh tekanan, yang kedua beralih dengan menembaki itu, yang ketiga beralih jika air dituangkan di atasnya, dll. Ini berarti bahwa saya harus memiliki perilaku yang berbeda, seperti ini:
Behaviour -> ToggleableBehaviour -> ToggleOnPressureBehaviour
-> ToggleOnShotBehaviour
-> ToggleOnWaterBehaviour
Apakah ini cara kerja gim yang sebenarnya atau apakah saya bodoh? Mungkin saya bisa memiliki hanya satu ToggleableBehaviour dan itu akan berperilaku sesuai dengan ButtonTypeAttribute . Jadi jika itu adalah ButtonType.Pressure
, ia melakukan ini, jika itu ButtonType.Shot
, ia melakukan sesuatu yang lain ...
Jadi apa yang saya inginkan? Saya ingin bertanya kepada Anda apakah saya melakukannya dengan benar, atau saya hanya bodoh dan saya tidak mengerti maksud komponennya. Saya tidak menemukan contoh yang bagus tentang bagaimana komponen bekerja dalam game, saya menemukan hanya beberapa tutorial yang menjelaskan cara membuat sistem komponen, tetapi tidak bagaimana menggunakannya.
sumber
Entity
memilikiEntityBody
, yang abstrak semua bit jelek. Perilaku kemudian dapat membaca posisi dariEntityBody
, menerapkan kekuatan untuk itu, menggunakan sendi dan motor yang dimiliki tubuh, dll. Memiliki simulasi fisika kesetiaan yang tinggi seperti Box2D tentu saja membawa tantangan baru, tetapi mereka cukup menyenangkan, imo.Component
/System
direferensikan beberapa kali di papan tulis. Implementasi kami memang memiliki beberapa kesamaan.