2012-04-29 211 views
5

我正在使用瓷磚製作java遊戲。我遇到碰撞元件有問題。我爲地圖上的每個圖塊定義矩形,併爲玩家定義另一個矩形。我遇到的麻煩是知道玩家在碰到矩形時從哪邊來,然後將玩家從玩家出發的方向推開。我已經制定了一個方法來檢查角色在矩形內的多少,所以它可以知道要推出多少角色,但我無法弄清楚如何判斷角色來自哪個角色。Java瓷磚遊戲 - 碰撞檢測

這裏是我目前的碰撞methoe - 記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; 
      } 
    } 
} 

任何幫助,將不勝感激

感謝

回答

2

保持你的性格兩個位置 - 它的位置(截至最後一幀,移動等)以及您想要移動它的位置。如果你沒有檢測到碰撞,那麼只能移動它 - 如果你不允許損壞狀態,你不必修復它。

編輯:collision方法應該是boolean - 它應該之前完成實際移動人物,像

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

EDIT2:以前只工作了一小步,如果你需要一個部分移動,你真的需要知道角色的原始位置,如move(originalPosition, desiredPosition, tile),在那裏你可以從originalPositiontile推導出方向。

重點是,在你有一個有效的位置之前,你並沒有實際移動角色。

+0

這將導致奇怪的情況,這取決於時間間隔。 – Matzi 2012-04-29 15:32:36

+0

@Matzi在執行某些用戶命令之前,並不是真正的驗證事情 - 如果它不驗證,您可以執行自定義處理。 – jmruc 2012-04-29 15:36:30

+0

@KirilRaychev我真的不明白你想說什麼 – grimrader22 2012-04-29 15:39:58

1

首先,任何雪碧(字符,這裏的瓷磚)應該有四個成員:XPOS,yPos,XVEC,YVEC。考慮到這一點,你知道角色的位置,並將在下一幀。

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

也看看你的代碼,你應該提高命題(例如,你檢查如果(rect1.intersects(RECT2))在四如果語句)。相反,只檢查相交(),並檢查每個可能的情況(左,右,頂部,底部命中)。

最後,該衝突方法應接受2個精靈的對象(例如,sprite1sprite2),然後檢查該相交()方法,同時考慮到精靈和的原始位置其向量。如果精靈在新位置相交,則相應地反轉對象的矢量。

+0

xVec和yVec變量代表什麼? – grimrader22 2012-04-30 15:42:43

+0

對不起,我不太清楚,那些精靈的方向向量(你也可以使用Vector2f或Point2D)。該值可以解釋爲精靈在每個方向上的速度。因此,如果角色恰好從左側擊中瓦片,則xVec是正值,並且yVec是0;在命中之後,xVec應該具有相同的值,但現在爲負值。讓我知道你是否需要任何幫助。 – 2012-04-30 16:17:38

+0

我不太明白你在說什麼,對不起,如果我是愚蠢的。 xand y Vecs會是速度嗎? – grimrader22 2012-05-01 00:52:08

1

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

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

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

  3. 現在你可以比較的Rx,RY,SX,SY,以確定哪一方是SX和Rx的SY和Ry

  4. 爲前:

    if Sx < Rx then 
        Sx = left side of Rx 
    
1

與掙扎這是我自己,但經過一些思考,這個檢查可以通過讓所有的實體在列表中完成,在我的代碼中,我必須阻止玩家移動塊。所有塊都在列表中。現在,當檢查玩家位置時,我創建一個新的矩形,並且將玩家的位置向前移動到更新將發生的下一幀的方向,如果矩形與那個方向的更新相交不會發生。我的繼承人此代碼:

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; 
     } 
    } 

collisionWithBlocks():

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,和改變我的代碼,但有足夠的瞭解這一點。 在你的情況下,我建議把實體放在一個List中,然後像我一樣檢查。