我正在尝试使用HTML5画布制作游戏以获得乐趣,但由于重力,我无法检测两个精灵之间的碰撞。
我的Player类中有一个tick()方法,在每个刻度线上,分别通过velocityX和velocityY增加玩家的x和y坐标。然后,我将gravity重力加到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,从而使玩家停止垂直移动。但是,在下一个勾选中,由于GRAVITY被添加到它上面,velocityY将增加,导致再次检测到碰撞,并且玩家在许多滴答之后慢慢地通过该块。
如果我在碰撞时将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坐标,并设置速度,因为我觉得这样会不那么毛刺。
我也试过设置布尔值来进行碰撞,以便在检测到碰撞但没有任何作用时不添加重力。有没有一种标准的,正确的方法呢?请帮忙。
另外,为了提高效率,我真的希望它只是通过循环来检查玩家是否移动时的碰撞,但我不确定如何因为由于重力导致速度Y总是高于零。
感谢。
编辑:我应该在上面的第二个例子中包括,播放器和块x和y坐标基于左下角而不是典型的左上角。我之所以这样做是因为我的精灵高度不同,我希望在精灵脚与地面碰撞的底部发生碰撞。
答案 0 :(得分:0)
你是否知道 isGrouned var会知道何时在你的播放器上施加重力,只有当 isGrounded == false 时才能应用重力。
你处于矢量环境中,你可以进行一种投机碰撞(here),这很难理解,但你只需要知道你的玩家的n + 1位置和chekc if他会碰撞。
如果您可以阅读有关碰撞的this french article,那么在许多情况下它都很有用。