designates my notes. / designates important. / designates very important.
Download the game assets from the following link below and unzip them into your new project folder: https://github.com/PacktPublishing/Godot-4-Game-Development-Projects-Second-Edition/tree/main/Downloads
You can also find the complete code for this chapter on GitHub at: https://github.com/PacktPublishing/Godot-4-Game-Development-Projects-Second-Edition/tree/main/Chapter02%20-%20Coin%20Dash
_process()
function is called on every frame, so you can use it to
update elements of your game that you expect to change often.The _process()
function includes a parameter called delta that is then
multiplied by velocity.
What is delta?
The game engine attempts to run at a constant 60 frames per second. However, this can change due to computer slowdowns, either in Godot or from other programs running on your computer at the same time. If the frame rate is not consistent, then it will affect the movement of objects in your game. For example, consider an object that you want to move at 10 pixels every frame. If everything runs smoothly, this will mean the object moves 600 pixels in one second. However, if some of those frames take a bit longer, then there may have been only 50 frames in that second, so the object only moved 500 pixels.
Godot, like many game engines and frameworks, solves this by passing you a value called delta, which is the elapsed time since the previous frame. Most of the time, this will be very close to 0.016 seconds (around 16 milliseconds). If you then take your desired speed of 600 px/second and multiply it by delta, you’ll get a movement of exactly 10 pixels. If, however, delta increased to 0.3 seconds, then the object would move 18 pixels. Overall, the movement speed remains consistent and independent of the frame rate.
As a side benefit, you can express your movement in units of pixels per second rather than pixels per frame, which is easier to visualize.
Getting nodes
When using the $ notation, the node name is relative to the node running the script. For example, $Node1/Node2 would refer to a node (Node2) that is a child of Node1, which is itself a child of the node that runs the script. Godot’s autocomplete will suggest node names as you type. Note that if the name contains spaces, you must put quote marks around it – for example, $“My Node”.
see: [[Godot - Node Paths]]
Download the game assets from the following link below and unzip them into your new project folder: https://github.com/PacktPublishing/Godot-4-Game-Development- Projects-Second-Edition/tree/main/Downloads
You can also find the complete code for this chapter on GitHub at: https://github.com/ PacktPublishing/Godot-4-Game-Development-Projects-Second-Edition/ tree/main/Chapter03%20-%20Space%20Rocks
In game development, you often need to know when two objects in the game space intersect or come into contact. This is known as collision detection. When a collision is detected, you typically want something to happen. This is known as collision response.
Godot offers three kinds of physics bodies, grouped under the PhysicsBody2D node type:
StaticBody2D: A static body is one that is not moved by the physics engine. It participates in collision detection but does not move in response. This type of body is most often used for objects that are part of the environment or do not need to have any dynamic behavior, such as walls or the ground.
RigidBody2D: This is the physics body that provides simulated physics. This means that you don’t control a RigidBody2D physics body’s position directly. Instead, you apply forces to it (gravity, impulses, and so on) and Godot’s built-in physics engine calculates the resultant movement, including collisions, bouncing, rotating, and other effects.
CharacterBody2D: This body type provides collision detection but no physics. All movement must be implemented in code, and you must implement any collision response yourself. Kinematic bodies are most often used for player characters or other actors that require arcade-style physics rather than realistic simulation, or when you need more precise control over how the body moves.
Connecting signals to preexisting functions.
func _physics_process(delta):
rotation += deg_to_rad(rotation_speed) * delta
follow.progress += speed * delta
position = follow.global_position
if follow.progress_ratio >= 1:
queue_free()
Introduction to particle effects.
A platformer requires gravity, collisions, jumping, and other physics behavior, so you might think that RigidBody2D would be the perfect choice to implement the character’s movement. In practice, you’ll find that the more realistic physics of the rigid body are not desirable for a platform character. To the player, realism is less important than responsive control and an action feel. So, as the developer, you want to have precise control over the character’s movements and collision response. For this reason, a kinematic style of physics is usually the better choice for a platform character.
The CharacterBody2D node is designed for implementing physics bodies that are to be controlled directly via code.
Do the same with the score_changed signal of the Level node, connecting it to the HUD’s update_score() method.
Note that if you don’t want to use the scene tree to connect the signals, or if you find the signal connection window confusing or difficult to use, you can accomplish the same thing in your script by adding these lines to the _ready() function of level.gd:
$Player.life_changed.connect($CanvasLayer/HUD.update_life)
score_changed.connect($CanvasLayer/HUD.update_score)
Tweens
var tween = create_tween().set_process_mode(Tween.TWEEN_PROCESS_PHYSICS)
tween.set_loops().set_parallel(false)
tween.tween_property($TileMap, "position", offset, duration / 2.0).from_current()
tween.tween_property($TileMap, "position", Vector2.ZERO, duration / 2.0)
set_loops()
tells tween to repeat once finished.• set_parallel(false)
tells tween to perform the two property tweens
sequentially rather than at the same time.
tween.set_trans(Tween. TRANS_SINE)
, for example, will make the platform slow
down at the ends of the movement for a more natural look. Try experimenting with
the other transition types..gltf
. It has the most features and is
very well supported in Godot.You may have noticed that as you’re moving the mouse, it can leave the game window, and when you click, you don’t interact with the game anymore. Most 3D games solve this problem by capturing the mouse – locking the mouse to the window. When you do this, you also need to give the player a way to free the mouse so that they can close the program or click on other windows, and a way to re-capture it to come back to the game.
For this game, you’ll capture the mouse at first, and then if the player presses Esc, free it and pause the game. Clicking in the game window will un-pause and resume.
All of this functionality is controlled through the Input.mouse_mode property. Then, mouse_mode can be set to one of the following values:
• MOUSE_MODE_VISIBLE: This is the default mode. The mouse is visible and free to move in and out of the window.
• MOUSE_MODE_HIDDEN: The mouse cursor is hidden.
• MOUSE_MODE_CAPTURED: The mouse is hidden and its position is locked to the window.
• MOUSE_MODE_CONFINED: The mouse is visible, but confined to the window.
func get_input(delta):
pitch_input = Input.get_axis("pitch_down", "pitch_up")
roll_input = Input.get_axis("roll_left", "roll_right")
You’ll notice that the path for the save file doesn’t begin with res:// like all of the other files you’ve been working with. The res:// designation represents your game’s project folder – the place where all the scripts, scenes, and assets are located. When you export your game, though, that folder becomes read-only. To store persistent data, you use a location on the device that’s set aside for the game to write to: user://. Where this folder is actually located depends on the operating system you’re using. For example, in Windows, it would be %APPDATA%\Godot\app_userdata[project_name].
You can find the paths for other supported operating systems here:
https://docs.godotengine.org/en/stable/tutorials/io/data_paths.html
[[Blender]]
The most common workflow is to export glTF files from Blender and import them into Godot. This is a stable and reliable workflow and will work well in most situations.
When you export a glTF file, you have two options: glTF binary (.glb) and glTF text (.gltf). The binary version is more compact and is therefore the preferred format, but either will work fine.
It’s common to import meshes from Blender and then make modifications such as adding collisions or removing unneeded nodes. To simplify this, you can add suffixes to the names of your objects to give Godot a hint about how you want them to be processed on import. Here are some examples:
• -noimp
– These objects will be removed from the imported scene.
• -col
, -convcol
, -colonly
– These options tell Godot to make a collision shape from
the named mesh. The first two options make a child triangle mesh or convex polygon shape,
respectively. The -colonly
option will remove the mesh entirely and replace it with a
StaticBody3D collision.
-rigid
– This object will be imported as a RigidBody3D.• -loop
– Blender animations with this suffix will be imported with the loop
option enabled.
With Godot 4, you have an additional option: importing .blend files directly into your Godot project. In order to use this feature, you need to have Blender installed on the same computer you’re using for Godot.
To set it up, open Editor Settings and look under FileSystem | Import. Here, you can set the path where you’ve installed Blender.