diff options
Diffstat (limited to 'demos/2d/tetris/grid.gd')
-rw-r--r-- | demos/2d/tetris/grid.gd | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/demos/2d/tetris/grid.gd b/demos/2d/tetris/grid.gd new file mode 100644 index 0000000000..dc89300881 --- /dev/null +++ b/demos/2d/tetris/grid.gd @@ -0,0 +1,216 @@ + + +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()) + + +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 + #print("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 + 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) + + + + |