2012-05-11 186 views
1

我一直在用LWJGL開發這個遊戲幾周。自從我增加跳躍能力以來,向上碰撞一直給我帶來很多問題。Java遊戲中的2D碰撞問題

遊戲是2D基於區塊的sidescroller的。總的來說,除了玩家跳躍之外,碰撞幾乎是完美的。起初我以爲「哦,也許我只需要改變跳躍機制」,但後來我意識到只有當玩家通過某個x座標時纔會發生。

現在,對於實際問題本身:如果通過一定的x座標當玩家跳躍,他們將通過瓷磚和測試頂級碰撞返回false。

這是整個Player類:

package Minecraft2D; 

import static Minecraft2D.World.BLOCK_SIZE; 
import Minecraft2D.Tools.Tools; 
import Minecraft2D.UI.Inventory; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 

import static Minecraft2D.Boot.*; 

import org.lwjgl.util.Rectangle; 
import org.newdawn.slick.opengl.Texture; 
import org.newdawn.slick.opengl.TextureLoader; 

public class Player { 

private float x; 
private float y; 
public int width = 32; 
public int height = 50; 
private float DX = 0; 
private float DY = 0; 
private Texture left = null; 
private Texture right = null; 
Texture texture = null; 

public boolean direction[] = { false, false, false, false }; 
public boolean collision = false; 
public boolean ground = false; 
public boolean jump = false; 
public boolean top = false; 

public Player(float x, float y) { 
    this.x = x; 
    this.y = y; 
    try { 

     this.left = TextureLoader.getTexture("PNG", new FileInputStream(new File(path + "player_left.png"))); 
     this.right = TextureLoader.getTexture("PNG", new FileInputStream(new File(path + "player_right.png"))); 
     this.texture = this.right; 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

public void draw() { 
    Tools.drawTexture((int)x, (int)y, width, height, texture); 
} 

public void checkCollision(Player player, Block block) { 

    if (player.getY() < block.getY() + BLOCK_SIZE && player.getX() < block.getX() + BLOCK_SIZE && player.getY() + this.height > block.getY() && player.getX() + this.width > block.getX() && block.getType() != BlockType.AIR) { 
     Rectangle top = new Rectangle(); 
     top.setBounds((int) player.x + 4, (int) player.y + 1, this.width - 8, 1); 
     Rectangle bottom = new Rectangle(); 
     bottom.setBounds((int) player.x + 4, (int) player.y + this.height, this.width - 8, 1); 
     Rectangle left = new Rectangle(); 
     left.setBounds((int) player.x, (int) player.y + 1, 1, this.height - 5); 
     Rectangle right = new Rectangle(); 
     right.setBounds((int) player.x + player.width, (int) player.y + 1, 1, this.height - 5); 
     Rectangle blok = new Rectangle(); 
     blok.setBounds((int) block.getX(), (int) block.getY(), BLOCK_SIZE, BLOCK_SIZE); 
     if (bottom.intersects(blok)) { 
      player.setY((block.getY() - this.height - 1)); 
      ground = true; 
      jump = false; 
     } else if (top.intersects(blok)) { 
      DY = 0; 
      this.top = true; 
      y -= (player.y) - (block.getY() + BLOCK_SIZE); 
     } 
     if (!top.intersects(blok)) { 
      if (left.intersects(blok)) { 
       player.setX(block.getX() + this.width); 
      } else if (right.intersects(blok)) { 
       player.setX(block.getX() - this.width); 
      } 
     } 

    } else { 
     collision = false; 
     ground = false; 
    } 


    if (!collision && !jump) { 
     setDY(.003f); 
    } 
    if (ground && !jump) { 
     DY = 0; 
    } 

    if (jump && DY < 0.003f) { 
     DY += 0.0001; 
    } else { 
     // jump = false; 
    } 

    if (top) { 
     DY = 0f; 
     top = false; 
    } 

    x += DX; 
    y += DY; 

    if (x > Boot.SCREEN_WIDTH) { 
     x = 0; 
    } 
    if (x < 0) { 
     x = Boot.SCREEN_WIDTH; 
    } 
} 

public float getX() { 
    return x; 
} 

public void setX(float x) { 
    this.x = x; 
} 

public float getY() { 
    return y; 
} 

public void setY(float y) { 
    this.y = y; 
} 

public void setDX(float dx) { 
    this.DX = dx; 
} 

public void setDY(float dy) { 
    this.DY = dy; 
} 

public void setJump() { 
    if (!jump) { 
     jump = true; 
     ground = false; 
     DY = -0.13f; 
     y -= 1; 
    } 
} 

public void setTexture(int tex) { 
    if (tex == 0) { 
     this.texture = this.left; 
    } 
    if (tex == 1) { 
     this.texture = this.right; 
    } 
} 

} 

==============

編輯:我不知道爲什麼,但我的性格更接近移動到地圖的0 x座標,角色的y座標增長非常緩慢。這可能與我收到的問題有關。我正在研究它,並且我懷疑當我將玩家的x和y值從雙打轉爲整數時,可能需要做些事情以便在頂部,底部,左側和右側矩形中使用。再次

編輯: 我不知道這是否重要,但我一直在檢查碰撞是這樣的:(這是在「引導」級)。

private void checkCollision() { 
      for (int x = 0; x < BLOCKS_WIDTH - 1; x++) { 
       for (int y = 0; y < BLOCKS_HEIGHT - 1; y++) { 
       Block blk = grid.getAt(x, y); 
       player.checkCollision(blk); 
      } 
     } 
} 
+0

什麼X座標? – Tharwen

+0

那麼,大約100以上的任何地方都可以正常工作,但任何情況都會低於100,我會遇到這個問題。 – TheElephantSeal

+1

警告:Player類永遠不會將「collision」設置爲「true」。 – Gunslinger47

回答

4

你爲什麼要傳遞一個球員進入checkCollision?看起來你不應該傳遞一個玩家,而是使用調用checkCollision方法的玩家的成員。我認爲這可能會導致你的困惑。如:

y -= (player.y) - (block.getY() + BLOCK_SIZE); 

這就像你正在試圖把球員塊低於B/C他們在跳躍過程中相交了。如果是這樣的話,它應該只是

y = (block.getY() + BLOCK_SIZE); 

我會從功能參數刪除播放器和重寫功能,看看你會得到什麼。希望有所幫助。

編輯

您的評論指出,可以不再通過玩家進入功能。不知道您的具體實現,但這裏是遊戲,我通常看到的樣子:

public class Player 
{ 
    private int x, y, dx, dy; 

    public void checkCollision(Block block) 
    { 
     if (isTopCollision(block)) 
     fall(block.getY() + block.getHeight()); 
    } 

    private boolean isTopCollision(Block block) 
    { 
     return y > block.getY() + block.getSize() && y < block.getY(); 
    } 

    private void fall(int adjustedY) 
    { 
     y = adjustedY; 
     top = true; 
     dy = 0; 
     // etc 
    } 
} 

public class MyGame 
{ 
    public void gameloop() 
    { 
     for (Block b : blocks) 
     player.checkCollision(b); 
    } 
} 
+0

謝謝,這解決了我的問題:) – TheElephantSeal

+0

嗯......這很奇怪。現在我不再將玩家傳遞給checkCollision方法,遊戲忽略了關於320 x coord的所有碰撞。頂部的碰撞再次發生,以及... – TheElephantSeal

+0

看我上面編輯 – jeff