Bileşen tabanlı bir oyunda çarpışma nasıl doğru bir şekilde ele alınır?


11

Bileşenlerin etrafında tasarlanmış bir oyunda çarpışmayı düzgün bir şekilde ele alma yollarının etrafına sarılmaya çalışıyorum.

Birçok örnek PhysicsComponent, varlığın bileşen listesine eklenen bir çeşit var ama gerçek uygulama beni karıştırıyor.

Bunun çalışması PhysicsComponentiçin etrafındaki dünyaya erişmesi gerekir. Bu benim için sezgisel bir anlam ifade etmiyor. Bir bileşen sadece konteynerinin (varlık) değil, aynı zamanda konteynerinin konteynerinin (dünya) farkında olmamalı mıdır?

Bana göre, seviye veya sahne bu varlıkların bir listesini tutmalı ve her oyun güncellemesi, hangi çarpışmayı belirlemek için varlıklar arasında dolaşmalıdır.

Benim sorum öncelikle, bunun iyi bir tasarım olup olmadığı ve ikincisi, hangi varlıkların çarpışabileceğini belirleme. Katı varlıkların boş bir IRigidBody arabirimi uygulayabileceğini düşünüyorum, böylece listedeki hangi varlıkların çarpışmayı desteklediğini belirleyebilir. Ancak bu bileşen tasarımını bozuyor mu?

Bunun yerine boş bir RigidBody bileşeni içermeli mi? Bu aslında daha iyi olabilir, çünkü her zaman boş olmayabilir ve bu yaklaşım daha fazla geleceğe yöneliktir. Bununla ilgili tek sorun karmaşıklıktır. Sahnenin, bu RigidBody bileşenine sahip olup olmadığını belirlemek için sadece her bir varlığın değil, aynı zamanda her bir varlığın bileşenlerini de dolaşması gerekir.

Üçüncüsü, çarpıştıklarında her iki taraf da bir şekilde bilgilendirilmeli ve bunu nasıl başaracağımdan emin değilim.

Her iki kurumun bir HealthComponent içerdiğini ve çarpıştıklarında her ikisinin de sağlıklarını keyfi bir değer 5 azaltacağını varsayalım.

Peki o zaman sahne çok mu sorumlu? Sahnelerin erişememesi gereken birçok şeyden sahne sorumlu olduğunda, bu muhtemelen elden çıkıp hantal kaldığını görebiliyordum.

Düzenleme: Soru daha fazla ayrıntıyla güncellendi.


4
Bu cevap bağlantı vermek için uygun görünüyor: gamedev.stackexchange.com/questions/13797/…
Andrew Russell

Andrew'un bağlantılı yanıtı, James'in yanıtı ve Nick Wiggill'in yanıtı + 1'leri hak ediyor. Bileşenleri, hem veri hem de yöntemlerle tipik bir sınıftan çok veri olarak düşünün (yöntemlere sahip olmayacakları, ancak çok fazla sorumluluk verilmemeleri gerekir). İyi bir bileşen çerçevesi örneği için Artemis bileşen sistemine ( piemaster.net/2011/07/entity-component-artemis ) bakın.
michael.bartnett

Yanıtlar:


5

Dürüst olmak gerekirse, bir şeylerin bileşen tasarımından, bileşenlerim zorunlu olmadıkça birbirlerini bilmiyorlar (Ve bu çok nadirdir). O zaman bile, genellikle bileşenleri doğrudan bileşenler yerine adı geçen bileşenlerin bazı yönetim sistemiyle konuşmayı tercih ederim. (Komut dosyası arabirimi nesneye nesneye benziyor, ancak gerçek motorda değil, hehe).

Bu amaçla, ilk söylediklerinize taraf olurum ve nesnelerin çarpışmaları için test edilmesi gereken her yerde var olan fizik bileşenlerine giderdim. Şimdi açıkça bu nesneler, çarpışma çözümü üzerine diğer bileşenleri kendileri bilgilendirmek zorunda kalabilirler, ancak belirtildiği gibi, bu, etkinliğin kendisinin yalnızca başka bir arabirim (bir yöneticiye veya bir olay mesajlaşma sistemi aracılığıyla) nesnelere gitmesini tercih ettiğim yerdir. bunlardan birine sahipsiniz).

Sanırım doğru yoldasınız ve sadece 'Evet, kulağa doğru geliyor' daha fazlasına ihtiyacınız var. Yani .. Evet, kulağa doğru geliyor.

Bu yardımcı olur umarım!


3

Normalde oyun motorları, varlıklar arasındaki çarpışmaları tespit etmek için bir 3. taraf kütüphanesi kullanır. Bu senaryoda, PhysicsComponent'e sahip olan varlıkları "fizik" dünyasına yaratır veya kaydeder. Ve iki varlık (A ve B) arasında bir çarpışma tespit ettiğinde, normalde A işletmesine, B işletmesine çarpıştığını ve B işletmesi için aynı şeyi B işletmesine çarpıştığını bildirerek A işletmesine çarpıştığını bildirir.

2D için, iyi bilinen bir serbest fizik kütüphanesi Box2D'dir. Ayrıca Chipmunk'a bir göz atmaya değer. 3D için, Bullet ücretsizdir (muhtemelen bulabileceğiniz en iyi ücretsizdir). Havok ve PhysX birçok üçlü A Oyununda kullanıldığı için ünlüdür.


2

Karşılaştığınız sorun, çarpışma algılamanın (bir fizik bileşeni taşıyan bir başkasına böyle bir referansa ihtiyaç duymanızın tek nedeni) daha yüksek bir düzeyde, genellikle doğrudan oyun döngünüz tarafından veya bunu yapan bir yardımcı fonksiyon / sınıf. Benim önce birisi cevabı bir kaç hafta çarpışma neden olursa sizin taraftan birisi imha edilecek akılda varlık benzer gerekçelerle kaldırılması ve yatak hakkında görüşmelerde, aynı cevap, onun belirli bir bağlam içinde, size çok alakalı olacak "yüksek güç" ün hala bedenlerin temizliğini yönetmek zorunda kalacağı için ... tabiri caizse.

Bunların herhangi birini yalnızca varlıklar arasında yapmak genellikle uygun değildir. İster çarpışma algılamada olduğu gibi doğrudan yönetim yoluyla, ister olaydaki gibi olay gönderimleriyle, katı bir mimaride, bu tür şeyler için neredeyse her zaman bir proxy vardır. bir istemci tarafı mesajlaşma yöneticisinin oynatıcılardan gönderilen mesajları dinlediği ve bunları herkese yeniden yayınlanması için sunucuya gönderdiği bir oyuncu mesajlaşma sistemi.


2

Şimdi bir projede seninle tamamen aynı problemle karşılaşıyorum. Bununla başa çıkmaya karar verdiğim şekli, bedeni fizik motorundan tutan bir "ColliderComponent" e sahip olmak. Vücutlar harici olarak tanımlanır (çalışma zamanında yüklenen şekil tanımları) ve daha sonra fizik dünyasına ve ait oldukları oyun varlıklarına eklenir .

Ben çarpışma tarafından haberdar edilecek bir "çarpışma dinleyici" ekleyebilirsiniz Box2D kullanıyorum. Gövde kullanıcı verilerine "ColliderComponent" e bir işaretçi eklediğim için, çarpışmanın bir parçası olan iki ColliderComponent'imi alabilirim.

Dolayısıyla, bir çarpışma olduğunda meydana gelen şey şudur: Çarpışmanın bir parçası olan ColliderComponent'leri, sahiplerine ait nesneye (oyun varlığı) bir mesaj gönderecek ve bu mesajı tüm bileşenlerine yayınlayacaktır.

Daha sonra her bileşen bu mesaja tepki verebilir, böylece "sağlık bileşeniniz" sağlıktan 5 puan kaldırabilir.


+1: Çok benzer bir yaklaşım kullanıyorum. Çarpışan varlık türüne bağlı olarak neden olunacak hasar miktarını nasıl belirliyorsunuz?
Den

@Alan çarpışmaya göre farklı mesajlar (veya mesaj verileri) gönderiyorum. Bu benim için iyi çalışıyor, çünkü ele alacak çok fazla vakam yok.
bummzack

0

"Dünya" çarpışmasını bilen bir çarpışma sistemi oluşturun. Daha sonra çarpışma bileşeninizde çarpışma sistemine A noktasından B noktasına bir ışın atmasını ve çarpışıp çarpışmadığını yanıtlamasını söyleyin.

İyi şanslar. Çarpışma sistemini oyun motorunun daha sıkıcı kısımlarından biri olarak görüyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.