]> Untitled Git - catris.git/blob - script/board.gd
f820e00660ee0a0189185bdfb11aba007f933906
[catris.git] / script / board.gd
1 extends Control
2 class_name Board
3
4
5 signal added_piece
6 signal end_round
7
8
9 @export var block_size: int = 20
10 @export var piece_catalogue: Array[PackedScene] = []
11
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
17
18 var num_pieces: int = 0
19
20 func _ready() -> void:
21         assert(piece_catalogue.size() >= 1, "Expected at least one piece in catalogue")
22         
23         # calculate grid
24         _grid_final_y_row = size.y / block_size
25         _grid_final_x_row = size.x / block_size
26         print("Grid is " + str(_grid_final_x_row) + " by " + str(_grid_final_y_row))
27         
28         for i in range(0, _grid_final_x_row):
29                 for j in range(0, _grid_final_y_row):
30                         _grid_filled.append(false)
31         
32         _on_turn_timer_timeout()
33
34
35 func _input(event: InputEvent) -> void:
36         if event.is_action_pressed("player_left"):
37                 _move(Vector2i(-1, 0))
38         elif event.is_action_pressed("player_right"):
39                 _move(Vector2i(1, 0))
40                 
41         if event.is_action_pressed("player_up"):
42                 # TODO: rotate
43                 pass
44
45         if event.is_action("player_down"):
46                 _move(Vector2i(0, 1))
47
48
49 func _add_player_piece():
50         var scene: PackedScene = piece_catalogue.pick_random()
51         var piece: Piece = scene.instantiate()
52         piece.block_size = block_size
53         
54         # TODO: start piece at center of board
55         _player_position = Vector2i(5, 0)
56         piece.position = _player_position * block_size
57         _player_piece = piece
58         
59         # add piece to scene tree and emit signal
60         add_child(piece)
61         num_pieces += 1
62         added_piece.emit()
63
64
65 func _move(v: Vector2i):
66         assert(_player_piece != null, "Player piece must not be null")
67         
68         var new_player_position: Vector2i = _player_position + v
69         
70         # for each cell in the block, offset it by new position and check for collision
71         for pos: Vector2i in _player_piece.cell_grid:
72                 pos += new_player_position
73                 if pos.x < 0 or pos.x >= _grid_final_x_row:
74                         # ignore input that moves beyond lateral boundaries
75                         return
76                 
77                 if _is_grid_position_taken(pos):
78                         # if movement is vertical and blocked, then we're done
79                         if v.y != 0:
80                                 end_round.emit()
81                         return
82                         
83         # update player position
84         _player_position = new_player_position
85         if _player_piece:
86                 _player_piece.position = _player_position * block_size
87
88         # if any cell's at the bottom of the grid, we're done
89         for pos: Vector2i in _player_piece.cell_grid:
90                 pos += _player_position
91                 if (pos.y >= _grid_final_y_row - 1):
92                         end_round.emit()
93
94 func _on_end_round():
95                 # fill in collision grid with piece cells
96                 for pos: Vector2i in _player_piece.cell_grid:
97                         pos += _player_position
98                         _set_grid_position(pos, true)
99
100                 # disconnect player controls from current piece
101                 _player_piece = null
102                 
103                 # now start a new round
104                 _on_turn_timer_timeout()
105
106
107 func _on_turn_timer_timeout() -> void:
108         if _player_piece == null:
109                 _add_player_piece()
110         else:
111                 _move(Vector2i(0, 1))
112         %turnTimer.start()
113
114
115 func _set_grid_position(v: Vector2i, b: bool):
116         _grid_filled[v.x + v.y * _grid_final_x_row] = b
117
118
119 func _is_grid_position_taken(v: Vector2i) -> bool:
120         return _grid_filled[v.x + v.y * _grid_final_x_row]