Oyunlar için davranış / Bileşen tabanlı sistem oluşturma


11

Arka fon

Oyun geliştirmeyi hobi olarak yapıyorum ve onları tasarlamanın daha iyi bir yolunu arıyorum. Şu anda, standart bir OOP yaklaşımı kullanıyorum (8 yıldır kurumsal gelişim yapıyorum, bu yüzden nartely geliyor). Örneğin bir "kötü adam"

public class Baddie:AnimatedSprite //(or StaticSprite if needed, which inherit Sprite)
{
    //sprite base will have things like what texture to use, 
    //what the current position is, the base Update/Draw/GetInput methods, etc..
    //an AnimatedSprite contains helpers to animated the player while 
    //a StaticSprite is just one that will draw whatever texture is there
}

Sorun

Diyelim ki ben 2 boyutlu bir platform yapıyorum ve Zıplayabilmek için baddie'ye ihtiyacım var. Genellikle ne yaptığımı Update / GetInput yöntemlerine uygun kodu ekleyin. Sonra oyuncuyu taramak, ördek, tırmanış vb yapmak gerekiyorsa ... kod oraya gidecek.

Eğer dikkatli olmazsam, bu yöntemler karmaşıklaşır, bu yüzden böyle yöntemler çiftleri oluştururum

CheckForJumpAction(Input input) ve DoJump()

CheckforDuckAction(Input input) ve DoDuck()

yani GetInput şöyle görünür

public void DoInput(Input input)
{
    CheckForJumpAction(input);
    CheckForDuckAction(input);
}

ve Güncelleme

public void Update()
{
    DoJump();
    DoDuck();
}

Eğer gidip oyuncunun atlaması ve ördek atması gereken başka bir oyun yaratırsam, genellikle işlevselliğe sahip bir oyuna girer ve kopyalarım. Dağınık, biliyorum. Bu yüzden daha iyi bir şey arıyorum.

Çözüm?

Blend'in bir öğeye ekleyebileceğim davranışlarını gerçekten seviyorum. Oyunlarımda da aynı konsepti kullanmayı düşünüyorum. Şimdi aynı örneklere bakalım.

Temel bir Davranış nesnesi oluştururdum

public class Behavior
{
    public void Update()
    Public void GetInput()
}

Ve bunu kullanarak davranışlar oluşturabilirim. JumpBehavior:BehaviorveDuckBehavior:Behavior

Sonra Sprite tabanına davranışlar bir koleksiyon eklemek ve her varlık için ne gerek eklemek.

public class Baddie:AnimatedSprite
{
    public Baddie()
    {
        this.behaviors = new Behavior[2];
        this.behaviors[0] = new JumpBehavior();
        //etc...
    }

    public void Update()
    {
        //behaviors.update
    }

    public GetInput()
    {
        //behaviors.getinput
    }
}

Şimdi Jump ve Duck'ı birçok oyunda kullanmak istersem, sadece davranışları ortaya çıkarabilirim. Sıradanlar için bir kütüphane bile yapabilirim.

Çalışıyor mu?

Anlayamadığım şey, devletlerin aralarında nasıl paylaşılacağıdır. Atlama ve Ördek'e bakıldığında, her ikisi de sadece çizilen dokunun geçerli kısmını değil, aynı zamanda oyuncunun durumunu da etkiler. (Atlama zamanla azalan miktarda yukarı doğru kuvvet uygularken, ördek sadece hareketi durduracak, baddie'nin dokusunu ve çarpışma boyutunu değiştirecek.

Çalışması için bunu nasıl birbirine bağlayabilirim? Davranışlar arasında bağımlılık özellikleri oluşturmalı mıyım? Her davranış olmalı bilmesine ebeveyn ile ilgili ve Doğrudan değiştirilemiyor? Düşündüğüm bir şey, bir delege tetiklendiğinde yürütülmesi için her davranışa geçebiliyordu.

Baktığım daha fazla sorun olduğundan eminim, ancak tüm amaç aynı oyundaki oyunlar ve varlıklar arasındaki bu davranışları kolayca yeniden kullanabilmem.

Bu yüzden size teslim ediyorum. Bunun nasıl yapılacağını / yapılacağını açıklamak ister misiniz? Daha iyi bir fikrin var mı? Can kulağı ile dinliyorum.


Bu gamedev.stackexchange.com adresinden daha iyi sorulabilir mi?
rcapote

Nereye gittiğinizi seviyorum ama ortaya çıkardığınız sorunları nasıl çözeceğinizden emin değilim. Çok ilginç ve oyun geliştirmenin ötesinde etkileri var.
Edward Strange

@rcapote bu site yazı tahtası / tartışmalar için değil mi?

2
@Joe - hayır, hayır. Burada "tartışma" dan bahsetmeyin, yoksa varlığınızı değiştirirsiniz. Bu site yalnızca Soru-> Yanıt-> Tamamlanan etkileşim türü içindir.
Edward Strange

Bileşen tabanlı varlık sistemleri, son zamanlarda game dev topluluğunda trend olmaya başlayan bir şeydir, bu yüzden orada daha iyi dikkat çekebileceğinizi düşündüm, ancak muhtemelen burada iyi cevaplar alacaksınız. Burada gamedev.net hakkında ilginç bulabileceğiniz ilginç bir tartışma var: gamedev.net/topic/…
rcapote

Yanıtlar:


1

Bu sunuma bir göz atın . Aradığınız desene oldukça yakın geliyor. Bu desen davranışları ve eklenebilir özellikleri destekler. Sunumun bundan bahsettiğini sanmıyorum, ancak eklenebilir etkinlikler de oluşturabilirsiniz. Bu fikir, WPF'de kullanılan bağımlılık özelliklerine benzer.


9

Bana göre bu Strateji Deseni'ni kullanmak için neredeyse ders kitabı davası gibi geliyor . Bu modelde, genel davranışlarınız, çalışma zamanında farklı davranış uygulamalarını değiştirmenize olanak tanıyacak arayüzlerde tanımlanabilir (bir güçlendirmenin karakterinizin atlama veya çalışma yeteneğini nasıl etkileyebileceğini düşünün).

(Tutarlı) bir örnek için:

// The basic definition of the jump behavior
public interface IJumpBehavior {
    void Jump();
}

Artık karakterinizin kullanabileceği çeşitli sıçramalar uygulayabilirsiniz, her bir atlama ile ilgili ayrıntıları bilmeden:

// This is the jump the character may have when first starting
public class NormalJump : IJumpBehavior {

     public void Jump() {
         Console.WriteLine("I am jumping, and being pretty boring about it!");
     }

}

// This is the jump of a character who has consumed a power-up
public class SuperJump : IJumpBehavior {
    public void Jump() { 
         Console.WriteLine("I am all hopped up on star power, now my jumps can do damage!");
     }
}

Atlama yeteneğine sahip olmak istediğiniz herhangi bir karakter şimdi bir IJumpable'a referans içerebilir ve çeşitli uygulamalarınızı tüketmeye başlayabilir

public class HeroCharacter {

    // By default this hero can perform normal jump.
    private IJumpBehavior _jumpBehavior = new NormalJump();

    public void Jump() {
        _jumpBehvaior.Jump();
    }

    // If you want to change the hero's IJumpable at runtime
    public void SetJump(IJumpBehavior jumpBehavior) {
      _jumpBehavior = jumpBehavior;
    }

}

Sonra kodunuz şöyle görünebilir:

HeroCharacter myHero = new HeroCharacer();

// Outputs: "I am jumping, and being pretty boring about it!"
myHero.Jump()

// After consuming a power-up
myHero.SetJump(new SuperJump());

// Outputs: "I am all hopped up on star power, now my jumps can do damage!"
myHero.Jump();

Artık bu davranışları kolayca yeniden kullanabilir veya daha fazla atlama türü eklemek istediğinizde daha da genişletebilir veya tek bir Yan kaydırma platformunda daha fazla oyun oluşturabilirsiniz.


tam olarak aradığım şey olmasa da, bu çok yakın ve beğendim. Emin olmak için onunla oynayacağım. Teşekkürler!

1

DCI mimarisine , yardımcı olabilecek OO programlarına ilginç bir göz atın .

Bir DCI stili mimarinin C # içinde uygulanması, basit etki alanı sınıflarının kullanılmasını ve etki alanı sınıflarının farklı roller altında işbirliği yapmasını sağlamak için Genişletme Yöntemleri ve Arabirimlerle Bağlam nesneleri (davranışları) kullanılmasını gerektirir. Arabirimler, bir senaryo için gerekli rolleri işaretlemek için kullanılır. Etki alanı sınıfları, amaçlanan davranışlarına uygulanan arabirimleri (roller) uygular. Roller arasındaki işbirliği, bağlam (davranış) nesnelerinde gerçekleşir.

Ayrı projelerden etki alanı nesneleri arasında paylaşılabilecek ortak davranışlar ve roller içeren bir kitaplık oluşturabilirsiniz.

C # 'daki kod örnekleri için C #' ta DCI'ye bakın .


0

Bir bağlam nesnesinden, bir davranıştan etkilenen sprite / nesnelerin durumunu değiştirmek için yöntemler sağlayan bir davranışa geçmeye ne dersiniz? Şimdi bir nesnenin birden fazla davranışı varsa, her biri bir bağlam içinde çağrılır ve onlara içeriği değiştirme şansı verilir. Bir özelliğin belirli bir modifikasyonu, diğer özelliklerin modifikasyonunu dışlar / kısıtlarsa, bağlam nesnesi, bu gerçeği belirtmek için bir tür bayrağı ayarlamaya yönelik yöntemler sağlayabilir veya istenmeyen değişiklikleri reddedebilir.

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.