Search code examples
javajpaneldrawgame-physicsrectangles

How to test for multiple intersections in java?


I am currently making a tower defence game.

Simply put it works like this: green circles (enemies) move across the screen. By clicking, you can place a tower. The enemy has a rectangle hidden underneath it, and the tower has a large opaque rectangle around it indicating its hit range. If they are colliding, the enemy starts to lose health, until it dies.

Before, I used this test to see if the enemy was within range of the tower:

for(int i=0;i<enemy.length; i++) //Runs for the total amount of enemies
{
  for(int j=0; j<boxes.length;j++) //Runs for the total amount of towers placed
  {
    if(enemy[i].getEBox().intersects(boxes[j]))  //boxes[j] is the towers' range box
    {
      enemy.setHealth(enemy.getHealth()-1);
    }
  }
}

However, I would like the towers to only be able to shoot one enemy at a time, most preferably the enemy at the front. To do this I need java to detect that there are multiple enemies colliding with the rectangle and only damage the front enemy.

Here is the test I ran to do this (The enemies array value go backwards so the first one to appear is enemy[0] and the last enemy[10] for example):

for(int i=1;i<enemy.length; i++) 
{
 for(int j=0; j<boxes.length;j++) 
  {
   if(enemy[i].getEBox().intersects(boxes[j])&&!(enemy[i-1].getEBox().intersects(boxes[j]))) 
    {
  enemy.setHealth(enemy.getHealth()-1);
    }
  }
}

however, the second condition always returns a positive. How can I change my if statement to conduct a successful test?


Solution

  • To make a tower only shoot at one enemy, flip the loops and break the inner loop when shooting starts.

    for(int j=0; j<boxes.length;j++) //Runs for the total amount of towers placed
    {
      for(int i=0;i<enemy.length; i++) //Runs for the total amount of enemies
      {
        if(enemy[i].getEBox().intersects(boxes[j]))  //boxes[j] is the towers' range box
        {
          enemy[i].setHealth(enemy[i].getHealth()-1);
          break; // skip remaining enemies, since towers has used
                 // up it's shooting capability for this round
        }
      }
    }
    

    If a tower can prioritize which enemy to shoot at, loop through all the enemies to find the best candidate, then shoot at it.

    for (int j=0; j<boxes.length; j++) //Runs for the total amount of towers placed
    {
       int enemyToShootIdx = -1;
       for (int i=0; i<enemy.length; i++) //Runs for the total amount of enemies
          if (enemy[i].getEBox().intersects(boxes[j]))  //boxes[j] is the towers' range box
             if (enemyToShootIdx == -1 || betterCandidate(boxes[j], enemy[i], enemy[enemyToShootIdx]))
                enemyToShootIdx = i;
       if (enemyToShootIdx != -1)
          enemy[enemyToShootIdx].setHealth(enemy[enemyToShootIdx].getHealth()-1);
    }
    

    Now you just have to implement the betterCandidate() method.