123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- 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)
|