Godot Version
4.4.1
What I’m trying to do
I have a grid of tiles that slowly goes down by adding 5 pixels to global_position.y
Every time the grid has descended the size of a tile (which is 16 pixels), I want to have a signal that tells the spawner to add a new row of tiles at the top, so that it seems like an endless amount of tiles falling down.
I have a specific scene to signal this, the new_row_signaller. This scene moves down at the same speed as the grid, and when it’s down more or equal to 16, it emits the spawn_new_row signal.
This is all the code in the new_row_signaller:
extends Node2D
var start_position = global_position.y
var current_position = global_position.y
var moving = true
var difference = 0
## This thing goes down to the height of 1 block
## and then resets itself
## emitting a spawn_new_row signal
func _ready() -> void:
start_position = global_position.y
func _physics_process(delta: float) -> void:
if moving:
global_position.y += GameVars.block_move_speed * delta
current_position = global_position.y
difference = current_position - start_position
if difference >= GameVars.TILE_SIZE:
SignalManager.spawn_new_row.emit()
global_position.y = start_position
The problem
The problem is, that the emitted signal is never at exact 16 pixels. It always overshoots a bit, which means that the new_row_signaller is not in sync with the grid after the first spawn, and this gap only increases with every signal and reset. Eventually, a row gets skipped.
Where the solution might be
The new_row_signaller is something that I still had of a previous try at this system. Now I’m working with TileMapLayers that are in a Node2D and the whole Node2D is moving down.
That means that global_position.y is always increasing and I can take my signals from there.
I have two possible solutions, but I don’t know how to implement them correctly.
- Using the remainder. When the remainder is on 0, I know I have to spawn in a new row.
- Using simply dividing, and then using the int of that. So int(simply_dividing), which gives me an integer that slowly grows as the grid moves down. And every time it changes, there could be a signal that tells to spawn a new row.
func _process(delta: float) -> void:
remainder_y = int(global_position.y) % 16
simply_dividing = global_position.y / 16
func _physics_process(delta: float) -> void:
if moving:
global_position.y += GameVars.block_move_speed * delta
func spawn_new_row():
for x in grid_width:
var pos = Vector2i(x, -simply_dividing)
# First get a base tile
set_base_tile(pos, "dirt")
Question
Because I check these solution in the _process function, there are many frames where the remainder is 0 or by dividing the integer stays on the same number.
So, while using any of the possible solutions above, I get many, many ‘hits’ which would send many signals.
Now here comes the question.
-
The remainder way
How do I create a function that checks if the remainder is on 0 and then emits only once that a new row needs to be spawned? -
The dividing way
How do I create a function that checks if the integer just changed and then emits only once that a new row needs to be spawned?