2
\$\begingroup\$

How would I go about making certain tiles in my array collide with my player? Like say I want every number 2 in the array to collide. I am reading my array from a txt file if that matters and I am using the slick2d library.

Here is my code if needed.

public class Tiles {

Image[] tiles = new Image[3];

int[][] map = new int[500][500];

Image grass, dirt, mound;

SpriteSheet tileSheet;

int tileWidth = 32;
int tileHeight = 32;

public void init() throws IOException, SlickException {
    tileSheet = new SpriteSheet("assets/tiles.png", tileWidth, tileHeight);

    grass = tileSheet.getSprite(0, 0);
    dirt = tileSheet.getSprite(7, 7);
    mound = tileSheet.getSprite(2, 6);
    tiles[0] = grass;
    tiles[1] = dirt; 
    tiles[2] = mound;

    int x=0, y=0;
BufferedReader in = new BufferedReader(new FileReader("assets/map.txt"));
String line;
while ((line = in.readLine()) != null) {
        String[] values = line.split(",");
    for (String str : values) {
            int str_int = Integer.parseInt(str);
            map[x][y]=str_int;
            //System.out.print(map[x][y] + " ");
            y=y+1;
        }
//System.out.println("");
x=x+1;
    y = 0;
}
    in.close();
}

public void update() {

}

public void render(GameContainer gc) {
    for(int x = 0; x < 50; x++) {
        for(int y = 0; y < 50; y ++) {
            int textureIndex = map[y][x];
            Image texture = tiles[textureIndex];
            texture.draw(x*tileWidth,y*tileHeight);
        }
    }
}

}

Edit - Solved

public boolean collision() {
    playerRect = new Rectangle(x,y, playerWidth, playerHeight);

    for(int i = 0; i < tiles.map.length; i++) {
        for(int j = 0; j < tiles.map.length; j++) {
            if(tiles.map[j][i] == 2 || tiles.map[j][i] == 3) {
                tileRect = new Rectangle(i*tiles.tileWidth, j*tiles.tileHeight, tiles.tileWidth,tiles.tileHeight);
                rect.add(tileRect);
            }
        }
    }  
    for(Rectangle collision : rect) {
        if(collision.intersects(playerRect)) { 
            return true;
        }
    }
    return false;
}
\$\endgroup\$
4
  • 2
    \$\begingroup\$ This looks like a "you need to learn how to use a debugger" kind of problem. \$\endgroup\$
    – Tetrad
    Commented Jun 13, 2012 at 3:11
  • 3
    \$\begingroup\$ I have spent the whole day trying to "use a debugger" and I cannot find the problem so I came here, a site where the whole point is asking for help, to see if someone could help me out or point me in the direction of solving my problem. I'm not asking for code to be written for me. I am just asking for a nudge in the right direction. Debugging isn't going to help me when I don't understand how to make it only collide with one item from the array in the first place. I didn't come here after trying for five minutes and beg for people to write me code. \$\endgroup\$
    – Corey
    Commented Jun 13, 2012 at 4:09
  • \$\begingroup\$ Your map is allocated as new int[500][500], but you are rendering only 50x50. Is this intentional? When you are reading the level, you are using x and y differently than in rendering. Same thing with the collision check. \$\endgroup\$
    – msell
    Commented Jun 13, 2012 at 6:57
  • \$\begingroup\$ Yes. It was Causing issues with lag so I put it to only 50x50 until I come up with a system for rendering only what is in my viewport. What I wanted to collide with renders on the screen because I have it at the beginning of the array, but it still doesn't collide \$\endgroup\$
    – Corey
    Commented Jun 13, 2012 at 17:22

1 Answer 1

2
\$\begingroup\$

You have a tile grid, and you have tile dimensions. That's a good start.

You're missing a key piece, though. You're trying to do collision between the player and the tiles (based purely on player location). This is a bit flawed. Instead, you should think about this problem as collision between player geometry and tile geometry.

To keep it simple, you can represent your player and tiles as rectangles. The player rectangle can be computed given the x location, y location, width, and height (if your player yet have height and width, you should add them).

Tile geometries (rectangles) can be computed in a similar manner, which should be fairly obvious:

  • x location = tile grid x index * tileWidth
  • y location = tile grid y index * tileHeight
  • width = tileWidth
  • height = tileHeight

Now do your collision checks. Hint: Have a look java.awt.Rectangle or java.awt.geom.Rectangle2D. These will help you.

\$\endgroup\$
7
  • \$\begingroup\$ Thank you this is very helpful. I knew how to do rectangle collision I just didn't know how to figure the tile rectangle with the index like you just showed me. The collision works now, but how would I go about making every number 2 in the array collidable and not just the tile at one certain index? \$\endgroup\$
    – Corey
    Commented Jun 14, 2012 at 21:07
  • 1
    \$\begingroup\$ Well, the easiest way (but not the fastest way) is to loop through your 2d array of ints (tiles). If the value == 2, create a Rectangle object from the tile (as shown above) and it add to an ArrayList. Then, just loop through this ArrayList of Rectangles and check for collisions with your player. If the level is small, this works well. If your levels are really big, you'll need to optimize this and be smarter about which tiles you need to consider for your collisions. But first, focus on making it work; then you can make it fast. \$\endgroup\$
    – larsbutler
    Commented Jun 14, 2012 at 22:22
  • \$\begingroup\$ Thanks again. I edited in at the bottom of post what I have so far. Is that the correct way I should create the rectangle? I'm not sure how I should loop through the arraylist though \$\endgroup\$
    – Corey
    Commented Jun 14, 2012 at 23:37
  • 1
    \$\begingroup\$ Yep, that part looks correct. To loop through an ArrayList, you can use a foreach loop: for(Object o : arrayList) { // do something with o } \$\endgroup\$
    – larsbutler
    Commented Jun 15, 2012 at 8:00
  • 1
    \$\begingroup\$ You just need to debug then. Put a print statement just inside your loop before the if(tiles.map[i][j] == 2) check and print the value at tiles.map[i][j]. If no points in the map are equal to 2, that's your problem. If that's the case, you need to initialize your map properly. \$\endgroup\$
    – larsbutler
    Commented Jun 16, 2012 at 12:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .