Tile-based game help!

I’ve been trying to make a tile engine for AAAGES, and I’ve got further than ever before! Well, I’ve been able to get the window up without any errors. But still no tiles. At one point there was one red one in the top left corner, but after a bit of tweaking that unfortunately disappeared. I’ve been using this as my example: https://github.com/captainkraft/Orc-Canyon

But, I’ve had an idea in my head for a while now for a small and simple-ish top-down puzzle game using the Slick2D library. In the game, you’re trying to break out of a jail cell, but walls block your exit. These walls are attached to pressure plates, and you have to stand on them to make the walls move. I’ve included a basic idea below (Paint ftw):

At the minute I’ve got 2 sorts of tiles, one black and one green. The window just shows empty blackness. I’m not sure if this is the correct way of going about this, so any suggestions are very welcome!

Code: http://pastebin.java-gaming.org/3038e0e8a2e

Thanks!

You have such nice names for your files…

     tileImg = new Image("res/cunt.png");
     
     tileImg = new Image("res/twat.png");

Oh man, meant to change those before posting :persecutioncomplex:

Also, add a break statement to each switch case, or it will fall through.

Thanks! I still haven’t managed to make it work, I’m stuck with my black screen of doom :clue:

Seems tileImg in Tiles is static, so it is replaced for “all” your tiles, every time a new tiles is created.
if I read your map creation code correctly, that means they all use “res/twat.png”.

Really going to have to change those names.

Thanks, how can I get around that? I’m using Slick’s drawImage() to draw the tiles, and the image needs to be declared static to be used as an argument.

Why not just use Slick2D’s built in tile system?

You make your map using a program called Tiled. Tiled saves your map as a .TMX file. You create a new TiledMap object in your game. Then you’re able to simply call tiledMapObjectName.render(x, y);

There is nothing there that requires it to be static, but you made the field static, so the it has to be called statically when you draw it.

On the line g.drawImage(Tiles.tileImg, Level.thex, Level.they);
remove “Tiles.”
and remove the static modifier on the field “tileImg”.

A-ha! Finally! I have tiles!

Thanks Vladiedoo. Do you have any ideas on how could make my idea work using this system?

TiledMap tmap = new TiledMap(ref);
int tileWidth = tmap.getWidth();
int tileHeight = tmap.getHeight();
int mapWidth = tmap.getWidth() * tmap.getTileWidth();
int mapHeight = tmap.getHeight() * tmap.getTileHeight();

    // Inside the init. function
		for (int x = 0; x < mapWidth; x++) {
			for (int y = 0; y < mapHeight; y++) {
				if (tmap.getTileId(x, y, layerIndex) == PRESSURE_PLATE_ID) {
					Polygon pressurePlate = new Polygon(new float[] { 0, 0, tileWidth , 0, tileWidth, -tileHeight, 0, -tileHeight });
					pressurePlate.setX(x * tileWidth );
					pressurePlate.setY(y * tileHeight);
				}
			}
		}


      // Inside the update function
		if (pressurePlate.intersects(playerPolygon) || pressurePlate.contains(playerPolygon)) {
			// Do your action here.
		}

Struggling to get that working :clue:

No errors, and everything else is rendered just fine, but I can’t get the pressure plate to work.

The first 8 steps and my code are covered in http://slick.cokeandcode.com/wiki/doku.php?id=01_-_tiled_and_maps

  1. Google Tiled
  2. First link should be “Tiled Map Editor”, click that
  3. On the right hand side click download (download your OS version)
  4. Open Tiled, go to File->New Map-> Set your map size and type (your game view is Orthogonal)
  5. Go to Edit->Preferences->Store tile later data as: “Base64(gzip compressed)”
  6. Go to Map->New Tileset->Find the tile image you want to use
  7. Draw in your map with your tiles located at the bottom right
  8. Go to File->Save As->Save your map into your game’s res folder

NOTE: Make sure to save your tile images where you save your map. So have your res folder contain the map AND the tiles.

Here is some example code for running your game, NOTE: I’m no expert in Slick2D and this code is incomplete and not optimized (in the future you will learn about using an entity system) but this should help you as a starting point.
http://pastebin.java-gaming.org/038ee1a8e2e

If all of he following still doesn’t help you: remember to add in a System.out.println(); at certain points to check what is and isn’t being called. Using System.out.println(); you can also display variable values and see if something is changing or being set properly. If even that doesn’t work try to pinpoint what isn’t working for you and I can help. Good luck!

Thanks, that was really detailed. A big help :slight_smile:

I still don’t get this bit though:

if (pressurePlate.intersects(player) || pressurePlate.contains(player)){
         // Set the blocking tile one higher and it's previous posion to a default walking tile.
         map.setTileId(x, y, layerIndex, tileid);
         map.setTileId(x, y, layerIndex, tileid);
      } else {
         // Set the blocking tile to be in the way again.
         map.setTileId(x, y, layerIndex, tileid);
         map.setTileId(x, y, layerIndex, tileid);
      }

How is this supposed to work? Thanks again.

NOTE: Currently (and in this post) I’ve been replying to your post as if the player has to constantly stand on your pressure plate in order for the block to be moved up. Once the player steps off the pressure plate the blocking wall is moved back into position.

This code checks if the player Polygon is either intersecting or contained by the the pressure plate Polygon. It basically reads “If the player is touching or inside the pressure plate”.

if (pressurePlate.intersects(player) || pressurePlate.contains(player)){

What this code does is change the map. It looks like to me your map is made up of these tiles, outer wall, pressure block, regular tiles, and blocking wall. In Tiled you’ll draw the map with the wall initially blocking the exit. Then with this code, when the player is standing on the pressure plate, you switch the tiles at and above the blocking wall so that the exit is now un-blocked.


// Each tile in your map has an ID, when you change its ID you change the tile.

// As an example we will say that the ID for a regular tile is 1 and that the ID for a regular tile is 2.
// We will also say that the x location of the blocking tile is 30 and its y location is 16.
if (pressurePlate.intersects(player) || pressurePlate.contains(player)){
         // Set the blocking tile to 1 position higher.
         map.setTileId(30, 15, 0, 2);
         // Set the old blocking position to a regular tile.
         map.setTileId(30, 16, 0, 1);
      } else {
         // Since the map is now blocked, do the reverse of the above
         // Set the blocking tile to default position.
         map.setTileId(30, 16, 0, 2);
         // Set the position above the blocking wall as a regular tile.
         map.setTileId(30, 15, 0, 1);
      }
}

That’s giving me a NullPointerException :frowning:

You have to put in values for those lines of code ;D.

For example


int x = 5;
int y = 5;
int layerIndex = 0;
int tileid = 2;
map.setTileId(x, y, layerIndex, tileid);

The above code will set the tile at coordinates (5, 5) to have the ID of 2. Ignore layerIndex, that’s used for more advanced collision.

Keep in mind that there are other solutions to use, you don’t have to use a tile, you can draw a polygon and move the polygon instead.

Please post your entire error message, it will help me help you :D.

java.lang.NullPointerException
	at george.game.cells.Level.update(Level.java:83)
	at org.newdawn.slick.state.StateBasedGame.update(StateBasedGame.java:268)
	at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:657)
	at org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:408)
	at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:318)
	at george.game.cells.GameMain.main(GameMain.java:28)
Sat Oct 20 00:48:03 BST 2012 ERROR:Game.update() failure - check the game code.
org.newdawn.slick.SlickException: Game.update() failure - check the game code.
	at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:663)
	at org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:408)
	at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:318)
	at george.game.cells.GameMain.main(GameMain.java:28)

And this is the bit that’s wrong :stuck_out_tongue:

if (pressurePlate.contains(player)){
	         // Set the blocking tile to 1 position higher.
	         map.setTileId(540, 180, 0, 4);
	         // Set the old blocking position to a regular tile.
	         map.setTileId(540, 240, 0, 1);
	      } else {
	         // Since the map is now blocked, do the reverse of the above
	         // Set the blocking tile to default position.
	         map.setTileId(540, 180, 0, 1);
	         // Set the position above the blocking wall as a regular tile.
	         map.setTileId(540, 240, 0, 4);
	      }
		if (pressurePlate.intersects(player) || pressurePlate.contains(player)) {
		System.out.println("C'est true");
	    }

Very sorry for the delay! Thanks for the help.

I should have clarified this, sorry.

You have

map.setTileId(540, 180, 0, 4);

But you actually need

map.setTileId(xTileLocation, yTileLocation, 0, 4);

The xTileLocation is the actual map tile location, not the pixel location on screen. For your code to work you would have to have at least 541 tiles in the x direction and 181 tiles in the y direction.

Ah, okay :stuck_out_tongue: Still getting the same error. The problem line is this one:

if (pressurePlate.contains(player)){

And the code for the Polygon is here:

for (x = 0; x < mapWidth; x++) {
			for (y = 0; y < mapHeight; y++) {
				//The third variable in "map.getTiledId(x, y, 0)" is the layer, if you don't know what this is just put 0.
				if (level1.getTileId(x, y, 0) == PRESSURE_PLATE_ID) {
					Polygon pressurePlate = new Polygon(new float[] { 0, 0, tileWidth, 0, tileWidth, -tileHeight, 0, -tileHeight });
					pressurePlate.setX(x * tileWidth);
					pressurePlate.setY(y * tileHeight);
				}
			}
		}
		//Makes the player a 50x50 square
		player = new Polygon(new float[] { 0, 0, tileWidth, 0, tileWidth, -tileHeight, 0, -tileHeight });
		// Makes the player start at (50, 50)
		player.setX(playerX);
		player.setY(playerY);

Have I made an error there? Thanks again.