virtualx-engine/demos/2d/tetris/grid.gd
Rémi Verschelde 7589b2bf60 Improve code formatting
The scripts were streamlined using more or less the following conventions:
 - space after a comma in lists of arguments
 - spaces around weak operators (+, -), no spaces around strong operators (*, /)
 - spaces around comparison operators and compound assignment operators
 - space after a comment start (#)
 - removed trailing spaces or tabs, apart from those that delimit the function indentation level (those could be removed too but since they are added automatically by the editor when typing code, keeping them for now)
 - function blocks separate by two newlines
 - comment sentences start with an upper-case letter
2015-12-09 08:39:12 +01:00

195 lines
4.3 KiB
GDScript

extends Control
# Simple Tetris-like demo, (c) 2012 Juan Linietsky
# Implemented by using a regular Control and drawing on it during the _draw() callback.
# The drawing surface is updated only when changes happen (by calling update())
# Member variables
var score = 0
var score_label = null
const MAX_SHAPES = 7
var block = preload("block.png")
var block_colors = [
Color(1, 0.5, 0.5),
Color(0.5, 1, 0.5),
Color(0.5, 0.5, 1),
Color(0.8, 0.4, 0.8),
Color(0.8, 0.8, 0.4),
Color(0.4, 0.8, 0.8),
Color(0.7, 0.7, 0.7)]
var block_shapes = [
[ Vector2(0, -1), Vector2(0, 0), Vector2(0, 1), Vector2(0, 2) ], # I
[ Vector2(0, 0), Vector2(1, 0), Vector2(1, 1), Vector2(0, 1) ], # O
[ Vector2(-1, 1), Vector2(0, 1), Vector2(0, 0), Vector2(1, 0) ], # S
[ Vector2(1, 1), Vector2(0, 1), Vector2(0, 0), Vector2(-1, 0) ], # Z
[ Vector2(-1, 1), Vector2(-1, 0), Vector2(0, 0), Vector2(1, 0) ], # L
[ Vector2(1, 1), Vector2(1, 0), Vector2(0, 0), Vector2(-1, 0) ], # J
[ Vector2(0, 1), Vector2(1, 0), Vector2(0, 0), Vector2(-1, 0) ]] # T
var block_rotations = [
Matrix32(Vector2(1, 0), Vector2(0, 1), Vector2()),
Matrix32(Vector2(0, 1), Vector2(-1, 0), Vector2()),
Matrix32(Vector2(-1, 0), Vector2(0, -1), Vector2()),
Matrix32(Vector2(0, -1), Vector2(1, 0), Vector2())]
var width = 0
var height = 0
var cells = {}
var piece_active = false
var piece_shape = 0
var piece_pos = Vector2()
var piece_rot = 0
func piece_cell_xform(p, er = 0):
var r = (4 + er + piece_rot) % 4
return piece_pos + block_rotations[r].xform(p)
func _draw():
var sb = get_stylebox("bg", "Tree") # Use line edit bg
draw_style_box(sb, Rect2(Vector2(), get_size()).grow(3))
var bs = block.get_size()
for y in range(height):
for x in range(width):
if (Vector2(x, y) in cells):
draw_texture_rect(block, Rect2(Vector2(x, y)*bs, bs), false, block_colors[cells[Vector2(x, y)]])
if (piece_active):
for c in block_shapes[piece_shape]:
draw_texture_rect(block, Rect2(piece_cell_xform(c)*bs, bs), false, block_colors[piece_shape])
func piece_check_fit(ofs, er = 0):
for c in block_shapes[piece_shape]:
var pos = piece_cell_xform(c, er) + ofs
if (pos.x < 0):
return false
if (pos.y < 0):
return false
if (pos.x >= width):
return false
if (pos.y >= height):
return false
if (pos in cells):
return false
return true
func new_piece():
piece_shape = randi() % MAX_SHAPES
piece_pos = Vector2(width/2, 0)
piece_active = true
piece_rot = 0
if (piece_shape == 0):
piece_pos.y += 1
if (not piece_check_fit(Vector2())):
# Game over
game_over()
update()
func test_collapse_rows():
var accum_down = 0
for i in range(height):
var y = height - i - 1
var collapse = true
for x in range(width):
if (Vector2(x, y) in cells):
if (accum_down):
cells[Vector2(x, y + accum_down)] = cells[Vector2(x, y)]
else:
collapse = false
if (accum_down):
cells.erase(Vector2(x, y + accum_down))
if (collapse):
accum_down += 1
score += accum_down*100
score_label.set_text(str(score))
func game_over():
piece_active = false
get_node("gameover").set_text("Game over!")
update()
func restart_pressed():
score = 0
score_label.set_text("0")
cells.clear()
get_node("gameover").set_text("")
piece_active = true
get_node("../restart").release_focus()
update()
func piece_move_down():
if (!piece_active):
return
if (piece_check_fit(Vector2(0, 1))):
piece_pos.y += 1
update()
else:
for c in block_shapes[piece_shape]:
var pos = piece_cell_xform(c)
cells[pos] = piece_shape
test_collapse_rows()
new_piece()
func piece_rotate():
var adv = 1
if (not piece_check_fit(Vector2(), 1)):
return
piece_rot = (piece_rot + adv) % 4
update()
func _input(ie):
if (not piece_active):
return
if (!ie.is_pressed()):
return
if (ie.is_action("move_left")):
if (piece_check_fit(Vector2(-1, 0))):
piece_pos.x -= 1
update()
elif (ie.is_action("move_right")):
if (piece_check_fit(Vector2(1, 0))):
piece_pos.x += 1
update()
elif (ie.is_action("move_down")):
piece_move_down()
elif (ie.is_action("rotate")):
piece_rotate()
func setup(w, h):
width = w
height = h
set_size(Vector2(w, h)*block.get_size())
new_piece()
get_node("timer").start()
func _ready():
# Initalization here
setup(10, 20)
score_label = get_node("../score")
set_process_input(true)