Learn Godot 4 by Making a 2D Platformer — Part 4: Level Creation #1

christine - Jul 20 '23 - - Dev Community

*You can find the links to the previous parts at the bottom of this tutorial.

At the beginning of this tutorial series, I told you that this game takes inspiration from the 1981 version of Donkey Kong. I’m bringing this up again because when I was studying the original version of the game to analyze its mechanics and gameplay, I found out that the original version of Donkey Kong only had four levels. Four levels seem incomparable to most games nowadays — I mean, we all probably know a guy who made it to level 506 in Candy Crush.

Figure 7: Donkey Kong Classic 4 Levels

Figure 7: Donkey Kong Classic 4 Levels

Back then, procedurally generated levels were not common. Procedural generation, where levels or content are generated algorithmically rather than manually designed, is a technique that has been used in many video games, especially in the roguelike genre and open-world games. However, the original Donkey Kong and its early successors primarily relied on handcrafted level design. This means that the developers created the levels themselves, which would explain why Donkey Kong only had four levels.

Creating a procedurally generated Donkey Kong-style level in Godot 4 involves algorithmically creating platforms, ladders, and other elements rather than manually placing them. Creating a procedurally generated Donkey Kong-style level in Godot 4 involves algorithmically creating platforms, ladders, and other elements rather than manually placing them. Since this is a beginners tutorial, we will not delve into the complexities of procedural generation today — and instead, we will keep it old-school, and make four levels — manually.

Along with a full tutorial series on advanced inventory, quest, and dialog systems, I’m also working on a separate series focusing on procedurally generated worlds and maps. These tutorials will be available for free later this year.


WHAT YOU WILL LEARN IN THIS PART:

  • How to create TileMap resources.
  • How to add physics and terrain layers.
  • How to change TileSet properties.

Let’s break apart the basics of one Donkey Kong level to identify the objects that our level would require:

Godot 2D Platformer

For now, we will only focus on adding our platforms, along with our ladders. We need to create each level with our start and end-point in mind. I recommend you read this article by MakeCode, which gives you a decent overview of Level Design fundamentals for Platformer games.

Let’s start with the basics first, which is drawing our game border (the outer four walls of our castle) onto our game screen. We will do this using the TileMap node. A tilemap is a grid of tiles used to create a game’s layout. To use tilemaps, you will need to create a TileSet first. A TileSet is a collection of tiles that can be placed in a TileMap node.

In simple terms, the Tilemap is the full set of tiles that we use to create our map or environment. For example:

Godot 2D Platformer

The Tileset is the tilemap resource that breaks the tilemap into small cubes which we then treat as individual objects. For example:

Godot 2D Platformer

Let’s add a new TileMap node to our Main scene. We’ll rename this node to Level.

Godot 2D Platformer

Godot 2D Platformer

To use this tilemap, we need to assign it with a TileSet resource. We can assign a new tileset resource in the Inspector Panel after selecting the TileMap node. We need to assign a “New TileSet” in the block next to your Tile Set property.

Godot 2D Platformer

This will open up two new resource blocks in your editor below: Tilemap and Tileset. We will use the Tilemap panel to draw our tilesets onto our screen, and we will use the Tileset panel to assign tilesheets to our Tilemap panel for drawing. We can also change the properties of our individual tiles in the Tileset panel.

Godot 2D Platformer

Let’s assign a new tilesheet to our Tilemap so that we can draw our castle border. To do this, click on your Tileset panel, and in your Filesystem Manager panel drag in the “res://Assets/Kings and Pigs/Sprites/14-TileSets/Terrain (32x32).png” tilesheet into your Tiles block. You can drag in as many tilesheets into this Tiles block as you want — since we will use many tilesheets to create our world.

Godot 2D Platformer

A popup will show asking you if you want to create a grid. Select yes because this will break our tilesheet into tiny manageable blocks.

Godot 2D Platformer

We can now go back to our Tilemap panel, where you will see your tilesheet available to you now. You can select, paint, and erase tiles using the tools above. If you select a tile and draw it onto your screen, it should be drawn as a new object!

Godot 2D Platformer

Here is an overview of the paint tools available in the Tilemap panel:

Godot 2D Platformer

Godot 2D Platformer

TILEMAP COLLISIONS

Before we start drawing our border, we first need to assign our floor and wall tiles with a physics layer. This will provide us with collision shapes for each tile. To do so, select the TileMap node, click the TileSet property value in the inspector to edit it then unfold Physics Layers and choose Add Element. We can now go back to our Tileset panel to configure our collision to our tiles.

Godot 2D Platformer

Here is an overview of the tools available in the TileSet panel:

Godot 2D Platformer

Godot 2D Platformer

Our tileset only contains cube-shaped items — since it only has floors and walls. Therefore, we can use our Paint mode panel to mass-add our collisions to our tiles. If we had different-shaped tiles, such as a tree, we would add the collisions for it in our Select mode panel since we would have to draw in the shapes for it.

We can draw in our individual collision shapes under the Physics Layer property in our Select and Paint mode panel. If you select a tile and navigate to its physics layer property, you can draw the shape in the block where the red outline is. It is here where you will draw out the shape of your item.

Godot 2D Platformer

As I mentioned prior, our shapes are simple squares, and therefore we can speed this process up in the Paint mode panel. Select the “Paint” panel and navigate to your physics layer property. You can still draw in the shape, just like in the Setup mode panel, but here we can mass-add this shape to many tiles. Let’s not alter this shape since we just need a cube. If you click on a tile, a blue box will outline it, which means that the collision shape from the box has been added to the tile!

Godot 2D Platformer

*Remember not to add collisions to tiles that you want your player to run through, or to tiles that you will use as backgrounds — since it will block your player.

Draw in your collisions as follows:

Godot 2D Platformer

TILEMAP TERRAINS

Now that we have our collisions added to our wall borders, we need to go ahead and draw them. We can do this manually by drawing each tile ourselves, or we can speed this process up via the use of autotiles. Godot offers terrainsto automatically create tile connections for tiles such as walls, floors, or terrains so that we don’t have to manually draw in the corners and edges of the tiles ourselves. This allows you to have the “correct” tile variants automatically used.

Figure 7: Terrains vs No Terrains

Figure 8: Terrains vs No Terrains

To add terrains, select the TileMap node, go to the inspector, and select your TileSet resource. Then add a new Terrain layer, which creates a terrain set that requires a terrain element. A terrain set could be something like “Grass”, and a terrain element could be something like “Grass_Forest”. The set will contain all the elements of the same category.

Godot 2D Platformer

Godot 2D Platformer

Let’s rename our Terrain Element to “Platform”. Also, change its color to one that is easily noticeable.

Godot 2D Platformer

Godot 2D Platformer

Now if we go into our Tileset panel, and under either our Setup or Paint mode, we can see that our Terrains property is now available to us. In the Select mode panel, you will see that our Terrain Set and Terrain both have ID values. -1 means “no terrain set” or “no terrain”, which means you must set Terrain Set to 0 or greater before you can set Terrain to 0 or greater. In our sense, Terrain Set “0” will contain all our platforms, with Terrain “0” being our “Platform” terrain element.

Godot 2D Platformer

You can then assign it bit peering values. The peering bits determine which tile will be placed depending on neighboring tiles. For example, if a tile has all its bits set to 0 or greater, it will only appear if all 8 neighboring tiles are using a tile with the same terrain ID. If a tile has its bits set to 0 or greater, but the top-left, top, and top-right bits are set to -1, it will only appear if there is space on top of it (including diagonally).

Godot 2D Platformer

We will not be assigning the bit peering values in the Select mode panel, but instead, we will be drawing them onto our map using the Paint mode panel. You can see in your Terrains property in the Paint mode panel, you can directly select the terrain element and set without providing an ID. Let’s select our Platform element.

Godot 2D Platformer

You can now draw in the bit-peering values by clicking on your tiles. Remember not to draw bit peering values onto obvious corners or sharp edges, since this will create awkward shapes when you draw your terrain.

Godot 2D Platformer

Draw in your Platform terrain as follows:

Godot 2D Platformer

If you now go back to your Tilemap panel, underneath Terrains, you can see that the “autotiles” for your Platform element have been created. If you select your Platform element, and you draw onto your map, the shapes should be automatically created and matched!

Godot 2D Platformer

Let’s create two new terrain elements in our Terrain Set. Call them “Platform_Wall” and “Platform_Floor”.

Godot 2D Platformer

Draw in your Platform_Wall terrain as follows:

Godot 2D Platformer

Draw in your Platform_Floor terrain as follows:

Godot 2D Platformer

If you now go back to your Tilemap panel, underneath Terrains, your new terrains should be created.

Godot 2D Platformer

Godot 2D Platformer

Let’s use these terrains and draw a border around the edge of our game screen — which is the blue border. Make sure your Player is kept within this border.

Godot 2D Platformer

Godot 2D Platformer

Before we test this out, we first need to fix our Player collision shape. If you enable your collisions in your Debug > Visible Collision Shapes option, and you run your scene, you will notice that the collision shape is far away from our player if they are running left or right (due to the space in the animation frame). This is a problem because if an obstacle hits our collision shape, our player will lose lives later on even though it hasn’t technically hit us!

Godot 2D Platformer

Godot 2D Platformer

Godot 2D Platformer

We can fix this issue by centering our collision shape to our AnimatedSprite2D node. Let’s change the CollisionShape2D node’s x position to have an offset of -7. This will center our shape at the start of the game. In your Inspector Panel, underneath Transform > Position, change the x value to -7, which will center the shape. Also make sure the shape of your Rectangle covers your player’s entire body.

Godot 2D Platformer

Now, in our code, we need to keep this shape centered when our player changes sides — since the animation has a space offset.



    ### Player.gd

    #older code 

    #animations
    func player_animations():
        #on left (add is_action_just_released so you continue running after jumping)
        if Input.is_action_pressed("ui_left") || Input.is_action_just_released("ui_jump"):
            $AnimatedSprite2D.flip_h = true
            $AnimatedSprite2D.play("run")
            $CollisionShape2D.position.x = 7

        #on right (add is_action_just_released so you continue running after jumping)
        if Input.is_action_pressed("ui_right") || Input.is_action_just_released("ui_jump"):
            $AnimatedSprite2D.flip_h = false
            $AnimatedSprite2D.play("run")
            $CollisionShape2D.position.x = -7

        #on idle if nothing is being pressed
        if !Input.is_anything_pressed():
            $AnimatedSprite2D.play("idle")


Enter fullscreen mode Exit fullscreen mode

Your code should look like this.

If we run our scene now, our border should block our player from falling since we have collisions on it, and we can finally jump around! Our collision shape should also now stay centered to our Player’s position.

Godot 2D Platformer

Godot 2D Platformer

That is all we’ll be doing for this part. I’d like you to take a break and go over these concepts that you’ve just learned — and read the documentation from the links provided to get a solid understanding of terrains, tilemaps, and tilesets. In the next part, we’ll be adding our ladder plus the rest of our platforms. Now would be a good time to save your project and make a backup of your project so that you can revert to this part if any game-breaking errors occur. Go back and revise what you’ve learned before you continue with the series, and once you’re ready, I’ll see you in the next part!


Next Part to the Tutorial Series

The tutorial series has 24 chapters. I’ll be posting all of the chapters in sectional daily parts over the next couple of weeks. You can find the updated list of the tutorial links for all 24 parts of this series on my GitBook. If you don’t see a link added to a part yet, then that means that it hasn’t been posted yet. Also, if there are any future updates to the series, my GitBook would be the place where you can keep up-to-date with everything!

Godot 2D Platformer


Support the Series & Gain Early Access!

If you like this series and would like to support me, you could donate any amount to my KoFi shop or you could purchase the offline PDF that has the entire series in one on-the-go booklet!

The booklet gives you lifelong access to the full, offline version of the “Learn Godot 4 by Making a 2D Platformer” PDF booklet. This is a 451-page document that contains all the tutorials of this series in a sequenced format, plus you get dedicated help from me if you ever get stuck or need advice. This means you don’t have to wait for me to release the next part of the tutorial series on Dev.to or Medium. You can just move on and continue the tutorial at your own pace — anytime and anywhere!

Godot 2D Platformer

This book will be updated continuously to fix newly discovered bugs, or to fix compatibility issues with newer versions of Godot 4.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .