如何简化这段代码或者更好的设计?

发布于 2024-09-02 04:28:57 字数 1223 浏览 11 评论 0原文

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

简单 = 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”只存储​​游戏设置的不同变量......这是仅存储数据的简单方法吗制作一个对象? thz u。

I am developing a game, the game have different mode. Easy, Normal, and Difficult.
So, I'm thinking about how to store the game mode. My first idea is using number to represent the difficulty.

Easy = 0 Normal = 1 Difficult = 2

So, my code will have something like this:

switch(gameMode){

case 0:
//easy
break;

case 1:
//normal
break;

case 3:
//difficult
break;

}

But I think it have some problems, if I add a new mode, for example, "Extreme", I need to add case 4... ... it seems not a gd design.

So, I am thinking making a gameMode object, and different gameMode is sub class of the super class gameMode.
The gameMode object is something like this:

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

But I think it seems too "bulky" to create an object to store gameMode, my "gameMode" only store different variables for game settings.... Is that any simple way to store data only instead of making an Object? thz u.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

神回复 2024-09-09 04:28:58

利用策略模式

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

Make use of the strategy pattern.

In Java terms:

public interface Strategy {
    void execute();
}

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

which you use as follows:

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();
因为看清所以看轻 2024-09-09 04:28:57

我认为您正在尝试表示配置数据表。如果您使用支持该配置的语言,请将其放入配置文件中,或者在代码中使用文字数据。

例如,您可以用 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

很容易添加更多通过扩展表来配置(更多参数或更多难度级别)。

I think you are trying to represent a table of configuration data. Either put this in a configuration file if you're using a language that supports that, or use literal data in your code.

For instance, you might write this in 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}
};

And when you want to read a particular setting, for example max_enemies for the easy level, then you can writedifficulty_settings[DIFFICULTY_EASY].max_enemies

It's easy to add more configuration (either more parameters, or more difficulty levels) by extending the table.

新人笑 2024-09-09 04:28:57

这里最重要的目标是集中检索与不同级别相关的值的逻辑。通过提供一个存储这些值的位置,可以最大限度地减少代码中需要更改的位置(如果您添加另一个级别、添加其他值等)。

类接口是此解决方案的一个不错的选择。但是,如果类表示的配置选项数量有限,则没有理由需要使用继承。您可以从封装逻辑的单个类开始。如果代码的其余部分通过类接口检索其设置,则稍后可以引入更复杂的设计,例如每种模式的子类(如果有必要对游戏的其余部分进行有限的修改)。

例如,第一个实现可能是这样的。

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() 语句,或者使用适合您的应用程序的其他机制。

The overriding goal you should have here is to centralize the logic for retrieving the values related to different levels. By providing one place where these values are stored, you minimize the number of places within the code you need to change if you add another level, add other values, etc.

A class interface is a good choice for this solution. However, if you have a limited number of configuration options represented by the class, there is no reason you need to use inheritance. You can start out with a single class that encapsulates the logic. If the rest of your code retrieves its settings via the class interface you can later introduce a more complex design, such as subclasses for each mode, if it becomes necessary with limited modifications to the rest of your game.

For example, a first implementation may be something like

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;

}

This combines the straightforwardness of a switch() statement with the benefits of a class interface. You can also swap out your switch() statement with a lookup table, as suggested by another poster, or some other mechanism as appropriate for your application.

心作怪 2024-09-09 04:28:57

我不了解 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(或您选择的其他源)读取,将模式数据保存到可序列化的文件中班级。我认为您不需要通过任何东西扩展基类。

I don't know java (which is what your examples look like), so I present my ideas in some simple C#.

Here is an idea. Use your game mode as a flag instead. If you start with:

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

Now you have levels 1-7 available.

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

In addition, either method you showed will require you to add more options should levels (modes) change, get added, etc. Have your mode templates read in from XML (or other source of your choice), save the mode data into a serializable class. I don't think you should need base class extended by anything.

等风来 2024-09-09 04:28:57

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

Use the switch approach in the constructor of your GameMode class.

墨洒年华 2024-09-09 04:28:57

除了一些语法问题之外,我认为您走在正确的轨道上。我认为您不必担心内存,因为可能同时只有一种模式。这是策略模式的一种形式。您可以扩展它,以便模式做更多的事情。例如,也许可以有一个generateEnemies方法来实际创建一组或列表的敌人,而不是基本上只保存常量。这会将更多策略移至模式对象中。超类中的健全默认值可以帮助避免冗余代码。

Besides some syntax issues, I think you're on the right track. I don't think you have to worry about memory, considering there is probably only one mode at once. This is a form of the strategy pattern. You could extend it so the modes do more. For instance, instead of basically just holding constants, perhaps there could be a generateEnemies method that actually creates a set or list of enemies. This moves more of the strategy into the mode object. Sane defaults in the superclass can help avoid redundant code.

飘落散花 2024-09-09 04:28:57

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

Its difficult to say what kind of refactoring could be done here, as there is too less information about other classes. But you could check the State pattern which encapsulates different behaviours in different state objects. Your approach of extending a base GameMode class is very similar to the state pattern. I think it's better than a switch-case-block... and patterns are reliable ways of doing things, if well applied.

青丝拂面 2024-09-09 04:28:57

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

我能想到的唯一在添加其他模式时无需添加代码的情况是,如果您根据 gameMode 的值生成游戏参数。

例如: maxenemy = 5 * gameMode;

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

Why do you think the switch is harder to mantain? If you add another mode you will have to add code, no matter what solution you employ.

The only case I can think of where you don't have to add code if you add another mode is if you generate the parameters of the game from the value of gameMode.

For instance: maxenemy = 5 * gameMode;

I think that unless you have very complicated initialisation to perform a switch is more than sufficient. I know, I know, objects and classes are nice and all that jazz, but if you just have to define a few vars and the thing works, investing time in developing a complex game mode class may not be a rewarding solution after all (I mean, how many game modes are you planning to add?).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文