Search code examples
javaswingjframegame-developmentintersection

Problem with collisions (intersections) in java game development using JFrame


I am making a 2d java game, where player needs to shoot tiles. I encountered a bug in my code, the bullet destroys nearby tiles, but not always and not properly.

PROBLEM VIDEO RECORD

You see, I want bullets to destroy the tile that it touches, and a tile at up, left, right, botton... You got it. Here is my code, I think I messed up something as always.

In my opinion the error is in the player class because it handles the destruction.

Short version of Player.java: (no imports, etc).

public class Player{
    public int pointX;
    public int pointY;
    public int velocityX;
    public int defaultVelX = 15;
    public int cooldown = 2;
    public boolean shooting = false;
    public Tile hitTile = null;
    YeahGame yg;
    Shot shot;
    TileManager tm;

    public Player(int x, int y, YeahGame yg) {
        this.pointX = x;
        this.pointY = y;
        this.yg = yg;
        tm = yg.tm;
    }
    public void shoot() {
        if (!shooting) {
            shot = new Shot(pointX, pointY, yg);
            shooting = true;
        }
    }
    public void Hit(int offsetX, int offsetY, int level) {
        Tile tl = tm.GetTile(hitTile.x + offsetX, hitTile.y + offsetY);
        if (tl != null && tl.isActive) {
            if (level >= tl.level) {
                tl.isActive = false;
            } else {
                tl.level -= level;
            }
        }
    }
    public void DestroyTiles() {
        Hit(0,0,1);
        Hit(1,0,1);
        Hit(0,1,1);
        Hit(-1,0,1);
        Hit(0,-1,1);
        if (cooldown > 0) {
            cooldown--;
        } else if (cooldown == 0) {
            tm.NewLayer();
            cooldown = 2;
        }
    }
    public boolean bulletCollision() {
        boolean is = false;
        if (shooting) {
            for (ArrayList<Tile> sampleRow : tm.rows) {
                for (Tile tile : sampleRow) {
                    if (tile.isActive) {
                        Rectangle shotRect = new Rectangle(shot.pointX+yg.tileSize/4, shot.pointY+yg.tileSize/4, yg.tileSize/2, yg.tileSize/2);
                        Rectangle tileRect = new Rectangle(tile.x * yg.tileSize, tile.y * yg.tileSize, yg.tileSize, yg.tileSize);

                        if (tileRect.intersects(shotRect)) {
                            is = true;
                            hitTile = tile;
                            break;
                        }
                    }
                }
                if (is) {
                    break;
                }
            }
        }
        return is;
    }
    public void update() {
        if (shooting) {
            shot.update();
            if (bulletCollision()) {
                DestroyTiles();
                shooting = false;
                shot = null;
            }
            else if (shot.pointY < 0) {
                shooting = false;
                shot = null;
            }
        }
    }
    public void draw(Graphics g) {
        g.setColor(Color.red);
        g.fillRect(pointX, pointY, yg.tileSize, yg.tileSize);
        if (shooting) {
            shot.draw(g);
        }
    }
}

Solution

  • Ok guys, the problem was in a function that I accidentally didn't include in my code here on stackoverflow. Here is the error part of the code:

    for (ArrayList<Tile> sampleRow : rows) {
     for (Tile tile : sampleRow) {
      if (tile.isActive) {
       tile.y += 1;
       if (tile.y == (yg.height/yg.tileSize)-yg.tileSize) {
        yg.failed = true;
       }
      }
     }
    }
    

    You see, it moves all the tiles down except disabled ones. They were over each other, blocking the collision detection, so I made it so every tile goes down, even disabled ones.

    for (ArrayList<Tile> sampleRow : rows) {
     for (Tile tile : sampleRow) {
      tile.y += 1;
      if (tile.isActive) {
       if (tile.y == (yg.height/yg.tileSize)-yg.tileSize) {
        yg.failed = true;
       }
      }
     }
    }