HTML Canvas: 2D Collision Detection

I need to program a very simple 2D canvas game with a symbol and several walls. A map (top view) is a multidimensional array ( 1=walls)

map = [
  [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
  [1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0],
  [1,0,0,1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,1,0,0,0,0,1,0,1,1,1,1,1,1,0,0,0,0,0,0,0,1],
  [1,0,0,1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1],
  [1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  [1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1],
  [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1],
  [1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1,1,0,1,1],
  [1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,0,0,0,0,1,1,0,1,1],
  [0,0,0,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,0,1,1],
  [1,1,1,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,0,1,1],
  [1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,0,0,0,0,1,1],
  [1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,1,0,0,1,1],
  [1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1],
  [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
];

A character must not walk on walls ... therefore, he must walk only on "0". I already have a map rendered, and the walking part of the character is working fine, but I can’t figure out how to check for collisions.

A very simple version is on JSBin . You can use the arrow keys or WASD to move (black square).

I already tried to make a very simple collision detection using something like this:

function checkCollision( x, y ) {
  if ( map[ Math.round( x ) ][ Math.round( y ) ] !== 0 ) {
    return true; // Collision
  }
  return false;
}

(. JSBin). Math.round ... Math.ceil Math.floor, .

" ", ?

+4
5

. ( , , , ). "" (, , ), (, 1 / config.tileSize ).

function checkCollision( x, y ) {
  var x1 = Math.floor(x + 1 / config.tileSize), 
      y1 = Math.floor(y + 1 / config.tileSize),
      x2 = Math.floor(x + 1 - 1 / config.tileSize), 
      y2 = Math.floor(y + 1 - 1 / config.tileSize);
  if (map[y1][x1] !== 0 || map[y2][x1] !== 0 || map[y1][x2] !== 0 || 
      map[y2][x2] !== 0) {
    return true; // Collision
  }
  return false;
}

JSBin

+1

:

0,1 , " " ( , ). 0.125 (1/8). / 1/8 , 1/8, .

"ok (x, y)", (, ) (x, y) ... :

return map[y|0][x|0] == 0; //  <expr>|0 is used to convert to integer

, new_charX new_charY charX, charY , :

(new_charX+s, new_charY+s)
(new_charX+1-s, new_charY+s)
(new_charX+s, new_charY+1-s)
(new_charX+1-s, new_charY+1-s)

s= 1/16 (.. ).

: http://jsbin.com/wipimidije/edit?js,output

+2

. , 2D-, ( ). , :

var map = [0,0,0,1,1,0,0,1,1,0,0,...];

//heres how to calculate the x/y if you need it for something else
var pos_x = position % NUM_OF_ROWS;
var pos_y = Math.floor(position / NUM_OF_ROWS);

//for collisions now you just check the value of the array at that index
leftKey.addEventListener('keypress', function() { 
    test(position - 1);
});
rightKey.addEventListener('keypress', function() { 
    test(position + 1);
});
upKey.addEventListener('keypress', function() { 
    test(position + NUM_OF_ROWS);
});
downKey.addEventListener('keypress', function() { 
    test(position - NUM_OF_ROWS);
});

function test(n) {
    if (map[n] === 0) {
        //if there no collision, update the position.
        position = n;
    } else {
        console.log('Collided!');
    }
}
+1

: - , - . . , , , . - . , . , charX + config.tileSize.

- . , , - , . , "" ( , ).

+1

, "", , 1, 0 , ,    ( [] [])... , , ...

Var nextpos = new position;

If(KEYLEFT){
    Nextpos.x = currpos - 1;
}

If(nextpos > 0 && nextpos < mapsize && tile[nextpos.x][nextpos.y])
    Player.pos = nextpos;
0

Source: https://habr.com/ru/post/1616115/


All Articles