如何检查与球员和球的碰撞?

时间:2015-11-10 16:40:45

标签: javascript

我试图用球和球员(平台)进行砖块比赛。如果球击中了球员,它应该像乒乓球一样朝另一个方向跑去。但是,它没有检测到碰撞。

这是代码

HTML:

<canvas id="canvas" width= "400" height= "400"></canvas>

的CSS:

#canvas{border:1px solid black}

JS:

var width = 400
var height = 400

var drawRect = function (x, y) {
  ctx.fillRect(x, y, 30, 5)
};

// The Ball constructor
var Player = function () {
  this.x = 395
  this.y = 395
  this.xSpeed = 5;
  this.ySpeed = 0;
};

// Update the ball's position based on its speed
Player.prototype.move = function () {
  this.x += this.xSpeed;
  this.y += this.ySpeed;

  if (this.x < 0) {
    this.x = width;
  } else if (this.x > width) {
    this.x = 0;
  } else if (this.y < 0) {
    this.y = height;
  } else if (this.y > height) {
    this.y = 0;
  }
};

// Draw the ball at its current position
Player.prototype.draw = function () {
  drawRect(this.x, this.y);
};

// Set the ball's direction based on a string
Player.prototype.setDirection = function (direction) {
    if (direction === "left") {
     this.xSpeed = -5;
     this.ySpeed = 0;
  } else if (direction === "right") {
     this.xSpeed = 5;
     this.ySpeed = 0;
  } else if (direction === "stop") {
     this.xSpeed = 0;
     this.ySpeed = 0;
  }
};

// Create the ball object
var player = new Player();

// An object to convert keycodes into action names
var keyActions = {
  32: "stop",
  37: "left",
  38: "up",
  39: "right",
  40: "down"
};

// The keydown handler that will be called for every keypress
$("html").keydown(function (event) {
  var direction = keyActions[event.keyCode];
  player.setDirection(direction);
});



var Ball = function () {
    this.x = 100;
    this.y = 100;
    this.xSpeed = -2
    this.ySpeed = 3;
};
var circle = function (x, y, radius, fillCircle) {
    ctx.beginPath();
    ctx.arc(x, y, radius, 0, Math.PI * 2, false)
    if (fillCircle) {
        ctx.fill();
    } else {
        ctx.stroke();
    }
}
Ball.prototype.move = function () {
    this.x += this.xSpeed
    this.y += this.ySpeed
};

Ball.prototype.draw = function () {
    circle(this.x, this.y, 3, true);
};

Ball.prototype.checkCollision = function () {
    if (this.x < 0 || this.x > 400) {
        this.xSpeed = -this.xSpeed
    }

    if (this.y < 0) {
        this.ySpeed = -this.ySpeed

    }
};

Ball.prototype.checkCollisionPlayer = function () {
    if (this.x === Player.x || this.y === player.y) {
     this.ySpeed = -this.ySpeed
     this.xSpeed = -this.xSpeed
    }
}
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
setInterval(function () {
    ctx.clearRect(0, 0, 400, 400);
    player.draw();
    player.move();
    ball.draw();
    ball.move();
    ball.checkCollision();
    ball.checkCollisionPlayer();
}, 40);
var ball = new Ball();

感谢您的支持。 :)

1 个答案:

答案 0 :(得分:1)

我添加了一个简单的盒子碰撞并更新了类,以获得球和球员的盒子尺寸。请记住,球盒必须调整半径偏移。

<强>更新

您必须知道被撞击的侧面或角落所需的那种碰撞检测。我更新了示例作为此的起点,但需要添加角落,我也不知道最佳检测。这些块被设置用于测试。我希望这有帮助。

var width = 400
var height = 400

function Brick(x, y, w, h, color) {
  this.x = x;
  this.y = y;
  this.color = color;
  this.w = w;
  this.h = h;
  this.hits = 0;
}

Brick.prototype.draw = function() {
  ctx.save();
  ctx.fillStyle = this.color;
  ctx.fillRect(this.x, this.y, this.w, this.h);
  ctx.fillStyle = "white";
  ctx.fillText(this.hits, this.x + 2, this.y + 10);
  ctx.restore();
};

var bricks = [
  new Brick(80, 120, 15, 15, 'red'),
  new Brick(220, 90, 15, 15, 'blue'),
  new Brick(340, 100, 50, 20, 'green')
];




// The Ball constructor
var Player = function() {
  this.x = 395
  this.y = 395
  this.xSpeed = 5;
  this.ySpeed = 0;
  this.w = 30;
  this.h = 5;
};


// Update the ball's position based on its speed
Player.prototype.move = function() {
  this.x += this.xSpeed;
  this.y += this.ySpeed;

  if (this.x < 0) {
    this.x = width;
  } else if (this.x > width) {
    this.x = 0;
  } else if (this.y < 0) {
    this.y = height;
  } else if (this.y > height) {
    this.y = 0;
  }
};

// Draw the ball at its current position
Player.prototype.draw = function() {
  ctx.fillRect(this.x, this.y, this.w, this.h);
};

// Set the ball's direction based on a string
Player.prototype.setDirection = function(direction) {
  if (direction === "left") {
    this.xSpeed = -5;
    this.ySpeed = 0;
  } else if (direction === "right") {
    this.xSpeed = 5;
    this.ySpeed = 0;
  } else if (direction === "stop") {
    this.xSpeed = 0;
    this.ySpeed = 0;
  }
};

// Create the ball object
var player = new Player();

// An object to convert keycodes into action names
var keyActions = {
  32: "stop",
  37: "left",
  38: "up",
  39: "right",
  40: "down"
};

// The keydown handler that will be called for every keypress
$("html").keydown(function(event) {
  var direction = keyActions[event.keyCode];
  player.setDirection(direction);
});



var Ball = function() {
  this.x = 100;
  this.y = 100;
  this.xSpeed = -2
  this.ySpeed = 3;
  this.radius = 3;
};
var circle = function(x, y, radius, fillCircle) {
  ctx.beginPath();
  ctx.arc(x, y, radius, 0, Math.PI * 2, false)
  if (fillCircle) {
    ctx.fill();
  } else {
    ctx.stroke();
  }
}
Ball.prototype.move = function() {
  this.x += this.xSpeed
  this.y += this.ySpeed
  if ((this.y + this.radius) > ctx.canvas.height) {
    // floor to ceiling
    this.y = 0;
  }
};

Ball.prototype.draw = function() {
  circle(this.x, this.y, this.radius, true);
};

Ball.prototype.getBox = function() {
  return {
    x: this.x - this.radius,
    y: this.y - this.radius,
    w: this.radius * 2,
    h: this.radius * 2
  };
};

Ball.prototype.checkCollision = function() {




  if (this.x < 0 || this.x > 400) {
    this.xSpeed = -this.xSpeed
  }

  if (this.y < 0) {
    this.ySpeed = -this.ySpeed
  } else {
    var boxA = this.getBox();

    switch (boxCollide(boxA, player)) {
      case 1:
      case 3:
        this.ySpeed = -this.ySpeed;
        break;
      case 2:
      case 4:
        this.xSpeed = -this.xSpeed;
        break;
    }
  }


};

// does box a collide with box b
// box = {x:num,y:num,w:num,h:num}
function boxCollide(a, b) {

  var ax2 = a.x + a.w;
  var ay2 = a.y + a.h;
  var bx2 = b.x + b.w;
  var by2 = b.y + b.h;

  // simple hit true, false
  //if (ax2 < b.x || a.x > bx2 || ay2 < b.y || a.y > by2) return false;
  // return true

  var xInRange = (a.x >= b.x && a.x <= bx2 || ax2 >= b.x && ax2 <= bx2);
  var yInRange = (a.y >= b.y && a.y <= by2 || ay2 >= b.y && ay2 <= by2);
  // Clockwise hit from top 1,2,3,4 or -1
  if (ay2 > b.y && a.y < by2 && xInRange) return 1; // A hit the top of B
  if (a.x < bx2 && ax2 > b.x && yInRange) return 2; // A hit the right of B
  if (a.y < by2 && ay2 > b.y && xInRange) return 3; // A hit the bottom of B
  if (ax2 > b.x && a.x < bx2 && yInRange) return 4; // A hit the right of B
  return -1; // nohit
}


Ball.prototype.checkCollisionPlayer = function() {
  if (this.x === Player.x || this.y === player.y) {
    this.ySpeed = -this.ySpeed
    this.xSpeed = -this.xSpeed
  }
}
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
setInterval(function() {
    ctx.clearRect(0, 0, 400, 400);
    player.draw();
    player.move();
    ball.draw();
    ball.move();
    ball.checkCollision();
    ball.checkCollisionPlayer();
    var boxA = ball.getBox();
    for (var i = 0; i < bricks.length; i++) {
      switch (boxCollide(boxA, bricks[i])) {
        case 1:
          ball.y = bricks[i].y - ball.radius - 1;
          ball.ySpeed = -ball.ySpeed;
          bricks[i].hits++;
          break;
        case 3:
          ball.y = bricks[i].y + ball.radius + bricks[i].h + 1;
          ball.ySpeed = -ball.ySpeed;
          bricks[i].hits++;
          break;
        case 2:
          ball.x = bricks[i].x + ball.radius + bricks[i].w + 1;
          ball.xSpeed = -ball.xSpeed;
          bricks[i].hits++;
          break;
        case 4:
          ball.x = bricks[i].x - ball.radius - 1;
          ball.xSpeed = -ball.xSpeed;
          bricks[i].hits++;
          break;
      }


      bricks[i].draw();
    }
  },
  40);
var ball = new Ball();
#canvas {
  border: 1px solid black
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" width="400" height="400"></canvas>