grid.gd 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. extends Control
  2. # Simple Tetris-like demo, (c) 2012 Juan Linietsky
  3. # Implemented by using a regular Control and drawing on it during the _draw() callback.
  4. # The drawing surface is updated only when changes happen (by calling update())
  5. var score = 0
  6. var score_label=null
  7. const MAX_SHAPES = 7
  8. var block = preload("block.png")
  9. var block_colors=[
  10. Color(1,0.5,0.5),
  11. Color(0.5,1,0.5),
  12. Color(0.5,0.5,1),
  13. Color(0.8,0.4,0.8),
  14. Color(0.8,0.8,0.4),
  15. Color(0.4,0.8,0.8),
  16. Color(0.7,0.7,0.7)]
  17. var block_shapes=[
  18. [ Vector2(0,-1),Vector2(0,0),Vector2(0,1),Vector2(0,2) ], # I
  19. [ Vector2(0,0),Vector2(1,0),Vector2(1,1),Vector2(0,1) ], # O
  20. [ Vector2(-1,1),Vector2(0,1),Vector2(0,0),Vector2(1,0) ], # S
  21. [ Vector2(1,1),Vector2(0,1),Vector2(0,0),Vector2(-1,0) ], # Z
  22. [ Vector2(-1,1),Vector2(-1,0),Vector2(0,0),Vector2(1,0) ], # L
  23. [ Vector2(1,1),Vector2(1,0),Vector2(0,0),Vector2(-1,0) ], # J
  24. [ Vector2(0,1),Vector2(1,0),Vector2(0,0),Vector2(-1,0) ]] # T
  25. var block_rotations=[
  26. Matrix32( Vector2(1,0),Vector2(0,1), Vector2() ),
  27. Matrix32( Vector2(0,1),Vector2(-1,0), Vector2() ),
  28. Matrix32( Vector2(-1,0),Vector2(0,-1), Vector2() ),
  29. Matrix32( Vector2(0,-1),Vector2(1,0), Vector2() )
  30. ]
  31. var width=0
  32. var height=0
  33. var cells={}
  34. var piece_active=false
  35. var piece_shape=0
  36. var piece_pos=Vector2()
  37. var piece_rot=0
  38. func piece_cell_xform(p,er=0):
  39. var r = (4+er+piece_rot)%4
  40. return piece_pos+block_rotations[r].xform(p)
  41. func _draw():
  42. var sb = get_stylebox("bg","Tree") # use line edit bg
  43. draw_style_box(sb,Rect2(Vector2(),get_size()).grow(3))
  44. var bs = block.get_size()
  45. for y in range(height):
  46. for x in range(width):
  47. if (Vector2(x,y) in cells):
  48. draw_texture_rect(block,Rect2(Vector2(x,y)*bs,bs),false,block_colors[cells[Vector2(x,y)]])
  49. if (piece_active):
  50. for c in block_shapes[piece_shape]:
  51. draw_texture_rect(block,Rect2(piece_cell_xform(c)*bs,bs),false,block_colors[piece_shape])
  52. func piece_check_fit(ofs,er=0):
  53. for c in block_shapes[piece_shape]:
  54. var pos = piece_cell_xform(c,er)+ofs
  55. if (pos.x < 0):
  56. return false
  57. if (pos.y < 0):
  58. return false
  59. if (pos.x >= width):
  60. return false
  61. if (pos.y >= height):
  62. return false
  63. if (pos in cells):
  64. return false
  65. return true
  66. func new_piece():
  67. piece_shape = randi() % MAX_SHAPES
  68. piece_pos = Vector2(width/2,0)
  69. piece_active=true
  70. piece_rot=0
  71. if (piece_shape==0):
  72. piece_pos.y+=1
  73. if (not piece_check_fit(Vector2())):
  74. #game over
  75. #print("GAME OVER!")
  76. game_over()
  77. update()
  78. func test_collapse_rows():
  79. var accum_down=0
  80. for i in range(height):
  81. var y = height - i - 1
  82. var collapse = true
  83. for x in range(width):
  84. if (Vector2(x,y) in cells):
  85. if (accum_down):
  86. cells[ Vector2(x,y+accum_down) ] = cells[Vector2(x,y)]
  87. else:
  88. collapse=false
  89. if (accum_down):
  90. cells.erase( Vector2(x,y+accum_down) )
  91. if (collapse):
  92. accum_down+=1
  93. score+=accum_down*100
  94. score_label.set_text(str(score))
  95. func game_over():
  96. piece_active=false
  97. get_node("gameover").set_text("Game Over")
  98. update()
  99. func restart_pressed():
  100. score=0
  101. score_label.set_text("0")
  102. cells.clear()
  103. get_node("gameover").set_text("")
  104. piece_active=true
  105. update()
  106. func piece_move_down():
  107. if (!piece_active):
  108. return
  109. if (piece_check_fit(Vector2(0,1))):
  110. piece_pos.y+=1
  111. update()
  112. else:
  113. for c in block_shapes[piece_shape]:
  114. var pos = piece_cell_xform(c)
  115. cells[pos]=piece_shape
  116. test_collapse_rows()
  117. new_piece()
  118. func piece_rotate():
  119. var adv = 1
  120. if (not piece_check_fit(Vector2(),1)):
  121. return
  122. piece_rot = (piece_rot + adv) % 4
  123. update()
  124. func _input(ie):
  125. if (not piece_active):
  126. return
  127. if (!ie.is_pressed()):
  128. return
  129. if (ie.is_action("move_left")):
  130. if (piece_check_fit(Vector2(-1,0))):
  131. piece_pos.x-=1
  132. update()
  133. elif (ie.is_action("move_right")):
  134. if (piece_check_fit(Vector2(1,0))):
  135. piece_pos.x+=1
  136. update()
  137. elif (ie.is_action("move_down")):
  138. piece_move_down()
  139. elif (ie.is_action("rotate")):
  140. piece_rotate()
  141. func setup(w,h):
  142. width=w
  143. height=h
  144. set_size( Vector2(w,h)*block.get_size() )
  145. new_piece()
  146. get_node("timer").start()
  147. func _ready():
  148. # Initalization here
  149. setup(10,20)
  150. score_label = get_node("../score")
  151. set_process_input(true)