Let us start another Godot Engine game tutorial for beginners. This will be a multipart tutorial series where we are going to create a simple top down 2D car racing game. The goal of this tutorial is to familiarise with the concepts and the workflow of Godot Engine. Once we understand these, it is very easy to make things with it.
If you don’t know, all the tutorials published in this blog were focused primarily towards mobile devices and this tutorial is no different. The game we are making is like a highway racer where the player needs to avoid other cars on the track. We can switch the lane by tapping on either side of the screen.
Create The Project
Create a Godot project somewhere on your computer. After creating the project we will be greeted with the Godot Editor window. As we need to setup some parameters in the project settings, go to the Menu > Scene > Project Settings and set the properties under the Display category like below:
width – 540
height – 960
test_width – 320
test_height – 480
orientation – portrait
stretch_mode – 2d
stretch_aspect – keep_height
The test_width and test_height can be changed as we prefer because this only affect the dimensions of the Godot play mode window while editing.
Now we can create our folder structure inside the project directory like this.
Download the assets required for this project from here. Now copy all the image assets into ‘assets/images’ folder. Great, project setup is done and we can create our first scene – the game scene.
Setup game scene
Add a Node2D to the scene and add a Sprite as its child. Rename the Node2D as ‘main’ and the Sprite as ‘bg’.
Setup the road
Select the ‘bg’ node and set the ‘road.png’ texture as its texture. We can do this by clicking the option for Texture property and click the Load option. Then choose the road.png image in the assets folder.
For 2d games, it is desirable to disable texture mipmaps so that our texture will look better. To do that, after choosing the texture, click on the small arrow to the right of the texture. Under the flags property, uncheck mipmaps. We are going to scroll the road texture to make the illusion of car movement, we need to check the Repeat flag also. We can also access this texture properties by double clicking the texture inside the Filesystem tab.
After setting up the texture, we need to align the road to the center of our game world. Our game dimensions is 540×960, so set the road position to 270, 480.
Creating the Player Car
We can add a Sprite and set the texture to display the car object. But there are some things to consider before we setup the car. The car has to collide with opponent cars. Godot Sprite node will not collide with anything and if we want something to follow physics we need to add nodes which exhibits some physics properties. Godot has built-in support for 2d and 3d physics and there are a bunch of nodes for physics.
RigidBody enables the object to follow physics behaviours.
There are two RigidBody nodes in Godot, RigidBody and RigidBody2D – for 3d and 2d respectively. The Rigidbody2D also has to know the shape of the object so that the collisions are calculated based on that shape. Create the player car like this.
The Rigidbody2D(renamed to Player) node will be the parent node for the player car, the Sprite node will display the car texture and the CollisionShape2D node will define the shape of the car. When we change the position of the RigidBody2D via script, all of its children will change their positions relatively. For this to work as expected, we need to make sure all the children under the parent node are positioned at 0,0.
Position the Player node at 270, 775 by setting the pos property of the ‘Player’ node in the inspector. Don’t try to drag the node using mouse. I will explain the problem below. For now just set the position in inspector by typing the values.
Set the Sprite’s properties as shown,
Make sure you disable the mipmapping for the car texture as we did for the road texture.
A CollisionShape/CollisionShape2D defines the collision shape for the parent RigidBody/RigidBody2D.
You may have noticed the warning sign on the CollisionShape2D node. This is Godot’s way of telling that the CollisionShape2D object requires a collision shape definition which is not set. It doesn’t know what shape it is – square, rectangle or a circle shape. Click on the sign and it shows this popup
To set the collision shape, select the CollisionShape2D in the hierarchy. Our car is in rectangle shape so set its shape property to New RectangleShape2D.
Now we need to define the bounds of the RectangleShape2D. We can set the rectangle width and height by dragging the two dots as shown below. Make sure to drag the inner dots which define the collision bounds. The outer dots are for scaling the node which if dragged, will mess up all collisions. If you have doubt, check if the CollisionShape2D node’s scale is 1,1. If it is different, set it to 1,1 and redo the step again.
Linking the children
This is the problem I told earlier. If we try to move the Player node using mouse, it won’t move the Player node, instead the CollisionShape2D child is moved. This is because the CollisionShape2D node is the top most one. This is not that good but Godot editor offers a nice option to link all the children so that if we drag on the object, the children are not moved and the parent object is moved. We don’t want to accidentally move the collision and sprite nodes.
Now save the scene as game.tscn under ‘/scenes’ folder. Test the game by pressing the Play button. We now need to select a default scene because Godot tells us to do so.
The popup has the option to select a default scene from there itself, click on the Select button and choose game.tscn. We can also do this by going to Project Settings. Press Play again, the game window appears.
There is some problem, the objects are offset. This is because we didn’t add any camera. We don’t have to add a camera but the mobile devices have different screen sizes and we need to make sure the game displays perfect on every screens.
Adding a Camera
Remember, we set the project width and height as 540×960 but the bg image width and height is 640×960. The extra width is to compensate for devices with different screen sizes. To display this correctly we need to add a Camera2D node and position it to the center of our game world which is 270, 480. Make sure to enable the ‘Current’ property of the Camera otherwise, the game will not display correctly.
If we run now, we see that the game is displayed correctly. One last step and we will conclude this part.
Creating the Player PackedScene
Right click on the Player node and select Save Branch as Scene in ‘packed/player’ folder. This will make the Player node as a PackedScene. A PackedScene can be loaded using script and can be instantiated multiple times. We don’t have to do this for the Player node, but we will do it so the node is not scattered inside the scene hierarchy.
That’s all for this part. In the next part, we will add opponents and spawn them on the track. Thanks for reading.
Read the next part of this tutorial here.
You can download the project source from here.