简体   繁体   中英

ArrayList only detects collision of last added object

I've run into a problem when detecting collision between the player and many of the same objects(in this case wall tiles). The problem is that my program only detects the collision when I'm in contact with the last added wall tile. This is written in java...

I am using rectangles(their intersects method) to detect collision.

Code samples:

Update tiles:

        for (int i = 0; i < wallTileArr.size(); i++)
    {
        wallTile = wallTileArr.get(i);
        wallTile.update(p);
        if(wallTile.getBounds().intersects(Screen.getBounds()))
        {
            wallTile.draw = true;
        }
        else if(!wallTile.getBounds().intersects(Screen.getBounds()))
        {
            wallTile.draw = false;
        }
    }

Here is my class that makes a wall out of the tiles:

     public Wall(int x, int y, int length, int dir, WallTile wallTile)
     {
 this.x = x;
 this.y = y;
 this.length = length;
 this.wallTile = wallTile;


    for(int i = 0; i < length; i++)
    {
        if (dir == 0)
        {
            Methods.addWallTile(new WallTile(x+(wallTile.size*i), y));
        }
        else if (dir == 1)
        {
            Methods.addWallTile(new WallTile(x, y+(wallTile.size*i)));
        }

        else if (dir != 0 || dir != 1)
        {
            System.out.println("Error in setting direction: 0 = horizontal, 1 = vertical. Your input is: "+dir );
            //Methods.Exit(1);
        }

    }

}

And here is my class that makes a room or house with walls:

     public HouseSmall_1(int x, int y,int size, int rotation, WallTile wallTile)
    {
this.x = x;
this.y = y;
this.wallTile = wallTile;
this.size = size;


if (rotation == 0)
{
    Methods.addWall(new Wall(x, y, size, 1, wallTile));
    Methods.addWall(new Wall(x+(size*wallTile.size), y, size, 1, wallTile));

    Methods.addWall(new Wall(x, y, size, 0, wallTile));
    Methods.addWall(new Wall(x, y+(size*wallTile.size), (size)/2, 0, wallTile));
    Methods.addWall(new Wall(x+wallTile.size+((size*wallTile.size)/2), y+(size*wallTile.size),(size/2), 0, wallTile));
}

}

The code that adds the tiles and walls into their arrayList:

public static void addWallTile(WallTile wallTile)
{
    Controller.wallTileArr.add(wallTile);
}

public static void addWall(Wall wall)
{
    Controller.wallArr.add(wall);
}

Update code for the collision in the wallTile.java file:

    public void update(Player p)
{
    x+=Screen.movementX;
    y+=Screen.movementY;

    if(getBounds().intersects(p.upGetBounds()))
    {

        p.walk = false;

    }
    else
    {
        p.walk = true;
    }
}

Why is this happening? And how do you suggest I fix it?

Feel free to ask for more code samples!

if(getBounds().intersects(p.upGetBounds()))
{

    p.walk = false;

}
else
{
    p.walk = true;
}

The problem is this code. You are resetting the flag for every tile that is NOT colliding with the player, and thus only last tile can collide successfully with the player and not get the flag reset.

ie - Lets say there are 2 tiles and #1 is colliding and #2 is not.

In first iteration of the loop -

#1 is colliding => p.walk = false;

In second iteration of the loop -

#2 is NOT colliding => p.walk = true; //value has been reset.

However if #2 was the one coliding, the flag cannot get reset.

To fix : remove the else clause and reset it once to true before the for loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM