0
votes

After searching a large amount of sites, including this one, every solution i have came across seems to not work, or only work on the first object in the list.

The Problem

Slick2Ds Rectangle class offers many different methods for collision, one being the intersects(Rectangle box); method that correctly detects collisions when using this class in conjunction with javas built in ArrayList class,to an extent. The problem I'm having is that only the first object in the list is being detected and correctly collided upon.

The following code handles collisions:

public void move(float x, float y) {
    if (blocks.size() > 0) {
        for (int i = 0; i < blocks.size(); i++) {
            Rectangle r = blocks.get(i);
            Rectangle p = new Rectangle(xx + x, yy + y, 32, 32);
            if (!r.intersects(p)) {
                xp = xx;
                yp = yy;
                xx += x;
                yy += y;
                break;
            } else {
                xx = xp;
                yy = yp;
                xx += 0;
                yy += 0;
                System.out.println("Collide" + new Date());
                break;
            }
        }
    }else{
        xp = xx;
        yp = yy;
        xx += x;
        yy += y;
    }
}

Key: xx = Player x; yy = Player y; xp = Players Last x Position; yp = Players Last y Position; r = Current Rectangle in the iteration list; p = Pre-calculated next position of the player

This basic codes job is to add movement by simulating a rectangle that will be in the next position the player is. if it does not collide then the player wont collide and we can move, but if it does collide then we don't move the player as the next location is not open.

But the code has a flaw as at some point during the iteration only the first box works, the others do detect collides but does not stop the box.

Correct Collision; logged in the console to confirm

Incorrect Collision; not logged in the console, even though its another instance of the same object

2
Instead of printing "Collide" + new Date(), I would print the values of the two intersecting rectangles - that way you can see whether they should actually be intersecting or not. - Andrew Williamson
i added a new logger for you guys to look at, to see if you can help me find my error - Draven Lewis
Why do both branches of the r.intersects(p) if statement break? - Karl
To not allow the code to add the movement in iterations , basically what it would do is after each iteration the speed would be multiplied exponentially. But I have found removing the break does not change the situation. Only making movement over a block slower. - Draven Lewis
Note that ArrayList is not important to the question or solution, any sort of List will act the same; indeed, any Iterable will also do if you use the enhanced for loop like for (final Rectangle r : blocks) { ... (and in Karl's answer) - Stephen P

2 Answers

0
votes

What happens if you use :

public void move(float x, float y) {

    boolean intersectedBlock = false;

    for (int i = 0; i < blocks.size(); i++) {
        Rectangle r = blocks.get(i);
        Rectangle p = new Rectangle(xx + x, yy + y, 32, 32);

        if (r.intersects(p)) {
            intersectedBlock = true;
            break;
        }
    }

    if (intersectedBlock) {
        xx = xp;
        yy = yp;
        xx += 0;
        yy += 0;
        System.out.println("Collide" + new Date());
    } else {
        xp = xx;
        yp = yy;
        xx += x;
        yy += y;
    }
}
0
votes

try to remove all the breaks. because if it find the intersects or not, it will break out of the loop.