Book Image

Godot 4 Game Development Projects - Second Edition

By : Chris Bradfield
5 (1)
Book Image

Godot 4 Game Development Projects - Second Edition

5 (1)
By: Chris Bradfield

Overview of this book

Godot 4.0 is one of the most sought-after open-source game engines, and if you’re enthusiastic about exploring its features, then this book is for you. Written by an author with over twenty-five years of experience, the Godot 4 Game Development Projects introduces the Godot game engine and its feature-rich 4.0 version. With an array of new capabilities, Godot 4.0 is a strong alternative to expensive commercial game engines. If you’re a beginner, this book will help you learn game development techniques, while experienced developers will understand how to use this powerful and customizable tool to bring their creative visions to life. This updated edition consists of five projects with an emphasis on the 3D capabilities of the engine that will help you build on your foundation-level skills through small-scale game projects. Along the way, you’ll gain insights into Godot’s inner workings and discover game development techniques that you can apply to your projects. Using a step-by-step approach and practical examples, this book covers everything from the absolute basics to sophisticated game physics, animations, and much more. By the time you complete the final project, you’ll have a strong foundation for future success with Godot 4.0 and you’ll be well on your way to developing a variety of games.
Table of Contents (10 chapters)

Part 3 – the Main scene

The Main scene is what ties all the pieces of the game together. It will manage the player, the coins, the clock, and all the other pieces of the game.

Node setup

Create a new scene and add a Node named Main. The simplest type of node is Node – it doesn’t do much at all on its own, but you’ll use it as the parent for all the game objects and add a script that will give it the functionality you need. Save the scene.

Add the player as a child of Main by clicking the Instantiate Child Scene button and choosing your saved player.tscn:

Figure 2.23: Instantiating a scene

Figure 2.23: Instantiating a scene

Add the following nodes as children of Main:

  • A TextureRect node named Background – for the background image
  • A Timer node named GameTimer – for the countdown timer

Make sure Background is the first child node by dragging it above the player in the node list. Nodes are drawn in the order shown in the tree, so if Background is first, that ensures it’s drawn behind the player. Add an image to the Background node by dragging the grass.png image from the assets folder into the Texture property. Change Stretch Mode to Tile, and then set the size to Full Rect by clicking the layout button at the top of the editor window:

Figure 2.24: Layout options

Figure 2.24: Layout options

Main script

Add a script to the Main node and add the following variables:

extends Node
@export var coin_scene : PackedScene
@export var playtime = 30
var level = 1
var score = 0
var time_left = 0
var screensize = Vector2.ZERO
var playing = false

The Coin Scene and Playtime properties now appear in the Inspector window when you select the Main node. Drag coin.tscn from the FileSystem panel and drop it into the Coin Scene property.

Initializing

To start things off, add the _ready() function:

func _ready():
    screensize = get_viewport().get_visible_rect().size
    $Player.screensize = screensize
    $Player.hide()

Godot automatically calls _ready() on every node when it’s added. This is a good place to put code that you want to happen at the beginning of a node’s lifetime.

Note that you’re referring to the Player node by name using the $ syntax, allowing you to find the size of the game screen and set the player’s screensize variable. hide() makes a node invisible, so you won’t see the player before the game starts.

Starting a new game

The new_game() function will initialize everything for a new game:

func new_game():
    playing = true
    level = 1
    score = 0
    time_left = playtime
    $Player.start()
    $Player.show()
    $GameTimer.start()
    spawn_coins()

In addition to setting the variables to their starting values, this function calls the player’s start() function that you wrote earlier. Starting GameTimer will start counting down the remaining time in the game.

You also need a function that will create a number of coins based on the current level:

func spawn_coins():
    for i in level + 4:
        var c = coin_scene.instantiate()
        add_child(c)
        c.screensize = screensize
        c.position = Vector2(randi_range(0, screensize.x),
            randi_range(0, screensize.y))

In this function, you create multiple instances of the Coin object and add them as children of Main (in code this time, rather than by manually clicking on the Instantiate Child Scene button). Whenever you instantiate a new node, it must be added to the scene tree using add_child(). Lastly, you choose a random position for the coin, using the screensize variable so that they won’t appear off screen. You’ll call this function at the start of every level, generating more coins each time.

Eventually, you’ll want new_game() to be called when the player clicks the start button on the menu. For now, to test that everything is working, add new_game() to the end of your _ready() function and click Run Project (F5). When you are prompted to choose a main scene, select main.tscn. Now, whenever you play the project, the Main scene will be started.

At this point, you should see your player and five coins appear on the screen. When the player touches a coin, it disappears.

Once you’re done testing, remove new_game() from the _ready() function.

Checking for remaining coins

The main script needs to detect whether the player has picked up all the coins. Since the coins are all in the coins group, you can check the size of the group to see how many remain. Since it needs to be checked continuously, put it in the _process() function:

func _process(delta):
    if playing and
    get_tree().get_nodes_in_group("coins").size() == 0:
        level += 1
        time_left += 5
        spawn_coins()

If no more coins remain, then the player advances to the next level.

This completes the main scene. The most important thing you learned in this step was how to dynamically create new objects in code using instantiate(). This is something that you will use again and again in building many types of game systems. In the last step, you’ll create one more scene to handle displaying game information, such as the player’s score and the time remaining.