繁体   English   中英

具有重力的2D碰撞检测-JavaScript

[英]2D Collision Detection With Gravity - JavaScript

我正在尝试使用HTML5画布制作游戏,但由于重力原因,我无法检测到两个精灵之间的碰撞。

我的Player类中有一个tick()方法,在每个刻度上,分别将其x和y坐标分别按其velocityX和velocityY递增。 然后,将重力添加到速度Y。 然后,我要检查播放器和屏幕上的块之间的冲突,这些块在屏幕底部对齐并存储在数组中。

这是代码:

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添加到了速度Y上,因此会增加速度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坐标设置为sprite,而只是设置速度,因为我认为这样会减少毛刺。

我还尝试为碰撞设置布尔值,以便在检测到碰撞但不起作用的情况下不增加重力。 是否有标准,适当的方法来做到这一点? 请帮忙。

另外,为了提高效率,我真的希望它只循环检查玩家是否在移动是否发生碰撞,但是我不确定这样做的原因,因为在重力作用下,speedY总是大于零。

谢谢。

编辑:我应该在上面的第二个示例中包括该播放器和块x和y坐标是基于左下角而不是典型的左上角。 我之所以这样做是因为我的精灵的高度不同,所以我想让碰撞在精灵脚与地面碰撞的底部起作用。

您是否知道isGrouned变量 ,该变量会知道何时在您的播放器上施加重力,因此只有在isGrounded == false时您才能施加重力。

您处于向量环境中,可以进行一种推测性碰撞( 在此处 ),这很难理解,但是您只需要知道玩家的n + 1位置并检查他是否会发生碰撞。

如果您可以阅读有关碰撞的法语文章 ,那么在许多情况下它可能会很有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM