检测碰撞JavaScript

时间:2015-04-01 01:21:10

标签: javascript canvas html5-canvas

我有2个盒子,1个是玩家,另一个是墙。如果在玩家正在移动的方向上有一堵墙,我希望玩家停止移动 在这个问题的底部提供了一个plunker链接,以显示2个框的功能。

使用w a s d移动盒子,我需要知道玩家如何能够检测到墙壁并在与墙壁接触时停止移动?这意味着玩家和墙壁不能处于相同位置,玩家必须绕墙而不是通过墙壁。
我今天需要这个,我会整晚都在,所以请不要犹豫,评论或回答这个问题,谢谢。

function Player(row, col) {
  this.isUpKey = false;
  this.isRightKey = false;
  this.isDownKey = false;
  this.isLeftKey = false;
  this.row = row;
  this.col = col;
  this.color = "#f00";
}

function drawWalls() {
    var walls = new Array();

    function Wall (row,col) {
        this.row = row;
        this.col = col; 
        this.color = "#000";
    }

    walls[walls.length] = new Wall(5,5);

    for (var b = 0; b < walls.length; b++) {
        ctxWall.fillStyle = walls[b].color; 
        ctxWall.fillRect(walls[b].row*25, walls[b].col*25, 25, 25);
    }
}


var players = [];
var ctxPlayer;
var ctxWall;
var currentPlayer;

window.onload = function() {
  ctxPlayer = document.getElementById('c').getContext('2d');
  ctxWall = document.getElementById('walls').getContext('2d');
  currentPlayer = players[players.length] = new Player(2, 2);
  setInterval(render, 25);
  drawWalls();
}
window.onkeypress = doKeyDown;

function render() {
  ClearPlayer();
  drawPlayer();
}

function drawPlayer() {
  for (var p = 0; p < players.length; p++) {
    ctxPlayer.fillStyle = players[p].color;
    ctxPlayer.fillRect(players[p].row * 25, players[p].col * 25, 25, 25);
  }
}

function doKeyDown(e) {
  console.log(e);
  if (e.keyCode == 97) {
    currentPlayer.isUpKey = true;
    --currentPlayer.row;
  }
  if (e.keyCode == 100) {
    currentPlayer.isDownKey = true;
    ++currentPlayer.row;
  }
  if (e.keyCode == 119) {
    currentPlayer.isLeftKey = true;
    --currentPlayer.col;
  }
  if (e.keyCode == 115) {
    currentPlayer.isRightKey = true;
    ++currentPlayer.col;
  }
}

function ClearPlayer() {
  ctxPlayer.clearRect(0, 0, 600, 400);
}

http://plnkr.co/edit/27URhP?p=preview

我试图将函数checkIfPlayerMovingIntoWall()添加到播放器和墙对象,请参阅下面的内容,但是没有发生任何事情。

function Wall (row,col) {
    this.row = row;
    this.col = col; 
    this.color = "#000";

    this.width= 25
    this.height= 25
    this.leftX = this.row;
    this.rightX = this.row + this.width;
    this.topY =  this.col;
    this.bottomY = this.col + this.height;
}
function Player(row, col) {
   this.isUpKey = false;
   this.isRightKey = false;
   this.isDownKey = false;
   this.isLeftKey = false;
   this.row = row;
   this.col = col;
   this.color = "#f00";

   this.width= 25
   this.height= 25
   this.leftX = this.row;
   this.rightX = this.row + this.width;
   this.topY =  this.col;
   this.bottomY = this.col + this.height;
}  
function checkIfPlayerMovingIntoWall() {
if (currentPlayer.topY < wall.bottomY &&
   currentPlayer.bottomY > wall.topY &&
   currentPlayer.leftX < wall.rightX &&
   currentPlayer.rightX > wall.leftX) {
    alert("collision detected");
  }
}

请不要犹豫回答或评论

1 个答案:

答案 0 :(得分:3)

根据你到目前为止的情况,我会这样做:

•设置一个包含墙的全局数组(现在您正在与名为Wall的函数进行比较) •设置全局变量以定义行和列的网格大小 •拨打checkIfPlayerMovingIntoWall()处理程序中的keydown。添加到此函数的属性告诉他我们想去哪里。如果它在墙上,则返回false并且不要移动。

// Code goes here

function Player(col, row) {
  this.isUpKey = false;
  this.isRightKey = false;
  this.isDownKey = false;
  this.isLeftKey = false;
  this.row = row;
  this.col = col;
  this.color = "#f00";

  this.width = 25
  this.height = 25
  this.leftX = this.row;
  this.rightX = this.row + this.width;
  this.topY = this.col;
  this.bottomY = this.col + this.height;
}

function Wall(row, col) {
  this.row = row;
  this.col = col;
  this.color = "#000";

  this.width = 25
  this.height = 25
  this.leftX = this.row;
  this.rightX = this.row + this.width;
  this.topY = this.col;
  this.bottomY = this.col + this.height;
}

function drawWalls(x,y) {
  walls.push( new Wall(x, y));

  for (var b = 0; b < walls.length; b++) {
    ctxWall.fillStyle = walls[b].color; // color the box that is on count which is being created by adding a new box to the count
    ctxWall.fillRect(walls[b].row * gridSize, walls[b].col * gridSize, walls[b].width, walls[b].height); // the box is a rectangle with a length of 50 and a width of 50 and when a new line is added time the row by 50 and col by 50
  }
}

function checkIfPlayerMovingIntoWall(direction) {
  var playerPos = [];
  switch (direction) {
    case 'up':
      playerPos = [currentPlayer.col, currentPlayer.row - 1];
      break;
    case 'down':
      playerPos = [currentPlayer.col, currentPlayer.row + 1];
      break;
    case 'left':
      playerPos = [currentPlayer.col - 1, currentPlayer.row];
      break;
    case 'right':
      playerPos = [currentPlayer.col + 1, currentPlayer.row];
      break;
    default:
      playerPos = [currentPlayer.col, currentPlayer.row];
  }
  for (i = 0; i < walls.length; i++) {
    var Wall = walls[i];
    if (playerPos[0] * gridSize < Wall.row * gridSize + Wall.width && playerPos[0] * gridSize + currentPlayer.width > Wall.row * gridSize &&
      playerPos[1] * gridSize < Wall.col * gridSize + Wall.height && playerPos[1] * gridSize + currentPlayer.height > Wall.col * gridSize) {
      console.log("they are touching")
      return true;
    }
  }
 return false;  
}

var walls = [];
var players = [];
var ctxPlayer;
var ctxWall;
var currentPlayer;
var gridSize = 25;

window.onload = function() {
  ctxPlayer = document.getElementById('c').getContext('2d');
  ctxWall = document.getElementById('walls').getContext('2d');
  currentPlayer = players[players.length] = new Player(2, 2);
  setInterval(render, 25);
  drawWalls(1,2);
  drawWalls(2,1); 
  drawWalls(4,1);
}
window.onkeydown = doKeyDown;

function render() {
  ClearPlayer();
  drawPlayer();
}

function drawPlayer() {
  for (var p = 0; p < players.length; p++) {
    ctxPlayer.fillStyle = players[p].color;
    ctxPlayer.fillRect(players[p].col * gridSize, players[p].row * gridSize, players[p].width, players[p].height);
  }
}

function doKeyDown(e) {
  e.preventDefault();
  if (e.which == 87 || e.which == 38) {
    currentPlayer.isUpKey = true;
    if (checkIfPlayerMovingIntoWall('up')) {
      return;
    }
    --currentPlayer.row;
  }
  if (e.which == 83 || e.which == 40) {
    if (checkIfPlayerMovingIntoWall('down')) {
      return;
    }
    currentPlayer.isDownKey = true;
    ++currentPlayer.row;
  }
  if (e.which == 65 || e.which == 37) {
    if (checkIfPlayerMovingIntoWall('left')) {
      return;
    }
    currentPlayer.isLeftKey = true;
    --currentPlayer.col;
  }
  if (e.which == 68 || e.which == 39) {
    if (checkIfPlayerMovingIntoWall('right')) {
      return;
    }
    currentPlayer.isRightKey = true;
    ++currentPlayer.col;
  }

}

function ClearPlayer() {
  ctxPlayer.clearRect(0, 0, 600, 400);
}
canvas {
  margin: 20px auto 0;
  display: block;
}
#canvasHUD,
#canvasPlayer,
#walls {
  margin: -400px auto 0;
}
<canvas width="600" height="400" id="c"></canvas>
<canvas width="600" height="400" id="walls"></canvas>

另外,我在右上角的x-y行列中进行了一些清理。

Forked plunk