2
\$\begingroup\$

I have been working on a way to do collision detection forever, and just can't figure it out. Here's my simple 2D array:

for (int x = 0; x < 16; x++) {
           for (int y = 0; y < 16; y++) {
              map[x][y] = AIR; 
              if(map[x][y] == AIR) {
                 air.draw(x * tilesize, y * tilesize);

              }

           }
        }

    for (int x = 0; x < 16; x++) {
           for (int y = 6; y < 16; y++) {
              map[x][y] = GRASS; 
              if(map[x][y] == GRASS) {
                 grass.draw(x * tilesize, y * tilesize);

              }

           }
        }
    for (int x = 0; x < 16; x++) {
           for (int y = 8; y < 16; y++) {
              map[x][y] = STONE; 
              if(map[x][y] == STONE) {
                 stone.draw(x * tilesize, y * tilesize);
              }

           }
        }

I want to do it with rectangles, and using the intersect() method, but how would I go about adding rectangles to all the tiles?

Edit:

My player moves like this:

if(input.isKeyDown(Input.KEY_W))
    {
        shiftY -= delta * speed;
        idY = (int) shiftY;

        if(shift == true)
        {
            shiftY -= delta * runspeed;
        }

        if(isColliding == true)
        {
            shiftY += delta * speed;
        }
    }

    if(input.isKeyDown(Input.KEY_S))
    {
        shiftY += delta * speed;
        idY = (int) shiftY;

        if(shift == true)
        {
            shiftY += delta * runspeed;
        }

        if(isColliding == true)
        {
            shiftY -= delta * speed;
        }
    }

    if (input.isKeyDown(Input.KEY_A)) {
        steve = left;
        shiftX -= delta * speed;
        idX = (int) shiftX;

        if(shift == true)
        {
            shiftX -= delta * runspeed;
        }

        if(isColliding == true)
        {
            shiftX += delta * speed;
        }
    }

    if (input.isKeyDown(Input.KEY_D)) {
        steve = right;
        shiftX += delta * speed;
        idX = (int) shiftX;

        if(shift == true)
        {
            shiftX += delta * runspeed;
        }

        if(isColliding == true)
        {
            shiftX -= delta * speed;
        }
    }

(I have tried my own collision code, but its horrible. Doesn't work in the slightest)

\$\endgroup\$
  • \$\begingroup\$ I'm not sure if this is relevant to the question, but it may save you some confusion later. You seem to be setting map[x][y] and then checking the value immediately after, which is always going to be true. \$\endgroup\$ – Nick Badal Oct 3 '12 at 0:27
  • \$\begingroup\$ Right, wasn't really worried about that, but I should probably change it shouldn't I? \$\endgroup\$ – opiop65 Oct 3 '12 at 0:30
  • \$\begingroup\$ Regarding your question, are you using a physics engine? \$\endgroup\$ – Nick Badal Oct 3 '12 at 0:41
  • 1
    \$\begingroup\$ You need to be more precise. Please edit your questions and indicate which objects need to be tested for collisions. Collisions are are usually tested for moving objects. In your example nothing is moving... \$\endgroup\$ – mikijov Oct 3 '12 at 0:41
  • \$\begingroup\$ I'm using Slick2D, so no. Could you recommend a good easy library that adds in collisions? \$\endgroup\$ – opiop65 Oct 3 '12 at 0:47
2
\$\begingroup\$

First, in your example you do:

if(isColliding == true)

Where isColliding is calculated?

An easy way to check for collision in a tiled environment is to check the tile facing the player e.g if the player wants to move up and if he's currently on tile x,y, you will check if the tile x,y-1 is a blocking tile (is not AIR in your case, i suppose).

The above method only works if the player have the size of the tiles and if the player move tile by tile, and it does not seem to be your case.

If your player has a totally different size than your tiles and/or can move more/less than TILE_SIZE per frame, you will need to use a bit more complex approach (also described here).

Basically, you need to create a new Shape for each of your game entities and keep them in a kind of Collection and each time your player move, proceed all the shapes in this collection and check if one of them intersect with your player's shape.

public Class CollisionSystem {

    public static List<Shape> collidingShapes = new...

    public static boolean checkPlayerCollision(Shape playerShape) {
        for (Shape s : collidingShapes) {
            if (s.intersects(playerShape) {
                 //or do some more precise collision calculation here, like pixel perfect
                 return true;
         }
         return false;
    }

It's a really simplified example since in a real case you will probably need to update position of the shapes for moving entities.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Wow, best and most simple answer I've found! Thanks! \$\endgroup\$ – opiop65 Oct 3 '12 at 10:49

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.