Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/91.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于Gravity-JavaScript的二维碰撞检测_Javascript_Html_Canvas_2d_Collision Detection - Fatal编程技术网

基于Gravity-JavaScript的二维碰撞检测

基于Gravity-JavaScript的二维碰撞检测,javascript,html,canvas,2d,collision-detection,Javascript,Html,Canvas,2d,Collision Detection,我试图用HTML5画布制作一个游戏来娱乐,但由于重力的原因,我很难检测到两个精灵之间的碰撞 在我的Player类中有一个tick方法,在每个tick上,分别通过其velocityX和velocityY增加Player的x和y坐标。然后,我把重力加到速度上。然后我想检查播放器和屏幕上的块之间的冲突,这些块在屏幕底部排列并存储在一个数组中 代码如下: Player.prototype.tick = function() { this.x += this.velocityX; thi

我试图用HTML5画布制作一个游戏来娱乐,但由于重力的原因,我很难检测到两个精灵之间的碰撞

在我的Player类中有一个tick方法,在每个tick上,分别通过其velocityX和velocityY增加Player的x和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,使播放器停止垂直移动。但是,在下一个滴答声中,由于重力作用,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坐标,而只是设置速度,因为我认为这样会减少故障

我还尝试为碰撞设置布尔值,以便在检测到碰撞但没有任何效果时不添加重力。有没有一个标准的,正确的方法来做这件事?请帮忙

此外,为了提高效率,我真的希望它只通过循环来检查碰撞,如果玩家正在移动,但我不确定如何进行,因为由于重力,速度总是高于零

谢谢


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

为什么我在碰撞时将velocityY设置为0,并将玩家的位置固定在块的正上方,它会起到一定的作用,除非站在木块上时,由于重力的作用,会不断检测到碰撞。错误的从物理学的角度来看,这是有道理的。嗯,我想这是有道理的,这是我目前在游戏中使用的,但效果不好。我认为可能一次检测到多个碰撞,或者有时检测到错误的碰撞。Idk