Collisions – the Lifeblood of Games
Games involving character movement need to detect when significant encounters take place – encounters with enemies, with collectible items, or maybe even with the world, such as not moving off a path. So our use case diagram now includes movement with the added possibility of collision.
The simplest component provided by Godot for detecting collisions is the Area2D. We can use this as the root of a scene, such as a scene that represents a player. The Area2D needs to have a CollisionShape2D, which needs a RectangleShape2D (or other shape) to actually define the hit area. And a sprite to represent the character graphically in the game.
In the diagram above the empty headed arrow connecting Player to Area2D indicates that Player extends the Area2D class (which is part of the Godot API). It extends it because it has additional components (the Sprite and the CollisionShape2D), and because it has custom code attached in the form of a script. The black diamond arrows indicate ownership (composition) – the Player has a Sprite and has a CollisionShape2D (which has a RectangleShape2D). These diagrams are part of the Unified Modeling Language (UML).
Using Multiple Scenes
Naturally our character needs others to encounter. Previously we have created a single scene in our game with a player character that moved around in response to keyboard input. With our games getting more complex it is possible to create a scene to represent each significant ‘character’ in the game, and then bring an instance of each of these into our main scene. If you have experience with Adobe Animate (Flash) this is very similar to creating MovieClip symbols to represent different parts of the game, and then bring an instance of each into the main Scene (which is also a MovieClip in Flash). I think this is also similar to creating prefabs in Unity, although it’s been a while so I might be wrong about that.
So the plan here is to create a player character that moves, and a few obstacles (enemies) that our player can encounter. Both player and obstacles will have an Area2D as its root, with a collision shape to determine the hitbox and a sprite for visual representation. Only the player will be able to move though (in this simple game). Here’s a shot of the Main scene in Godot. Note on the left that we have several scenes (.tscn files) now, not just the one that we have used up until now. The Main scene is the one that starts the game, and it includes instances of the Player scene and Enemy scene (3 of them).
When a collision takes place a signal (event) occurs. In Godot we can easily create event handling code by selecting the signal in the Inspector (actually, in the Node panel next to the Inspector), clicking on Connect, and a function will be created for us to respond to that particular signal being ‘emitted’ by a collision. The signal contains a reference to the object that caused the collision, so we can tell it to vanish. Here’s the Player scene showing the signals bottom right, with the area_entered signal connected to the _on_Player_area_entered() function.
And here’s the code for the Player script. We’ve changed the movement code a little to use the clamp() function to make sure our Player does not go outside the game area.
When the Player encounters an enemy (obstacle, red square) the enemy disappears. The last line of code area.queue_free() specifies that whatever was run into (the area) is destroyed by the queue_free() function, a safe way to destroy objects in a game.
If you’re interested in learning the Godot Game Engine there are several tutorial series on YouTube, but I recommend the Packt book Godot Engine Game Development Projects by Chris Bradfield, which I have as a Kindle edition.