4

所以我正在编写一个 rpg java 游戏,并决定使用自定义事件来使两个类之间的通信更容易。起初我写了一个“enemyDeathEvent”来让玩家知道敌人是否死亡。

首先我做了我的 EnemyListener:

public interface EnemyListener {

    public void playerDeathEvent(EnemyEvent e);
}

之后我创建了 EnemyEvent 类:

public class EnemyEvent {

    private Enemy enemy;

    public EnemyEvent(Enemy enemy) {
        this.enemy = enemy;
    }

    public Enemy getSource() {
        return enemy;
    }
}

然后我设置了 Enemy 类:

public class Enemy {

    //......
    private boolean dead;

    private Set<EnemyListener> listeners;

    public Enemy() {
        listeners = new HashSet<EnemyListener>();
    }

    //checks if the enemy is dead
    public void update() {
        if(health <= 0) dead = true;

        if(dead) fireDeathEvent();
    }

    //fires the death event
    protecd synchronized void fireDeathEvent() {
        EnemyEvent e = new EnemyEvent(this);
        for(EnemyListener listener : listeners) {
            listeners.enemyDeathEvent(e);
        }
    }

    public void addEnemyListener(EnemyListener listener) {
        listeners.add(listener);
    }  
}

最后,在播放器中实现了 EnemyListener:

public class Player implements EnemyListener {

    @Override
    public void enemyDeathEvent(EnemyEvent e) {
        System.out.println(e.getSource().getName() + " died!");
    }
}

因此,当敌人死亡时,我的玩家类中的enemyDeathEvent()方法将被调用。一切正常,但我的实际问题是游戏不止一次调用此方法。原因是我的update()方法连接到一个线程,该线程每秒更新游戏物理等 30 次。

@Override
public void run() {
    while(gameRunning) {
        update();
        render();
        try {
            Thread.sleep(1000/30);  //30FPS
        } catch(InterruptedException e) {
            e.printStackTrace();
        }
    }
}

所以我的问题是:我怎样才能解决这个问题,以便我的方法将被调用一次?

我将不胜感激每一个帮助!谢谢

4

3 回答 3

1

dead当敌人死亡时,您可以只更新场并触发一次事件:

public void update() {
    if(!dead && health <= 0) {
        dead = true;
        fireDeathEvent();
    }
}
于 2015-06-08T10:49:11.393 回答
0

Enemy一旦实例死亡,您需要停止更新实例。

就像是:

void update() {
    if (dead) return;
    ...
}

作为更通用的解决方案,您的所有游戏实例都应继承自基类(例如EntityBase)。基类可以有一个名为的字段isEnabled和一个基本的更新方法:

void update() {
    if (!isEnabled) return;
    updateImpl();
}
abstract void updateImpl();

继承你的EntityBase类的所有类都必须实现该updateImpl()方法。现在要停止更新实例,只需将isEnabled标志设置为false.

void updateImpl() {
    if(health <= 0) {
        dead = true;
        isEnabled = false;
    }
    if(dead) fireDeathEvent();
}
于 2015-06-08T10:48:53.230 回答
0

你需要一些特殊的敌人状态来表示被杀状态并在更新方法中检查它

于 2015-06-08T10:49:55.720 回答