猿问

多个对象如何在没有实例引用的情况下向对象发送通知(在 java 中)?

我正在用 Java 开发视频游戏,我想在所有敌人都死后进入下一个级别。我有一个 Enemy 类、一个 Level 类和一个 WorldGame 类。在 WorldGame 中,我移除了敌人,但我不知道如何在所有敌人都死了而必须进入下一个级别时通知级别,而不将 Level 的实例传递给所有敌人。你有什么建议吗?


class Alien {


}


class GameWorld {

  removeEnemy();

}


class Level {

  goToNextLevel();

}


慕桂英546537
浏览 139回答 4
4回答

神不在的星期二

查看观察者设计模式。Java 中的内置版本已被删除,但您可以轻松编写自己的版本。(事件的)侦听器仍然是 Java 模式的一个示例。这个想法是,一个 Java 对象,比如 A,可以被另一个 Java 对象,比如 O“观察”。事实上,可以有任意数量的“观察者”。所有观察者都是独立的,彼此不了解,A 对观察者一无所知。现在,A 可以做的是在有理由这样做时(通过调用方法)发出通知(A 可能是一个死去的怪物)。这导致在所有观察者中调用一个特殊方法(更新),然后可以采取行动(例如,减少仍然活着的怪物的数量)。关键是一旦所有设置完成,任何类都不需要引用其他类。听起来你正在寻找这样的东西。

翻翻过去那场雪

我认为你在混淆责任。关卡(或敌人)不知道其他敌人。我认为你更需要这样的东西: class GameWorld {     public void mainGameLoop() {       ...       removeEnemiesThatRequireRemoval();       if (getNumberEnemiesLeft() == 0) {         currentLevel = levelsManager.goToNextLevel(currentLevel);意义:级别类不知道“下一个”级别(它只知道自己)如前所述:一个敌人不知道(所有剩余的)敌人这就是您的中央“控制结构”需要具备的所有知识。它不应该去任何其他地方。这应该是你的中心主题:任何对象都应该确切地知道它需要什么来完成它的核心工作,而不是更多。它的核心工作也应该尽可能清晰和具体。

慕无忌1623718

在您的示例中,您可以使用事件侦听器机制。创建事件AllEnemiesDeadEvent和侦听器接口AllEnemiesDeadListener。将侦听器的注册表保存在GameWorld. 让 Gameworld 在它调用时跟踪死去的敌人removeEnemy()。当所有敌人都死了它会引发事件。现在,让 Level 类注册AllEnemiesDeadListener并在该事件发生时得到通知。如果Level是唯一对此事件感兴趣的类,请保持简单。只需调用Level#gotoNextLevel()而GameWorld不是事件模型。

小怪兽爱吃肉

假设您的应用程序中的 GameWorld 类可以访问所有关卡,而这些关卡又在该关卡上有敌人。您可以参考以下代码库并提出最适合您需求的解决方案。public class GameWorld {&nbsp; &nbsp; private List<GameLevel> gameLevels;&nbsp; &nbsp; private GameLevel currentLevel;&nbsp; &nbsp; public GameWorld() {&nbsp; &nbsp; &nbsp; &nbsp; gameLevels = new LinkedList<GameLevel>();&nbsp; &nbsp; &nbsp; &nbsp; this.instantiate();&nbsp; &nbsp; }&nbsp; &nbsp; private void instantiate() {&nbsp; &nbsp; &nbsp; &nbsp; // instantiate game adding levels to it&nbsp; &nbsp; }&nbsp; &nbsp; public void moveToNextLevel() {&nbsp; &nbsp; &nbsp; &nbsp; currentLevel = currentLevel.next();&nbsp; &nbsp; }}public class Enemy {&nbsp; &nbsp; private EnemyType enemyType;&nbsp; &nbsp; private GameLevel gameLevel;&nbsp; &nbsp; public Enemy(GameLevel level, EnemyType type) {&nbsp; &nbsp; &nbsp; &nbsp; enemyType = type;&nbsp; &nbsp; &nbsp; &nbsp; gameLevel = level;&nbsp;&nbsp; &nbsp; }&nbsp; &nbsp; private void create() {&nbsp; &nbsp; &nbsp; &nbsp; // .. instantiation task&nbsp; &nbsp; &nbsp; &nbsp; gameLevel.listEnemy(this);&nbsp; &nbsp; }&nbsp; &nbsp; private void killEnemy() {&nbsp; &nbsp; &nbsp; &nbsp; // clean up task&nbsp; &nbsp; &nbsp; &nbsp; gameLevel.delistEnemy(this);&nbsp; &nbsp; &nbsp; &nbsp; // .. clean up task&nbsp; &nbsp; }}public class GameLevel {&nbsp; &nbsp; private GameWorld gameWorld;&nbsp; &nbsp; private List<Enemy> enemies;&nbsp; &nbsp; private GameLevel nextLevel;&nbsp; &nbsp; public GameLevel(GameWorld world) {&nbsp; &nbsp; &nbsp; &nbsp; enemies = new ArrayList<Enemy>();&nbsp; &nbsp; &nbsp; &nbsp; gameWorld = world;&nbsp; &nbsp; }&nbsp; &nbsp; public void listEnemy(Enemy enemy) {&nbsp; &nbsp; &nbsp; &nbsp; enemies.add(enemy);&nbsp; &nbsp; }&nbsp; &nbsp; public void delistEnemy(Enemy enemy) {&nbsp; &nbsp; &nbsp; &nbsp; enemies.remove(enemy);&nbsp; &nbsp; &nbsp; &nbsp; if(enemies.isEmpty()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; gameWorld.moveToNextLevel();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public void setNextLevel() {&nbsp; &nbsp; &nbsp; &nbsp; // set next level after this&nbsp; &nbsp; }&nbsp; &nbsp; public GameLevel next() {&nbsp; &nbsp; &nbsp; &nbsp; return nextLevel;&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Java
我要回答