简体   繁体   English

C ++状态:事件序列不是非常面向对象的

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

I am struggling to make my code more object orientated. 我正在努力使我的代码更面向对象。

I have a small program that wishes to accomplish 2 very simple states: An input state, and a result state. 我有一个小程序,希望完成2个非常简单的状态:输入状态和结果状态。

The input state seems simple to resolve as although it is graphical it is "self-updating." 输入状态似乎很容易解决,因为它是图形化的,它是“自我更新”的。 The user drops sprites and removes sprites on to the screen to produce an input. 用户在屏幕上放置精灵并将其删除,以产生输入。

The result state is annoying me because I have produced some very ugly code for it, that is not at all Object Orientated. 结果状态让我很烦,因为我为此编写了一些非常丑陋的代码,而这些代码根本不是面向对象的。

This state is required to do things sequentially and I am struggling to find examples of how that is done with Objects. 必须按此状态顺序执行操作,而我正在努力寻找有关如何使用对象完成操作的示例。 It's basically some animation with the same object: here is some Pseudo-Code. 基本上是带有相同对象的某些动画:这是一些伪代码。

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

So I am guessing it needs to move to having some sort of state engine, but I am struggling to see how to accomplish sequential events using states. 因此,我猜想它需要转向使用某种状态引擎,但是我正在努力查看如何使用状态来完成顺序事件。 These states are always the same, and so can be hard coded, they will not change based upon the input given. 这些状态总是相同的,因此可以进行硬编码,它们不会根据给定的输入而改变。

Any help will be most gratefully recieved. 非常感谢您的任何帮助。

UPDATE 更新

Maybe we could think about this second state as a cut-scene in a 2d game. 也许我们可以将第二种状态视为2D游戏中的过场动画。 We want a character to walk on to the screen, say something and then walk off. 我们希望角色走到屏幕上,说些什么然后走开。

So the way I'm doing it at the moment is managing this part of the programs state via the switch statement. 因此,我目前的操作方式是通过switch语句管理程序的这一部分状态。 This function is called every time we are in the "result" part of our program, and we are using the switch statement to update the positions of our sprites. 每当我们进入程序的“结果”部分时,都会调用此函数,并且我们使用switch语句更新子画面的位置。 Once we have reached the end of the first set of movements we move to the next switch statement and keep doing that until it is completed. 一旦到达第一组动作的末尾,我们将移至下一个switch语句,并继续执行直到完成为止。 It works but I was hoping to use a " gamestate " Class, that could take ownership of the graphics and sound, and move things as appropriate. 可以工作,但是我希望使用“ gamestate”类,该类可以获取图形和声音的所有权,并适当移动内容。

Note: making some assumptions here because I don't have any context. 注意:在这里做一些假设,因为我没有任何上下文。

It sounds like each sprite should have its own cycle, rather than the entire game logic moving about the sprites. 听起来每个精灵都应该有自己的循环,而不是整个游戏逻辑都围绕着精灵运动。 Adapting this into an object-orientated design, you can wrap each sprite in some class: 将其调整为面向对象的设计后,可以将每个精灵包装在某个类中:

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

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

Then you can inherit from this class for specific sprites: 然后,您可以从此类继承特定的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 ...
        }
}

From the main game logic you can then update every 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();
}

You can naturally adopt this logic for entire scenes too: 您自然也可以对整个场景采用这种逻辑:

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

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

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

        ...
};

As for whether you should be removing or changing the use of states, what do you intend to gain from doing that? 至于您应该删除还是更改状态的使用,您打算从中获得什么呢?

It's hard to recommend a different approach without knowing all the flaws of the current approach. 在不了解当前方法的所有缺陷的情况下,很难推荐一种不同的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM