2016-06-22 14 views
0

Ich weiß, dass Slick2D aufgegeben wird, aber ich fühle mich mit dieser Bibliothek komfortabel Code eingeben.Slick2D Kollision mit Tilemap

Vielleicht haben Sie das gleiche über Slick2d, Kollisionen gesehen. Jetzt habe ich ein Problem, das ich nicht lösen kann, und ich bin mit diesem Problem seit 2 Wochen. In meinem Spiel gibt es eine TileMap, wo ich alle Elemente gefunden habe, die zu "solid" Layer gehören und ich zeichne Rechtecke an der gleichen Stelle, um mit Physik zu arbeiten. Das Problem ist, dass mein Charakter (ist eine Menge von Animationen) nicht die Rechtecke, die zu der Solid-Layer meiner Tilemap gehört.

Wenn ich eine For-Schleife verwende, erkennt der Charakter die Rechtecke nicht. Aber wenn ich die ifs-Anweisungen nach allen Rezepten durchsuche, funktioniert die Kollision.

Weiß jemand, warum ist das passiert?

Sorry über meine Englisch>. <

Jede Hilfe wird geschätzt.

Danke!

Edit: Hier ist der Code über meine Kollision.

Stufe Klasse, die die tilemap enthält:

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

}

Meine Spieler-Klasse mit den Attributen über Physik:

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

}

Das aktuelle Niveau auf ich bin arbeiten:

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

}

HINWEIS: Die Methode getTileId von Slick2D tut gut funktionieren, das ist, warum ich Matrix bin mit [j] [i] anstelle von Matrix [i] [j]

+0

Anstatt einen Link zu teilen, sollten Sie Ihren Code hier veröffentlichen. Alles, was an deiner Kollision beteiligt ist. – eldo

Antwort

0

So gibt gibt viele Tutorials im Internet, die erklärt, wie dies zu tun:

I recommened diese bekommen ein gutes Verständnis von dem, was Sie falsch kann tun könnte:

Slick2d | Entity collision detection

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


Ich empfehle ihren Spieler einen hitbox zu geben. Zum Beispiel ein 32 * 32 Rechteck, das ist wichtig für einfach & präzise Kollisionserkennung, da Sie die Shape.interseects (Shape s) -Methode verwenden können.

Ich habe Ihren Code ausgecheckt und was fehlt ist in meinem Verständnis, was fehlt ist die Kollisionserkennung auf der Player-Seite. Sie bestimmen gerade, welche Kacheln "blockiert" sind. Von Ihrer Annäherung an jede blockierte Kachel ist eine Form mit einem x, y in einem Array gespeichert.

Was Sie auf der Spielerseite tun müssen, ist nach der Bewegung zu prüfen. Aktion, wenn die Richtung, in die sich Ihr Spieler bewegen möchte, blockiert ist oder nicht.

Annäherung ohne Hitbox eines Spielers, kann sich jedoch unpersönlich verhalten und hängt von Ihrer Geschwindigkeit ab. Dies sollte am besten mit einer Geschwindigkeit von 1 Kachel pro Bewegungsbefehl funktionieren. E.G.

Meiner Meinung nach wäre es besser, wenn Sie das Gleiche mit der Prüfung auf Kollision durch Formen tun.

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

Beachten Sie, dass Sie wahrscheinlich nicht in der Lage sein, diese zu verwenden, indem man, da es unpräzisen verhalten wird, werden Sie brauchen, um sie Ihre Anforderungen zu optimieren. Aber es sollte dein Spieldesign überdenken und dir einen Hinweis geben, wo dein Problem sein könnte.

Hoffe das hilft dir.

+0

Danke für die Antwort! Ich werde so schnell wie möglich daran arbeiten und ich werde Sie bemerken, wenn es mir funktioniert :) –

+0

Fühlen Sie sich frei, Fragen zu stellen, wenn etwas unklar ist. Ich bin gerade bei der Arbeit, aber wenn ich zu Hause bin, könnte ich Ihnen meinen Code zur Verfügung stellen, um Dinge für Sie zu klären. –