0

I know that Slick2D is abandoned but I feel comfortable type code with this library.

Maybe you've seen the same thing about Slick2d, collisions. Now, I have an issue that I cannot solve, and I am with this problem for 2 weeks. In my game, there is a TileMap, where I found all of elements that belongs to "solid" Layer and I draw rectangles at the same position to work with physics. The problem is that my character (is an amount of animations) doesnt detect the rectangles that belongs to the solid layer of my tilemap.

If I use a for loop, the character doesnt detect the rectangles. But if I check through ifs statements all of rects, the collision works.

Does anyone know why is this happenning?

Sorry about my English >.<

Any help will be apreciated.

Thanks!

Edit: Here is the code about my collision.

Level class which contains the tilemap:

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

}

My player class with the attributes about physics:

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

}

The current level on I am working:

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

}

NOTE: The method getTileId from Slick2D doesnt work well, that's why I am using matrix[j][i] instead of matrix[i][j]

Julian Egea
  • 3
  • 1
  • 2
  • Instead of sharing a link you should post your code here. Everything that is involved in your collision. – eldo Jun 22 '16 at 11:22

1 Answers1

0

So there are a lot of tutorials on the Internet which explains how to do this:

I can recommened These to get a good understanding of what you might be doing wrong:

Slick2d | Entity collision detection

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


I strongly recommend to give your Player a hitbox. For Example a 32*32 rectangle, this is essential for easy & precise collision detection since you can make use of the shape.intersects(Shape s) method.

I checked out your code and what is missing from my understanding what is missing is the collision detection on the Player side. So right now you are determining which tiles are "blocked". From your Approach every blocked tile is a Shape with a x,y stored in a Array.

What you Need to do on playerside is checking after the movement Action if the direction where your Player wants to move is blocked or not.

Approach without a Player hitbox, might behave unprecisily though and depends on your velocity. This should work best with a velocity of 1 tile per movement command. 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.
   }

}

In my opinion it would be better if you do the same with checking for collision by shapes.

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

Note that you probably wont be able to use this one by one since it will behave imprecisely, you'll Need to tweak it to your demands. But its supposed to rethink your game design and give you a hint where ur Problem might be.

Hope this helps you.

Community
  • 1
  • 1
LOLWTFasdasd asdad
  • 2,625
  • 5
  • 26
  • 39