# LD46: Tetris is working! (sort of)

Update!

I have basic blocks that fall by themselves and that I can move around with left/right on the keyboard. They will collide with each other and the walls/floor, and once they stick, a new block will spawn.

# Basic movement

The first thing to do is set up movement on the blocks. We’ll give them a KinematicBody2D and a script to handle keyboard controls.

The PixelEngine there is the falling sand block that I made in the [previous post]https://blog.jverkamp.com/2020/04/17/ludum-dare-46-tetris-sand/. That just handles the UI and the falling sand, it’s an animated sprite.

Then movement via script:

# Block.gd
func _physics_process(delta):
# Keyboard controls
if Input.is_action_pressed("ui_right"):
velocity += IMPULSE

if Input.is_action_pressed("ui_left"):
velocity -= IMPULSE

# Apply friction and gravity
velocity *= DECAY
velocity.y = FALLING

# Move the block
body.move_and_collide(velocity)


And that’s it. It moves left and right and falls down.

# Collisions

To collide, we need something to collide with:

And that’s actually it. No code. I didn’t think I’d like that part of Godot… but it’s really handy.

Now the blocks fall down and can crash into walls.

# Respawning

Now for the slightly tricky part. I want blocks to stop moving when they collide and then spawn a new block. Stopping them is actually pretty easy:

func _physics_process(delta):
...

# Move the block
var collision = body.move_and_collide(velocity)

# If we hit something, start a counter, if that goes long enough, lock the block
if collision:
velocity = Vector2.ZERO
stuck_time += delta
if stuck_time > LOCK_TIME:
set_physics_process(false)
else:
stuck_time = 0


Just tell Godot to stop the _physics_process calls to this object.

To respawn blocks, I’m going to use signals :

# Block.gd
signal on_lock

func _physics_process(delta):
...
if collision:
velocity = Vector2.ZERO
stuck_time += delta
if stuck_time > LOCK_TIME:
set_physics_process(false)
emit_signal("on_lock")
else:
stuck_time = 0

# Main.gd
extends Node2D

func _on_Block_on_lock():
var new_block = Block.instance()
new_block.name = "Block" + str(blocks.get_child_count() + 1)
new_block.position = Vector2(80, 20)
new_block.connect("on_lock", self, "_on_Block_on_lock")

print('Spawned ' + new_block.name)


And… that’s actually it. The Main scene/script is connected via UI for the first signal, but after that, whenever a Block fires the on_lock signal to Main, Main will create a new Block instance (with a unique name), set it to the top of the screen, and wire up the new signal.

It’s really that easy.

Godot is nice.

Up next:

• Make the blocks into tetrominos.
• Work on the falling sand simulation
• Have the sand ‘drop’ into a shared simulation when the blocks lock (using the previous signal!)

This is fun!