Можно ли поместить игровую логику в функцию отрисовки? - PullRequest
4 голосов
/ 12 февраля 2010

Я делаю игру, и я наконец-то закончил игровой процесс, но теперь пришло время создать меню и экран рекордов. Я не совсем уверен, как это сделать, игра будет в другом состоянии (MENU_STATE, GAMEPLAY_STATE, SCORESCREEN_STATE) и в каждом состоянии я хочу рисовать разные вещи на экране, можно ли мне делать что-то подобное то

draw function()
{
    if MENU_STATE
        draw menu
    if GAMEPLAY_STATE
        draw game
    if SCORESCREEN_STATE
        draw scores
}

Я строго следовал логике в функции рисования, и до сих пор это было хорошо, но я действительно не могу придумать другой способ сделать это.

Ответы [ 6 ]

5 голосов
/ 12 февраля 2010

Вы можете использовать отдельные классы для трех состояний, реализуя общий интерфейс и вместо установки константы для состояния, установить экземпляр одного из классов:

interface IState {
    void draw();
}

class Menu implements IState {
    void draw() {
        // Draw menu
    }
}

class Game implements IState {
    void draw() {
        // Draw game
    }
}

void draw() {
    state.draw();
}

Это все еще не идеально (вы не хотите рисовать код в своем состоянии, вам нужно что-то более отдельное), но абстракция является обычной и может быть актуальной (и ее трудно советовать дальше без зная больше о своей архитектуре).

3 голосов
/ 12 февраля 2010

Вы вызываете некоторые функции рисования в этой подпрограмме, но это не значит,
Вы должны назвать это ничья .

Возможно, это более уместно в вашем случае:

// pseudocode
on_game_state function(state)
{
    select (state):
      MENU_STATE:
        draw menu
      GAMEPLAY_STATE:
        draw game
      SCORESCREEN_STATE:
        draw scores
}
1 голос
/ 12 февраля 2010

Аналогично ответу Эндрю Айлетта и, предполагая, что объектно-ориентированный язык, возможно, вы могли бы сделать что-то вроде:

Interface IState {
    void init();
    void update();
    void draw();
}

class GameplayScene implements IState {
    void init() {
        // initialize gameplay
    }
    void update() {
        // update game logic
    }
    void draw() {
        // draw game
    }
}

class MenuScene implements IState {
    void init() {
        // initialize menu
    }
    void update() {
        // update menu logic
    }
    void draw() {
        // draw menu
    }
}

class ScoresScene etc...

class TitleScene etc...

// Somewhere else, probably in the Game class
void Main() {
    // Init game
    Scene currentScene = new TitleScene;
    while (Scene != null) {
        Scene.init();
        Scene.update();
        Scene.draw();
    }
    // Exit game
}

Вам также нужно подумать о том, как обрабатывать переходы между сценами. У каждого класса сцены может быть переменная-член, называемая чем-то вроде nextScene, и основная функция запрашивает ее в начале цикла, чтобы переключиться на нужную сцену.

Если вы не можете позволить себе роскошь использовать объектно-ориентированный язык программирования (например, C ++, Java, C #, Python и т. Д.), То оба Колина и Ника Д ответы могут помочь, хотя я постараюсь разместить оператор switch в одном месте (скажем, одну большую функцию game_update), чтобы позволить добавлять новые состояния, внося изменения в одном месте. В качестве альтернативы, вы можете использовать дизайн конечного автомата Колина, чтобы сделать что-то более общее, и для этого явно не требуется жестко закодированный оператор switch. (хотя, если честно, сейчас я не могу придумать, как это сделать)

1 голос
/ 12 февраля 2010

Использование машины состояний сделало бы это проще. Каждое состояние будет иметь свой собственный набор функций обновления и рисования, которые вызываются, когда он находится на вершине стека состояний. Вместо одной функции рисования с внутренними переключателями состояния у вас будут Game_Draw (), Menu_Draw (), HighScoreScreen_Draw () и т. Д. Аналогичным образом ваши функции обновления могут быть выделены.

static void StateMachine_DrawTopState()
{
   switch(stateMachine_topState)
   {
       case STATE_GAMEPLAY:
       {
           Gameplay_Draw();
       }
       break;
       case STATE_MENU:
       {
           Menu_Draw();
       }
       break;
   }
}
0 голосов
/ 12 февраля 2010

Да, все в порядке, программистам разрешено изменять правила для повышения производительности. Представление и модель игрового мира довольно часто являются одним и тем же, чтобы избежать задержки, возникающей при разделении вида и модели.

Нет никаких причин, по которым вы не можете сделать меню и рекорды объектами своего игрового мира, это было сделано ранее во многих играх.

0 голосов
/ 12 февраля 2010

Абсолютно не нормально помещать игровую логику в функцию рисования.

Однако, если это облегчает вашу жизнь в этом конкретном случае, все равно все в порядке.

Вы всегда можете изменить его позже, если он станет беспорядком.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...