summaryrefslogtreecommitdiff
path: root/demos/2d/tetris/grid.gd
diff options
context:
space:
mode:
Diffstat (limited to 'demos/2d/tetris/grid.gd')
-rw-r--r--demos/2d/tetris/grid.gd216
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)
+
+
+
+