Bileşen tabanlı varlık sistemlerinde oyun durumu ve girdi işleme


16

Sorum şu:

Oyun durumu nesnelerini bir yığın halinde tutmak zorunda kalmadan varlık sistemimdeki oyun durumlarını nasıl ele alabilirim?

Dolayısıyla, varlık sistemimin tasarımı, bir varlığın örneğin girdi olaylarına kaydolması gerektiğinde, girdi bileşeninin girdi sistemini çağırdığı ve "bu varlığı bu girdi için kaydet" olduğu anlamına gelir. Her şey yolunda ve iyi, ancak buna oyun durumları kavramını eklerseniz (bir duraklama ekranı söyleyin), bir varlığın mevcut durumda olup olmadığını ve girdiyi alması gerekiyorsa bir sorun haline gelir.

Giriş bileşenini / sistemini, "bu oyun durumlarında bu giriş için bu varlığı kaydet" diyerek artırmayı başardım, ancak bu, her varlığın hangi eyaletlerde kullanılacağını bilmesini gerektirir ve bu açık olmayabilir. Ayrıca, kayıtlı durum başına (ve geri arama kullanan diğer sistemlerde) oyun durumlarının bir listesini tutmak çok verimli gelmez.

Sahip olduğum başka bir fikir, oyun durumunu temsil eden bir varlık olacağından, devre dışı olarak işaretlendiğinden, giriş olayı oluştururken varlığın devre dışı bırakılmış bir oyun devlet varlığının torunu olmadığını kontrol etmektir. Her geri arama için ebeveyni çalışmak pahalı görünüyor.

Başka bir fikir, tüm sistemlerin verilerini mevcut duruma karşı anahtarlanmış olarak saklamasıdır, böylece girdiyi oluştururken hedef varlık aday bile olmaz. Ancak bu, farklı eyaletlerdeki varlıklar arasındaki iletişime izin verme yeteneğini gerçekten incitiyor (duraklatma ekranları için çok fazla sorun değil, Oblivion / Skyrim'de kilit seçmeyi düşünün).

Sahip olduğum diğer tek fikir, tüm bileşenlerin bir durum değişikliği olaylarını işlemesini ve kaydettikleri herhangi bir şeyi devre dışı bırakmak için ilgili sistemleriyle iletişim kurmasını ve bu duruma geri döndüğünde yeniden etkinleştirmelerini sağlamaktır.

İkincisi (bir nesneyi devre dışı olarak işaretleyin) ve ileri (her bir bileşenin devlet değişiklikleriyle ilgilenmesi) fikirlerimin en iyisi gibi görünüyor, ancak hiçbiri bana özellikle büyük olarak atlamıyor.

Bunun nasıl yapılacağı konusunda başka fikirleri olan var mı?

edit Bu soruya özel olarak girdi hakkında konuşurken, çarpışmalar, zamanlayıcı olayları gibi varlıklara mesaj / olay gönderebilen herhangi bir sistem anlamına gelebilir.


6
Bunu şu şekilde yapıyorum: Ekranlar, MenuScreen PauseScreen GameScreen var, her ekran kendi Dünyasını (Varlıklar için kapsayıcı) ve sistemleri (RenderingSystem gibi) oluşturabilir ve sonra GameScreen'de Dünya, CameraComponent ile Varlık oluşturabilir ve CameraComponent.RenderTarget'ı ekranlar arka plan. Bu şekilde kendi varlıkları ve sistemleri (basitleştirilmiş oluşturucu gibi) olacak InventoryScreen ekleyebilirsiniz. Giriş ekrandan dünyaya geçirilebilir, bu nedenle kullanıcı arayüzünüz, girişi ekrana
geçirip


2
@ Byte56 Gerçekten değil, sadece birincisi oyun siteleriyle ilgilidir (diğer 2 tanesi varlıkların içindeki eyaletlerdir) ve bu benim yaşadığım problemle gerçekten başa çıkmıyor. Oyun duraklatılmış durumda olduğunda, giriş sistemine oyuncu varlığına bir hareket mesajı göndermesini durdurmak için bir şey olması gerekir (örneğin), bunu yapmak için iyi bir yol bulamıyorum.
elFarto

1
Tamam, onları ilgili olarak düşünün. İyi soru.
MichaelHouse

1
Geçmişte bileşen tabanlı sistemlerime sıkıntı veren dikkate alınması gereken başka bir şey: çok katmanlı kullanıcı arayüzü. Dünya ya da çok seviyeli ekranların üzerinde iletişim kutusu. Şimdiye kadar yaptığım her oyunda ortaya çıktı, bu yüzden bu sorunu çözebilecek bir yaklaşımı göz önünde bulundurduğunuzdan emin olun.
ADB

Yanıtlar:


14

Sık kullanılan, Intent Systemgirdiyi soyutlayan ve bağlamı ve ilgili oyun sitelerini takip eden bir ara maddedir.

Niyet sistemi, örneğin simülasyon duraklatıldığında giriş iletimini durduracaktır. Ayrıca denetleyici olayları ve hedefleri (yön hareket, koş, ateş, yeniden yükle ...) arasındaki eşlemeyi de gerçekleştirir.

Bu şekilde diğer rakipleriniz belirli gamepad / girişlere (BUTTON_A, BUTTON_B ve BUTTON_X, BUTTON_O ...) bağımlı olmaz, ancak hepsi aynı amaçlara tepki verir (IntentRun, IntentReload ...).

Diğer bir avantaj, niyet sisteminin, gibi hedefleri işleyebileceğiniz simülasyonun dışında bile herhangi bir aboneye niyet gönderebileceğinden, eklenen / kaldırılan mevcut denetleyicilerin farkında olabilmesidir AddPlayer(controllerID).

Olaylar / mesaj yoluyla veya doğrudan sisteme sağladığınız oyun durumu hakkında ne kadar bilgi size kalmış. Ancak Niyet sistemine harcanan zaman genellikle buna değer.

Sisteme bağlandıklarında hedefler oluşturacak Niyet Bağlamlarını yönetebilirsiniz.

Bağlama öncelik verilebilir, yani:

  • SimulationAvailableContext, simülasyonu kullanılabilir durumdayken (ancak çalışmıyorken) simülasyona gönderir, örneğin kamerayı hareket ettir, yakınlaştır, uzaklaştır, oynatıcı ekle / kaldır ...
  • SimulationRunningContext, duraklatılan hareket çalar olmadığında simülasyonu amaçlara gönderir, birimi pozisyona gönderir, çeker ...

Bu şekilde, şu anda alakalı olan bağlamları ekleyebilir ve kaldırabilirsiniz.

Ve tüm niyet sistemleri hakkında bir şey, simülasyon duraklatılmışken çalıştırılması gerektiğidir.

Simülasyonla ilgili olmayan güncellemeleri bozmadan oyun simülasyonunu oynatmak / duraklatmak için sıklıkla kullanılan bir yol, farklı zaman kümeleri kullanmaktır. yani GenericSystem::onTime(Long time, Long deltaTime, Long simTime, Long simDeltaTime).

Bu yaklaşımla, motorunuz oyunların simTime'ındaki artışları engelleyebilir, bu da kullanılan animasyon ve fizik motorlarındaki güncellemeleri engellerken simTime and simDeltaTime, duraklama sırasında bile hareket etmesi gerekiyorsa kamera bahar efektinizin sürekli güncellenmesine izin verir. veri indirilirken sanal bir oyun içi reklam panosuna yükleme etkisi ...


Bunun tüm varlıklar üzerinde bir grup "Devlet Değişti" işlevleri olarak adlandırılması gerekmemesini seviyorum. Yanlış zamanda yanlış niyetlerin gönderilmesi konusunda endişelenmelisiniz, ama bence bu alternatiften daha iyi.
Thomas Marnell

varlıklarınız zıplamasına izin vermezken (yani yere dokunmama), varlıklarınız Jump gibi niyetleri görmezden gelebilir. ancak oyun duraklatıldığında bu tür niyetleri almaktan endişe etmek zorunda kalmazlar.
Coyote

Zaten kurumun girdi sistemine hangi mesajları ileteceğini bildirmesine izin vermeyi düşünmüştüm, ama durumları girdinin kendisine koymayı düşünmemiştim, bu iyi bir fikir. Ayrıca zaman ve simTime ayırmak da güzel.
elFarto

Simülasyonla ilgili durumunuzu simülasyonla ilgili olmayan şeylerle şişirmekten kaçınmalısınız. Tüm kullanıcı arayüzünü ve oyuncu ile ilgili kodu simülasyonun kendisinden mümkün olduğunca uzağa taşıyın ve simülasyonda yalnızca niyetlere odaklanın.
Coyote

Hey @Coyote, bu sistem çok ilginç geliyor. Bu soruyu cevaplayarak biraz daha bilgi verebilir misiniz ? Teşekkürler!
pek

2

Global bir olay sistemi oluşturmaya ve ardından her bir varlığınız için bir olay dinleyici bileşenine sahip olmaya ne dersiniz? Bir etkinlikten sonra "Oyun Durumu Değişikliği" her bir varlık için ayrı ayrı bileşenlerle uğraşabilirsiniz.

Diyelim ki bir giriş bileşeniniz var. Olay dinleyicisi bileşeni oyun durumu değişikliği olayını aldıktan sonra, söz konusu giriş bileşeni için çok özel değerleri değiştirir, bu nedenle herhangi bir girdi çağrısı almaz veya sisteme veya sahibine herhangi bir hareket veya yanıt çağrısı yapmaz.

Bileşenlerimin çoğu (Lua aracılığıyla) yazıldığından bu benim için çalışıyor. Yani, bir tuşa basıldığında bir kez tetiklenen ve bir hareket + yönünü tetiklediğinde tetiklenen bir giriş bileşenim var ve daha sonra tuş bırakıldığında tetiklenir ve durma + yönünü tetikler. Ayrıca, herhangi bir işlevi tetiklemeyi durdurmak ve gerekirse durdurmak için giriş bileşeniyle (oyun duraklatıldıysa) temas eden bir olay dinleyicisi bileşeni de vardır. Daha sonra başka bir komut dosyası kullanarak aynı olaylara ve tuşlara farklı bir tepki ile başka bir varlık kolayca ekleyebilirim. Bu şekilde, farklı eyaletlerdeki farklı varlıklar arasındaki etkileşimi kaydedebilir ve hatta çok daha özelleştirilebilir hale getirebilirsiniz. Dahası, bazı varlıklarda olay dinleyici bileşeni bile olmayabilir.

Az önce açıkladığım, dördüncü çözümünüzün pratik bir örneğidir.

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.