I use a grid bast collision detection routine and it will be much faster. I have a 2D array of Sets of game objects (or of Towers in your case). It should be a set because a tower should only be stored in an array location once. You need to calculate the towers minimum and maximum x and y locations. Typically the minimum is their bottom left corner, and the maximum is the Towers top right corner.
You then divide the x values of these corners by the width of the array, and the y value by the height of the array. Then you iterate from the new minimum x and y through to the maximum x and y, adding the tower into the Set in each location in the array.
This is untested psudo code for adding a tower…
final int TOWER_GRID_WIDTH = 20;
final int TOWER_GRID_HEIGHT = 20;
Set<Tower>[][] towerGrid = new Set<Tower>[TOWER_GRID_WIDTH][TOWER_GRID_HEIGHT];
/* grid setup code here */
Tower tower = // get tower
int minX = Math.floor( (tower.getX()-tower.getWidth()/2) / TOWER_GRID_WIDTH );
int minY = Math.floor( (tower.getY()-tower.getHeight()/2) / TOWER_GRID_HEIGHT );
int maxX = Math.ceil( (tower.getX()+tower.getWidth()/2) / TOWER_GRID_WIDTH );
int maxY = Math.ceil( (tower.getY()+tower.getHeight()/2) / TOWER_GRID_HEIGHT );
for (int x = minX; i <= maxX; x++) {
for (int y = minY; i <= maxY; y++) {
towerGrid[x][y].put( tower );
}
}
When a Tower’s size or location changes (i.e. moved or resized) then you need to remove it from all of it’s locations and then re-add it. There are then a range of optimizations you can run to make this more efficient (like checking if a Tower has moved from one grid space to another before removing/re-adding, and only updating when you check for collisions).
When you want to perform a collision check you just work out what array elements the Tower is in (like above) and then iterate over all the towers in each of those sets. Those are the towers to check against.
You should also try different grid sizes as they will yield different amounts of performance.