簡體   English   中英

Java Tile Game-碰撞檢測

[英]Java Tile Game - Collision Detection

我正在使用圖塊制作Java游戲。 我在碰撞元素方面遇到麻煩。 我為地圖上的每個圖塊定義了矩形,為播放器定義了另一個矩形。 我遇到的麻煩是,當玩家碰到矩形時,知道玩家來自哪一側,然后將玩家朝玩家所在的方向推開。 我已經制作了一種方法,可以檢查矩形中有多少字符,因此可以知道將其推出多少,但是我不知道如何知道字符來自哪一側。

這是我當前的碰撞方法-注意rect1是角色,rect2是磁貼

public void collision(Rectangle rect1, Rectangle rect2) {
    float xAdd;
    float xAdd2;
    float yAdd;
    float yAdd2;

    boolean hitRight = false;
    boolean hitLeft = false;
    boolean hitTop = false;
    boolean hitBot = false;

    Vector2f rect1Origin = new Vector2f(rect1.x, rect1.y);
    Vector2f rect2Origin = new Vector2f(rect2.x, rect2.y);
    Vector2f rect1Mid = new Vector2f((rect1.x + rect1.width) / 2,(rect1.y + rect1.height) / 2);
    Vector2f rect2Mid = new Vector2f((rect2.x + rect2.width) / 2,(rect2.y + rect2.height) / 2);

    Vector2f rect1A = new Vector2f(rect1Origin.x + rect1.width, rect1.y);
    Vector2f rect1B = new Vector2f(rect1Origin.x, rect1Origin.y+ rect1.height);
    Vector2f rect1C = new Vector2f(rect1Origin.x + rect1.width,rect1Origin.y + rect1.height);

    Vector2f rect2A = new Vector2f(rect2Origin.x + rect2.width, rect2.y);
    Vector2f rect2B = new Vector2f(rect2Origin.x, rect2Origin.y
            + rect2.height);
    Vector2f rect2C = new Vector2f(rect2Origin.x + rect2.width,
            rect2Origin.y + rect2.height);

    xAdd = rect2C.x - rect1B.x;
    xAdd2 = rect1C.x - rect2B.x;

    yAdd = rect2A.y - rect1B.y;
    yAdd2 = rect2C.y - rect1A.y;


    if (rect1Mid.y < rect2Mid.y) {
        if (rect1.intersects(rect2)) {
            y_pos += yAdd;
        }
    }
    if (rect1Mid.y > rect2Mid.y) {
        if (rect1.intersects(rect2)) {
            System.out.println(yAdd2);
            y_pos += yAdd2;
        }

    }
    if(rect1Mid.x > rect2Mid.x){
        if(rect1.intersects(rect2)){
            hitRight = true; x_pos += xAdd;
        }
    } 
    if(rect1Mid.x< rect2Mid.x){ 
          if(rect1.intersects(rect2)) {
              x_pos += -xAdd2;
          } 
    }
}

任何幫助將不勝感激

謝謝

保持角色的兩個位置-角色的位置(從上一幀開始,移動等)以及您想將其移動到的位置。 然后僅在沒有檢測到碰撞的情況下才移動它-如果您不允許出現損壞的狀態,則不必修復它。

編輯: collision方法應該是boolean -應該實際移動角色之前完成,例如

if (!collision(character, tile))
{
    doMove(character);
}
else
{
    //custom handling if required
}

Edit2:前一個僅適用於一小步,如果需要局部移動,則確實需要知道角色的原始位置,例如move(originalPosition, desiredPosition, tile) ,您可以在其中從originalPositiontile

要點是,在為角色指定有效位置之前,您實際上並未移動它。

首先,任何Sprite (此處的字符和圖塊)應具有四個成員:xPos,yPos,xVec,yVec。 考慮到這一點,您將知道角色在下一幀中將要在哪里。

sprite.xPos += sprite.xVec;
sprite.yPos += sprite.yVec;

還請看一下您的代碼,您應該改進命題(例如,檢查四個if語句中的if(rect1.intersects(rect2)) )。 相反,僅檢查一次intersects() ,並在內部檢查每種可能的情況(左,右,頂部,底部命中)。

最后,碰撞方法應該接收2個Sprite對象(例如, sprite1sprite2 ),然后在考慮到sprite及其向量的原始位置的情況下,檢查intersects()方法。 如果精靈在新位置相交,則可以相應地反轉對象的矢量。

假設您可以檢測到與代碼的沖突。 這是一種確定角色相對於矩形對象的位置的方法。

  1. 找到矩形的中點。 (Rx,Ry)。

  2. 找到角色精靈的中間點。 (Sx,Sy)。

  3. 現在,您可以比較Rx,Ry,Sx和Sy,確定Rx和Ry的Sx和Sy在哪一側

  4. 例如:

     if Sx < Rx then Sx = left side of Rx 

我本人為此而苦苦掙扎,但經過一番思考,可以通過將所有實體都放在一個列表中來完成此檢查,在我的代碼中,我不得不阻止播放器在各個塊之間移動。 所有塊都在列表中。 現在,當檢查玩家位置時,我將創建一個新的Rectangle並將玩家位置向前一幀朝着下一幀更新的方向進行,如果矩形與該方向相交的更新不會發生。 這是我的代碼:

    if (isKeyPressed(KeyEvent.VK_LEFT)) {
        if(!collisionWithBlocks(1)){
            pl.x = pl.x - updatePlayerPosition;
        }
    }
    if (isKeyPressed(KeyEvent.VK_RIGHT)) {
        if(!collisionWithBlocks(0)){
            pl.x = pl.x + updatePlayerPosition;
        }
    }
    if (isKeyPressed(KeyEvent.VK_UP)) {
        if(!collisionWithBlocks(3)){
            pl.y = pl.y - updatePlayerPosition;
        }
    }
    if (isKeyPressed(KeyEvent.VK_DOWN)) {
        if(!collisionWithBlocks(2)){
            pl.y = pl.y + updatePlayerPosition;
        }
    }

crashWithBlocks():

public boolean collisionWithBlocks(int side){
    for(Block b : main.blocks){
        Rectangle block = b.getBounds();
        Rectangle player = null;
        if(side == 0){
            player = new Rectangle(pl.x + updatePlayerPosition, pl.y, pl.getWidth(), pl.getHeight());
        } else if(side == 1){
            player = new Rectangle(pl.x - updatePlayerPosition, pl.y, pl.getWidth(), pl.getHeight());
        } else if(side == 2){
            player = new Rectangle(pl.x, pl.y + updatePlayerPosition, pl.getWidth(), pl.getHeight());
        } else if(side == 3){
            player = new Rectangle(pl.x, pl.y - updatePlayerPosition, pl.getWidth(), pl.getHeight());
        }

        if(player.intersects(block)){
            return true;
        }
    }

    return false;
}

updatePlayerPosition為2,並且在我的代碼中進行了更改,但足夠了。 對於您的情況,我建議將實體放入列表中,然后像檢查一樣進行檢查。

暫無
暫無

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

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