128 lines
2.7 KiB
GDScript
128 lines
2.7 KiB
GDScript
extends Node2D
|
|
|
|
|
|
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
|
|
|
|
const RASTER_SIZE = 64
|
|
const BOTTOM = RASTER_SIZE * 10
|
|
|
|
|
|
func _ready():
|
|
$GravityTimer.connect("timeout", self, "update_board")
|
|
|
|
active_shape = get_random_shape()
|
|
|
|
|
|
func get_random_shape():
|
|
var new_shape = shapes[randi() % shapes.size()].instance()
|
|
add_child(new_shape)
|
|
return new_shape
|
|
|
|
|
|
func update_board():
|
|
if can_active_move_down():
|
|
move_active_down()
|
|
else:
|
|
turn_active_into_static()
|
|
check_for_full_line()
|
|
|
|
active_shape = get_random_shape()
|
|
|
|
|
|
func move_active_down():
|
|
active_shape.position.y += RASTER_SIZE
|
|
|
|
|
|
func can_active_move_down():
|
|
if active_shape.position.y >= BOTTOM:
|
|
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
|
|
|
|
|
|
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()
|
|
elif line_block.position.y < line_count_y:
|
|
# Move higher-up blocks down
|
|
line_block.position.y += RASTER_SIZE
|
|
|
|
|
|
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
|
|
|
|
|
|
func rotate_shape():
|
|
active_shape.rotation_degrees += 90
|
|
|
|
|
|
func drop():
|
|
while can_active_move_down():
|
|
move_active_down()
|
|
|
|
# Restart the timer to give full time for sliding the piece
|
|
$GravityTimer.start()
|
|
|
|
|
|
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
|
|
|
|
|
|
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"):
|
|
rotate_shape()
|
|
elif event.is_action_pressed("drop"):
|
|
drop()
|