2

我正在制作一个具有抽象 Fighter 类的文本游戏。在 Fighter 中,我有一个名为 protected boolean isGround 的变量。然后我有 2 个扩展 Fighter 的抽象类,称为 AirFighter 和 GroundFighter,它们基本上将 isGround 设置为 True 或 False,具体取决于它们是否是地面单位。

然后我想设置游戏,以便在我的战斗阶段游戏检查玩家 1 的速度是否比玩家 2 快,并根据谁更快然后像 p1.attack(p2) 那样做,并打印出那场战斗,比如每个玩家的剩余生命值或类似的东西。

我想要一些空中战斗机攻击空中,或者攻击空中和地面的方式,我希望一些地面战斗机只攻击地面,或者地面和空中。我将如何在保持松散耦合的同时做到这一点?这是一个设计模式的课程,它让我感到沮丧。有没有设计模式可以帮助我解决这个问题?

想想星际争霸,这基本上就是我的游戏所模仿的,像海军陆战队这样的某些单位可以攻击地面和空中,有些空中单位只能攻击空中,有些可以两者兼而有之。我希望能够做到这一点而不会有一些讨厌的 if else 检查语句。

4

2 回答 2

1

一个简单的方法是在基础Fighter中有一个方法可以用来检查它是否Fighter可以攻击另一个:

public abstract class Fighter {
    public abstract boolean isGround ();
    public abstract boolean canAttack (Fighter target);
}

然后子类可以覆盖canAttack并做出适当的决定。例如:

public class SurfaceToAirLauncher extends Fighter {
    @Override public boolean isGround () {
        // missile launcher is on the ground
        return true; 
    }
    @Override public boolean canAttack (Fighter target) {
        // we can only attack air targets
        return (target != null && !target.isGround());
    }
}

public class Dragon extends Fighter {
    @Override public boolean isGround () {
        // dragons are in the air
        return false; 
    }
    @Override public boolean canAttack (Fighter target) {
        // dragons can attack every target.
        return (target != null);
    }
}

public class Knight extends Fighter {
    @Override public boolean isGround () {
        // knights are on the ground
        return true; 
    }
    @Override public boolean canAttack (Fighter target) {
        // knights can only attack dragons
        return (target != null && target instanceof Dragon);
    }
}

null如果您知道target永远不会,您可以删除检查null。为了完整起见,我将其包括在内。

于 2013-08-13T04:15:32.037 回答
-1

我建议使用装饰器模式。您有一个 SimpleFighter 作为您的基类(它有一个只返回 false 的 canAttack(Fighter敌人) 方法)和一个 FighterDecorator,两者都实现了 Fighter 接口。在此处查看如何设置构造函数和委托方法:

http://en.wikipedia.org/wiki/Decorator_pattern

然后你有两个扩展 FighterDecorator 的类:

GroundKillerDecorator 有一个 canAttack() 方法,它说:

if(enemy.isGround) return true; else return super.canAttack();

具有 canAttack() 方法的 AirKillerDecorator 说:

if(!enemy.isGround) return true; else return super.canAttack();

...

那应该让你像这样组成你的战士

new GroundKillerDecorator( new AirKillerDecorator( new SimpleFighter() ))

最理想的情况是,您可以将 SimpleFighter 替换为其他两个类,AirFighter 和 GroundFighter,它们实现不同的基本行为(而不是默认情况下无法攻击任何东西),但仍实现相同的 Fighter 接口。

于 2013-08-13T05:08:00.750 回答