2

我正在开发一个游戏,游戏有不同的模式。简单,正常和困难。所以,我正在考虑如何存储游戏模式。我的第一个想法是用数字来表示难度。

容易 = 0 正常 = 1 困难 = 2

所以,我的代码会是这样的:

switch(gameMode){

case 0:
//easy
break;

case 1:
//normal
break;

case 3:
//difficult
break;

}

但是我觉得有一些问题,如果我添加一个新的模式,例如“Extreme”,我需要添加case 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”只存储​​游戏设置的不同变量......这是只存储数据而不是制作对象的简单方法吗?你。

4

8 回答 8

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

通过扩展表格可以轻松添加更多配置(更多参数或更多难度级别)。

于 2010-05-22T12:17:44.297 回答
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(或您选择的其他源)读取,将模式数据保存到可序列化的班级。我认为您不应该需要任何扩展的基类。

于 2010-05-22T12:02:00.487 回答
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() 语句的直接性和类接口的优点。您还可以按照另一张海报的建议或其他适合您的应用程序的机制,将您的 switch() 语句替换为查找表。

于 2010-05-22T13:46:33.583 回答
0

在 GameMode 类的构造函数中使用 switch 方法。

于 2010-05-22T11:53:29.443 回答
0

除了一些语法问题外,我认为您走在正确的轨道上。考虑到一次可能只有一种模式,我认为您不必担心内存。这是策略模式的一种形式。您可以扩展它,以便模式执行更多操作。例如,除了基本上只保存常量之外,也许还有一个 generateEnemies 方法,它实际上创建了一组或一组敌人。这会将更多的策略移动到模式对象中。超类中的健全默认值有助于避免冗余代码。

于 2010-05-22T11:53:46.473 回答
0

很难说这里可以进行什么样的重构,因为关于其他类的信息太少了。但是您可以检查将不同行为封装在不同状态对象中的状态模式。您扩展基本 GameMode 类的方法与状态模式非常相似。我认为它比 switch-case-block 更好......如果应用得当,模式是可靠的做事方式。

于 2010-05-22T11:55:19.543 回答
0

为什么你认为开关更难维护?如果您添加另一种模式,则无论您采用何种解决方案,都必须添加代码。

我能想到的唯一一种情况是,如果您添加另一种模式,则无需添加代码,即您从gameMode.

例如:maxenemy = 5 * gameMode;

我认为除非你有非常复杂的初始化来执行切换就足够了。我知道,我知道,对象和类都很好,但如果你只需要定义一些变量并且事情就可以工作,那么花时间开发一个复杂的游戏模式类可能并不是一个有回报的解决方案(我意思是,您打算添加多少种游戏模式?)。

于 2010-05-22T12:25:22.233 回答
0

利用策略模式

在 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();
于 2010-05-22T12:36:09.013 回答