0
\$\begingroup\$

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];
    }
}

im not sure about

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.

enter image description here

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;
                        }
                    }
                }
            }
    }
\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

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.

\$\endgroup\$
6
  • \$\begingroup\$ 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) \$\endgroup\$
    – Peter
    Commented May 26, 2016 at 12:05
  • \$\begingroup\$ @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. \$\endgroup\$
    – Greffin28
    Commented May 26, 2016 at 12:11
  • \$\begingroup\$ 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 :( ) \$\endgroup\$
    – Peter
    Commented May 26, 2016 at 14:04
  • \$\begingroup\$ @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. \$\endgroup\$
    – Greffin28
    Commented May 26, 2016 at 14:21
  • \$\begingroup\$ yea thanks , two hours and i was changed my collision detection. Hope all be ok :( \$\endgroup\$
    – Peter
    Commented May 26, 2016 at 14:39
1
\$\begingroup\$

Expanding on Greffin28's Answer

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.
}

This will need to be adapted for your game of course.

\$\endgroup\$
3
  • \$\begingroup\$ +1 For the collision and .equals() forgot to mention that when comparing strings. \$\endgroup\$
    – Greffin28
    Commented May 26, 2016 at 14:46
  • \$\begingroup\$ I didn't actually read his code but yes, that's probably a big part of his problem! I'll add a bit to my answer. \$\endgroup\$
    – Shaun Wild
    Commented May 26, 2016 at 14:49
  • \$\begingroup\$ thank for you answer, im little improved my collision detection and hope all ok. \$\endgroup\$
    – Peter
    Commented May 26, 2016 at 14:51

You must log in to answer this question.

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