|
@@ -6,160 +6,162 @@ Using tilemaps
|
|
|
Introduction
|
|
|
------------
|
|
|
|
|
|
-Tilemaps can be used to make levels for 2D games.
|
|
|
-A tilemap is a grid of (usually square) image tiles which form the scenery of a level or area in a game. The placed tiles in a tilemap are instances of 'reference tiles' from a tileset. The tileset can be thought of as a pallete with which a tilemap (level) can be 'painted':
|
|
|
+A tilemap is a grid of tiles used to create a game's layout. There are several
|
|
|
+benefits to using :ref:`TileMap <class_TileMap>` nodes to design your levels.
|
|
|
+First, they make it possible to draw the layout by "painting' the tiles onto a
|
|
|
+grid, which is much faster than placing individual :ref:`Sprite <class_Sprite>`
|
|
|
+nodes one by one. Second, they allow for much larger levels because they are
|
|
|
+optimized for drawing large numbers of tiles. Finally, you can add collision,
|
|
|
+occlusion, and navigation shapes to tiles, adding additional functionality to
|
|
|
+the TileMap.
|
|
|
+
|
|
|
+.. image:: img/tileset_draw_atlas.png
|
|
|
+
|
|
|
+Project setup
|
|
|
+-------------
|
|
|
|
|
|
-.. image:: img/tilemap.png
|
|
|
+This demo we'll use the following tiles taken from Kenney's "Abstract Platformer"
|
|
|
+art pack. You can find the complete set `here <https://kenney.nl/assets/abstract-platformer>`_
|
|
|
+but for this demo we'll stick to this small set.
|
|
|
|
|
|
-Collision shapes can be added to the tiles in a tileset to create solid geometry. Tilemaps can be used for both side view and top-down 2D games.
|
|
|
+.. image:: img/tilesheet.png
|
|
|
|
|
|
-Making a tileset
|
|
|
-----------------
|
|
|
+Create a new project and place the above image in the project folder.
|
|
|
|
|
|
-Here are some tiles for a tileset.
|
|
|
-They are all part of the same image file. This is helpful for a game's performance.
|
|
|
-There are so-called *texture packers* that will generate these spritesheets
|
|
|
-out of several separate tile images.
|
|
|
-But keeping them as separate images also works.
|
|
|
+When using a tileset, it's important that adjacent tiles match up. Godot's default
|
|
|
+is to import 2D images using an interpolated "filter" mode, which will result in
|
|
|
+ugly borders between the tiles. Select the image and click the Import tab. Turn
|
|
|
+off ``Filter`` and click "Reimport". See :ref:`doc_import_images` for details.
|
|
|
|
|
|
-.. image:: img/tileset.png
|
|
|
+TileMap node
|
|
|
+------------
|
|
|
|
|
|
-Create a new project and move the above PNG image into the project directory. Next,
|
|
|
-go into the image's import settings and turn off ``Filter``. Keeping it on will cause
|
|
|
-issues later. ``Mipmaps`` should already be disabled; if not, disable this too.
|
|
|
+Add a new :ref:`TileMap <class_TileMap>` node to the scene. By default, a TileMap
|
|
|
+uses a square grid of tiles. You can also use a perspective-based "Isometric" mode
|
|
|
+or define your own custom tile shape.
|
|
|
|
|
|
-The easiest way to edit and maintain a tileset is exporting
|
|
|
-it from a specially prepared scene. We'll create that next.
|
|
|
+.. image:: img/tilemap_mode.png
|
|
|
|
|
|
-TileSet scene
|
|
|
--------------
|
|
|
+Under the "Cell" section in the Inspector are many properties you can adjust to
|
|
|
+customize your tilemap's behavior:
|
|
|
|
|
|
-Create a new scene with a regular Node or Node2D as root. For each reference tile you want to define,
|
|
|
-add a sprite node as a child. Since our tiles measure 50x50 pixels, you should turn on the grid
|
|
|
-(``View -> Show Grid`` or ``G`` key) and enable snap (``Use Snap`` icon or ``Shift + S`` keys).
|
|
|
-Moving tiles with the mouse might still be inaccurate,
|
|
|
-so use your arrow keys as well.
|
|
|
+.. image:: img/tilemap_size.png
|
|
|
|
|
|
-If more than one tile is present in the source image, make sure to use
|
|
|
-the region property of the sprite to adjust which part of the texture is being
|
|
|
-used.
|
|
|
+- ``Cell Size``
|
|
|
+ This defines the size of the grid. This should match the pixel size
|
|
|
+ of your tiles. The default value is ``(64, 64)``.
|
|
|
|
|
|
-Give the sprite node an appropriate and unique name. This will ensure
|
|
|
-that, in subsequent edits to the tileset (for example, if you've added
|
|
|
-collision, changed the region, etc), the tile will still be **identified
|
|
|
-correctly and updated**.
|
|
|
+- ``YSort``
|
|
|
+ This causes tiles to be drawn in order of their ``Y`` position, so that
|
|
|
+ "lower" tiles are drawn on top of "higher" ones.
|
|
|
|
|
|
-Here's a screenshot that shows
|
|
|
-where everything of relevance is:
|
|
|
+- ``Half Offset`` and ``Tile Origin``
|
|
|
+ These properties affect the position of the tile relative to the grid position.
|
|
|
|
|
|
-.. image:: img/tile_example.png
|
|
|
+- ``Quadrant``
|
|
|
+ Defines the chunk size used for batched drawing. This can negatively
|
|
|
+ affect performance. Don't change it unless you know what you're doing.
|
|
|
|
|
|
-Add all the reference tiles in the way described above, adjusting the offsets as needed (that is, if you have
|
|
|
-multiple tiles in a single source image). Again, *remember that their names must
|
|
|
-be unique*.
|
|
|
+- ``Custom Transform``
|
|
|
+ Used to alter the tile's shape. Use this if you have non-square tiles.
|
|
|
|
|
|
-.. image:: img/tile_example2.png
|
|
|
+All of these options can be left at their defaults for this demo.
|
|
|
|
|
|
-Collision Shapes
|
|
|
-----------------
|
|
|
+Creating a TileSet
|
|
|
+------------------
|
|
|
|
|
|
-To add collision shapes to the tiles, create a StaticBody2D child for each sprite.
|
|
|
-This is a static collision node. Then create a CollisionShape2D or
|
|
|
-CollisionPolygon as a child of the StaticBody2D. The CollisionPolygon is easier to edit.
|
|
|
+Once you've configured your tilemap, it's time to add a
|
|
|
+:ref:`TileSet <class_TileSet>`. A TileSet is a
|
|
|
+:ref:`Resource <class_Resource>` that contains the data about your
|
|
|
+tiles - their textures, collision shapes, and other properties. When the game
|
|
|
+runs, the TileMap combines the individual tiles into a single object.
|
|
|
|
|
|
-.. image:: img/tile_example3.png
|
|
|
+To add a new TileSet, click on the "Tile Set" property and select "New
|
|
|
+TileSet".
|
|
|
|
|
|
-Edit the polygon; this will give the tile a collision shape and remove
|
|
|
-the warning icon next to the CollisionPolygon node. **Remember to use snap!**
|
|
|
-Using snap will make sure collision polygons are aligned properly, allowing
|
|
|
-a character to walk seamlessly from tile to tile. Also **do not scale or move**
|
|
|
-the collision and/or collision polygon nodes. Leave them at offset 0,0, with
|
|
|
-scale 1,1 and rotation 0 with respect to the parent sprite.
|
|
|
+.. image:: img/tilemap_add_tileset.png
|
|
|
|
|
|
-.. image:: img/tile_example4.png
|
|
|
+When you do this, the "TileSet" panel will open at the bottom of the editor
|
|
|
+window:
|
|
|
|
|
|
-Keep adding collision shapes to all tiles that need them. Note that BG is
|
|
|
-a background tile, so it should not have a collision shape.
|
|
|
+.. image:: img/tilemap_tool.png
|
|
|
|
|
|
-.. image:: img/tile_example5.png
|
|
|
+First, you need to add the texture(s) that you'll use for the tiles. Click the
|
|
|
+"Add Texture(s) to TileSet" button and select the ``tilesheet.png`` image.
|
|
|
|
|
|
-Then save this scene for future editing.
|
|
|
-"tileset_edit.scn" would be a sensible name for it.
|
|
|
+Next, click "New Single Tile" and drag in the image to select the tile you want.
|
|
|
+Click the "Enable Snap" button to make it easier to select the entire tile. A
|
|
|
+yellow rectangle appears around the selected tile.
|
|
|
|
|
|
-Exporting a TileSet
|
|
|
--------------------
|
|
|
+.. image:: img/tilemap_add_tile.png
|
|
|
|
|
|
-With the scene created and still open in the editor, use Scene > Convert To > Tile Set from the Scene Menu:
|
|
|
+Click on the TileMap in the scene tree, and you'll see that the newly created
|
|
|
+tile now appears on the right side. Click in the viewport and you can place
|
|
|
+tiles. Right-click to remove them.
|
|
|
|
|
|
-.. image:: img/tileset_export.png
|
|
|
+.. image:: img/tilemap_draw.png
|
|
|
|
|
|
-Then choose a filename, like "mytiles.tres". Make sure the "Merge With
|
|
|
-Existing" option is toggled on. This way, every time the tileset
|
|
|
-resource file is overwritten, existing tiles are merged and updated
|
|
|
-(they are referenced by their unique name, so again, **name your tiles
|
|
|
-properly**).
|
|
|
+It's easy to accidentally select and move the tilemap node. To avoid this, use
|
|
|
+the node's lock button:
|
|
|
|
|
|
-.. image:: img/tileset_merge.png
|
|
|
+.. image:: img/tile_lock.png
|
|
|
+
|
|
|
+Collision Shapes
|
|
|
+----------------
|
|
|
|
|
|
-Using the TileSet in a TileMap
|
|
|
-------------------------------
|
|
|
+If you're making a map that needs collisions - walls, floor, or other obstacles,
|
|
|
+for example - then you'll need to add collision shapes to any tiles that you
|
|
|
+want to be considered "solid".
|
|
|
|
|
|
-Create a new scene, using any node or node2d as root, and then create a
|
|
|
-:ref:`TileMap <class_TileMap>` as
|
|
|
-a child.
|
|
|
+Click "TileSet" at the bottom of the editor window to return to the tileset
|
|
|
+tool. Click the tile you previously defined (outlined in yellow). Select the
|
|
|
+"Collision" tab and click the "Create a new rectangle" button. Make sure you
|
|
|
+still have grid snap enabled, then click and drag in the tile. A square
|
|
|
+collision shape appears in light blue:
|
|
|
|
|
|
-.. image:: img/tilemap_scene.png
|
|
|
+.. image:: img/tileset_add_collision.png
|
|
|
|
|
|
-Go to the TileSet property of this node and assign the one created in
|
|
|
-previous steps:
|
|
|
+You can add occlusion and navigation shapes to the tile in the same way.
|
|
|
|
|
|
-.. image:: img/tileset_property.png
|
|
|
+Atlas tiles
|
|
|
+-----------
|
|
|
|
|
|
-Also set the cell size to '50', since that is the size used by the
|
|
|
-tiles. Quadrant size is a tuning value. The default value of 16 means that the engine will
|
|
|
-draw and cull (erase) the tilemap in blocks of 16x16 tiles. This value is
|
|
|
-usually fine, but can be used to fine tune
|
|
|
-performance in specific cases if you know what you're doing.
|
|
|
+Rather than adding individual tiles one at a time, you can define a group of
|
|
|
+tiles all at once using an atlas. Click "New Atlas" and drag to select the
|
|
|
+entire tile sheet.
|
|
|
|
|
|
-Painting your world
|
|
|
--------------------
|
|
|
+.. image:: img/tileset_atlas.png
|
|
|
|
|
|
-Make sure the TileMap node is selected. A red grid will
|
|
|
-appear on the screen, allowing you to paint on it with the tile currently selected in the
|
|
|
-left palette.
|
|
|
+If you haven't already, make sure to change the "Step" in the snap settings to
|
|
|
+`(64, 64)`, or your tiles may be chopped into smaller pieces. You can find
|
|
|
+this in the Inspector:
|
|
|
|
|
|
-.. image:: img/tile_example6.png
|
|
|
+.. image:: img/tileset_snap.png
|
|
|
|
|
|
-It's easy to accidentally select and move the tilemap node. To avoid this
|
|
|
-use the node's lock button:
|
|
|
+Once you've defined the atlas you can add collision shapes to the individual
|
|
|
+tiles as before. You can also click "Icon" to select one of the tiles to represent
|
|
|
+the atlas.
|
|
|
|
|
|
-.. image:: img/tile_lock.png
|
|
|
+Back in the TileMap, you can select the atlas tile and you'll see all of the
|
|
|
+tiles it contains:
|
|
|
+
|
|
|
+.. image:: img/tileset_draw_atlas.png
|
|
|
|
|
|
-If you accidentally place a tile somewhere you don't want it to be, you
|
|
|
-can delete it with ``RMB`` (the right mouse button) while in the tilemap editor.
|
|
|
+In addition to saving time when defining the tiles, this can help by grouping
|
|
|
+similar tiles together when you're working with a large number of tiles.
|
|
|
|
|
|
-You can flip and rotate sprites in the TileMap editor (note:
|
|
|
-flipping the sprite in the TileSet will have no effect). Icons at the
|
|
|
-top right of the editor allow flipping and rotating of the currently
|
|
|
-selected sprite - you can also use the A and S keys to flip the sprite
|
|
|
-horizontally and vertically. With a brick pattern like this tutorial uses,
|
|
|
-flipping the sprites would create unpleasant discontinuities unless you're
|
|
|
-flipping an entire region of bricks. But for some kinds of tiles, flipping
|
|
|
-can be a convenient and space-saving feature.
|
|
|
+Tips and tricks
|
|
|
+---------------
|
|
|
|
|
|
-Offset and scaling artifacts
|
|
|
-----------------------------
|
|
|
+- If you're using a :ref:`Camera2D <class_Camera2D>` to scroll your level, you
|
|
|
+ may notice lines appearing between your tiles. To fix this, open Project
|
|
|
+ Settings and enable "Use Pixel Snap" in the "Rendering/Quality" section.
|
|
|
|
|
|
-When using a single texture for all the tiles, scaling the tileset or moving it to a non pixel-aligned location can cause filtering artifacts:
|
|
|
+- You can flip and rotate tiles using the icons at the top right of the editor.
|
|
|
|
|
|
-.. image:: img/tileset_filter.png
|
|
|
+- To draw straight lines, hold <Shift> while clicking and dragging a tile.
|
|
|
|
|
|
-To avoid this situation use the approach below that makes the most sense for your game:
|
|
|
+- Tools such as copy, paste, and bucket fill, can be found in the "TileMap"
|
|
|
+ menu in the upper-right.
|
|
|
|
|
|
-- Disable filtering and mipmaps for either the tileset texture or all tile textures if using separate images (see the :ref:`doc_import_images` asset pipeline tutorial).
|
|
|
-- Enable pixel snap (Set ``Project > Project Settings >
|
|
|
- Rendering > Quality > 2d > Use Pixel Snap`` to true; you can also search for ``Pixel Snap``).
|
|
|
-- Viewport Scaling can often help with shrinking the map (see the
|
|
|
- :ref:`doc_viewports` tutorial). Adding a camera, setting it to ``Current`` and playing around with its ``Zoom`` may be a good starting point.
|
|
|
-- You can use a single, separate image for each tile. This will remove all artifacts, but
|
|
|
- can be more cumbersome to implement and is less optimized.
|
|
|
+.. image:: img/tilemap_menu.png
|