2016-06-22 20 views
0

Slick2Dは放棄されていますが、私はこのライブラリで快適な型コードを感じています。Slick2Dのタイルマップとの衝突

Slick2dについても同じことが起こりました。今、私は解決できない問題があり、私はこの問題を2週間持っています。私のゲームでは、TileMapがあります。そこでは、「ソリッド」レイヤーに属するすべての要素が見つかり、同じ位置に四角形を描いて物理学を処理します。問題は、私のキャラクター(アニメーションの量です)が、私のタイルマップのソリッドレイヤーに属する矩形を検出しないことです。

forループを使用すると、文字が四角形を検出しません。しかし、ifsステートメントを使ってすべてのrectをチェックすれば、衝突は機能します。

誰もがなぜこのようなことを知っていますか?

私の英語についてはごめんなさい>。 <

助けが必要です。

ありがとうございます!

編集:ここで私の衝突に関するコードです。タイルマップが含まれてい

レベルクラス:物理学についての属性を持つ

public class Level extends TiledMap{ 

private int tileId; 
private int layerIndex; 
private boolean solids[][]; 
private Shape rects[][]; 

public Level(String path) throws SlickException { 
    super(path); 
    solids = new boolean [super.getWidth()][super.getHeight()]; 
    rects = new Rectangle[super.getWidth()][super.getHeight()]; 
    tileId=0; 
    layerIndex=0; 
} 

public int getTileId() { 
    return tileId; 
} 

public int getLayerIndex() { 
    return layerIndex; 
} 

public boolean[][] getSolids() { 
    return solids; 
} 

public Shape[][] getRects() { 
    return rects; 
} 
public Shape getSingleRect(int i, int j){ 
    return rects[i][j]; 
} 

public void setTileId(int tileId) { 
    this.tileId = tileId; 
} 

public void setLayerIndex(String layerName) { 
    this.layerIndex = super.getLayerIndex(layerName); 
} 

public void setSolid(int i, int j, boolean solid) { 
    this.solids[j][i] = solid; 
} 

public void setRect(int i, int j, Shape rect) { 
    this.rects[j][i] = rect; 
} 

//other methods 
public void printSolidMatrix(){ 
    System.out.println("SOLID MATRIX"); 
    for(int i=0;i<super.getWidth();i++){ 
     for(int j=0;j<super.getHeight();j++){ 
      System.out.print(solids[j][i]+" "); 
     } 
     System.out.println(); 
    } 
} 

public void drawDebugRects(Graphics g){ 
    layerIndex = this.getLayerIndex(); 
    tileId = 0; 
    for(int i=0;i<this.getWidth();i++){ 
     for(int j=0;j<this.getHeight();j++){ 
      tileId = this.getTileId(j, i, layerIndex); 
      g.draw(rects[j][i]); 
     } 
    } 
} 
public boolean collidesWith(Shape s){ 
    for(int i=0;i<this.getWidth();i++){ 
     for(int j=0;j<this.getHeight;j++){ 
      if(s.intersects(rects[j][i]) && solids[j][i]){ 
      } 
     } 
    } 
    return false; 
} 

}

マイプレイヤークラス:私は上の

public class Player{ 

private Level map; 
private float x; 
private float y; 
private boolean falling; 

private Shape bounds; 

public Player(Level map) throws SlickException{ 

    falling = true; 
    x=0; 
    y=500; 
    this.map = map; 
    this.setBounds(this.x, this.y, this.x*32, this.y*32); 
} 
public float getX() { 
    return x; 
} 
public void increaseX(float x) { 
    this.x += x; 
} 
public float getY() { 
    return y; 
} 
public void increaseY(float y) { 
    this.y += y; 
} 
public Shape getBounds() { 
    return bounds; 
} 
public void setBounds(float x, float y, float width, float height) { 
    bounds = new Rectangle(x, y, this.currentAnimation.getWidth(), this.currentAnimation.getHeight()); 
} 
public boolean isFalling() { 
    return falling; 
} 
public void setFalling(boolean falling) { 
    this.falling = falling; 
} 

public void render(GameContainer gc, Graphics g) throws SlickException { 
    this.getCurrentAnimation().draw(this.getX(), this.getY()); 
    this.setBounds(this.getX(), this.getY(), this.getCurrentAnimation().getWidth(),this.getCurrentAnimation().getHeight()); 
    g.draw(this.getBounds()); 
} 
public void update(GameContainer gc, int delta) throws SlickException { 
    this.getCurrentAnimation().update(delta); 
    //character movement 
      if(gc.getInput().isKeyDown(Input.KEY_D)){ 
       this.setRight(true); 
       this.setCurrentAnimation(this.getWalkAnimation()); 
       this.increaseX(2.5f); 
      } 

      else if(gc.getInput().isKeyDown(Input.KEY_A)){ 
       this.setRight(false); 
       this.setCurrentAnimation(this.getWalkAnimationReverse()); 

       if(this.getX()<0){ 

       }else{ 
        this.increaseX(-2.5f); 
       } 
      } 
      else{ 
       if(!this.isRight()){ 
        this.setCurrentAnimation(this.getStandAnimationReverse()); 
       }else{ 
        this.setCurrentAnimation(this.getDefaultAnimation()); 
       } 
      }  
} 

}

現在のレベル働く:

public class IntroStage extends BasicGameState{ 


Level map; 
Player p; 


@Override 
public void init(GameContainer gc, StateBasedGame sbg) throws SlickException { 
    initMap(); 
    p = new Player(map); 
    //map.printSolidMatrix(); 
} 

@Override 
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException { 
    map.render(0, 0); 
    map.drawDebugRects(g); 
    p.render(gc, g); 
} 

@Override 
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException { 
    p.update(gc, delta); 

    //this if make character fall while he doesnt collides 
    if(map.collidesWith(p.getBounds())){ 
     p.increaseY(delta); 
    } 
    else{ 
     p.increaseY(0); 
    } 
} 

@Override 
public int getID() { 
    return 1; 
} 


public void initMap() throws SlickException{ 
    map = new Level("res/tiles/test.tmx"); 
    map.setLayerIndex("suelo"); 
    int id=0; 
    int x=0; 
    int y=0; 
    for(int i=0; i<map.getWidth();i++){ 
     for(int j=0;j<map.getHeight();j++){ 
      id = map.getTileId(j, i, map.getLayerIndex()); 
      x=j*32; 
      y=i*32; 
      map.setRect(i, j, new Rectangle(x, y, map.getTileWidth(), map.getTileHeight())); 
      if(id!=0){ 
       map.setSolid(i, j, true); 
      } 
      else{ 
       map.setSolid(i, j, false); 
      } 
     } 
    } 
} 

}

:Slick2DからメソッドgetTileIdは私が行列[j]を使用しています理由です、うまく動作does notの[i]の代わりに行列の[I] [J]

+0

リンクを共有する代わりに、ここにコードを掲載する必要があります。あなたの衝突に関わるすべて。 – eldo

答えて

0

だから、これを実行する方法について説明し、インターネット上のチュートリアルがたくさんある:

私はあなたが間違っているかもしれないものをよく理解を得るためにこれらをrecommenedことができます。

Slick2d | Entity collision detection

https://gamedev.stackexchange.com/questions/59308/how-do-i-detect-and-handle-collisions-using-a-tile-property-with-slick2d


私は強くあなたのプレイヤーにヒットボックスを与えることをお勧めします。例32×32の長方形の場合は、shape.intersects(Shape s)メソッドを使用できるので、easy & exactの場合には、これは不可欠です。

私はあなたのコードをチェックしましたが、何が欠けているのか理解できなかった点は、プレーヤー側の衝突検出です。だから今あなたはどのタイルが "ブロック"されているかを判断しています。あなたのアプローチから、ブロックされたすべてのタイルは、配列に格納されたx、yを持つシェイプです。

プレイヤーサイドで行う必要があるのは、プレイヤーが移動したい方向がブロックされているかどうかを確認するアクションです。

プレーヤーのヒットボックスなしでアプローチすると、速度が不安定になる可能性があり、速度にもよります。これは移動コマンドごとに1タイルの速度で最も効果的です。 E.G.

if(gc.getInput().isKeyDown(Input.KEY_D)){ 
    if(Level.solids[Player.x+Player.xv][Player.y] == false){ // Checking whether the tile to the right of the Player is returning false or true 
    // ...Do your movement/Animation stuff. 
    } 

} 

私の考えでは、同じことをシェイプによる衝突をチェックするといいでしょう。

if(gc.getInput().isKeyDown(Input.KEY_D)){ 
    for(Shape s : Level.shapes){ 
    if(!Player.hitbox.intersects(s)){ 
    // ...Do your movement/Animation stuff. 
    } 

それが不正確に動作しますので、あなたはおそらく文句を言わないあなたはあなたの要求にそれを微調整する必要があります、1でこのいずれかを使用することができるように注意してください。しかし、あなたのゲームデザインを考え直し、あなたには問題があるかもしれないヒントを与えるはずです。

希望すると、これが役立ちます。

+0

答えをありがとう!私はできるだけ早くそれに取り組むだろうと私はあなたに気づいてくれます:) –

+0

何かが不明な場合はお気軽に質問してください。 私は今仕事中ですが、自宅にいるときには自分のことを明確にするためのコードを提供することができます。 –