Skip to main content
Header image

Discover Godot, an Open Source Game Engine

Discover an open-source game engine with nothing to be ashamed of the bigger ones.

What is Godot? #

Godot is a free and open-source game engine released in 2007 and written in C and C++. A game engine is an application that can help you develop your games using a GUI with many features already included inside it.
To name a few: Physics, collision detection, image, audio, and so many others.
You can use it for 2D or 3D games as well.

The advantage of using a game engine is to develop in one place and export in many different ones, like Windows, macOS, Linux, or on mobile for iOS and Android.

There are a lot of game engines in the marketplace, but today I want to talk about Godot, why I love it, and why I use it.

This tutorial presents you Godot 4 and not Godot 3.

Discover Godot together #

This is the stater interface when you just created your project:

Godot Starter Interface

Quit neat and straightforward! Let’s discover each part of the interface that I marked with numbers on the image.

  1. It is the scene. It is where you will put your game objects. In 3D games, it could be the character, a wall, a door, a… you got it, I think.
    In 2D, it could be an image, a tilemap, or any 2D stuff required for your game.
  2. It is the architecture of your nodes. A node is a game object where you attach a script to apply any behavior you want.
    But every node has a particular specificity; it could be an image, a timer, or many other things useful to build a game. Each node has properties that can be changed in the inspector to change the defaults behaviors of a node. We will see it later in this tutorial.
  3. The toolbar, this is where you can select tools used to manipulate a node, like moving or rotating, for example.
    Scenes tabs will also be displayed there, allowing you to switch between them as you can with browsers.
  4. You may create a 3D, perhaps a 2D game; here, you can select which game you want. The plane will adapt depending on your choice. On the above picture, the 3D plane is selected. Here is how the 2D one is rendered:

Godot 2D Plane

The third tab is Script; it’s where you will code. Yes, you read well; Godot has a built-in editor that allows you to code directly inside it, with autocompletion, documentation, and coffee… OK, maybe not this one, but you can open a PR for this 😉

AssetLib allows you to install assets to extend your game’s functionalities.

  1. This is the inspector. As I said before, when you click on a node, in this part of the interface, you can change values that will affect the node itself. For example, if you have a sprite node, you can change its angle in the inspector.
    Take a look at the video to see it in action:

Powerful isn’t it?! 😎

  1. The files inspector. This is where you can see all the files of your project. You can create, delete, rename, or organize all files.

Development #

You may be wonder which languages you can develop your game with Godot; by default, you can choose GDScript or C#. I can bet that you don’t know one of these two languages. It’s logical, GDScript has been developed for Godot, and it is the official language of the engine. Don’t go Google it; here is the link to learn the basics.

BUT! It does not stop here! You can use more languages to develop with Godot. People out there are fantastic and created bindings to allow using other languages like Rust or Golang to work with Godot. I let you Google it this time because I will focus on GDScript in this tutorial.

GDScript #

GDScript is a language developed especially for Godot; its syntax is very close to Python.
In Godot 4, GDScript has been updated to version 2, allowing it to do more than it can do in Godot 3.x.

Let’s take look at the basic syntax.

# Declare a variable of type "int" and assign it the value 10.
var my_var: int = 10

# Declare a variable and assign it the value 10.
# Short variable declarations (:=) will let the compiler
# determine the variable type.
# Here it will assume that the type is "int" as the value is an integer.
var my_var := 10

# Function declaration with one parameter of type "string".
func my_function(my_param: String):
	# Print to the console the parameter.
	print(my_param)

I’m sure you can see some similarities with Python now, and yes, the indentations define the code blocks.

For sure, there are some differences, like variables declarations need to have the keyword var or const at the beginning or to use func instead of def.

Move the sprite in the window #

We will learn how to move the sprite we created in the upper video.

Moving the sprite in the window is possible, but we want something else; a sprite alone is useless. You will need to make the sprite a child of another node, a CharacterBody2D.
The CharacterBody2D node helps create a playable character controlled by a script. Here is the official description:

Specialized 2D physics body node for characters moved by script.

You need to know that Godot is full of valuable shortcuts, and you will understand. Right-click on the sprite and click on Reparent on New Node.
Select the node CharacterBody2D and validate. Your sprite is now a child of the node CharacterBody2D; isn’t that cool?

Create and attach a script to the CharacterBody2D node #

To create a script, right-click on the node CharacterBody2D and click on Attach Script. A window will open; change the path where you want to save your script and click on Create. I recommend you create a folder called scripts at the root of your project and save scripts inside.

The script editor will open automatically. Create a function called _physics_process as the following:

func _physics_process(delta):
	pass

If you are unfamiliar with Python, pass is a placeholder keyword that does nothing. It is used to prevent the script from crashing if no code is written inside the function.

Like Pyhton, GDScript uses indentation to define code blocks.

I know you are wondering what is the delta parameter 🤔 It is the time between two frames. A game runs at 60 frames every second so the delta parameter will give you the time elapsed from one frame to the next one.

Move the sprite #

The physics process function is called every frame, and as we need to move the sprite and detect collisions, this is the right place to do it.

Update your code as follows:

var axis: Vector2 = Vector2.ZERO

func _physics_process(delta):
	# Check if the user is pressing the up key.
	if Input.is_action_pressed("ui_up"):
		axis.y -= 1
	# Check if the user is pressing the down key.
	elif Input.is_action_pressed("ui_down"):
		axis.y += 1
	else:
		# Nether up or down is pressed, reset the axis.y value.
		axis.y = 0

Let’s take a look step by step at what we just did. First, we add a variable called axis of type Vector2 with a default value of 0, which means x = 0 and y = 0.
Then, we check if the user is pressing the up key; if so, decrease the axis.y value by 1, which means that the sprite will move up. If the user is pressing the down key, increase the axis.y value by 1, which means that the sprite will move down. In case the user is doing none of these actions, we set the axis.y value to 0 to reset the movement.

That’s great, but still not enough… OK, let’s add the left and right movements:

if Input.is_action_pressed("ui_left"):
	axis.x -= 1
elif Input.is_action_pressed("ui_right"):
	axis.x += 1
else:
	axis.x = 0

Very little has changed here except checking if the user is pressing left or right; there is no need for further explanation.

One more thing before having fun 😅 The vector needs to be normalized. To do so, add the following line after the lines we just added:

axis = axis.normalized()

So simple 😎 Maybe you are wondering why we are doing this. Well, if you press right, you will move by 1 pixel, but if you press up and right simultaneously, you will move by 1.41 pixels, not one as you may think!

To understand why, you must know how to calculate a vector length. x = 1^2 and y = 1^2, so x + y = 2 as 1^2 = 1; then, you need to calculate the square root of 2, which is 1.41.

OK, finally, we reached the last part to be able to move the sprite! Add the following after the line we just added:

move_and_collide(axis * 300 * delta)

Move and collide is a built-in method of the CharacterBody2D node. It is used to move the node and detect collisions with other nodes, but this is different from the subject of this tutorial.

The axis represents the vector with just created, the 300 is a speed value, and the delta is the time between two frames. It is essential to multiply with the delta; if you don’t do this, the node will move faster on a computer with high performance, to put it simply. This allows you to run your game the same on every computer, and it considers whether your computer is lagging or not.

Run the project #

I’m sure you can’t wait to run the game! To do so, click on the Play Scene button at the top right of the editor.

How to run the project

The difference between the Play Scene and the left one, which is the Play button, is simple; the Play button will run the main scene of your game, and the Play Scene will run the scene you are currently working on.

You will have this result:

Add a speed variable #

Hard coding something in a script is a bad practice. Create a variable to store the speed value:

var speed: int = 300

# Other code

move_and_collide(axis * speed * delta)

Much better!

The full script #

extends CharacterBody2D

var speed: int = 300
var axis: Vector2 = Vector2.ZERO


func _physics_process(delta: float) -> void:
	# Check if the user is pressing the up key.
	if Input.is_action_pressed("ui_up"):
		axis.y -= 1
	# Check if the user is pressing the down key.
	elif Input.is_action_pressed("ui_down"):
		axis.y += 1
	else:
		# Nether up or down is pressed, reset the axis.y value.
		axis.y = 0

	# Same as before, but for the keys left and right.
	if Input.is_action_pressed("ui_left"):
		axis.x -= 1
	elif Input.is_action_pressed("ui_right"):
		axis.x += 1
	else:
		axis.x = 0

	# Normalize the vector.
	axis = axis.normalized()

	# Move the node and detect collisions.
	move_and_collide(axis * speed * delta)

A last one more tip #

Input.is_action_pressed("key") returns a boolean; casting it to an int will return 1 if the key is pressed and 0 if not.

You can simplify the code a bit by doing as follows:

extends CharacterBody2D

var speed: int = 300
var axis: Vector2 = Vector2.ZERO


func _physics_process(delta: float) -> void:
	axis.y = int(Input.is_action_pressed("ui_down")) - int(Input.is_action_pressed("ui_up"))
	axis.x = int(Input.is_action_pressed("ui_right")) - int(Input.is_action_pressed("ui_left"))

	axis = axis.normalized()

	move_and_collide(axis * speed * delta)

This will give the same result as the previous script but is a bit more compact. Let’s understand how this works.

If you press the key down, the result will be 1 - 0 = 1, so you will go down; if you press up only, the result will be 0 - 1 = -1, so you will go up. The same thing happens for the left and right keys.

Awesome, right? 😎

Conclusion #

You learned what Godot Engine is and how to use it and play a little with it.
You will want to continue your journey with Godot and create some awesome games!

Thank you for reading me. If you enjoyed this article and consider offering me a ☕, I will be very grateful, and it will help me write new articles.

Tags

See Also

No results...