Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm trying to build a collision response ( it uses vectors2f from slick2d ) so that enemies don't overlap on each other so basicly what I'm doing right now is, I loop trough all enemies in array trough the same array of enemies to check if they collide or not , if they collide I swap their velocity.

The code partialy works for some enemies and doesn't for others. If anyone can give me some links how to code this or advise me how to do it , that would be nice. I already google'd to see if I could find something like this but I couldn't find anything.

Here is the code for the current code i got: http://pastebin.com/AbCvTtV0

Slick 2d documentation : http://www.slick2d.org/javadoc/

share|improve this question
add comment

closed as too localized by Byte56, Josh Petrie, Anko, Trevor Powell, bummzack Apr 13 '13 at 7:41

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

4 Answers

up vote 1 down vote accepted

I'm going to expand on Dirk's answer a little bit.

You might get 2 collisions (for example once for colliding enemy 2 with enemy 5 and once for colliding enemy 5 with enemy 2) and thus reverting the swapping of velocities. You could resolve this by starting your second loop not with k = 0 but with k = i+1.

This will allow you to get rid of the IF block starting on line 7: if(enemies.get(i) != enemies.get(k))

(Furthermore, you should make sure the collision boxes are not overlapping after you swapped the velocities.)

To do this you should add some code to your IF block starting on line 12. Just make sure that enemies.get(i) and enemies.get(k) are not overlapping anymore by either moving one or both of them. If you need further help consider posting your Enemy class so we can take a look at what methods you have available.

share|improve this answer
    
pastebin.com/pS2EFbQ7 –  Matthew Apr 10 '13 at 6:49
    
do i sub vectors of enemies if they collide and apply the new velocity to each –  Matthew Apr 10 '13 at 11:22
    
also both collisions i tried , only affects one enemy constantly but others just ignore it –  Matthew Apr 10 '13 at 11:52
    
Its hard for me to visualize what exactly is happening with your enemies, but hopefully I can still help. Take a look at this code: pastebin.com/DXXYs2bV On collision it swaps velocities and then makes sure the enemies move the required distance so that they aren't colliding anymore. Provided I understand how your classes work. –  Vincenzo Apr 11 '13 at 2:16
add comment

You might get 2 collisions (for example once for colliding enemy 2 with enemy 5 and once for colliding enemy 5 with enemy 2) and thus reverting the swapping of velocities. You could resolve this by starting your second loop not with k = 0 but with k = i+1.

(Furthermore, you should make sure the collision boxes are not overlapping after you swapped the velocities.)

share|improve this answer
add comment

This question is probably irrelevant now, but for future reference, as well with anyone coming here with the same problem:

I would use the "java.awt.rectangle", and store the X, Y, and width and height values there. It includes one of my favorite methods: public boolean intersects(Rectangle other). I'm assuming there is a class called "Entity", but if the name for your enemy class is different, just use that. I'm also assuming that you have an arraylist of entities somewhere. Again, if it is a hashmap or just regular array, or has a different name, replace the "Entity e: entities" with the proper name and method to access your data.

Stick this in the entity class (no need to modify it):

private java.awt.Rectangle bounds;

public Entity(/*your other paramaters here*/, java.awt.Rectangle bounds){
    this.bounds = bounds;
}

/* Other methods go here */

public void setBounds(java.awt.Rectangle bounds){
    this.bounds = bounds;
}

public java.awt.Rectangle getBounds(){
    return bounds;
}

public boolean colliding(Entity possibleCollider){
    return bounds.intersects(possibleCollider.getBounds());
}

Then, all you have to do is test for collisions in your main loop (or updating thread; doesn't matter where it goes, as long as it's being checked regularly). You may need to modify it if you do not have an arraylist as your entity storage mechanism:

for (Entity e1: entities){ // Compare 1 entity
    for (Entity e2: entities){ //to all the others
        if (e1 != e2){
            //This is indeed another entity, not the same one.

            e1.velocity.x = -e1.velocity.x
            /* You can reverse just the x 
             * if you want; otherwise do the same
             * thing with e2. Also, if you want the Y
             * direction reversed as well, simply copy and replace X with Y.
             */


            /* Entity is colliding with another, 
             * Do whatever else you need to here (such as applying damage)
             */ 
        }
    }
}
share|improve this answer
    
but i have top down shooter, not 2d sidescroller –  Matthew Apr 11 '13 at 16:04
add comment

public void updateEnemy(ArrayList enemies, int delta, Player player){

    for (int i = 0; i < enemies.size(); ++i)
        enemies.get(i).update(delta);

// Then run the collision code
for (int i = 0; i < enemies.size(); ++i)
{


    enemies.get(i).update(delta);

    enemies.get(i).velocity = new Vector2f(player.getX() - enemies.get(i).getX(), player.getY() - enemies.get(i).getY());
    enemies.get(i).position.add(enemies.get(i).velocity.scale(enemies.get(i).speed));

        for (int j = 0; j < enemies.size(); ++j)
        {
                if (j == i) continue; // so it doesn't check itself



                // Calculate the euclidian distance between a and b
                float distanceX = enemies.get(i).getX() - enemies.get(j).getX();
                float distanceY = enemies.get(i).getY() - enemies.get(j).getY();

                float distance = (float) Math.sqrt(distanceX * distanceX + distanceY * distanceY);
                float overlap,directionX,directionY;
                if (distance < 30)
                {
                        overlap = 30 - distance;

                        // Normalize and set to half the overlap
                        directionX = (distanceX / distance) * (overlap / 2);
                        directionY = (distanceY / distance) * (overlap / 2);

                        // Update a and b's positions
                        enemies.get(i).position.x =(enemies.get(i).position.x + directionX);
                        enemies.get(i).position.y =(enemies.get(i).position.y + directionY);

                        enemies.get(j).position.x =(enemies.get(j).position.x - directionX);
                        enemies.get(j).position.y =(enemies.get(j).position.y - directionY);
                }
        }
}
}
share|improve this answer
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.