Slide 1

Slide 1 text

libGDX: Tiled Maps

Slide 2

Slide 2 text

CREATING TILED MAPS

Slide 3

Slide 3 text

Tiled Maps

Slide 4

Slide 4 text

Tiled Editor: Tiled • Editing tools for stamp, fill and terrain brushes • Rectangle, ellipse, polygon and image objects can be placed • Support for orthogonal, isometric and staggered maps • Download: http://www.mapeditor.org/

Slide 5

Slide 5 text

Isometric (3D effect)

Slide 6

Slide 6 text

Isometric vs Isometric staggered

Slide 7

Slide 7 text

Create tilesheet png

Slide 8

Slide 8 text

Creating new Map

Slide 9

Slide 9 text

Layers • Your world may contain layers • You can disable and enable layers during runtime • You can add object layers for easy collision detection

Slide 10

Slide 10 text

USING MAPS IN LIBGDX

Slide 11

Slide 11 text

Loading Map • To load a map – TiledMap tiledMap = new TmxMapLoader().load("runner.tmx"); • To render a map, use TiledMapRenderer – TiledMapRenderer tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap);

Slide 12

Slide 12 text

Render and Camera @Override public void render () { batch.setProjectionMatrix(camera.combined); // // Which part of the map are we looking? Use camera's viewport tiledMapRenderer.setView(camera); // Render all layers to screen. tiledMapRenderer.render(); }

Slide 13

Slide 13 text

MOVE CAMERA

Slide 14

Slide 14 text

Render and Camera @Override public void render () { batch.setProjectionMatrix(camera.combined); // move camera (YOU HAVE TO IMPLEMENT THIS) moveCamera(); // Which part of the map are we looking? Use camera's viewport tiledMapRenderer.setView(camera); // Render all layers to screen. tiledMapRenderer.render(); }

Slide 15

Slide 15 text

moveCamera() public void moveCamera() { // Lot of possibilities. // 1) Just move the camera to some direction: camera.translate(1,0); // moves x++ // 2) Move to certain point camera.position.x = 200; // 3) Move to direction of some sprite camera.position.x = player.getX(); // Update camera movement camera.update(); }

Slide 16

Slide 16 text

COLLISION DETECTION

Slide 17

Slide 17 text

Collision Checking /** * Checks if player has collided with collectable */ private void checkCollisions() { // Let's get the collectable rectangles layer MapLayer collisionObjectLayer = (MapLayer)tiledMap.getLayers().get("collectable-rectangles"); // All the rectangles of the layer MapObjects mapObjects = collisionObjectLayer.getObjects(); // Cast it to RectangleObjects array Array rectangleObjects = mapObjects.getByType(RectangleMapObject.class); // Iterate all the rectangles for (RectangleMapObject rectangleObject : rectangleObjects) { Rectangle rectangle = rectangleObject.getRectangle(); // SCALE given rectangle down if using world dimensions! if (playerSprite.getBoundingRectangle().overlaps(rectangle)) { clearCollectable(); } } }

Slide 18

Slide 18 text

MOVING OBJECT

Slide 19

Slide 19 text

0 px, 0 px 32 px 32 px

Slide 20

Slide 20 text

32 px, 32 px

Slide 21

Slide 21 text

32,32 1. Arrow key right pressed 2. Movement x = x + 5 32 px, 32 px

Slide 22

Slide 22 text

37 px , 32 px 1. Arrow key right pressed 2. Movement x = x + 5 3. Crash!

Slide 23

Slide 23 text

Does 37,32 collide collide with wall? No... 37 px , 32 px

Slide 24

Slide 24 text

37,32 We need to check each corner! 69,32 69,64 37,64

Slide 25

Slide 25 text

37,32 Check if the next frame collides with bg. If not, move to next frame 69,32 69,64 37,64

Slide 26

Slide 26 text

37,32 69,32 69,64 37,64 float currentX = playerSprite.getX(); float currentY = playerSprite.getY(); float newX = currentX; float newY = currentY; if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)) { newX += moveAmount; } if(checkIfInWall(newX, newY)) { playerSprite.setPosition(newX, newY); }

Slide 27

Slide 27 text

Converting Sprite position to Tiled Map index 32 px 0 1 2 3 4 5 6 7 8 9 7 6 5 4 3 2 1 0 32 px 250,120

Slide 28

Slide 28 text

Converting Sprite position to Tiled Map index 32 px 250 px / 32 px = 7.8 -> 7 120 px / 32 px = 3.8 -> 3 Index is (7, 3) 0 1 2 3 4 5 6 7 8 9 32 px 7 6 5 4 3 2 1 0

Slide 29

Slide 29 text

isFree - method private boolean isFree(float x, float y) { // Calculate coordinates to tile coordinates // example, (32,32) => (1,1) int indexX = (int) x / TILE_WIDTH; int indexY = (int) y / TILE_HEIGHT; // Is the coordinate / cell free? return (wallCells.getCell(indexX, indexY) == null); }

Slide 30

Slide 30 text

Checking all Corners public boolean checkIfInWall(float newX, float newY){ float downYPos = newY; float upYPos = playerSprite.getHeight() + downYPos; float leftXPos = newX; float rightXPos = playerSprite.getWidth() + leftXPos; boolean upLeft = isFree(leftXPos, upYPos); boolean downLeft = isFree(leftXPos, downYPos); boolean upRight = isFree(rightXPos, upYPos); boolean downRight = isFree(rightXPos, downYPos); return upLeft && downLeft && upRight && downRight; }

Slide 31

Slide 31 text

37,32 69,32 69,64 37,64 Notice: if walls are smaller in size than player, the previous code will not work...

Slide 32

Slide 32 text

When using Meters • Creating the map, scale it down – tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap, 1 / 100f); • When detecting collisions, Rectangle given is in pixels, scale it down!

Slide 33

Slide 33 text

Scaling Rectangle private void checkCollisions() { // Let's get the collectable rectangles layer MapLayer collisionObjectLayer = (MapLayer)tiledMap.getLayers().get("collectable-rectangles"); // All the rectangles of the layer MapObjects mapObjects = collisionObjectLayer.getObjects(); // Cast it to RectangleObjects array Array rectangleObjects = mapObjects.getByType(RectangleMapObject.class); // Iterate all the rectangles for (RectangleMapObject rectangleObject : rectangleObjects) { Rectangle tmp = rectangleObject.getRectangle(); // SCALE given rectangle down if using world dimensions! Rectangle rectangle = scaleRect(tmp, 1 / 100f); if (playerSprite.getBoundingRectangle().overlaps(rectangle)) { clearCollectable(); } } }

Slide 34

Slide 34 text

Scaling Rectangle private Rectangle scaleRect(Rectangle r, float scale) { Rectangle rectangle = new Rectangle(); rectangle.x = r.x * scale; rectangle.y = r.y * scale; rectangle.width = r.width * scale; rectangle.height = r.height * scale; return rectangle; }