我正在尝试使用 HTML5 画布制作游戏以获得乐趣,但由于重力,我无法检测到两个精灵之间的碰撞。
我的 Player 类中有一个 tick() 方法,在每个刻度上,玩家的 x 和 y 坐标分别通过它的 velocityX 和 velocityY 递增。然后,我将重力添加到velocityY。然后我想检查玩家和屏幕上的块之间的碰撞,这些块排列在屏幕底部并存储在一个数组中。
这是代码:
Player.prototype.tick = function() {
this.x += this.velocityX;
this.y += this.velocityY;
this.velocityY += GRAVITY;
var blocks = world.getOnScreenBlocks();
for (var i=0; i<blocks.length; i++) {
//Check for collision of this object (Player) with blocks[i]
}
}
}
我花了几个小时试图让碰撞检测工作但放弃了。我知道如何将玩家的坐标与每个块的坐标进行比较以检测碰撞,但问题是在发生碰撞时进行调整。
如果我检测到块顶部的碰撞,我可以将velocityY 设置为0,导致玩家停止垂直移动。然而,在下一个滴答声中,速度 Y 将增加,因为重力被添加到它上面,导致再次检测到碰撞,并且玩家在许多滴答声后慢慢穿过块。
如果我在碰撞时将velocityY 设置为0 并将玩家的位置固定在块的上方,它会有点工作,除非在站在块上时会检测到不断的碰撞,因为重力试图将它向下推。
这是我最接近在块的所有四个侧面进行碰撞检测的方法:
var blocks = world.getOnScreenBlocks();
for (var i=0; i<blocks.length; i++) {
var block = blocks[i];
var left1 = this.x;
var left2 = block.getX();
var right1 = this.x + this.sprite.getWidth();
var right2 = block.getX() + block.getSprite().getWidth();
var top1 = this.y - this.sprite.getHeight();
var top2 = block.getY() - block.getSprite().getHeight();
var bottom1 = this.y;
var bottom2 = block.getY();
//Check for collision at top
if (this.velocityY > 0) {
if (left1 < right2 && right1 > left2 && bottom1 >= top2 && bottom1 <= bottom2) {
this.y = top2;
this.velocityY = 0;
}
}
//Check for collision at bottom
else if (this.velocityY < 0) {
if (left1 < right2 && right1 > left2 && top1 <= bottom2 && top1 >= top2) {
this.y = bottom2 + this.sprite.getHeight();
this.velocityY = 0;
}
}
//Check for collision on right
if (this.velocityX > 0) {
if (top1 < bottom2 && bottom1 > top2 && right1 >= left2 && right1 <= right2) {
this.x = left2 - this.sprite.getWidth();
this.velocityX = 0;
}
}
//Check or collision on left
else if (this.velocityX < 0) {
if (top1 < bottom2 && bottom1 > top2 && left1 <= right2 && left1 >= left2) {
this.x = right2;
this.velocityX = 0;
}
}
}
这有点工作,但确实有问题。我真的想避免在发生碰撞时设置精灵的 x 和 y 坐标,而只设置速度,因为我认为这样会减少故障。
我还尝试为碰撞设置布尔值,以便在检测到碰撞但没有任何效果时不增加重力。有没有标准的、正确的方法来做到这一点?请帮忙。
另外,为了提高效率,我真的希望它只通过循环来检查玩家是否在移动时是否发生碰撞,但我不确定如何,因为由于重力,velocityY 将始终高于零。
谢谢。
编辑:我应该在上面的第二个示例中包含这一点,玩家和块的 x 和 y 坐标基于左下角,而不是典型的左上角。我这样做是因为我的精灵高度不同,我想让碰撞在精灵脚与地面碰撞的底部起作用。