2012-05-11 7 views
1

私は数週間、このゲームをLWJGLで作業しています。私がジャンプする能力を加えて以来、上向きの衝突は私に多くの問題をもたらしてきました。Javaのゲームにおける2D衝突の問題

ゲームは、2Dタイルベースのサイドローラです。全体的に、プレーヤーがジャンプするときを除いて、衝突はほぼ完璧です。最初は "ああ、ジャンプの仕組みを変えるだけでいいのかもしれない"と思ったが、プレイヤーにあるx座標が渡されたときにしか起こらないことに気づいた。

実際の問題自体:あるx座標を渡したときにジャンプした場合、それらはタイルを通過し、トップコリジョンのテストではfalseを返します。

これは、全体のプレーヤーのクラスです:

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の値を倍精度から整数にキャストして、上、下、左、右の四角形で使用するときに何かする必要があるという疑いがあります。

再びEDIT: これは重要な場合、私は知らないが、私はこのような衝突をチェックされています:(これは「ブート」クラスである。)

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

をあなたがプレーヤーを渡しているのはなぜintoCollision?プレーヤーを渡すべきではなく、代わりにcheckCollisionメソッドを呼び出すプレーヤーのメンバーを使用するように思えます。私はそれがあなたのためにいくつかの混乱につながるかもしれないと思う。次のようになります。

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

これはジャンプ中に交差したブロックの下にプレーヤーをプッシュしようとしているようです。その場合、それはちょうど

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

私は関数の引数からプレーヤーを削除し、あなたが得るものを見てプレイヤーを削除します。希望が役立ちます。あなたは、もはや関数にプレーヤーを渡すことはできません

EDIT

コメント状態。正確な実装についてはわかりませんが、私が典型的に見たゲームは次のようになります:

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