+2 votes

Hey folks-

I'm working on making a Tetris game for the sake of practice with the engine. I've decided that the easiest way to do this would be to have a singular data-manager object, the Grid, which keeps tabs on where the blocks are, etc. Since I didn't want to have to handle a node for every single block on the board, I decided I would just allow the Grid to hold its own data and draw the board and the blocks as necessary.

I have the Grid's width and height exported as variables, and I'd like to be able to call update() in the editor only when width or height get changed. Right now I have it redrawing on every _process call, which works and probably isn't causing any meaningful performance issues, but I felt this was a good chance to ask if there's a way to only call CanvasItem.update() when certain variable values get updated in the inspector, or failing that, when any exported variables get changed in the inspector.

in Engine by (46 points)

1 Answer

+5 votes

The way I usually do is by binding a setter to the variable with setget, so you know what to do when the variable is set externally:

export var width = 10 setget set_width

func set_width(new_width):
    if width != new_width:
        width = new_width
        # Do what you want when the variable changed

More info on setget: http://docs.godotengine.org/en/latest/reference/gdscript.html#setters-getters

Note: just curious, why not use a Tilemap for drawing your grid?

by (29,090 points)

Shoot, I totally forgot about setget. I guess I need to reread the docs, haha.
I'm mostly doing it this way because -
A- I won't need to manually modify the tile map when I need to change the width or height
B- If I handle the grid and the blocks in one object, I don't need to worry about managing multiple objects/blocks or having the block "layer" get somehow desynchronized from the grid
C- Reducing the amount of objects in the scene reduces the amount of draw calls that need to be made. With this system I'll only need to draw any given location on the grid once per movement, whether there's a block or not.
D- Good practice for thinking outside the box and making a game the non-standard route. My initial thought was to make the blocks all be separate objects which would be "unpacked" when they land, which would be the way modern game dev engines seem to encourage things but it's harder to handle in the long run. However, if the grid object handles all the logic for where blocks are at any given time, it's easier to tell when to delete lines, etc.
Most of the inpsiration for taking this route comes from TetrOS, which is a tetris game someone made small enough to fit on the boot sector of a computer, clocking in at 446 bytes. I haven't looked into the source code enough to understand it, but I figure they take an approach similar to this.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.