Upgrade to Pro — share decks privately, control downloads, hide ads and more …

LibGDX: Tiled Maps

LibGDX: Tiled Maps

D9e65f4b0af059ae9ba243c8c2265e4f?s=128

Jussi Pohjolainen

February 11, 2021
Tweet

Transcript

  1. libGDX: Tiled Maps

  2. CREATING TILED MAPS

  3. Tiled Maps

  4. 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/
  5. Isometric (3D effect)

  6. Isometric vs Isometric staggered

  7. Create tilesheet png

  8. Creating new Map

  9. Layers • Your world may contain layers • You can

    disable and enable layers during runtime • You can add object layers for easy collision detection
  10. USING MAPS IN LIBGDX

  11. Loading Map • To load a map – TiledMap tiledMap

    = new TmxMapLoader().load("runner.tmx"); • To render a map, use TiledMapRenderer – TiledMapRenderer tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap);
  12. 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(); }
  13. MOVE CAMERA

  14. 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(); }
  15. 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(); }
  16. COLLISION DETECTION

  17. 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<RectangleMapObject> 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(); } } }
  18. MOVING OBJECT

  19. 0 px, 0 px 32 px 32 px

  20. 32 px, 32 px

  21. 32,32 1. Arrow key right pressed 2. Movement x =

    x + 5 32 px, 32 px
  22. 37 px , 32 px 1. Arrow key right pressed

    2. Movement x = x + 5 3. Crash!
  23. Does 37,32 collide collide with wall? No... 37 px ,

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

  25. 37,32 Check if the next frame collides with bg. If

    not, move to next frame 69,32 69,64 37,64
  26. 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); }
  27. 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
  28. 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
  29. 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); }
  30. 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; }
  31. 37,32 69,32 69,64 37,64 Notice: if walls are smaller in

    size than player, the previous code will not work...
  32. 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!
  33. 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<RectangleMapObject> 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(); } } }
  34. 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; }