避免使用以下实例:

Avoiding use of instance of:

我正在编写一个简单的游戏,其中有一组对象,玩家可以在网格上四处移动,收集硬币并躲避怪物。

我的 class 结构如下所示。

游戏控制器 - 负责生成硬币和跟踪游戏状态

Grid - class 存储当前在网格上的对象,以及一些与网格相关的方法。

GridObject - 表示网格上对象的抽象 class。例如玩家、怪物或硬币。

玩家、怪物、硬币 - 全部扩展 GridObject。

最OOP的碰撞处理编程方式是什么?期望的结果是:玩家击中怪物 - 结束游戏,玩家击中硬币 - 增加分数,怪物击中硬币 - 没有。

目前,当一个GridObject移动时,它通知board对象它要移动;如果这会导致碰撞,我会调用 GameController 上的处理程序(通过侦听器模式)来处理碰撞。在那个以两个 GridObject 作为参数的处理程序中,我使用了很多 "instanceof" 命令来区分上述情况。

避免使用所有这些的最佳方法是什么 "instanceof",我读到的通常意味着糟糕的设计?

您可以使用 GridObject 中的枚举来确定类型,而不是使用 instanceof。这样,您只需比较一个枚举来检查哪些对象发生碰撞。例如,(警告,语法可能不完全正确)

public enum ObjectType {
    Player, Monster, Coin
}

private final ObjectType type;

public GridObject(ObjectType type) {
    this.type = type;
}

public ObjectType getType() {return type;}

然后在您的子类中,您必须执行以下操作:

public Player(your parameters) {
    super(ObjectType.Player);
}

然后要检查类型,您可以这样做:

switch(gridObject.getType()) {
    case ObjectType.Player:
       // do something 
       break;
    case ObjectType.Monster:
        // do something else
        break;
    case ObjectType.Coin:
        // do something else
        break;
}

引入一些接口怎么样:

interface Interactable { 

   InteractionResult interact(WorldEntity entity);

}

interface WorldEntity {

    boolean isMonster();

    boolean isPlayer();

    boolean isPowerUp();

}

现在我们可以说当玩家与其他事物交互时我们可以做:

   public InteractionResult interact(WorldEntity entity) {
       if(entity.isMonster()) {
           return new DeathInteraction(this);
       }
       ...
   }

你并没有消除所有的条件,但至少你开始组织你的抽象并解耦你的 类。