Time to start developing in Godot!
Having watched a few quick tutorial videos on how Godot worked, I began setting up my first scene.
Since the Tetris game is played in a grid, my scene began with a TileMap, which allows me to set a 10x20 tilemap (essentially a grid) for the game. I followed a beginner's guide to Tetris in Godot video to complete this step.
The tutorial video then proceeded to create Tetris blocks for the game. In the video, the developer used individual variables for the vertex positions for each of the 7 different blocks, and the code looks something like this:
And this piece of code is repeated 7 times with minimal changes! ("How horrendous!" is what my software engineering module professors would say, if they ever see this coding style)
Therefore, as something of a Software Engineer myself, I decided to embrace the Object Oriented Programming Principles, and re-implement this code using inheritance and polymorphism. Thus began the long research into OOP in Godot...
OOP for Tetris in Godot
First of all, there has to be a Base Tetris class. This class declares (only the names, without values) a few variables, including the current vertice positions of the Tetris block, the 4 possible orientations of this block, as well as the current rotation angle. Each child class (e.g. Tetris_L for L-shaped Tetris blocks) will then define their own values for these variables when they are instantiated with _ready()
.
The base class also has a function rotate()
, which rotates the Tetris block clockwise by updating its vertices and angle accordingly.
With the classes set up, I implemented a function to draw Tetris blocks on the tilemap. It is surprisingly simple: Simply instantiate a Tetris child class, grab its coordinates variable, and set the corresponding coordinates on the TileMap to a random color!
With the blocks ready, the next step is to make them start moving!
Lessons Learned
Instantiating a class in Godot: I have encountered two types of files in Godot so far. One is the
.tscn
files, which are for scenes, and another is the.gd
files, which are for GD scripts. The classes are in.gd
files, which must be instantiated with.new()
, instead of with.load()
andinstantiate()
which is for scenes.The
_ready()
function: In the GDScript, there exists a_ready()
function. Initially, I treated it as an equivalent function to__init__()
in Python and Java, though after some debugging I found that there exist some subtle differences. In Python for instance, theinit()
functions for classes are called immediately when the class objects are instantiated. On the other hand, for GDScript objects,_ready()
is only called when the object enters the scene tree, so you have to get the scene tree andadd_child()
to it before your instantiated object is fully instanced. I was stuck on this for a while wondering why my instanced objects did not have the updated variable values I defined in their_ready()
functions, but now we know!
Top comments (0)