1

我正在尝试使用 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 坐标基于左下角,而不是典型的左上角。我这样做是因为我的精灵高度不同,我想让碰撞在精灵脚与地面碰撞的底部起作用。

4

0 回答 0