9 @export var block_size: int = 20
10 @export var piece_catalogue: Array[PackedScene] = []
12 var _grid_filled: Array[bool] = []
13 var _player_position: Vector2i = Vector2i.ZERO
14 var _player_piece: Piece = null
15 var _grid_final_y_row: int = 0
16 var _grid_final_x_row: int = 0
18 var num_pieces: int = 0
19 const start_pos: Vector2i = Vector2i(5, 2)
21 func _ready() -> void:
22 assert(piece_catalogue.size() >= 1, "Expected at least one piece in catalogue")
25 _grid_final_y_row = size.y / block_size
26 _grid_final_x_row = size.x / block_size
27 print("Grid is " + str(_grid_final_x_row) + " by " + str(_grid_final_y_row))
29 for i in range(0, _grid_final_x_row):
30 for j in range(0, _grid_final_y_row):
31 _grid_filled.append(false)
33 _on_turn_timer_timeout()
36 func _input(event: InputEvent) -> void:
37 if event.is_action_pressed("player_left"):
38 _move(Vector2i(-1, 0))
39 elif event.is_action_pressed("player_right"):
42 if event.is_action_pressed("player_up"):
44 _player_piece.rotate_cells_left()
46 # if player piece has cells off to the right or left of the board,
47 # then shift it back onto the board
49 var rightmost: int = 0
50 for pos: Vector2i in _player_piece.get_cell_grid():
51 pos += _player_position # remember, pos is relative!
54 elif pos.x > _grid_final_x_row - 1 and pos.x > rightmost:
55 rightmost = pos.x - _grid_final_x_row - 1
58 print("l,r: %d, %d" % [leftmost, rightmost])
61 _move(-Vector2i(leftmost, 0))
63 _move(-Vector2i(rightmost, 0))
65 if event.is_action_pressed("player_down"):
66 # move piece to bottom
69 b = _move(Vector2i(0, 1))
72 func _add_player_piece():
73 var scene: PackedScene = piece_catalogue.pick_random()
74 var piece: Piece = scene.instantiate()
75 piece.block_size = block_size
77 # TODO: start piece at center of board
78 _player_position = start_pos
79 piece.position = _player_position * block_size
82 # add piece to scene tree and emit signal
88 # returns TRUE if piece can move more, FALSE if end state
89 func _move(v: Vector2i) -> bool:
90 assert(_player_piece != null, "Player piece must not be null")
92 var new_player_position: Vector2i = _player_position + v
94 # for each cell in the block, offset it by new position and check for collision
95 for pos: Vector2i in _player_piece.get_cell_grid():
96 pos += new_player_position
97 if pos.x < 0 or pos.x >= _grid_final_x_row:
98 # ignore input that moves beyond lateral boundaries
101 if _is_grid_position_taken(pos):
102 # if movement is vertical and blocked, then we're done
107 # update player position
108 _player_position = new_player_position
110 _player_piece.position = _player_position * block_size
112 # if any cell's at the bottom of the grid, we're done
113 for pos: Vector2i in _player_piece.get_cell_grid():
114 pos += _player_position
115 if (pos.y >= _grid_final_y_row - 1):
122 func _on_end_round():
123 # disconnect player controls from current piece
124 var piece: Piece = _player_piece
127 # fill in collision grid with piece cells
128 for pos: Vector2i in piece.get_cell_grid():
129 pos += _player_position
130 _set_grid_position(pos, true)
132 # now start a new round
133 _on_turn_timer_timeout()
136 func _on_turn_timer_timeout() -> void:
137 if _player_piece == null:
140 _move(Vector2i(0, 1))
144 func _set_grid_position(v: Vector2i, b: bool):
145 _grid_filled[v.x + v.y * _grid_final_x_row] = b
148 func _is_grid_position_taken(v: Vector2i) -> bool:
149 return _grid_filled[v.x + v.y * _grid_final_x_row]