簡體   English   中英

如何在2D碰撞檢測中正確解決碰撞的位置?

[英]How do I resolve a collision's position properly in 2D collision detection?

我當前的實現如下所示:

if (shapesCollide) {
    if (velocity.y > 0) entity.position.y = other.position.y - entity.size.y;
    else entity.position.y = other.position.y + other.size.y;

    velocity.y = 0;

    if (velocity.x > 0) entity.position.x = other.position.x - entity.size.x;
    else entity.position.x = other.position.x + other.size.x;

    velocity.x = 0;
}

但是,這會導致在兩個軸上都發生移動時產生怪異的處理-例如,使entity向下移動到object的左側,然后將其移動以與object碰撞,將正確解決水平碰撞,但會破壞垂直運動。

我以前只是去了

if (shapesCollide) {
    position = oldPosition;
    velocity = { 0, 0 };
}

但是,這導致了另一個多軸問題:如果我的entity停在object上方,則它將無法移動,因為重力引起的移動將不斷抵消兩個速度。 我還嘗試過分別考慮兩個軸,但這會在僅考慮兩個速度時發生碰撞時導致問題。

解決兩軸碰撞的最佳解決方案是什么?

我假設可以將實體視為或多或少是圓形的,並且尺寸是實體的半徑?

我們可能需要一些向量數學來解決這個問題。 (我不知道c ++中的平方根函數,因此請注意sqrt。)嘗試以此替換掉if(shapesCollide)內的代碼,然后看它如何為您工作。

float rEntity = sqrt(entity.size.x * entity.size.x + entity.size.y * entity.size.y);
float rOther = sqrt(other.size.x * other.size.x + other.size.y * other.size.y);

float midX = (entity.position.x + other.position.x) / 2.0;
float midY = (entity.position.y + other.position.y) / 2.0;

float dx = entity.position.x - midX;
float dy = entity.position.y - midY;
float D = sqrt(dx * dx + dy * dy);

rEntityrOther是對象的半徑,並且midXmidY是它們的中心坐標。 dxdy是從實體到中心的距離。

然后做:

entity.position.x = midX + dx * rEntity / D;
entity.position.y = midY + dy * rEntity / D;

other.position.x = midX - dx * rOther / D;
other.position.y = midY - dy * rOther / D;

您可能應該檢查D是否不為0,如果是,則僅設置dx = 1,dy = 0,D = 1或類似的值。

您還應該這樣做:

velocity.x = 0;
velocity.y = 0;

如果您希望實體停止。

為了更准確地建模,您還可以嘗試以下操作:

float rEntity = sqrt(entity.size.x * entity.size.x + entity.size.y * entity.size.y);
float rOther = sqrt(other.size.x * other.size.x + other.size.y * other.size.y);

float midX = (entity.position.x * rOther + other.position.x * rEntity) / (rEntity + rOther);
float midY = (entity.position.y * rOther + other.position.y * rEntity) / (rEntity + rOther);

float dxEntity = entity.position.x - midX;
float dyEntity = entity.position.y - midY;
float dEntity = sqrt(dxEntity * dxEntity + dyEntity * dyEntity);

float dxOther = other.position.x - midX;
float dyOther = other.position.y - midY;
float dOther = sqrt(dxOther * dxOther + dyOther * dyOther);

entity.position.x = midX + dxEntity * rEntity / dEntity;
entity.position.y = midY + dyEntity * rEntity / dEntity;

other.position.x = midX + dxOther * rOther / dOther;
other.position.y = midY + dyOther * rOther / dOther;

在考慮半徑時找到中點。 但我不能保證那行得通。 同樣,最后添加的符號也很重要。

我希望這會有所幫助(並能奏效)。 讓我知道是否有不清楚的地方。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM