使用相同id的链表冲突检测

时间:2014-01-03 22:30:20

标签: java list linked-list collision detection

我正在开发一款小游戏,现在我需要实现一些碰撞检测。我正在为我的所有游戏对象使用一个链表。我区分这些对象的方法是使用对象ID。我能够成功检测到具有不同ID的对象的冲突,但我无法有效地使用具有相同ID的对象。如果有一种简单的方法可以让我徘徊,也许有人可以给我一个例子。或者我可能只需要更多if语句。下面的代码正在运行,但正如您所看到的,每个对象的对象ID都不同。有没有办法修改此代码,以便它可以使用相同的ID。例如,我想知道敌人何时相互接触,以便我能够检测到并采取相应行动。

public void Collision(LinkedList<GameObject> object, Graphics g){
    for(int i = 0; i < handler.object.size(); i++){
        GameObject enemy = handler.object.get(i);
        for(int j = 0; j < handler.object.size(); j++){
            GameObject tempObject1 = handler.object.get(j);             

        if(enemy.getId() == ObjectId.Enemy && tempObject1.getId() == ObjectId.Bullet){
            if(getBounds().intersects(enemy.getBounds())){
                handler.removeObject(enemy);
                handler.removeObject(tempObject1);

            }
        }
        }

    }

}

2 个答案:

答案 0 :(得分:0)

嗯,伙计,你需要实现equals和hash代码,并验证它们是否正常运行单元测试。

两个主要的IDE都会为您生成代码。在Joshua Bloch的Effective Java中也有一个很好的讨论。

What issues should be considered when overriding equals and hashCode in Java?

永远不应该检查ID的等号。

答案 1 :(得分:0)

这是一个需要重新分解代码的答案。它使用已知模式来解决碰撞及其检测问题。假定存在的GameObject类应该有intersects方法。

我可能会使用碰撞调度程序接口实现一个碰撞侦听器接口,并在我需要的地方使用它们。

接口将具有以下方法:

CollisionListener是需要了解冲突的类实现的接口:

public interface CollisionListener {
    // respond to a collision event
    public void collisionEvent(CollisionEvent ce);
}

CollisionDispatcher是发现和通知其他人实施冲突的类的接口,以及其他注册的类。这可能是你的Game类,或者那种类的主类。

interface CollisionDispatcher {
    // add a collision listener who should be notified about each collision
    public void addCollisionListener(CollisionListener cl);
    // notify all subscribers (listeners) on collision event
    public void notifyCollision(CollisionEvent ce);
}

我添加了一个实现两者的main的示例。你可能想要一些不同的东西。

这是部分代码:

private Collection<CollisionListener> cls;
private Collection<GameObject> gameObjects;

public Game(){
    this.cls = new ArrayList<CollisionListener>();
    this.addCollisionListener(this);
}
@Override
public void collisionEvent(CollisionEvent ce) {
    System.out.println("Collision occured between "
            + ce.getGameObject1().toString() + " and "
            + ce.getGameObject1().toString());
}

@Override
public void addCollisionListener(CollisionListener cl) {
    this.cls.add(cl);
}

@Override
public void notifyCollision(CollisionEvent ce) {
    // notify to all listeners
    for (CollisionListener cl : this.cls){
        cl.collisionEvent(ce);
    }

}

    public void checkForCollisions(){
        // check for collisions
        for (GameObject go1 : gameObjects){
            for (GameObject go2 : gameObjects){
                // first part is ok cause we are looking for the same object
                if (go1 != go2 && go1.interesects(go2)){
                    this.notifyCollision(new CollisionEvent(go1, go2));
                }
            }
        }
    }

CollisionEvent类可能如下所示:

public class CollisionEvent {

    private GameObject go1, go2;
    public CollisionEvent(GameObject g1, GameObject g2){
        this.go1 = go1;
        this.go2 = go2;
    }

    public GameObject getGameObject1(){
        return this.go1;
    }
    public GameObject getGameObject2(){
        return this.go2;
    }
}

我希望你觉得这很有用。如果你这样做,read more

一个非常有用的优化是只有移动对象在移动时检查碰撞,这样你只需要一个循环:

// in GameObject
public void checkForCollisions(){
    // check for collisions
    for (GameObject go2 : gameObjects){
        // first part is ok cause we are looking for the same object
        if (this != go2 && this.interesects(go2)){
             this.notifyCollision(new CollisionEvent(go1, go2));
        }
    }
}

如果这是您正在寻找的行为,您还可以通过直接通知碰撞的对象来优化(以设计为代价,why?)。这次CollisionEvent只能有一个参数(相应地重新考虑其余的代码),GameObject类将有notifyCollisioncollisionEvent方法:

// in GameObject
public void checkForCollisions(){
    // check for collisions
    for (GameObject go2 : gameObjects){
        // first part is ok cause we are looking for the same object
        if (this != go2 && this.interesects(go2)){
             go2.notifyCollision(new CollisionEvent(go2));
        }
    }
}

您也可以在没有事件对象的情况下直接在侦听器上调用方法。