Cách cấu trúc trạng thái trò chơi trong một hệ thống dựa trên thực thể / thành phần


11

Tôi đang tạo một trò chơi được thiết kế với mô hình thành phần thực thể sử dụng các hệ thống để giao tiếp giữa các thành phần như được giải thích ở đây . Tôi đã đạt đến điểm trong sự phát triển của mình rằng tôi cần thêm các trạng thái trò chơi (như tạm dừng, chơi, bắt đầu cấp độ, bắt đầu vòng, kết thúc trò chơi, v.v.), nhưng tôi không chắc làm thế nào để làm điều đó với khuôn khổ của mình. Tôi đã xem ví dụ mã này trên các trạng thái trò chơi mà mọi người dường như tham chiếu, nhưng tôi không nghĩ rằng nó phù hợp với khuôn khổ của tôi. Dường như mỗi bang xử lý bản vẽ và cập nhật riêng của mình. Khung công tác của tôi có SystemManager xử lý tất cả các cập nhật bằng hệ thống. Ví dụ: đây là lớp RenderingSystem của tôi:

public class RenderingSystem extends GameSystem {

    private GameView gameView_;

    /**
     * Constructor
     * Creates a new RenderingSystem.
     * @param gameManager The game manager. Used to get the game components.
     */
    public RenderingSystem(GameManager gameManager) {
        super(gameManager);
    }

    /**
     * Method: registerGameView
     * Registers gameView into the RenderingSystem.
     * @param gameView The game view registered.
     */
    public void registerGameView(GameView gameView) {
        gameView_ = gameView;
    }

    /**
     * Method: triggerRender
     * Adds a repaint call to the event queue for the dirty rectangle.
     */
    public void triggerRender() {
        Rectangle dirtyRect = new Rectangle();

        for (GameObject object : getRenderableObjects()) {
            GraphicsComponent graphicsComponent =
                    object.getComponent(GraphicsComponent.class);
            dirtyRect.add(graphicsComponent.getDirtyRect());
        }

        gameView_.repaint(dirtyRect);
    }

    /**
     * Method: renderGameView
     * Renders the game objects onto the game view.
     * @param g The graphics object that draws the game objects.
     */
    public void renderGameView(Graphics g) {
        for (GameObject object : getRenderableObjects()) {
            GraphicsComponent graphicsComponent =
                    object.getComponent(GraphicsComponent.class);
            if (!graphicsComponent.isVisible()) continue;

            GraphicsComponent.Shape shape = graphicsComponent.getShape();
            BoundsComponent boundsComponent =
                    object.getComponent(BoundsComponent.class);
            Rectangle bounds = boundsComponent.getBounds();

            g.setColor(graphicsComponent.getColor());

            if (shape == GraphicsComponent.Shape.RECTANGULAR) {
                g.fill3DRect(bounds.x, bounds.y, bounds.width, bounds.height,
                        true);
            } else if (shape == GraphicsComponent.Shape.CIRCULAR) {
                g.fillOval(bounds.x, bounds.y, bounds.width, bounds.height);
            }
        }
    }

    /**
     * Method: getRenderableObjects
     * @return The renderable game objects.
     */
    private HashSet<GameObject> getRenderableObjects() {
        return gameManager.getGameObjectManager().getRelevantObjects(
                getClass());
    }

}

Ngoài ra tất cả các cập nhật trong trò chơi của tôi là theo sự kiện. Tôi không có một vòng lặp như của họ mà chỉ đơn giản là cập nhật mọi thứ cùng một lúc.

Tôi thích khung công tác của mình vì nó giúp dễ dàng thêm GameObject mới, nhưng không gặp vấn đề gì mà một số thiết kế dựa trên thành phần gặp phải khi giao tiếp giữa các thành phần. Tôi ghét phải tặc lưỡi chỉ để tạm dừng làm việc. Có cách nào để tôi có thể thêm trạng thái trò chơi vào trò chơi của mình mà không cần xóa thiết kế thành phần thực thể không? Ví dụ về trạng thái trò chơi có thực sự phù hợp với khuôn khổ của tôi không và tôi chỉ thiếu một cái gì đó?

EDIT: Tôi có thể đã không giải thích khuôn khổ của tôi đủ tốt. Các thành phần của tôi chỉ là dữ liệu. Nếu tôi viết mã bằng C ++, có lẽ chúng sẽ là cấu trúc. Đây là một ví dụ về một:

public class BoundsComponent implements GameComponent {

    /**
     * The position of the game object.
     */
    private Point pos_;

    /**
     * The size of the game object.
     */
    private Dimension size_;

    /**
     * Constructor
     * Creates a new BoundsComponent for a game object with initial position
     * initialPos and initial size initialSize. The position and size combine
     * to make up the bounds.
     * @param initialPos The initial position of the game object.
     * @param initialSize The initial size of the game object.
     */
    public BoundsComponent(Point initialPos, Dimension initialSize) {
        pos_ = initialPos;
        size_ = initialSize;
    }

    /**
     * Method: getBounds
     * @return The bounds of the game object.
     */
    public Rectangle getBounds() {
        return new Rectangle(pos_, size_);
    }

    /**
     * Method: setPos
     * Sets the position of the game object to newPos.
     * @param newPos The value to which the position of the game object is
     * set.
     */
    public void setPos(Point newPos) {
        pos_ = newPos;
    }

}

Các thành phần của tôi không giao tiếp với nhau. Hệ thống xử lý giao tiếp liên thành phần. Hệ thống của tôi cũng không liên lạc với nhau. Chúng có chức năng riêng biệt và có thể dễ dàng được giữ riêng biệt. MovementSystem không cần biết RenderingSystem đang hiển thị gì để di chuyển các đối tượng trò chơi một cách chính xác; nó chỉ cần đặt đúng giá trị trên các thành phần, để khi RenderingSystem kết xuất các đối tượng trò chơi, nó có dữ liệu chính xác.

Trạng thái trò chơi không thể là một hệ thống, bởi vì nó cần phải tương tác với các hệ thống hơn là các thành phần. Đó không phải là thiết lập dữ liệu; nó xác định chức năng nào cần được gọi.

Một GameStateComponent sẽ không có ý nghĩa vì tất cả các đối tượng trò chơi đều có chung một trạng thái trò chơi. Các thành phần là những gì tạo nên các đối tượng và mỗi một khác nhau cho mỗi đối tượng khác nhau. Ví dụ, các đối tượng trò chơi không thể có cùng giới hạn. Chúng có thể có giới hạn chồng chéo, nhưng nếu chúng có chung BoundComponent, chúng thực sự là cùng một đối tượng. Hy vọng rằng, lời giải thích này làm cho khuôn khổ của tôi bớt khó hiểu.

Câu trả lời:


4

Tôi sẽ thừa nhận rằng tôi đã không đọc liên kết bạn đã đăng. Sau khi chỉnh sửa và đọc liên kết được cung cấp, vị trí của tôi đã thay đổi. Dưới đây phản ánh điều này.


Tôi không biết rằng bạn cần phải lo lắng về trạng thái trò chơi theo nghĩa truyền thống. Xem xét cách tiếp cận của bạn để phát triển, mỗi hệ thống cụ thể đến mức chúng có hiệu lực quản lý nhà nước của trò chơi.

Trong một hệ thống thực thể, các thành phần chỉ là dữ liệu, phải không? Một nhà nước cũng vậy. Ở dạng đơn giản nhất, nó chỉ là một lá cờ. Nếu bạn xây dựng các trạng thái của mình thành các thành phần và cho phép các hệ thống của bạn tiêu thụ dữ liệu của các thành phần đó và phản ứng với các trạng thái (cờ) trong chúng, bạn sẽ xây dựng quản lý trạng thái của mình vào từng hệ thống.

Có vẻ như các hệ thống quản lý như ví dụ AppHub không áp dụng rất tốt cho mô hình phát triển của bạn. Tạo một siêu hệ thống đóng gói các hệ thống khác dường như đánh bại mục đích tách logic khỏi dữ liệu.

Điều này có thể giúp bạn hiểu ý của tôi về việc không phải xử lý rõ ràng trạng thái trò chơi:

http://paulgestwicki.blogspot.com/2012/03/components-and-systems-of-morgans-ston.html


Xin vui lòng xem chỉnh sửa của tôi. Xin lỗi nếu tôi đã nhầm lẫn.
Eva

Cập nhật để phản ánh những khám phá mới và chỉnh sửa của bạn. Hy vọng rằng ai đó có nhiều kinh nghiệm hơn trong việc xây dựng các hệ thống thực thể sẽ hòa nhập, vì đây không phải là lĩnh vực mà tôi có nhiều kinh nghiệm.
Cypher

Còn việc gỡ bỏ và thêm hệ thống khi trạng thái trò chơi thay đổi thì sao? Ví dụ: khi bạn tạm dừng trò chơi, có lẽ không cần MovementSystem hoặc CollisionSystem của bạn, nhưng bạn vẫn muốn RenderSystem của bạn vẽ những thứ trên màn hình. Các hệ thống hoạt động có thể đại diện cho một trạng thái trò chơi?
argenkiwi

0

Nhà nước là một giá trị áp dụng cho một đối tượng. Trạng thái trò chơi, như tên cho thấy, sẽ là trạng thái của một đối tượng 'Trò chơi'. Đối tượng Trò chơi đó - hoặc nhiều khả năng là một thành phần cụ thể trên đó - sẽ theo dõi trạng thái hiện tại và tạo hoặc phá hủy bất kỳ đối tượng nào cần thiết để tạo điều kiện cho trạng thái hiện tại. Vì các thành phần của bạn chỉ là dữ liệu, bạn sẽ cần một Hệ thống mới để xử lý việc này, mặc dù có thể chỉ có một phiên bản của thành phần được liên kết.

Thật khó để nhận xét về cách bạn sẽ thực hiện tạm dừng khi không rõ cách bạn thực hiện cập nhật. Quá trình phát ra các sự kiện cập nhật có thể chọn không làm như vậy, nếu đối tượng trò chơi nói rằng trò chơi bị tạm dừng. Làm thế nào đối tượng trò chơi giao tiếp với quá trình cập nhật tùy thuộc vào bạn; có lẽ getRelevantObjectscuộc gọi của bạn sẽ cho phép người cập nhật tìm đối tượng Trò chơi hoặc ngược lại.

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.