Tạo một hệ thống dựa trên hành vi / Thành phần cho các trò chơi


11

Lý lịch

Tôi phát triển game như một sở thích, và đang tìm kiếm một cách tốt hơn để thiết kế chúng. Hiện tại, tôi đang sử dụng một phương pháp OOP tiêu chuẩn (Tôi đã thực hiện phát triển doanh nghiệp được 8 năm nên nó xuất hiện thường xuyên). Lấy ví dụ một "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
}

Vấn đề

Hãy nói rằng tôi đang tạo một platformer 2d và cần baddie để có thể Nhảy. Thông thường những gì tôi làm là thêm mã thích hợp trong các phương thức Update / GetInput. Sau đó, nếu tôi cần làm cho người chơi bò, vịt, leo trèo, v.v ... mã sẽ đến đó.

Nếu tôi không cẩn thận, các phương thức đó sẽ bị lộn xộn, vì vậy tôi sẽ tạo ra các cặp phương thức như thế này

CheckForJumpAction(Input input)DoJump()

CheckforDuckAction(Input input)DoDuck()

vì vậy GetInput trông giống như

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

và Cập nhật trông giống như

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

Nếu tôi đi và tạo một trò chơi khác mà người chơi cần phải nhảy và đạp vịt, tôi thường vào một trò chơi có chức năng và sao chép nó. Lộn xộn, tôi biết. Đó là lý do tại sao tôi đang tìm kiếm một cái gì đó tốt hơn.

Giải pháp?

Tôi thực sự thích cách Blend có các hành vi tôi có thể gắn vào một yếu tố. Tôi đã suy nghĩ về việc sử dụng khái niệm tương tự trong các trò chơi của tôi. Vì vậy, hãy nhìn vào các ví dụ tương tự.

Tôi sẽ tạo một đối tượng Hành vi cơ sở

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

Và tôi có thể tạo ra các hành vi bằng cách sử dụng đó. JumpBehavior:BehaviorDuckBehavior:Behavior

Sau đó tôi có thể thêm một tập hợp các hành vi vào cơ sở Sprite và thêm những gì tôi cần cho mỗi thực thể.

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

Vì vậy, bây giờ Nếu tôi muốn sử dụng Jump và Duck trong nhiều trò chơi, tôi chỉ có thể mang các hành vi qua. Tôi thậm chí có thể làm một thư viện cho những người phổ biến.

Nó có hoạt động không?

Những gì tôi không thể tìm ra là làm thế nào để chia sẻ trạng thái giữa họ. Nhìn vào Jump và Duck, cả hai không chỉ ảnh hưởng đến phần hiện tại của kết cấu được vẽ mà còn ảnh hưởng đến trạng thái của người chơi. (Nhảy sẽ áp dụng một lực giảm dần theo thời gian, trong khi vịt sẽ ngừng chuyển động, thay đổi kết cấu và kích thước va chạm của baddie.

Làm thế nào tôi có thể buộc nó lại với nhau để nó hoạt động? Tôi có nên tạo thuộc tính phụ thuộc giữa các hành vi? Tôi có nên cho mỗi hành vi biết về cha mẹ và trực tiếp sửa đổi nó không? Một điều tôi nghĩ là có thể chuyển một đại biểu vào từng hành vi để được thực thi khi nó được kích hoạt.

Tôi chắc chắn có nhiều vấn đề hơn tôi đang xem xét, nhưng toàn bộ mục đích là để tôi có thể dễ dàng sử dụng lại các hành vi này giữa các trò chơi và các thực thể trong cùng một trò chơi.

Vì vậy, tôi chuyển nó cho bạn. Quan tâm để giải thích làm thế nào / nếu điều này có thể được thực hiện? Bạn có ý kiển nào tốt hơn không? Tôi là tất cả tai.


Điều này có thể được hỏi tốt hơn tại gamedev.stackexchange.com ?
RCapote

Tôi thích nơi bạn sẽ đến nhưng tôi không chắc làm thế nào để giải quyết các vấn đề bạn đưa ra. Rất thú vị và có ý nghĩa ngoài việc phát triển trò chơi.
Edward Strange

@rcapote không phải là trang web này để thảo luận / thảo luận?

2
@Joe - không, không Thậm chí không đề cập đến "thảo luận" ở đây hoặc bạn sẽ bị loại khỏi sự tồn tại. Trang web này chỉ dành cho Câu hỏi-> Trả lời-> Đã hoàn thành loại tương tác.
Edward Strange

Chà, hệ thống thực thể dựa trên thành phần là thứ bắt đầu thịnh hành trong cộng đồng nhà phát triển trò chơi gần đây vì vậy tôi cho rằng bạn có thể được chú ý tốt hơn ở đó, nhưng dù sao bạn cũng sẽ nhận được câu trả lời tốt. Đây là một cuộc thảo luận thú vị trên gamedev.net về vấn đề này mà bạn có thể thấy thú vị: gamedev.net/topic/
mẹo

Câu trả lời:


1

Hãy xem bài trình bày này . Âm thanh khá gần với loại mẫu bạn đang tìm kiếm. Mẫu này hỗ trợ các hành vi và thuộc tính đính kèm. Tôi không nghĩ rằng bài thuyết trình đề cập đến nó, nhưng bạn cũng có thể tạo các sự kiện đính kèm. Ý tưởng này tương tự như các thuộc tính phụ thuộc được sử dụng trong WPF.


9

Đối với tôi điều này nghe có vẻ giống như một trường hợp gần như trong sách giáo khoa khi sử dụng Mẫu chiến lược . Trong mô hình này, các hành vi chung của bạn có thể được xác định trong các giao diện cho phép bạn trao đổi các cách thực hiện khác nhau trong thời gian chạy (nghĩ về cách tăng sức mạnh có thể ảnh hưởng đến khả năng nhảy hoặc chạy của nhân vật).

Ví dụ (giả định):

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

Bây giờ bạn có thể thực hiện các loại bước nhảy khác nhau mà nhân vật của bạn có thể sử dụng, mà không nhất thiết phải biết chi tiết về từng bước nhảy cụ thể:

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

Bất kỳ nhân vật nào bạn muốn có khả năng nhảy đều có thể chứa tham chiếu đến IJumpable và có thể bắt đầu sử dụng các triển khai khác nhau của bạn

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

}

Sau đó, mã của bạn có thể trông giống như:

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

Giờ đây, bạn có thể dễ dàng sử dụng lại các hành vi này hoặc thậm chí mở rộng chúng sau này khi bạn muốn thêm nhiều kiểu nhảy hơn hoặc tạo thêm các trò chơi được xây dựng trên một nền tảng cuộn Side.


trong khi không chính xác những gì tôi đang tìm kiếm, điều này rất gần và thích nó. Tôi sẽ chơi xung quanh với nó để đảm bảo. cảm ơn!

1

Hãy xem kiến trúc DCI một cách thú vị về lập trình OO có thể giúp ích.

Việc triển khai kiến ​​trúc kiểu DCI trong C # yêu cầu sử dụng các lớp miền đơn giản và sử dụng các đối tượng Ngữ cảnh (hành vi) với Phương thức mở rộng và Giao diện để cho phép các lớp miền cộng tác dưới các vai trò khác nhau. Giao diện được sử dụng để đánh dấu các vai trò cần thiết cho một kịch bản. Các lớp miền thực hiện các giao diện (vai trò) áp dụng cho hành vi dự định của chúng. Sự hợp tác giữa các vai trò diễn ra trong các đối tượng bối cảnh (hành vi).

Bạn có thể tạo một thư viện các hành vi và vai trò phổ biến có thể được chia sẻ giữa các đối tượng miền từ các dự án riêng biệt.

Xem DCI trong C # để biết ví dụ về mã trong C #.


0

Điều gì về việc chuyển trong một đối tượng bối cảnh vào một hành vi cung cấp các phương thức để thay đổi trạng thái của các họa tiết / đối tượng bị ảnh hưởng bởi một hành vi? Bây giờ nếu một đối tượng có một vài hành vi thì mỗi đối tượng được gọi trong một vòng lặp cho họ cơ hội thay đổi bối cảnh. Nếu một sửa đổi nhất định của một quy tắc thuộc tính ra / ràng buộc sửa đổi các thuộc tính khác, đối tượng bối cảnh có thể cung cấp các phương thức để đặt một số loại cờ để chỉ ra thực tế này hoặc đơn giản là nó có thể từ chối các sửa đổi không mong muốn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.