How to do pixel-perfect collision detection of a player and the walls (JavaScript Game)

为君一笑 提交于 2019-12-23 06:23:09

问题


I'm making a 2D game in JavaScript. For it, I need to be able to "perfectly" check collision between my players(the game has two players, open the picture please) and the walls! I mean, I have a function that actually works, but when I make them jump against the walls they pass through the walls and keep moving until they reach another area or even leave the canvas! Also, if they are falling down and I make them collide with a wall, they just stop there wich is also pretty bad! I really need help with that!! It's a university project and I have to finnish it really soon!

My game looks like this

The collision detection function I have is here:

function blockRectangle (objA, objB) {
  var distX = (objA.x + objA.width / 2) - (objB.x + objB.width / 2);
  var distY = (objA.y + objA.height / 2) - (objB.y + objB.height / 2);

  var sumWidth = (objA.width + objB.width) / 2;
  var sumHeight = (objA.height + objB.height) / 2;

  if (Math.abs(distX) < sumWidth && Math.abs(distY) < sumHeight) {
    var overlapX = sumWidth - Math.abs(distX);
    var overlapY = sumHeight - Math.abs(distY);

    if (overlapX > overlapY) {
      objA.y = distY > 0 ? objA.y + overlapY : objA.y - overlapY;
    }
    else {
      objA.x = distX > 0 ? objA.x + overlapX : objA.x - overlapX;
    }
  }
}

I did the walls with a maze and I'm using a for cycle to check the collisions with all of the walls I have saved in an array! As you can see here:

for (var i in walls) {
  var wall = walls[i];
  
  if ((player.x < (wall.x + wall.width)) && ((player.x + player.width) > wall.x) && (player.y < (wall.y + wall.height)) && ((player.height + player.y) > wall.y)) {
    player.falling = false;
  }
  blockRectangle(player, wall);
}

Please help me!!! Thank you all!


回答1:


In your case I doubt a pixel perfect collision is required.

You can maintain a boolean matrix to store the position of solid objects. Solid objects like walls or players. Then in every frame you can check if your player is trying to move to a position where there is a solid object, if it is then stop it. You don't have to create grid of width x height in pixels, but rather choose a largest block (single element in the grid) in which each solid object reasonably occupies most of the block.

For example you can choose block size to be player_width / 2 x player_height /2.

See following image with grid

Another simple way could be to just check the background pixel color. Since your game is simple, background and object colors are different. So you just have to check if the player is trying to move somewhere where pixel color is not of background, thus there is a solid object and player should stop. You don't have to test for a lot of pixels, just 1 pixel in the direction the player is trying to move. (1 for horizontal and 1 for vertical). This however can not be used if you don't have a clear background color. Background color here is kind of the boolean grid for us in the previous suggestion.



来源:https://stackoverflow.com/questions/43944290/how-to-do-pixel-perfect-collision-detection-of-a-player-and-the-walls-javascrip

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!