0
\$\begingroup\$

Right. So I was making this simple game. The player is two tiles wide, and four tiles high. My current code is really buggy (it was better before my rewrite)

Here it is:

    float newx = position.x + velocity.x;
    float newy = position.y + velocity.y;

    int tx = (int) newx;
    int ty = (int) newy;

    Tile tile = WorldHandler.currentWorld.getTile(tx, ty);
    Tile ground = WorldHandler.currentWorld.getTile((int) position.x, (int) position.y-1);

    if (tile.type == 0) {
        position.x = newx;
        position.y = newy;
    }
    if (ground.type != 0) {
        grounded = true;
        //position.y = Math.round(position.y);
    }       

    if (grounded) {
        velocity.x = 0.0f;
        velocity.y = 0.0f;
        //position.y = Math.round(position.y);
    } else {
        velocity.x = velocity.x * (1.0f - Math.min(0.1f, 1.0f));
        velocity.y += 0.0f;
    }

it basically uses the indices for performance.

But I need a decent collision detection system that wouldn't be painful to implement, would AARBs be of use here? Also, the game loop is a tick based one, it runs at 30 ticks/s.

\$\endgroup\$
1
\$\begingroup\$

It is not clear what shape your tiles are. If they are all rectangles, just use the contains method. Check for collisions in your running or present methods (whichever to call the ongoing loop).

If you have different shaped tiles, you could try using methods like the following:

public static boolean overlapCircles(MyCircle c1, MyCircle c2) {
    float distance = c1.center.distSquared(c2.center);
    float radiusSum = c1.radius + c2.radius;
    return distance <= radiusSum * radiusSum;
}

public static boolean overlapRectangles(MyRect r1, MyRect r2) {
    if(r1.lowerLeft.x < r2.lowerLeft.x + r2.width &&
            r1.lowerLeft.x + r1.width > r2.lowerLeft.x &&
            r1.lowerLeft.y < r2.lowerLeft.y + r2.height &&
            r1.lowerLeft.y + r1.height > r2.lowerLeft.y)
        return true;
    else
        return false;
}

public static boolean overlapCircleRectangle(MyCircle c, MyRect r) {
    float closestX = c.center.x;
    float closestY = c.center.y;
    Log.i("in overlap tester", "");

    if(c.center.x < r.lowerLeft.x){
        closestX = r.lowerLeft.x;
        Log.i("in x", "");
    }
    else if(c.center.x > r.lowerLeft.x + r.width){
        closestX = r.lowerLeft.x + r.width;
    }

    if(c.center.y < r.lowerLeft.y){
        closestY = r.lowerLeft.y;
    }
    else if(c.center.y > r.lowerLeft.y + r.height){
        closestY = r.lowerLeft.y + r.height;
    }

    return c.center.distSquared(closestX, closestY) < c.radius * c.radius;
}

In the main part of the game I called them using:

private boolean collideWithEnemy() {
    boolean hit = false;
    MyCircle playerCir = new MyCircle(player.pPos[0], player.pPos[1], 5);
    MyCircle en1Cir = new MyCircle(en1.pos[0], en1.pos[1], 10);
    hit = OverlapTester.overlapCircles(playerCir, en1Cir);

    //If the hit was true for en1 without the if it would turn it false.
    if (!hit) {
        MyCircle en2Cir = new MyCircle(en2.pos[0], en2.pos[1], 10);
        hit = OverlapTester.overlapCircles(playerCir, en2Cir);
        if(!hit) {
            MyRect en3Rect = new MyRect(en3.pos[0], en3.pos[1], 20, 20);
            hit = OverlapTester.overlapCircleRectangle(playerCir, en3Rect);
            if(hit) {
                en3.pos[0] = -20;
            }
        }
    }
    return hit;
}
\$\endgroup\$
  • \$\begingroup\$ Nice! The rectangle method is what I need. \$\endgroup\$ – EEVV Feb 22 '16 at 7:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.