-1

I am developing a small game and now I am at the point where I need to implement some collision detection. I am using one linked list for all my game objects. The way I am differentiating between those objects is by using object ID. I am able to successfully detect collision with objects that have different IDs but I am unable to do so efficiently using objects with the same ID. I was wandering if there is an easy way of doing it and perhaps someone can point me to an example. Or maybe I just need more if statements. The code bellow is working but as you can see the objects IDs are different for each object. Is there a way of modifying this code so that it would work using same IDs. For example I want to know when enemies are touching each other so that I can detect it and act accordingly.

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

            }
        }
        }

    }

}
AstroCB
  • 11,800
  • 20
  • 54
  • 68
  • 1
    Not familiar with the problem space you're dealing with, but I'm guessing a [Set](http://java.sun.com/javase/6/docs/api/java/util/Set.html) of GameObjects id's might be helpful? – hd1 Jan 03 '14 at 22:35
  • Where are you using the arguments passed to the collision function? Why is the collision function named with capital letters as opposed to Java standards? What is the purpose of "Collision" with respect to it's arguments? – Reut Sharabani Jan 03 '14 at 22:36

2 Answers2

0

Um, dude, you need to implement equals and hash code, and verify that they are working properly with a unit test.

Both the major IDEs will generate the code for you. There's also an excellent discussion of it in Joshua Bloch's Effective Java.

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

Should never check for equals of IDs.

Community
  • 1
  • 1
Rob
  • 10,529
  • 6
  • 34
  • 54
0

This is an answer that requires re-factoring of your code. It uses a known pattern to solve the problem of collisions and their detection. The GameObject class that's assumed to exist should have the intersects method available.

I would probably implement a collision listener interface with a collision dispatcher interface and have them used where I need them.

The interfaces would have methods like the following:

CollisionListener is the interface that classes who need to know about collisions implement:

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

CollisionDispatcher is the interface that classes who spot and notify about collisions to others implements, and other register to. This is probably your Game class, or some main class of that sort.

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

I've added an example of a main that implements both. You may want something a bit different.

This is partial code:

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

The CollisionEvent class can look like this:

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

I hope you find this useful. If you do, read more.

A very useful optimization is to have only moving objects check for collisions as they move, this way you only need one loop like this:

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

You can also optimize (on the expense of design, why?) by notifying the object that's collided into directly, if that's the behavior you're looking for. This time the CollisionEvent can have only one parameter (re-factor the rest of the code accordingly), and the GameObject class will have the notifyCollision and collisionEvent methods:

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

You can also use invocation of methods on your listeners directly without the event object.

Reut Sharabani
  • 27,609
  • 5
  • 62
  • 82
  • Thank you I find your answer very useful. At this point it seems a bit complicated to me but I guess that is because of my lack of practice in java. However I will try my best to implement this pattern it to my game... – user3158909 Jan 03 '14 at 23:34
  • Make sure you make it fit your needs. I'm by no means an expert but I'm also not new. Naming convention should be a priority and the first thing you can do is change the name of your "Collision" method to "collision". Unlike C# or other programming languages, method in Java start with lowercase letters and use camelCase. – Reut Sharabani Jan 03 '14 at 23:36