簡體   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