调用自定义事件一次(游戏开发)

时间:2015-06-08 10:45:15

标签: java custom-events

所以我正在编写一个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;
    }
}

然后我建立了敌人类:

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();
        }
    }
}

所以我的问题是:我如何解决这个问题,以便我的方法被调用一次?

我很感激每一个帮助!感谢

3 个答案:

答案 0 :(得分:1)

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

public void update() {
    if(!dead && health <= 0) {
        dead = true;
        fireDeathEvent();
    }
}

答案 1 :(得分: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();
}

答案 2 :(得分:0)

你需要一些特殊的状态来指示杀死状态,并在更新方法中检查它