Buat sistem berbasis perilaku / Komponen untuk permainan

11

Latar Belakang

Saya melakukan pengembangan game sebagai hobi, dan saya mencari cara yang lebih baik untuk mendesainnya. Saat ini, saya menggunakan pendekatan OOP standar (saya telah melakukan pengembangan usaha selama 8 tahun sehingga muncul secara nasional). Ambil contoh "baddie"

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
}

Masalah

Katakanlah saya membuat platformer 2d, dan perlu baddie untuk dapat Melompat. Biasanya yang saya lakukan adalah menambahkan kode yang sesuai dalam metode Perbarui / GetInput. Lalu jika saya perlu membuat pemain merangkak, bebek, memanjat, dll ... kode akan pergi ke sana.

Jika saya tidak hati-hati, metode-metode itu berantakan, jadi saya akhirnya membuat pasangan metode seperti ini

CheckForJumpAction(Input input) dan DoJump()

CheckforDuckAction(Input input) dan DoDuck()

jadi GetInput terlihat seperti

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

dan Pembaruan terlihat seperti

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

Jika saya pergi dan membuat game lain di mana pemain harus melompat dan merunduk, saya biasanya pergi ke permainan yang memiliki fungsi dan menyalinnya. Berantakan, saya tahu. Itulah mengapa saya mencari sesuatu yang lebih baik.

Larutan?

Saya sangat suka bagaimana Blend memiliki perilaku yang dapat saya lampirkan pada suatu elemen. Saya telah berpikir tentang menggunakan konsep yang sama dalam permainan saya. Jadi mari kita lihat contoh yang sama.

Saya akan membuat objek Perilaku dasar

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

Dan saya dapat membuat perilaku menggunakan itu. JumpBehavior:BehaviordanDuckBehavior:Behavior

Saya kemudian dapat menambahkan kumpulan perilaku ke basis Sprite dan menambahkan apa yang saya butuhkan untuk setiap entitas.

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
    }
}

Jadi sekarang. Jika saya ingin menggunakan Lompat dan Bebek dalam banyak permainan, saya hanya bisa membawa perilaku itu selesai. Saya bahkan bisa membuat perpustakaan untuk yang umum.

Apakah itu bekerja?

Apa yang saya tidak tahu adalah bagaimana berbagi keadaan di antara mereka. Melihat Jump and Duck, keduanya tidak hanya mempengaruhi bagian tekstur saat ini yang sedang digambar, tetapi juga kondisi pemain. (Lompat akan menerapkan jumlah penurunan ke atas dari waktu ke waktu, sementara bebek hanya akan menghentikan gerakan, mengubah tekstur dan ukuran tumbukan baddie.

Bagaimana saya bisa mengikat ini jadi itu berfungsi? Haruskah saya membuat properti ketergantungan antara perilaku? Haruskah setiap perilaku saya tahu tentang orang tua dan memodifikasinya secara langsung? Satu hal yang saya pikir bisa lulus delegasi ke setiap perilaku untuk dieksekusi ketika dipicu.

Saya yakin ada lebih banyak masalah yang saya perhatikan, tetapi seluruh tujuannya adalah agar saya dapat dengan mudah menggunakan kembali perilaku ini di antara game, dan entitas dalam game yang sama.

Jadi saya menyerahkannya kepada Anda. Mau jelaskan bagaimana / jika ini bisa dilakukan? Apakah Anda punya ide yang lebih baik? Saya mendengarkan.


sumber
Ini mungkin lebih baik ditanyakan di gamedev.stackexchange.com ?
rcapote
Saya suka ke mana Anda akan pergi tetapi saya tidak yakin bagaimana mengatasi masalah yang Anda kemukakan. Sangat menarik dan memiliki implikasi di luar pengembangan game.
Edward Strange
@rcapote bukankah situs ini untuk papan tulis / diskusi?
2
@ Jo - tidak, tidak. Bahkan tidak menyebutkan "diskusi" di sini atau Anda akan keluar dari keberadaan. Situs ini hanya untuk jenis Pertanyaan-> Jawab-> Selesai interaksi.
Edward Strange
Nah, sistem entitas berbasis komponen adalah sesuatu yang sudah mulai tren di komunitas pengembang game belakangan ini jadi saya pikir Anda mungkin mendapatkan perhatian yang lebih baik di sana, tetapi Anda mungkin akan mendapatkan jawaban yang baik di sini. Berikut adalah diskusi menarik di gamedev.net tentang masalah ini yang mungkin menarik bagi Anda: gamedev.net/topic/…
rcapote

Jawaban:

1

Lihatlah presentasi ini . Kedengarannya cukup dekat dengan jenis pola yang Anda cari. Pola ini mendukung perilaku dan properti yang dapat dilampirkan. Saya tidak berpikir presentasi menyebutkannya, tetapi Anda juga dapat membuat acara yang dapat dilampirkan. Ide ini mirip dengan properti dependensi yang digunakan dalam WPF.

Nieldy
sumber
9

Bagi saya ini kedengarannya seperti kasus buku teks hampir untuk menggunakan Pola Strategi . Dalam pola ini, perilaku generik Anda dapat didefinisikan dalam antarmuka yang akan memungkinkan Anda untuk menukar implementasi perilaku yang berbeda saat runtime (pikirkan tentang bagaimana power-up dapat memengaruhi kemampuan melompat atau berlari dari karakter Anda).

Untuk contoh (dibuat-buat):

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

Sekarang Anda dapat menerapkan berbagai jenis lompatan yang dapat digunakan karakter Anda, tanpa harus mengetahui detail tentang setiap lompatan spesifik:

// 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!");
     }
}

Setiap karakter yang Anda ingin memiliki kemampuan untuk melompat bisa sekarang berisi referensi ke IJumpable dan dapat mulai mengkonsumsi berbagai implementasi Anda

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;
    }

}

Maka kode Anda dapat terlihat seperti:

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();

Sekarang Anda dapat dengan mudah menggunakan kembali perilaku ini, atau bahkan memperpanjangnya nanti karena Anda ingin menambahkan lebih banyak jenis lompatan, atau membuat lebih banyak game yang dibangun pada satu platform Pengguliran Samping.

mclark1129
sumber
sementara tidak persis apa yang saya cari, ini sangat dekat dan menyukainya. Saya akan bermain-main dengan itu untuk memastikan. Terima kasih!
1

Lihatlah arsitektur DCI pandangan yang menarik tentang pemrograman OO yang dapat membantu.

Menerapkan arsitektur gaya DCI dalam C # membutuhkan menggunakan kelas domain sederhana, dan menggunakan objek Konteks (perilaku) dengan Metode Ekstensi dan Antarmuka untuk memungkinkan kelas domain berkolaborasi di bawah peran yang berbeda. Antarmuka digunakan untuk menandai peran yang diperlukan untuk skenario. Kelas domain mengimplementasikan antarmuka (peran) yang berlaku untuk perilaku yang diinginkan. Kolaborasi antara peran terjadi dalam objek konteks (perilaku).

Anda bisa membuat perpustakaan perilaku dan peran umum yang dapat dibagi di antara objek domain dari proyek terpisah.

Lihat DCI dalam C # untuk contoh kode dalam C #.

Ed James
sumber
0

Bagaimana dengan meneruskan objek konteks menjadi perilaku yang menyediakan metode untuk mengubah keadaan sprite / objek yang dipengaruhi oleh perilaku? Sekarang jika suatu objek memiliki beberapa perilaku mereka masing-masing dipanggil dalam satu lingkaran memberi mereka kesempatan untuk mengubah konteksnya. Jika modifikasi tertentu dari properti mengesampingkan / membatasi modifikasi properti lain, objek konteks dapat menyediakan metode untuk mengatur beberapa jenis flag untuk menunjukkan fakta ini, atau hanya dapat menolak modifikasi yang tidak diinginkan.

Jonny Dee
sumber