diff --git a/tutorials/2d/img/tilemap_add_tile.png b/tutorials/2d/img/tilemap_add_tile.png new file mode 100644 index 000000000..bc22128ee Binary files /dev/null and b/tutorials/2d/img/tilemap_add_tile.png differ diff --git a/tutorials/2d/img/tilemap_add_tileset.png b/tutorials/2d/img/tilemap_add_tileset.png new file mode 100644 index 000000000..54479d80a Binary files /dev/null and b/tutorials/2d/img/tilemap_add_tileset.png differ diff --git a/tutorials/2d/img/tilemap_draw.png b/tutorials/2d/img/tilemap_draw.png new file mode 100644 index 000000000..445ad5f54 Binary files /dev/null and b/tutorials/2d/img/tilemap_draw.png differ diff --git a/tutorials/2d/img/tilemap_menu.png b/tutorials/2d/img/tilemap_menu.png new file mode 100644 index 000000000..b166ff011 Binary files /dev/null and b/tutorials/2d/img/tilemap_menu.png differ diff --git a/tutorials/2d/img/tilemap_mode.png b/tutorials/2d/img/tilemap_mode.png new file mode 100644 index 000000000..9bea02056 Binary files /dev/null and b/tutorials/2d/img/tilemap_mode.png differ diff --git a/tutorials/2d/img/tilemap_size.png b/tutorials/2d/img/tilemap_size.png new file mode 100644 index 000000000..32713aff2 Binary files /dev/null and b/tutorials/2d/img/tilemap_size.png differ diff --git a/tutorials/2d/img/tilemap_tool.png b/tutorials/2d/img/tilemap_tool.png new file mode 100644 index 000000000..b41f0bc0f Binary files /dev/null and b/tutorials/2d/img/tilemap_tool.png differ diff --git a/tutorials/2d/img/tileset_add_collision.png b/tutorials/2d/img/tileset_add_collision.png new file mode 100644 index 000000000..065621215 Binary files /dev/null and b/tutorials/2d/img/tileset_add_collision.png differ diff --git a/tutorials/2d/img/tileset_atlas.png b/tutorials/2d/img/tileset_atlas.png new file mode 100644 index 000000000..9eba838d5 Binary files /dev/null and b/tutorials/2d/img/tileset_atlas.png differ diff --git a/tutorials/2d/img/tileset_draw_atlas.png b/tutorials/2d/img/tileset_draw_atlas.png new file mode 100644 index 000000000..cf609ffd9 Binary files /dev/null and b/tutorials/2d/img/tileset_draw_atlas.png differ diff --git a/tutorials/2d/img/tileset_snap.png b/tutorials/2d/img/tileset_snap.png new file mode 100644 index 000000000..bcf5074ae Binary files /dev/null and b/tutorials/2d/img/tileset_snap.png differ diff --git a/tutorials/2d/img/tilesheet.png b/tutorials/2d/img/tilesheet.png new file mode 100755 index 000000000..642333df8 Binary files /dev/null and b/tutorials/2d/img/tilesheet.png differ diff --git a/tutorials/2d/using_tilemaps.rst b/tutorials/2d/using_tilemaps.rst index bf20d6875..0485c7b3e 100644 --- a/tutorials/2d/using_tilemaps.rst +++ b/tutorials/2d/using_tilemaps.rst @@ -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 ` 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 ` +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/tilemap.png +.. image:: img/tileset_draw_atlas.png -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. - -Making a tileset ----------------- - -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. - -.. image:: img/tileset.png - -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. - -The easiest way to edit and maintain a tileset is exporting -it from a specially prepared scene. We'll create that next. - -TileSet scene +Project setup ------------- -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. +This demo we'll use the following tiles taken from Kenney's "Abstract Platformer" +art pack. You can find the complete set `here `_ +but for this demo we'll stick to this small set. -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. +.. image:: img/tilesheet.png -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**. +Create a new project and place the above image in the project folder. -Here's a screenshot that shows -where everything of relevance is: +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/tile_example.png +TileMap node +------------ -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*. +Add a new :ref:`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. -.. image:: img/tile_example2.png +.. image:: img/tilemap_mode.png + +Under the "Cell" section in the Inspector are many properties you can adjust to +customize your tilemap's behavior: + +.. image:: img/tilemap_size.png + +- ``Cell Size`` + This defines the size of the grid. This should match the pixel size + of your tiles. The default value is ``(64, 64)``. + +- ``YSort`` + This causes tiles to be drawn in order of their ``Y`` position, so that + "lower" tiles are drawn on top of "higher" ones. + +- ``Half Offset`` and ``Tile Origin`` + These properties affect the position of the tile relative to the grid position. + +- ``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. + +- ``Custom Transform`` + Used to alter the tile's shape. Use this if you have non-square tiles. + +All of these options can be left at their defaults for this demo. + +Creating a TileSet +------------------ + +Once you've configured your tilemap, it's time to add a +:ref:`TileSet `. A TileSet is a +:ref:`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. + +To add a new TileSet, click on the "Tile Set" property and select "New +TileSet". + +.. image:: img/tilemap_add_tileset.png + +When you do this, the "TileSet" panel will open at the bottom of the editor +window: + +.. image:: img/tilemap_tool.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. + +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. + +.. image:: img/tilemap_add_tile.png + +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/tilemap_draw.png + +It's easy to accidentally select and move the tilemap node. To avoid this, use +the node's lock button: + +.. image:: img/tile_lock.png Collision Shapes ---------------- -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. +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". -.. image:: img/tile_example3.png +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: -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/tileset_add_collision.png -.. image:: img/tile_example4.png +You can add occlusion and navigation shapes to the tile in the same way. -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. +Atlas tiles +----------- -.. image:: img/tile_example5.png +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. -Then save this scene for future editing. -"tileset_edit.scn" would be a sensible name for it. +.. image:: img/tileset_atlas.png -Exporting a TileSet -------------------- +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: -With the scene created and still open in the editor, use Scene > Convert To > Tile Set from the Scene Menu: +.. image:: img/tileset_snap.png -.. image:: img/tileset_export.png +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. -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**). +Back in the TileMap, you can select the atlas tile and you'll see all of the +tiles it contains: -.. image:: img/tileset_merge.png +.. image:: img/tileset_draw_atlas.png -Using the TileSet in a TileMap ------------------------------- +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. -Create a new scene, using any node or node2d as root, and then create a -:ref:`TileMap ` as -a child. +Tips and tricks +--------------- -.. image:: img/tilemap_scene.png +- If you're using a :ref:`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. -Go to the TileSet property of this node and assign the one created in -previous steps: +- You can flip and rotate tiles using the icons at the top right of the editor. -.. image:: img/tileset_property.png +- To draw straight lines, hold while clicking and dragging a tile. -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. +- Tools such as copy, paste, and bucket fill, can be found in the "TileMap" + menu in the upper-right. -Painting your world -------------------- - -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. - -.. image:: img/tile_example6.png - -It's easy to accidentally select and move the tilemap node. To avoid this -use the node's lock button: - -.. image:: img/tile_lock.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. - -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. - -Offset and scaling artifacts ----------------------------- - -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: - -.. image:: img/tileset_filter.png - -To avoid this situation use the approach below that makes the most sense for your game: - -- 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 \ No newline at end of file