Mengidentifikasi Entitas 'Jenis' dalam Sistem Entitas-Komponen

10

Jika Entitas tidak memiliki 'tipe' eksplisit (misalnya pemain) dan hanya kumpulan komponen, bagaimana cara mengidentifikasi entitas yang harus dan tidak seharusnya dikerjakan oleh sistem saya? Misalnya, dalam permainan Pong, dayung dan bola keduanya bertabrakan dengan batas jendela. Namun, sistem penanganan tabrakan untuk masing-masing akan berbeda, oleh karena itu sistem seharusnya tidak menangani entitas dengan tipe yang salah.

void PlayerCollisionSystem::update(std::vector<Entity *> entities) {
  typedef std::vector<Entity *>::iterator EIter;
  for (EIter i = entities.begin(); i != entities.end(); ++i) {
    Entity *player = *i; // How do I verify that the entity is a player?

    // Get relevant components.
    PositionComponent *position = player->getComponent<PositionComponent>();
    VelocityComponent *velocity = player->getComponent<VelocityComponent>();
    SpriteComponent *sprite = player->getComponent<SpriteComponent>();

    // Detect and handle player collisions using the components.
  }
}

Baik pemain dan bola berbagi jenis komponen yang relevan untuk penanganan tabrakan namun implementasi sistem mereka akan berbeda.

Jika saya memiliki wadah semua entitas game, bagaimana cara mengidentifikasi tipe entitas tertentu tanpa mewarisi Entityatau menyertakan variabel anggota seperti std::string type, dalam hal mana entitas tidak lagi sekadar kumpulan komponen?

Garee
sumber

Jawaban:

21

Jawaban Nicol Bolas langsung, tetapi melangkah ke samping dan melihat masalah Anda dari jauh: Anda benar-benar tidak memerlukan jenis entitas.

Anda hanya perlu peduli apakah "apakah objek memiliki komponen X" atau tidak dan masalah Anda adalah bahwa Anda belum diidentifikasi dengan benar X. Jika dua objek berperilaku berbeda maka berikan mereka komponen yang berbeda atau cukup beri tanda boolean pada komponen jika itu membuatnya berperilaku berbeda untuk konfigurasi objek yang berbeda. Gunakan sistem komponen untuk membuat keputusan tentang perilaku, bukan "tipe" entitas. Itulah inti menggunakan komponen.

Anda sepenuhnya diperbolehkan memiliki PaddlePhysicskomponen / sistem dan BallPhysicskomponen / sistem terpisah jika mereka berperilaku berbeda. Atau Anda dapat memecah komponen menjadi potongan-potongan yang lebih granular sehingga Anda memiliki Bouncekomponen yang hanya dimiliki Ball dan StopAtBoundarykomponen yang keduanya Balldan Paddledimiliki jika bagian dari perilaku cukup rumit untuk membenarkan berbagi kode. Atau Anda bisa membuat PongPhysicskomponen yang memiliki boolean flag yang Bouncesditetapkan trueuntuk Balldan falseuntuk Paddle. Anda bahkan dapat membuat WallCollisionkomponen dasar dan kemudian memperoleh komponen itu untuk mendapatkan komponen BallWallCollisionyang menambahkan perilaku ekstra yang diperlukan di sana.

Sean Middleditch
sumber
4
Saya pikir ini harus menjadi jawaban yang diterima karena sama sekali tidak ada kendala atau masalah dengan ECS "vanilla". Entitas pemberian tag dapat dengan mudah dilakukan dengan membuat komponen khusus yang berfungsi sebagai penanda. Ini juga bisa menjadi PlayerTypeComponent dummy yang tidak melakukan apa pun yang berguna tetapi hanya berfungsi sebagai tag.
tiguchi
19

Suatu sistem hanya berguna jika bermanfaat. Jika suatu sistem di mana suatu entitas "hanya kumpulan komponen" kurang berguna daripada sistem di mana entitas sebagian besar merupakan "kumpulan komponen", maka lakukan itu .

Berhentilah mencoba membuat sistem "murni" dan fokus untuk membuat yang bagus yang melakukan apa yang Anda butuhkan. Gunakan komponen hingga komponen tidak lagi berguna bagi Anda. Kemudian gunakan sesuatu yang lain.

Anda sudah menghabiskan lebih banyak waktu untuk memikirkan hal ini daripada yang seharusnya.

Nicol Bolas
sumber
sangat bagus +1 "Kamu sudah menghabiskan lebih banyak waktu memikirkan hal ini daripada yang pantas"
wes
8
Saya tidak berpikir ini adalah jawaban sama sekali, Topik penyempurnaan ECS adalah salah satu yang patut mendapat perhatian signifikan, dan Garee (ketika dia memposting ini pada tahun 2013) mungkin tidak menghabiskan cukup waktu untuk memikirkannya. Gagasan bahwa topik tersebut tidak pantas mendapatkan lebih banyak waktu menyiratkan bahwa sistem harus sederhana atau sepele dan umumnya tidak layak untuk zaman kita. Saya lebih suka jawaban Sean Middleditch karena sebenarnya mencoba menjawab pertanyaan daripada mengabaikannya.
Gavin Williams
Jawaban yang bagus Saya menemukan diri saya harus mengatakan ini kepada diri sendiri sesekali. Fokus untuk bergerak maju.
Dominic Bou-Samra
5

Jika Anda ingin memberikan entitas tipe eksplisit, cara termudah adalah dengan menentukan variabel tipe dalam kelas entitas. Hanya pertahankan pola EC selama ini berguna.

Kalau tidak jenisnya tersirat melalui atribut komponen. Sebagai contoh, komponen fisika akan memiliki atribut untuk mobile vs stasioner. Sistem kemudian tahu kapan dua ponsel bertabrakan (bola dan dayung). Demikian pula Anda dapat memiliki atribut untuk bagaimana sistem tabrakan harus merespons. Hentikan saja obyeknya atau refleksikan? Melihat atribut seharusnya memberi Anda gagasan tentang apa entitas itu, tetapi itu tidak relevan. Sistem seharusnya tidak perlu tahu apa jenis entitas yang mereka kerjakan, mereka harus diberi informasi yang cukup menggunakan komponen yang disediakan untuk mereka.

Akhirnya, dapat menambahkan komponen tambahan yang berisi tipe, tetapi, seperti menambahkan tipe ke entitas, Anda akhirnya akan menulis banyak jenis kode spesifik, mengalahkan tujuan sistem EC.

MichaelHouse
sumber
0

Entitas adalah seperangkat komponen. Anda tidak dapat menetapkan label yang rapi ke set acak. Menyerahkan batasan tipe adalah harga untuk fleksibilitas yang luar biasa.

Tentu saja Anda dapat memiliki kelas entitas (diketik) khusus yang memberlakukan pembatasan pada komponen.

Idealnya komponen independen. Jadi solusi untuk masalah Anda adalah memanggil penanganan tabrakan pada setiap subkomponen, secara berurutan. Dalam aplikasi nyata ada saling ketergantungan dan masalah pemesanan. Jika itu masalahnya, Anda memerlukan logika 'dispatcher' di setiap metode kelas Entity.

Karl
sumber