I am optimizing my "little" Java (LibGDX) shooter game, and perhaps unsurprisingly, collision detection is a "bottleneck"; I've kind of reached my performance goals already, but I want to tweak the game anyways.
Every monster in the game can collide with every other monster + friendly bullets. The game is a single-screen shooter. I am using a QuadTree.
In my Sprite/Entity-class, I have a method:
public boolean canCollideWith(Sprite s) {
return true;
}
This method is called twice in a loop within a loop, meaning that when enough Sprites are added, it gets called a lot. It shows up as a high HotSpot in VisualVM.
I override the method in various sub-classes, e.g. in the Bullet-class:
@Override
public boolean canCollideWith(Entity e) {
if (friendly) {
return (e instanceof Monster && !(e instanceof Player))
|| e instanceof Missile;
}
else
return e instanceof Player || e instanceof Warp;
}
...and in the Monster-class:
public boolean canCollideWith(Entity e) {
return e instanceof Bullet && ((Bullet) e).isFriendly() || e instanceof Monster || e instanceof Tagger || e instanceof Flower || e instanceof Shockwave;
}
I don't really like these instanceof's in the first place... what would be an elegant and a fast solution to optimize this (hopefully both :)?
Excluding the QuadTree part, here's my whole collision detection method:
public static void collisionDetection(Array<? extends Sprite> sprites) {
for (int i = 0; i < sprites.size; i++) {
Sprite s1 = sprites.get(i);
if (!s1.isCollidable()) continue;
for (int k = i + 1; k < sprites.size; k++) {
Sprite s2 = sprites.get(k);
if (s1 == s2) continue;
if (!s2.isCollidable()) continue;
if (!s1.canCollideWith(s2)) continue;
if (!s2.canCollideWith(s1)) continue;
boolean intersects = s1.intersects(s2);
if (intersects) {
s1.fireIntersectionEvent(s2);
s2.fireIntersectionEvent(s1);
s1.intersectsWith(s2);
s2.intersectsWith(s1);
}
}
}
}
Thanks for any ideas.