Bileşen tabanlı tasarımda girdi işleme


12

Bu sorunun birkaç kez sorulduğunu biliyorum, ancak bileşen tabanlı bir motorda giriş işlemeyi nasıl uygulayacağımdan hala emin değilim.

Kullandığım bileşen tabanlı tasarım T = Machine'in blog serisine ve Varlıkların sadece id olduğu Artemis'e dayanıyordu .

Girdi işlemeyi uygulamada üç temel fikrim var:

  1. Giriş bileşeni, ilgilendiği etkinlikleri tutacaktır. Giriş sistemi, anahtar ve fare olaylarını oyun olaylarına çevirecek ve giriş bileşeniyle varlıklar arasında geçiş yapacak ve eğer olayla ilgileniyorlarsa giriş sistemi tarafından uygun bir eylem gerçekleştirilecektir. Bu eylem giriş sistemine sabit olarak kodlanır.
  2. Giriş bileşeni yok. Belirli olaylara sahip varlıkları giriş sistemine kaydedersiniz. Girdi sistemi daha sonra uygun eylemi gerçekleştirebilmek için diğer sistemlere ileti (varlık kimliği ve olay türüyle birlikte) gönderir. Veya ilk durumda olduğu gibi, eylemler giriş sistemine sabit olarak kodlanır.
  3. İlk yönteme benzer şekilde, ancak eylemi girdi sistemine sabit olarak kodlamak yerine, bileşen std::map<std::function>girdi sistemi tarafından çağrılacak olan işlevlere (yani ) ilişkin bir olaylar haritası içerecektir . Bu, aynı olayı farklı eylemlerle birleştirebilme özelliğine sahiptir.

Yukarıdaki yöntemlerden herhangi birini önerir misiniz veya esnek bir girdi işleme sistemi uygulamama yardımcı olacak önerileriniz var mı? Ayrıca, henüz çok iş parçacığına aşina değilim ama uygulamayı iş parçacığı dostu yapacak herhangi bir öneri de bekliyoruz.

Not: Uygulamanın yerine getirmesini istediğim bir ek gereksinim, aynı girişi, örneğin bir kamera objesini ve oynatıcıyı aynı anda taşımak gibi birçok objeye aktarabileceğim.


2
Genellikle (kamera oynatıcıyı takip ettiğinde) kamerada giriş almak istemezsiniz, bunun yerine kameranın oynatıcı konumunu kontrol etmesini ve takip etmesini sağlarsınız.
Luke B.11

1
Kameranın oynatıcıyı takip etmesi veya “kendisi” olmasının kavramsal olarak önemi yoktur. Bununla birlikte, tasarım ilkelerini bozmadan önerinizin bileşen tabanlı bir tasarımda nasıl uygulanacağından emin değilim.
Grieverheart

1
@ Luke B .: Biraz düşündükten sonra, kamerayı ayrı bir sınıf olarak da yapabileceğinizi görüyorum, takip edilecek bir varlığa bir işaretçi alıyorsunuz.
Grieverheart

Yanıtlar:


8

Sanırım, tıpkı bir bileşen sistemindeki malzemelerle ilgili cevabım gibi , her şeyi bir “bileşene” itmeye çalıştığınız bir sorunla karşılaşıyorsunuz. Bunu yapmak zorunda değilsiniz ve bunu yaparken, yuvarlak deliklere bir grup kare mandal takmaya çalışarak muhtemelen gerçekten hantal bir arayüz oluşturuyorsunuz.

Oynatıcıdan girdi alma işlemini ele alan bir sisteminiz var gibi görünüyor. Daha sonra bu girdiyi eylemlere ("ileriye doğru" veya "geriye doğru") veya olaylara dönüştüren ve bunları ilgili taraflara gönderen bir yaklaşımı tercih ederim. Geçmişte, bileşenlerin kendilerini bu olaylar için kaydetmelerine izin vermiyordum , üst düzey sistemin açıkça "denetlenen varlığı" seçtiği bir yaklaşımı tercih ettim . Ancak, özellikle doğrudan girdiler tarafından uyarılmayan eylemleri gerçekleştirmek için aynı iletileri yeniden kullanacaksanız, bu şekilde çalışabilir.

Yine de, hem kamera varlığı hem de oynatıcı varlığı "ileri hareket" (et cetera) iletisine yanıt vererek kamerayı izleyen davranışların uygulanmasını önermem. Bu, oyuncu için iyi hissetmeyecek iki nesne arasında son derece sağlam bir bağlantı oluşturur ve ayrıca oyuncu sola veya sağa döndüğünde kameranın oynatıcıyı yörüngeye oturtması gibi şeyleri ele almayı biraz daha zorlaştırır: bir varlığınız var "sola döndür" e yanıt vermek, oyuncuya esir olduğunu varsayarak, ama bu hiç bir zaman köleleştirilmemişse doğru tepki veremeyeceği anlamına gelir. Ve bunu yapacaksanız, iki fiziksel nesneyi birlikte kölelemek için uygun esneklik tweakable'larıyla birlikte uygun bir sistem de uygulayabilirsiniz.

Çoklu iş parçacığıyla ilgili olarak, gerçekten değdiğinden daha fazla komplikasyona neden olacağı için burada kullanmaya gerek duymuyorum ve doğal olarak seri bir sorunla uğraşıyorsunuz, bu yüzden sadece çok fazla iş parçacığı eklemeniz gerekiyor senkronizasyon ilkelleri.


Sorumu düşündüğüm oyunu oynuyorum ve kendime cevap vermek üzereydim. Ayrıca, AK işleminden giriş işlemeyi ayırmaktan daha iyi olmam gerektiği sonucuna vardım, bu yüzden bunun bir onayını görmek güzel. Bunu yapmayı nasıl düşündüğüm, sinyallerin kullanımı ve birkaç varlığı bir olay türüyle ilişkilendirme yeteneğidir. Aynı zamanda kamerayı ayırmaya karar verdim, ancak bu gerçekten gerekli değil ve bir varlık olarak sahip olmak aynı derecede geçerli olacaktı. Bence hala EC'lere yeni başlayan bir kişi olduğunuzda, bir şeyi bir bileşen veya varlık haline getirmenin faydalarının ne olduğunu düşünmeniz gerekir.
Grieverheart

4

Deneyimlerim taraflı olabilir, ancak çoklu platform projelerinde girdi aygıtları doğrudan varlık sistemine maruz kalmaz.

Giriş aygıtları, tuşlardan, düğmelerden, eksenden, fareden, dokunmatik yüzeylerden, ivmeölçerlerden olayları alan alt düzey bir sistem tarafından yönetilir ...

Bu olaylar daha sonra bir bağlama bağlı niyet oluşturucu katmanı yoluyla gönderilir.

Her jeneratör, işlevleriyle ilgili bileşenlerden, varlıklardan ve sistemlerden gelen doygun değişiklikler için kayıt yapar.

Bu jeneratörler daha sonra varlıkların bir bileşeni olduğu niyet sistemine veya doğrudan doğru bileşenlere yönlendirme için mesajlar / niyetler gönderir.

Bu şekilde, aynı girişe sahip olan "her zaman" a güvenebilirsiniz, yani JUMP_INTENT (1), JUMP_INTENT (0), AIM_INTENT (1) ...

Ve "tümü" kirli platforma bağımlı girdi çalışması varlık sisteminizin dışında kalır.


Fotoğraf makinesiyle ilgili olarak, oynatıcının etrafında hareket etmek istiyorsanız, kendi niyet bileşenini kaydedebilir ve göndereceğiniz hedefleri dinleyebilir.

Aksi takdirde müzikçaları takip ederse, müzikçalara giden girdileri asla dinlememelidir. Müzikçalar tarafından yayılan durum değişikliklerini (ENTITY_MOVED (dönüşüm)) dinlemeli ve buna göre hareket etmelidir. Bir fizik sistemi kullanıyorsanız, çeşitli eklemlerden birini kullanarak kamerayı müzikçalara bile bağlayabilirsiniz.


Çakal, cevabın için teşekkürler. Burada diğer yazınızı da okudum . En büyük endişem girdinin nasıl özetleneceği değil. Zaten anahtar baskıları ve benzeri şeyleri işleyen daha düşük seviyeli bir yapım var ve bir tane daha dolaylama seviyesi eklemek zor olmayacak. Benim sorunum, örneğin niyet sisteminiz tarafından oluşturulan olayları ele almak. Doğru anlarsam, yönteminizde hiç giriş bileşeni yoktur. Hangi varlıkların girdiye ihtiyacı olduğunu ve bunu nasıl ele aldığınızı nasıl anlarsınız? Daha somut örnekler verebilir misiniz?
Grieverheart

2

InputComponent'in faydası nedir? Kuşkusuz hangi eylemi gerçekleştirdiği öğelere karar vermek girdi komutunun ayrıcalığıdır. Klasik örnek, oyuncuyu zıplatmaktır. "Jump" olaylarını dinleyen her varlıkta bir InputComponent'e sahip olmak yerine, jump komutunun "player" olarak işaretlenen varlığı aramasına ve gerekli mantığın kendisini gerçekleştirmesine neden izin vermiyorsunuz?

Action jump = () =>
{
    entities["player"].Transform.Velocity.Y += 5;
};

OP'den başka bir örnek:

Action moveRight = () =>
{
    foreach (var entity in entities.Tagged("player", "camera"))
        entity.Transform.Position.X += 5;
};
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.