# 2D Collision in tilemap - ArrayOutOfBounds

im trying to do collision detection with world based on tilemaps (two dimensional array) array -

private int WIDTH = 10;
private int HEIGHT = 6;
String[][] simplemap = new String[][]{

{ "0","1","2","3","4","5","6","7","8","g",},
{ "11","g","","","","","g","","","g",},
{ "22","g","","","","","g","","","g",},
{ "33","g","","","","","g","","","g",},
{ "44","g","","","","","g","","","g",},
{ "g","g","g","g","g","g","g","g","g","g",},
{ "g","g","g","g","g","g","g","g","g","g",},
};


than i create array from blocks and trying to show it

create blocks :

blocks = new Enemy[HEIGHT][WIDTH];
for(int i =0;i<HEIGHT;i++){
for(int j=0;j<WIDTH;j++){
blocks[i][j]= new Enemy(context,0,0);
blocks[i][j].boxWidth=blockWidth;
blocks[i][j].boxHeight=blockHeight;
blocks[i][j].x=blockWidth*j;
blocks[i][j].y=blockHeight*i;
blocks[i][j].state = simplemap[i][j];
}
}


blocks[i][j].x=blockWidth*j;
blocks[i][j].y=blockHeight*i;


but if write blockWidth*i (not j) than map building like rotated on 90 degree. Maybe error here in this code. Not sure Than in glDraw i draw my map

for (int i = 0; i < HEIGHT; i++) {
for (int j = 0; j < WIDTH; j++) {
if ( blocks[i][j].state == "g") {
blocks[i][j].draw(gl);
}
}
}


For collision i do a this code (it's for Y collision detection) for X collision code similar

for(int i = (int)ball.y/tileSize; i<(ball.y+ball.boxWidth)/tileSize; i++) {
for(int j = (int)ball.x/tileSize; j<(ball.x+ball.boxWidth)/tileSize;j++) {
//System.out.print("  i = "+i+"j "+j);
Log.e("ERROR ", " "+i+":"+j);
Log.e("ERROR", "DY = "+dy);
if (blocks[i][j].state=="g") {
//do what we need, check directions or something other
}
}
}


Problem Map drawing ok with this code , and my object work only in small area like i =HEIGHT, In tests its like when i start moving from left to right side - i see 10 blocks(like road) app always crashed with nullpointerexception(from array out of bounds) after 4-5 blocks on road. I think i just not correct building my map and position . With this code i see on phone correct map, if change i and j when we set position for every blocks - than its rounded on 90 degree. Also exception on code if (blocks[i][j].state=="g") array out of bounds . Length 6 etc. I cant understand where my error, can any good guy help me ? please.

Regards, Peter.

Thank you all guys Not sure if its right - but in test its show all correct; code for collision on Y

public void checkColisionY(){

dy = dy + gravity * dt;
ball.y = ball.y + dy * dt + 0.05f * gravity * dt * dt;
for(int i = (int)ball.y/tileSize; i<(ball.y+ball.boxWidth)/tileSize; i++){
for(int j = (int)ball.x/tileSize; j<(ball.x+ball.boxWidth)/tileSize;j++)
{

if(dy>0){
if(ball.y+ball.boxWidth>=blocks[i+1][j].y && blocks[i+1][j].state =="g"){
ball.y = blocks[i+1][j].y-ball.boxWidth;
dy=dy*energyloss;
dy = dy * -1;
}
}
}
}
}


For accessing the array i suggest you make a function like the following:

String getState(int x, int y) {
if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) return "g"; // Let's say all blocks outside the map is solid.
return blocks[y][x].state;
}


This simple function can save you from array out of bounds error. Basically, the function check the x and y which you want to access, if it is outside the array then return for example "g" which i suppose is ground/solid? You may change it to whatever value you want.

And for this:

blocks[i][j].x=blockWidth*j;
blocks[i][j].y=blockHeight*i;


If you switch j with i, it's no wonder for me if it is rotated 90 degree. As in your for loop j is x, and i is y. Changing j/i to x/y might help you out of the confusion.

• im little not understand , in my case it's right code ? x = blockWidthj ? or i have somewhere error and here must be x=blockWidthi ? ArrayOutOfBounds come cos i cant understand where my error with building. it's like position of my object always changed in i position (y) Commented May 26, 2016 at 12:05
• @Peter your code is correct. it is x=blockWidth * j if you want it to be blockWidth * i, then change the j with i in the for loop like for(int i=0; i<WIDTH; i++). As i said, you might want to change i and j to x and y to help you clear your confusion. And for the ArrayOutOfBounds error, see the function in my answer. Commented May 26, 2016 at 12:11
• well, im not get error now , but my ball still drop down when moving on random box :(( like on screenshot but its can happened on other boxs (at start, at end and its random :( ) Commented May 26, 2016 at 14:04
• @Peter You mean your ball fall through boxes like there's no obstacles? If that's the case i suggest you to improve your collision detection system. From what i understand from your code, you check the tile at the box position and at the box position + boxWidth. You don't want to do that, what you want to do is check where the ball is going to (it's destination) instead. Commented May 26, 2016 at 14:21
• yea thanks , two hours and i was changed my collision detection. Hope all be ok :( Commented May 26, 2016 at 14:39

Tile Based Collision Detection in Games

In tile based games it's really easy and fast to detect whether an object is colliding with a tile. Some psuedo- code to accomplish this:

/**
* Moves our entity along the x, then y. If we do both at the same time the entity
* will not move if any of the collision detections fail (won't be able to slide)
*/
public boolean doMove(int x, int y){
boolean cx = move(x, 0);
boolean cy = move(0, y);
return cx || cy; //return whether we moved (you may use this later for something else)
}

/**
* Actually perform the move and roll back the entities position if the move fails
*/
public boolean move(int x, int y){
pos.x += x;
pos.y += y;
boolean overlapping = checkCollision();
if(overlapping){
pos.x -= x;
pos.y -= y;
return false;
}else{
return true;
}
}

/**
* Check if our top left point is currently inside a tile, you can repeat this for all 4 corners for bounding boxes or do some
* other fancy stuff for a circle.
*/
public boolean checkCollision(){
int tx = pos.x/TILE_SIZE; //Check which tile our entity is stood on
int ty = pos.y/TILE_SIZE;

if(tiles[tx][ty].equals("g")){ //Note that I use .equals() and not == this is
return true;               //because Strings are objects and they are not equal
}                              //in an object sense. Their contents are just
return false;                  //the same. so .equals() returns true and == will not.
}


• +1 For the collision and .equals() forgot to mention that when comparing strings. Commented May 26, 2016 at 14:46