2016-08-25 21 views
0

我在努力使我的代码更加面向对象。C++:事件序列不是很面向对象

我有一个小程序希望完成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 

所以我猜它需要移动到某种状态引擎,但我很努力地看到如何使用状态完成顺序事件。这些状态总是相同的,所以可以进行硬编码,它们不会根据给定的输入而改变。

任何帮助将最感激地收到。

UPDATE

也许我们可以想想这第二个状态作为一个2D游戏切场景。我们希望一个角色走到屏幕上,说点什么,然后走开。

所以我现在做的方式是通过switch语句管理这部分程序状态。每次我们进入程序的“结果”部分时都会调用这个函数,我们使用switch语句来更新我们精灵的位置。一旦我们到达第一组运动的末尾,我们就转到下一个开关语句,并继续这样做直到它完成。它工程但我希望能使用“游戏状态”类,它可以取得图形和声音的所有权,并适当地移动东西。

+0

“我正在努力使我的代码更加面向对象。” - 在1995年,在E3宣布这个名为“Java”的新事物之后,每个人都是这样。 “超过18个gazillion不同的整数,你永远无法探索它们,每个班都不同,以光速执行你的代码。” –

+0

你需要重构你的代码,而不是只是跳到“面向对象的编程训练”,直到它被重构。除非我们看到你没有发布的功能中常见的东西,否则这就是所有可以说的。 – PaulMcKenzie

回答

1

注意:在这里做一些假设是因为我没有任何上下文。

听起来像每个精灵都应该有自己的循环,而不是整个游戏逻辑移动的精灵。 适应到面向对象的设计,这一点,你可以在一些 类包装每个精灵:

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

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

然后你可以从该类继承的特定精灵:

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

     ... 
}; 

至于你是否应该删除或改变使用状态,你打算从这样做中获得什么?

在不了解当前方法的所有缺陷的情况下,很难推荐不同的方法。

+0

这是我开始的好地方。感谢您花时间打破这一切并写出来,我非常感谢。我确信我可以根据自己的需要调整这种方法。 –