2016-08-25 6 views
0

Я изо всех сил пытаюсь сделать свой код более ориентированным на объект.C++ States: последовательность событий не очень объектно ориентирована

У меня есть небольшая программа, которая хочет выполнить 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 для обновления позиций наших спрайтов. Как только мы достигли конца первого набора движений, мы переходим к следующему оператору switch и продолжаем делать это до тех пор, пока оно не будет завершено. Это работает, но я надеялся использовать класс «gamestate», который может взять на себя ответственность за графику и звук и, в случае необходимости, перемещать вещи.

+0

«Я изо всех сил пытаюсь сделать свой код более ориентированным на объект». - Все в 1995 году, после того, как эта новая вещь под названием «Java» была объявлена ​​на E3. «Более 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

Это отличное место для меня. Спасибо, что нашли время, чтобы сломать это и записать его, я очень благодарен. Я уверен, что смогу адаптировать этот подход к моим потребностям. –