X-Git-Url: http://git.purplebirdman.com/catris.git/blobdiff_plain/2f553c6c1c71810a4ff47a966c2bf39893233373..337edaab89f707658130d1a332cc169180fe9f67:/script/board.gd diff --git a/script/board.gd b/script/board.gd index 5368ddd..bc05616 100644 --- a/script/board.gd +++ b/script/board.gd @@ -1,18 +1,27 @@ extends Control class_name Board + +signal added_piece +signal end_round + + @export var block_size: int = 20 -@export var cell_catalogue: Array[PackedScene] +@export var piece_catalogue: Array[PackedScene] = [] var _grid_filled: Array[bool] = [] var _player_position: Vector2i = Vector2i.ZERO -var _player_cell: Cell = null +var _player_piece: Piece = null var _grid_final_y_row: int = 0 var _grid_final_x_row: int = 0 -var _num_pieces: int = 0 +var num_pieces: int = 0 +const start_pos: Vector2i = Vector2i(5, 2) func _ready() -> void: + assert(piece_catalogue.size() >= 1, "Expected at least one piece in catalogue") + + # calculate grid _grid_final_y_row = size.y / block_size _grid_final_x_row = size.x / block_size print("Grid is " + str(_grid_final_x_row) + " by " + str(_grid_final_y_row)) @@ -26,72 +35,109 @@ func _ready() -> void: func _input(event: InputEvent) -> void: if event.is_action_pressed("player_left"): - _move_cell(Vector2i(-1, 0)) + _move(Vector2i(-1, 0)) elif event.is_action_pressed("player_right"): - _move_cell(Vector2i(1, 0)) + _move(Vector2i(1, 0)) if event.is_action_pressed("player_up"): - # TODO: rotate - pass - - if event.is_action("player_down"): - _move_cell(Vector2i(0, 1)) - - -func _add_player_cell(): - var scene: PackedScene = cell_catalogue.pick_random() - var cell: Cell = scene.instantiate() - cell.block_size = block_size + if _player_piece: + _player_piece.rotate_cells_left() + + # if player piece has cells off to the right or left of the board, + # then shift it back onto the board + var leftmost: int = 0 + var rightmost: int = 0 + for pos: Vector2i in _player_piece.get_cell_grid(): + pos += _player_position # remember, pos is relative! + if pos.x < leftmost: + leftmost = pos.x + elif pos.x > _grid_final_x_row - 1 and pos.x > rightmost: + rightmost = pos.x - _grid_final_x_row - 1 + - _player_position = Vector2i(5, 0) - cell.position = _player_position * block_size - _player_cell = cell + print("l,r: %d, %d" % [leftmost, rightmost]) + + if leftmost < 0: + _move(-Vector2i(leftmost, 0)) + elif rightmost > 0: + _move(-Vector2i(rightmost, 0)) + + if event.is_action_pressed("player_down"): + # move piece to bottom + var b := true + while b: + b = _move(Vector2i(0, 1)) + + +func _add_player_piece(): + var scene: PackedScene = piece_catalogue.pick_random() + var piece: Piece = scene.instantiate() + piece.block_size = block_size - add_child(cell) - _num_pieces += 1 - print("Added piece: " + str(_num_pieces)) + # TODO: start piece at center of board + _player_position = start_pos + piece.position = _player_position * block_size + _player_piece = piece + + # add piece to scene tree and emit signal + add_child(piece) + num_pieces += 1 + added_piece.emit() -func _move_cell(v: Vector2i): - var new_player_position: Vector2i = _player_position + v +# returns TRUE if piece can move more, FALSE if end state +func _move(v: Vector2i) -> bool: + assert(_player_piece != null, "Player piece must not be null") - if new_player_position.x < 0 or new_player_position.x >= _grid_final_x_row: - # ignore input that moves beyond lateral boundaries - return + var new_player_position: Vector2i = _player_position + v - if _is_grid_position_taken(new_player_position): - # if movement is vertical and blocked, then we're done - if v.y != 0: - _end_round() - return + # for each cell in the block, offset it by new position and check for collision + for pos: Vector2i in _player_piece.get_cell_grid(): + pos += new_player_position + if pos.x < 0 or pos.x >= _grid_final_x_row: + # ignore input that moves beyond lateral boundaries + return false + if _is_grid_position_taken(pos): + # if movement is vertical and blocked, then we're done + if v.y != 0: + end_round.emit() + return false + # update player position _player_position = new_player_position - if _player_cell: - _player_cell.position = _player_position * block_size + if _player_piece: + _player_piece.position = _player_position * block_size + + # if any cell's at the bottom of the grid, we're done + for pos: Vector2i in _player_piece.get_cell_grid(): + pos += _player_position + if (pos.y >= _grid_final_y_row - 1): + end_round.emit() + return false - # if at the bottom of the grid, we're done - if (_player_position.y == _grid_final_y_row - 1): - _end_round() + return true -func _end_round(): - print("Time for a new piece!") + +func _on_end_round(): # disconnect player controls from current piece - _player_cell = null + var piece: Piece = _player_piece + _player_piece = null # fill in collision grid with piece cells - _set_grid_position(_player_position, true) - #_print_grid() + for pos: Vector2i in piece.get_cell_grid(): + pos += _player_position + _set_grid_position(pos, true) # now start a new round _on_turn_timer_timeout() func _on_turn_timer_timeout() -> void: - if _player_cell == null: - _add_player_cell() + if _player_piece == null: + _add_player_piece() else: - _move_cell(Vector2i(0, 1)) + _move(Vector2i(0, 1)) %turnTimer.start() @@ -101,11 +147,3 @@ func _set_grid_position(v: Vector2i, b: bool): func _is_grid_position_taken(v: Vector2i) -> bool: return _grid_filled[v.x + v.y * _grid_final_x_row] - - -func _print_grid(): - for i in range(0, _grid_final_y_row): - var row = [] - for j in range(0, _grid_final_x_row): - row.append(_grid_filled[j + i * _grid_final_x_row]) - print(str(row))