Merge pull request #2474 from cbscribe/tilemap_update

Update TileMap tutorial for 3.1
This commit is contained in:
Max Hilbrunner
2019-05-28 18:10:08 +02:00
committed by GitHub
13 changed files with 127 additions and 125 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
tutorials/2d/img/tilesheet.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -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/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 <https://kenney.nl/assets/abstract-platformer>`_
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 <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.
.. 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 <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.
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 <class_TileMap>` as
a child.
Tips and tricks
---------------
.. image:: img/tilemap_scene.png
- 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.
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 <Shift> 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