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\$
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\$
  • \$\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 May 26 '16 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 May 26 '16 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 May 26 '16 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 May 26 '16 at 14:21
  • \$\begingroup\$ yea thanks , two hours and i was changed my collision detection. Hope all be ok :( \$\endgroup\$ – Peter May 26 '16 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\$
  • \$\begingroup\$ +1 For the collision and .equals() forgot to mention that when comparing strings. \$\endgroup\$ – Greffin28 May 26 '16 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 May 26 '16 at 14:49
  • \$\begingroup\$ thank for you answer, im little improved my collision detection and hope all ok. \$\endgroup\$ – Peter May 26 '16 at 14:51

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.