为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕桂英546537 2023-05-10 13:20:46
我正在用 Java 开发视频游戏,我想在所有敌人都死后进入下一个级别。我有一个 Enemy 类、一个 Level 类和一个 WorldGame 类。在 WorldGame 中,我移除了敌人,但我不知道如何在所有敌人都死了而必须进入下一个级别时通知级别,而不将 Level 的实例传递给所有敌人。你有什么建议吗?class Alien {}class GameWorld {  removeEnemy();}class Level {  goToNextLevel();}
查看完整描述

4 回答

?
神不在的星期二

TA贡献1963条经验 获得超6个赞

查看观察者设计模式。Java 中的内置版本已被删除,但您可以轻松编写自己的版本。(事件的)侦听器仍然是 Java 模式的一个示例。

这个想法是,一个 Java 对象,比如 A,可以被另一个 Java 对象,比如 O“观察”。事实上,可以有任意数量的“观察者”。所有观察者都是独立的,彼此不了解,A 对观察者一无所知。

现在,A 可以做的是在有理由这样做时(通过调用方法)发出通知(A 可能是一个死去的怪物)。这导致在所有观察者中调用一个特殊方法(更新),然后可以采取行动(例如,减少仍然活着的怪物的数量)。

关键是一旦所有设置完成,任何类都不需要引用其他类。

听起来你正在寻找这样的东西。


查看完整回答
反对 回复 2023-05-10
?
翻翻过去那场雪

TA贡献2065条经验 获得超13个赞

我认为你在混淆责任。关卡(或敌人)不知道其他敌人。我认为你更需要这样的东西:


 class GameWorld { 


    public void mainGameLoop() {

       ...

       removeEnemiesThatRequireRemoval();

       if (getNumberEnemiesLeft() == 0) {

         currentLevel = levelsManager.goToNextLevel(currentLevel);

意义:

  • 级别类不知道“下一个”级别(它只知道自己)

  • 如前所述:一个敌人不知道(所有剩余的)敌人

这就是您的中央“控制结构”需要具备的所有知识。它不应该去任何其他地方。

这应该是你的中心主题:任何对象都应该确切地知道它需要什么来完成它的核心工作,而不是更多。它的核心工作也应该尽可能清晰和具体。


查看完整回答
反对 回复 2023-05-10
?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

在您的示例中,您可以使用事件侦听器机制。创建事件AllEnemiesDeadEvent和侦听器接口AllEnemiesDeadListener。将侦听器的注册表保存在GameWorld. 让 Gameworld 在它调用时跟踪死去的敌人removeEnemy()。当所有敌人都死了它会引发事件。

现在,让 Level 类注册AllEnemiesDeadListener并在该事件发生时得到通知。

如果Level是唯一对此事件感兴趣的类,请保持简单。只需调用Level#gotoNextLevel()GameWorld不是事件模型。


查看完整回答
反对 回复 2023-05-10
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

假设您的应用程序中的 GameWorld 类可以访问所有关卡,而这些关卡又在该关卡上有敌人。您可以参考以下代码库并提出最适合您需求的解决方案。


public class GameWorld {


    private List<GameLevel> gameLevels;

    private GameLevel currentLevel;


    public GameWorld() {

        gameLevels = new LinkedList<GameLevel>();

        this.instantiate();

    }


    private void instantiate() {

        // instantiate game adding levels to it

    }


    public void moveToNextLevel() {

        currentLevel = currentLevel.next();

    }


}


public class Enemy {


    private EnemyType enemyType;

    private GameLevel gameLevel;


    public Enemy(GameLevel level, EnemyType type) {

        enemyType = type;

        gameLevel = level; 

    }


    private void create() {

        // .. instantiation task

        gameLevel.listEnemy(this);

    }


    private void killEnemy() {

        // clean up task

        gameLevel.delistEnemy(this);

        // .. clean up task

    }


}


public class GameLevel {


    private GameWorld gameWorld;

    private List<Enemy> enemies;

    private GameLevel nextLevel;


    public GameLevel(GameWorld world) {

        enemies = new ArrayList<Enemy>();

        gameWorld = world;

    }


    public void listEnemy(Enemy enemy) {

        enemies.add(enemy);

    }


    public void delistEnemy(Enemy enemy) {

        enemies.remove(enemy);

        if(enemies.isEmpty()) {

            gameWorld.moveToNextLevel();

        }

    }


    public void setNextLevel() {

        // set next level after this

    }


    public GameLevel next() {

        return nextLevel;

    }


}



查看完整回答
反对 回复 2023-05-10
  • 4 回答
  • 0 关注
  • 110 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信