1
votes

So basically for the past age and a half I've been trying to get this box guy (player) that when he collides with another box, he stops moving in the direction he collided with the box in. It is sort of successful but at seemingly random moments if I'm moving up and hit the box on the player's left side it may spaz into the box it collided with and flies down. It is the same in every direction.

public int checkCollision(ID id){
    for(int i = 0; i < handler.obj.size(); i++){ //Cycles through all the objects
        GameObject go = handler.obj.get(i); //Stores a temp GameObject
        if(go.getID() == id){ //Checks if the id matches and if so do the collision stuff.
            if(getBoundsT().intersects(go.getBounds())){
                System.out.println("collided top");
                y = go.getY() + go.getHeight();
                velY = 0;
                return 0; //Top side
            }
            if(getBoundsB().intersects(go.getBounds())){
                System.out.println("collided bottom");
                y = go.getY() - height;
                velY = 0;
                return 1; //Bottom side
            }
            if(getBoundsL().intersects(go.getBounds())){
                x = go.getX() + width;
                velX = 0;
                System.out.println("collided left");
                return 2; //Left Side
            }
            if(getBoundsR().intersects(go.getBounds())){
                System.out.println("collided right");
                x = go.getX() - width;
                velX = 0;
                return 3; //Right Side
            }
            if(getBounds().intersects(go.getBounds())){
                System.out.println("collided on all sides");
                return 4; //All the sides
            }
        }
    }
    return 5; //No Collision
}

The checkCollision method is called 60 times every second. The getBounds(l/r/u/d) function just returns a rectangle on either the left, right, top (up), or bottom (down) side corresponding to the letter. Id is just what the player is colliding with. In this scenario it is the wall so wherever it says id it is just the wall. (I've made sure the rectangles don't go out of the area they are supposed to.)

I've tried everything I can think of so any help would be appreciated! (This is my first question sorry if it's written horribly)

Edit: Intersecting Code (getBounds) This is in the GameObject class that all objects inherit.

public Rectangle getBoundsB() {
        return new Rectangle((int)(x + (width/2) - (width/4)), (int)(y + height/2), (int)(width / 2), (int)(height / 2));
    }
    public Rectangle getBoundsT() {
        return new Rectangle((int)(x + (width/2) - (int)(width/4)), (int) y, (int)width / 2, (int)(height / 2));
    }
    public Rectangle getBoundsR() {
        return new Rectangle((int)(x + width - 5), (int)(y + 5), 5, (int)(height - 10));
    }
    public Rectangle getBoundsL() {
        return new Rectangle((int)x, (int)(y + 5), 5, (int)(height - 10));
    }

    public Rectangle getBounds() {
        return new Rectangle((int)x, (int)y, (int)width, (int)height);
    }

and in the tick method (called every 60 seconds):

checkCollision(ID.Wall);
1
How are you checking if an intersection happens. It could be specifying that it intersects at more than one point and the first if statement that matches gets returned. So if it interests at the left and bottom it might return bottom first. - Brion
Are you only checking if the left edge intersects the right edge? Or are you doing if left edge intersects with any edge? - Brion
So I've done something similar in the past. What was happening is that it checked in sequential order. So when I did my intersect check, it showed that the left edge was intersected with both left and bottom. If it is happening in yours, it would always return in top, bottom, left, right order. So even if you intersect from the left, it may return bottom. - Brion
It could be. Could you provide your intersect code too? - Brion
So it looks like this is exactly what's occurring. Imagine, lining up two equal size rectangles side by side. It would intersect on 3 possible sides even if only by 1 pixel. - Brion

1 Answers

1
votes

The image below shows the 3 sides of the rectangle against a wall. If I press the rectangle against the wall the left corner of the blue and green line touches the wall, and the red line touches the wall. So what's happening is because you check top first, it sees that at that single point there was an intersection and returns true for Top intersection instead of left.

enter image description here

I think you could fix this modifying how you get your top/bottom bounds. Maybe by subtracting 1 from the width you return your bounds at.