tetris-mobile/GameBoard.gd

128 lines
2.7 KiB
GDScript3
Raw Normal View History

2021-11-17 16:30:13 +01:00
extends Node2D
2021-11-17 23:31:27 +01:00
var shapes = [
preload("res://ShapeI.tscn"),
preload("res://ShapeJ.tscn"),
preload("res://ShapeL.tscn"),
preload("res://ShapeZ.tscn"),
preload("res://ShapeS.tscn"),
preload("res://ShapeT.tscn"),
preload("res://ShapeO.tscn")
]
var active_shape: TetrisShape
2021-11-17 16:30:13 +01:00
const RASTER_SIZE = 64
2021-11-17 17:02:34 +01:00
const BOTTOM = RASTER_SIZE * 10
2021-11-17 16:30:13 +01:00
func _ready():
$GravityTimer.connect("timeout", self, "update_board")
2021-11-17 23:31:27 +01:00
active_shape = get_random_shape()
2021-11-17 16:30:13 +01:00
2021-11-17 17:02:34 +01:00
func get_random_shape():
2021-11-17 23:31:27 +01:00
var new_shape = shapes[randi() % shapes.size()].instance()
2021-11-17 17:02:34 +01:00
add_child(new_shape)
return new_shape
2021-11-17 16:30:13 +01:00
func update_board():
2021-11-17 18:24:58 +01:00
if can_active_move_down():
move_active_down()
else:
2021-11-17 17:02:34 +01:00
turn_active_into_static()
check_for_full_line()
active_shape = get_random_shape()
2021-11-17 18:24:58 +01:00
func move_active_down():
2021-11-17 16:30:13 +01:00
active_shape.position.y += RASTER_SIZE
2021-11-17 18:24:58 +01:00
func can_active_move_down():
2021-11-17 23:31:27 +01:00
if active_shape.position.y >= BOTTOM:
2021-11-17 18:24:58 +01:00
return false
for block in active_shape.get_blocks():
var down_x = block.global_position.x
var down_y = block.global_position.y + RASTER_SIZE
if is_block_at_position(down_x, down_y):
return false
return true
2021-11-17 17:02:34 +01:00
func turn_active_into_static():
for block in active_shape.get_blocks():
var global_shape_position = block.global_position
active_shape.remove_child(block)
$StaticBlocks.add_child(block)
block.global_position = global_shape_position
active_shape.free()
func check_for_full_line():
var line_counts = {} # Maps a y position to a count
for block in $StaticBlocks.get_children():
if not line_counts.has(block.position.y):
line_counts[block.position.y] = 0
line_counts[block.position.y] += 1
for line_count_y in line_counts.keys():
if line_counts[line_count_y] == 10:
# Free this line
for line_block in $StaticBlocks.get_children():
if line_block.position.y == line_count_y:
line_block.free()
2021-11-17 17:52:33 +01:00
elif line_block.position.y < line_count_y:
2021-11-17 17:02:34 +01:00
# Move higher-up blocks down
line_block.position.y += RASTER_SIZE
2021-11-17 16:30:13 +01:00
func move_left():
# TODO: Check for collision
active_shape.position.x -= RASTER_SIZE
func move_right():
# TODO: Check for collision
active_shape.position.x += RASTER_SIZE
2021-11-17 17:52:33 +01:00
func rotate_shape():
active_shape.rotation_degrees += 90
2021-11-17 17:02:34 +01:00
func drop():
2021-11-17 18:24:58 +01:00
while can_active_move_down():
move_active_down()
2021-11-17 17:02:34 +01:00
# Restart the timer to give full time for sliding the piece
$GravityTimer.start()
2021-11-17 18:24:58 +01:00
func is_block_at_position(pos_x, pos_y):
for block in $StaticBlocks.get_children():
if block.global_position.x == pos_x and block.global_position.y == pos_y:
return true
return false
2021-11-17 16:30:13 +01:00
func _input(event):
if event.is_action_pressed("move_left"):
move_left()
elif event.is_action_pressed("move_right"):
move_right()
elif event.is_action_pressed("rotate"):
2021-11-17 17:52:33 +01:00
rotate_shape()
2021-11-17 16:30:13 +01:00
elif event.is_action_pressed("drop"):
2021-11-17 17:02:34 +01:00
drop()