Morgan Blem Morgan Blem - 7 months ago 22
Java Question

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?

Answer

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.