2010-05-22 1 views
2

Я развиваю игру, игра имеет другой режим. Легкий, нормальный и сложный. Итак, я думаю о том, как сохранить игровой режим. Моя первая идея - использовать число, чтобы представить трудность.Как упростить этот код или улучшить дизайн?

Easy = 0 Нормальный = 1 Трудный = 2

Итак, мой код будет иметь что-то вроде этого:

switch(gameMode){ 

case 0: 
//easy 
break; 

case 1: 
//normal 
break; 

case 3: 
//difficult 
break; 

} 

Но я думаю, что есть какие-то проблемы, если я добавить новый режим, например, «Экстремальный», мне нужно добавить случай 4 ... ... кажется, это не дизайн gd.

Итак, я думаю, что создание объекта gameMode, а другой gameMode является подклассом суперкласса gameMode. Объект GameMode что-то вроде этого:

class GameMode{ 
    int maxEnemyNumber; 
    int maxWeaponNumber; 
     public static GameMode init(){ 
     GameMode gm = GameMode(); 
     gm.maxEnemyNumber = 0; 
     gm.maxWeaponNumber = 0; 
     return gm; 
     }  

    } 

class EasyMode extends GameMode{ 

     public static GameMode init(){ 
     GameMode gm = super.init(); 
     gm.maxEnemyNumber = 10; 
     gm.maxWeaponNumber = 100; 
     return gm; 
     }  
} 


class NormalMode extends GameMode{ 

     public static GameMode init(){ 
     GameMode gm = super.init(); 
     gm.maxEnemyNumber = 20; 
     gm.maxWeaponNumber = 80; 
     return gm; 
     }  
} 

Но я думаю, что это кажется слишком «громоздким», чтобы создать объект для хранения GameMode, мой «GameMode» только хранить различные переменные для настройки игры .... Это любой простой способ хранения данных вместо создания объекта? thz u.

+1

Какой язык вы используете? –

+0

выглядит как java – IAbstract

ответ

2

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

Например, вы можете написать в C:

typedef enum difficulties { 
    DIFFICULTY_EASY, 
    DIFFICULTY_MEDIUM, 
    DIFFICULTY_HARD 
} difficulties; 

struct { 
    int max_enemies; 
    int max_weapons; 
} difficulty_settings[] = { 
    {10, 4}, 
    {20, 5}, 
    {30, 6} 
}; 

И когда вы хотите прочитать определенную настройку, например max_enemies для легкого уровня, то вы можете написать difficulty_settings[DIFFICULTY_EASY].max_enemies

Это легко чтобы добавить дополнительную конфигурацию (либо больше параметров, либо больше уровней сложности), расширяя таблицу.

0

Используйте подход переключателя в конструкторе вашего класса GameMode.

+0

Почему? Разве это не сложно поддерживать? – Simon

+0

Сложнее чем? –

0

Помимо некоторых проблем с синтаксисом, я думаю, что вы на правильном пути. Я не думаю, что вам нужно беспокоиться о памяти, учитывая, что, вероятно, есть только один режим. Это форма strategy pattern. Вы можете расширить его, чтобы режимы делали больше. Например, вместо того, чтобы просто содержать константы, возможно, может быть метод generateEnemies, который фактически создает набор или список врагов. Это переводит большую часть стратегии в объект режима. Sane значения по умолчанию в суперклассе могут помочь избежать избыточного кода.

0

Сложно сказать, какой рефакторинг может быть сделан здесь, поскольку информации о других классах слишком мало. Но вы можете проверить State pattern, который инкапсулирует различные типы поведения в разных объектах состояния. Ваш подход к расширению базового класса GameMode очень похож на шаблон состояния. Я думаю, что это лучше, чем блок-блок switch ... и шаблоны - надежные способы делать вещи, если они хорошо применяются.

1

Я не знаю java (это то, на что похожи ваши примеры), поэтому я представляю свои идеи на простом C#.

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

[Flags] 
enum GameModes 
{ 
    Unknown = 0, 
    ModeA = 1, 
    ModeB = 2, 
    ModeC = 4, 
} 

Теперь у вас есть уровни 1-7.

GameModes Difficulty = GameModes.ModeA | GameModes.ModeB; // difficulty = 3 
GameModes Difficulty = GameModes.ModeB; // difficulty = 2 

Кроме того, любой метод вы показали, потребует от вас, чтобы добавить больше вариантов должны уровни (режимы) изменения, добавляются и т.д. ли ваши шаблоны режим чтения в с XML (или другого источника по вашему выбору), сохранить данные режима в сериализуемый класс. Я не думаю, что вам нужен базовый класс, расширенный чем угодно.

0

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

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

Например: maxenemy = 5 * gameMode;

Я думаю, что если у вас есть очень сложная инициализация выполнять переключение более чем достаточно. Я знаю, я знаю, что объекты и классы хороши и все это джаз, но если вам просто нужно определить несколько варов, и все работает, время инвестирования в разработку сложного игрового режима не обязательно будет полезным решением (I сколько игровых режимов вы планируете добавить?).

0

Использовать strategy pattern.

В Java условиях:

public interface Strategy { 
    void execute(); 
} 

public class SomeStrategy implements Strategy { 
    public void execute() { 
     System.out.println("Some logic."); 
    } 
} 

который используется следующим образом:

Map<String, Strategy> strategies = new HashMap<String, Strategy>(); 
strategies.put("strategyName1", new SomeStrategy1()); 
strategies.put("strategyName2", new SomeStrategy2()); 
strategies.put("strategyName3", new SomeStrategy3()); 

// ... 

strategies.get(s).execute(); 
1

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

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

Например, первая реализация может быть что-то вроде

enum mode { 
    MODE_EASY = 0, 
    MODE_NORMAL = 1, 
    MODE_DIFFICULT = 2, 
}; 

class gameSettings { 
    public gameSettings(mode GameMode) { 
     m_mode = GameMode; 
    } 

    public int getMaxWeaponNumber() { 
     int maxWeaponNumber; 
     switch(m_mode) { 
      case EASY_MODE: 
       maxWeaponNumber = 100; 
       break; 

      // Other mode settings.    
     } 

     return maxWeaponNumber; 
    } 

    // Other game settings.... 

    private mode m_mode; 

} 

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