Quantcast
Channel: Question and Answer » libgdx
Viewing all articles
Browse latest Browse all 434

Optimizing Collision Detection in a 2D Game

$
0
0

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.


Viewing all articles
Browse latest Browse all 434

Trending Articles