Tiled getTileProperty method (Slick2D)

Slick2D warns that its getTileProperty() method will not perform well.
Is it a viable way to implement collision despite the warning?
For example setting either a tile or object in Tiled with properties “passable” and “false”,
then iterating through the map when it is instantiated and adding all appropriate tiles to an array?

Or should I think of something else! :]

Thanks!

Yes, this would be a way to go. Create 2d array of booleans and set values during map loading…then ask this array if the tile is blocked instead of tile property. Or you can add second layer to your tilemap.

To keep everything cleaned up I was going to keep the first layer strictly background. The next layer would be collision (and maybe movable objects if I can get this project moving), and then an object layer for collectables/items.

My programming is a bit rusty! My loop seems to think every tile has passable as false. Gonna have to double check my loop. My reward for fixing collision tonight is sleep!

And while I’m at it I should clean up this bit of code I have so in Init() I call a Map Loading method instead of all the messy code. It’s all coming back to me :]


public void MapInit() throws SlickException {
	map = new TiledMap("assets/maps/testmap.tmx");
	System.out.println(map.getHeight() + "" + map.getWidth());
		
	//puts tiles with blocked set true in the collision array
        blocked = new boolean[map.getWidth()][map.getHeight()];
        for (int x=0;x<map.getWidth();x++) {
        for (int y=0;y<map.getHeight();y++) {
            System.out.println(x + " " + y);
            int id = map.getTileId(x, y, 0);
            String value = map.getTileProperty(id, "blocked", "true");
            if (value.equalsIgnoreCase("true")) {
            	System.out.println(value);
            	blocked[x][y] = true;
            }
          }
        }
        
}

Am I making one of those errors I’m going to laugh at later? Or am I just misusing the method.

My method instantiates the map, sets the blocked array to the size of the map (in tiles as per the Slick2D method).
Then it loops through the map, checks each tile for the given property, in this case “blocked” defined with “true”.
And finally, if the value is true, it adds that tile to the array.

Currently, it is passing every single tile to the array as if it is ignoring the properties set in Tiled.

EDIT: In the meantime I’ve resorted to using the TileID instead of the tile property which works, but feels a bit cheap since I want to do more complicated things later. I’d rather have the code more readable by using “blocked”, than by having magic numbers everywhere.

EDIT2!: After some frustrating fixes I have collision working (badly) and have come to realize I just don’t know what the hell I’m doing with floats.
My collision check takes in a float, and my array has to check an integer value and return true or false. I thought I was smart taking the player position it was checking and dividing that by the map’s width or height (for x and y) which put the collision near where it should be… but it’s acting strangely, letting me move halfway through some blocks before I collide, and occurring on some tiles it shouldn’t.

Reference Code:

Collision Check


private boolean tryToMove(float x, float y) {
	      float newx = playerX + x;
	      float newy = playerY + y;
	      // checks the blocked array for collision
	      if (isBlocked((newx/map.getWidth()), (newy/map.getHeight()))) {
	          //can't move if blocked is true at the given location
	          return false;
	      }else{
	    	  //allows the move
              return true;
	      }       
	}

Relevant movement stuff in Update()


Input input = container.getInput();
		
		float fdelta=delta*0.1f;

		if (input.isKeyDown(Input.KEY_UP))
		{
			if(tryToMove(playerX, playerY - fdelta)){
				playerY -= fdelta;
				System.out.println(playerX/map.getTileWidth() + " " + playerY/map.getTileHeight());
			}
		}	
		
		else if (input.isKeyDown(Input.KEY_DOWN))
		{
			if(tryToMove(playerX, playerY + fdelta)){
				playerY += fdelta;
				System.out.println(playerX/map.getTileWidth() + " " + playerY/map.getTileHeight());

			}
		}
		else if (input.isKeyDown(Input.KEY_LEFT))
		{
			if(tryToMove(playerX - fdelta, playerY)){
				playerX -= fdelta;
				System.out.println(playerX/map.getTileWidth() + " " + playerY/map.getTileHeight());

			}
		}
		else if (input.isKeyDown(Input.KEY_RIGHT))
		{
			if(tryToMove(playerX + fdelta, playerY)){
				playerX += fdelta;
				System.out.println(playerX/map.getTileWidth() + " " + playerY/map.getTileHeight());

			}
		}