[solved] How to have multiple tiles a player can't go through?

The title may be a bit confusing, but I’ll explain. In my new game, Diamonds, I want the player to not be able to go through stone or supports. As is, my code can only handle one. A code sample is below.


                           if (keyCode == KeyEvent.VK_UP) { 
				if (!m.getMap(p.getTileX(), p.getTileY() - 1).equals("s")) { // "s" means stone.
						p.move(0, -1); // I call a move() method from my player class
				}
			}

Thanks,

-DarkCart

Just use Rectangles and check for intersection.

If I understand your question correctly, you want something like this:


Set<String> blockingTiles = new HashMap<String>();
blockingTiles.add("s");
...
Tile tile = m.getMap(p.getTileX(), p.getTileY() - 1);
if (!blockingTiles.contains(tile)) {
   p.move(0, -1);
}

Exactly. I’m not familiar with HashMap, so I didn’t think of that. Thanks :slight_smile:

The fastest way is probably to use rectangles, and check if you’re intersecting with them. I’m not sure the LibGDX equiv, but this is how you’d do it in slick2d: (I’m sure it can be translated to Lib)

I am going to assume you have a multi-layered map, if you don’t (or, you only need to check one layer) you can remove the third forloop.

This also uses slick2d’s TiledMap and Rectangle class, you’ll have to translate it to something in your own program to fetch the required variables.

Search for, then creates rectangles:


	ArrayList<Rectangle> collisionBoxes = new ArrayList<Rectangle>;
	int tileId
	for (int x = 0; x < map.getWidth(); x++) {
		for (int y = 0; y < map.getHeight(); y++) {
			for (int l = 0; l < map.getLayers; l++) {
				//Create block rectangle here, checking for a blocked tile in position X, Y, L. The code in here is for doing it in Slick with TiledMap, you can change it to match your needs though.
				tileId = map.getTileId(x, y, l); //fetch the tile you're checking
				if (map.getProperty(tileId, "blocked", "false").equals("true")){ //Check if that tile has a blocked property, can also just check if it's "s" as well, like your original code.
					collisionBoxes.add(new Rectangle(x, y, map.getTileWidth, map.getTileHeight));
				}
			}
		}
	}

Create one for your player:


Rectangle playerBox = new  Rectangle(0,0,characterHeight, characterWidth);

Put this in the update loop to keep the box centered on the player


playerBox.setX(playerX);
playerBox.setY(playerY);

Then, also in the area your controls are in, put something along these lines in for each axis you can move on (north/south/east/west):


	for (int x = 0; x < collisionBoxes.length; x++) {
		if (playerBox.intersects(collisionBoxes.get(x))){
			canMoveNorth = false; // then where ever your controls are, have it check is canMoveNorth before allowing the player to move.
			playerY += 2; //bump player back a bit so he's not stuck.
		}
	}

This is all untested code, no doubt full of typos/errors. It’s also built using Slick2D, but it should be easy enough to understand whats going on and rebuild it in another library.

Either way, hopefully it gets you going in the right direction (if you want to use rectangles) :stuck_out_tongue:

In response to Rayvolution’s post… You don’t need to do any libGDX or slick2d specific collision detection classes. Just use the Rectangle class that already exists in Java and work with it. Saves you from having to learn a lot more and it’ll work well enough for most purposes.