簡體   English   中英

C ++狀態:事件序列不是非常面向對象的

[英]C++ States: Sequence of Events is not very object orientated

我正在努力使我的代碼更面向對象。

我有一個小程序,希望完成2個非常簡單的狀態:輸入狀態和結果狀態。

輸入狀態似乎很容易解決,因為它是圖形化的,它是“自我更新”的。 用戶在屏幕上放置精靈並將其刪除,以產生輸入。

結果狀態讓我很煩,因為我為此編寫了一些非常丑陋的代碼,而這些代碼根本不是面向對象的。

必須按此狀態順序執行操作,而我正在努力尋找有關如何使用對象完成操作的示例。 基本上是帶有相同對象的某些動畫:這是一些偽代碼。

Static int objectx = 120, object y = 120;
Static int state=0

switch(state)
{
Case 0:
//....move object right
//....once object is far enough right
state = 1;

Case 1:
//....move object down
//....once object is far enough down
state = 2;

...etc

因此,我猜想它需要轉向使用某種狀態引擎,但是我正在努力查看如何使用狀態來完成順序事件。 這些狀態總是相同的,因此可以進行硬編碼,它們不會根據給定的輸入而改變。

非常感謝您的任何幫助。

更新

也許我們可以將第二種狀態視為2D游戲中的過場動畫。 我們希望角色走到屏幕上,說些什么然后走開。

因此,我目前的操作方式是通過switch語句管理程序的這一部分狀態。 每當我們進入程序的“結果”部分時,都會調用此函數,並且我們使用switch語句更新子畫面的位置。 一旦到達第一組動作的末尾,我們將移至下一個switch語句,並繼續執行直到完成為止。 可以工作,但是我希望使用“ gamestate”類,該類可以獲取圖形和聲音的所有權,並適當移動內容。

注意:在這里做一些假設,因為我沒有任何上下文。

聽起來每個精靈都應該有自己的循環,而不是整個游戲邏輯都圍繞着精靈運動。 將其調整為面向對象的設計后,可以將每個精靈包裝在某個類中:

class NPC : Sprite {
    private:
        Position CurrentPosition;
        int CurrentState;

    public:
        virtual void Think() = 0;
        virtual void Render() = 0;
};

然后,您可以從此類繼承特定的Sprite:

class GobbledyGook : NPC {
    private:
        const int FinalState = 10;

    public:        
        bool Completed = false;

        void Think() override {
            if(Completed)
                return;

            switch(CurrentState) {
                // ... repeating logic here ...
            }

            CurrentState++;

            if(CurrentState == FinalState)
                Completed = true;
        }

        void Render() override {
            // ... draw the sprite ...
        }
}

然后,您可以從主要游戲邏輯更新每個精靈:

// Spawn a GobbledyGook into existence.
my_npcs.insert(new GobbledyGook());

// In frame logic.
bool finished = true;
for( NPC* n : my_npcs )
{
    n->Think();
    if(!n->Completed)
        finished = false;
}

if(finished) {
    // Result state.
}

// In render logic.
for( NPC* n : my_npcs )
{
    n->Render();
}

您自然也可以對整個場景采用這種邏輯:

class Intro : Cutscene {
    private:
        vector<NPC*> SceneSprites;

    public:
        void Think() override {
            switch(CurrentState) {
                ...
            }

            for( NPC* n : SceneSprites ) {
                n->Think();
            }
        }

        ...
};

至於您應該刪除還是更改狀態的使用,您打算從中獲得什么呢?

在不了解當前方法的所有缺陷的情況下,很難推薦一種不同的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM