我正在尝试使用html canvas构建一款游戏。这是一款空气曲棍球游戏,我已经做得很不错了。游戏中有三个圆形:被击打的圆盘和两个控制器(用于撞击圆盘/圆形)。
我已经让圆盘从墙壁上反弹,并且有一个函数来检测圆盘何时与控制器相撞。我遇到的问题是当两个圆形相撞时,控制器应该保持静止,圆盘应该以正确的方向移动。我已经阅读了一堆文章,但仍然无法搞定。
以下是我的进展代码链接。您可以看到冰球从控制器上反弹,但方向不正确。您还会发现,如果冰球从控制器后面来,它会穿过控制器。 http://codepen.io/allanpope/pen/a01ddb29cbdecef58197c2e829993284?editors=001
我想要的是弹性碰撞,但不确定如何解决。我找到了这篇文章,但未能让它起作用。
以下是我的碰撞检测函数。Self指圆盘,controller[i]是圆盘撞击的控制器。
this.discCollision = function() {
for (var i = 0; i < controllers.length; i++) {
// Minus the x pos of one disc from the x pos of the other disc
var distanceX = self.x - controllers[i].x,
// Minus the y pos of one disc from the y pos of the other disc
distanceY = self.y - controllers[i].y,
// Multiply each of the distances by itself
// Squareroot that number, which gives you the distance between the two disc's
distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY),
// Added the two disc radius together
addedRadius = self.radius + controllers[i].radius;
// Check to see if the distance between the two circles is smaller than the added radius
// If it is then we know the circles are overlapping
if (distance <= addedRadius) {
var newVelocityX = (self.velocityX * (self.mass - controllers[i].mass) + (2 * controllers[i].mass * controllers[i].velocityX)) / (self.mass + controllers[i].mass);
var newVelocityY = (self.velocityY * (self.mass - controllers[i].mass) + (2 * controllers[i].mass * controllers[i].velocityX)) / (self.mass + controllers[i].mass);
self.velocityX = newVelocityX;
self.velocityY = newVelocityY;
self.x = self.x + newVelocityX;
self.y = self.y + newVelocityY;
}
}
}
更新
拆解了一个圆形碰撞演示并尝试实现他们的碰撞公式。下面是代码,可以向前和向下撞击冰球/圆盘,但出现问题时无法向后或向上撞击。
this.discCollision = function() {
for (var i = 0; i < controllers.length; i++) {
// Minus the x pos of one disc from the x pos of the other disc
var distanceX = self.x - controllers[i].x,
// Minus the y pos of one disc from the y pos of the other disc
distanceY = self.y - controllers[i].y,
// Multiply each of the distances by itself
// Squareroot that number, which gives you the distance between the two disc's
distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY),
// Added the two disc radius together
addedRadius = self.radius + controllers[i].radius;
// Check to see if the distance between the two circles is smaller than the added radius
// If it is then we know the circles are overlapping
if (distance < addedRadius) {
var normalX = distanceX / distance,
normalY = distanceY / distance,
midpointX = (controllers[i].x + self.x) / 2,
midpointY = (controllers[i].y + self.y) / 2,
delta = ((controllers[i].velocityX - self.velocityX) * normalX) + ((controllers[i].velocityY - self.velocityY) * normalY),
deltaX = delta*normalX,
deltaY = delta*normalY;
// Rebound puck
self.x = midpointX + normalX * self.radius;
self.y = midpointY + normalY * self.radius;
self.velocityX += deltaX;
self.velocityY += deltaY;
// Accelerate once hit
self.accelerationX = 3;
self.accelerationY = 3;
}
}
}