From 90a1fdd5accc33521b3a8b6b67fc6718e6a98f88 Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Thu, 13 Feb 2020 13:51:14 +0100 Subject: [PATCH] refactor keyboard handling --- game/src/Piece.gd | 5 ++ game/src/Taquin.gd | 164 ++++++++++++++++++++++++------------------- game/src/Taquin.tscn | 4 +- 3 files changed, 97 insertions(+), 76 deletions(-) diff --git a/game/src/Piece.gd b/game/src/Piece.gd index a512067..497b73f 100644 --- a/game/src/Piece.gd +++ b/game/src/Piece.gd @@ -19,3 +19,8 @@ func _ready() -> void: mat.set_shader_param("scale", Vector3(piece_scale.x, piece_scale.y, 1.0)) mat.set_shader_param("offset", Vector3(taquin_position.x, taquin_position.y, 0.0)) $ColorRect.material = mat + +func debug_print(name: String): + print("%s order: %s" % [name, order]) + print("%s taquin index: %s" % [name, taquin_index]) + print("%s taquin position: %s" % [name, position]) diff --git a/game/src/Taquin.gd b/game/src/Taquin.gd index 2f05810..b98bd9b 100644 --- a/game/src/Taquin.gd +++ b/game/src/Taquin.gd @@ -12,25 +12,27 @@ export var difficulty: int = 10 enum Direction { UP, DOWN, LEFT, RIGHT } -var interpiece: int = 4 -var min_padding = 15 -var padding = Vector2(min_padding, min_padding) +var interpiece := 4 +var min_padding := 15 +var padding := Vector2(min_padding, min_padding) var pieces: Array = [] -var missing_piece: Vector2 -var rng = RandomNumberGenerator.new() +var rng := RandomNumberGenerator.new() -var current_animation_path: String = "AnimationPlayer/MockPiece:position" +var current_animation_path := "AnimationPlayer/MockPiece:position" + +var swipe := Vector2(0, 0) +var is_sliding := false -var swipe = Vector2(0, 0) -var is_sliding = false var current_sliding_piece: Piece = null -var current_origin = Vector2.ZERO -var current_goal = Vector2.ZERO -var current_axis = Vector2.ZERO -var current_slide = Vector2.ZERO -var local_min_position = Vector2.ZERO -var local_max_position = Vector2.ZERO +var missing_piece: Piece = null + +var current_origin := Vector2.ZERO +var current_goal := Vector2.ZERO +var current_axis := Vector2.ZERO +var current_touch_slide := Vector2.ZERO +var local_min_position := Vector2.ZERO +var local_max_position := Vector2.ZERO func position_for_index(index: Vector2, size: int) -> Vector2: return padding + Vector2(index.x * (size + interpiece), index.y * (size + interpiece)) @@ -74,8 +76,7 @@ func _ready() -> void: if r == rows - 1 && c == columns - 1: piece.visible = false - missing_piece.x = c - missing_piece.y = r + missing_piece = piece $Background.add_child(piece) pieces_row.append(piece) @@ -84,12 +85,8 @@ func _ready() -> void: shuffle(difficulty) -func _input(event): - if $AnimationPlayer.is_playing(): - # Disable input during animation - return - - var game_state = get_node("/root/Main/GameState") as GameState +func _process(delta): + var game_state = get_node_or_null("/root/Main/GameState") as GameState if game_state != null: match game_state.current_state: # If we are in the winning animation, fast-forward to game over screen @@ -99,58 +96,59 @@ func _input(event): GameState.State.GAME_OVER: return +func _input(event): + if $AnimationPlayer.is_playing(): + # Disable input during animation + return + # # Handle keyboard input # if event.is_action_pressed("ui_up"): - move_piece(Direction.DOWN) - if event.is_action_pressed("ui_down"): move_piece(Direction.UP) + if event.is_action_pressed("ui_down"): + move_piece(Direction.DOWN) if event.is_action_pressed("ui_left"): - move_piece(Direction.RIGHT) - if event.is_action_pressed("ui_right"): move_piece(Direction.LEFT) + if event.is_action_pressed("ui_right"): + move_piece(Direction.RIGHT) # # Handle touch input # if event is InputEventScreenDrag: -# print("screen drag") swipe = event.relative if not is_sliding: is_sliding = true - current_slide = Vector2(0, 0) + current_touch_slide = Vector2.ZERO var angle = swipe.angle() var direction = direction_for_angle(angle) debug_print_direction(direction) current_sliding_piece = sliding_piece_for_direction(direction) if current_sliding_piece != null: - current_origin = current_sliding_piece.position current_axis = axis_for_direction(direction) var local_end_position = current_axis * (current_sliding_piece.size + interpiece) local_min_position = Vector2(min(0, local_end_position.x), min(0, local_end_position.y)) local_max_position = Vector2(max(0, local_end_position.x), max(0, local_end_position.y)) current_goal = current_sliding_piece.position + local_end_position - current_slide += swipe + current_touch_slide += swipe if current_sliding_piece != null: - var delta = current_slide.project(current_axis) + var delta = current_touch_slide.project(current_axis) delta.x = clamp(delta.x, local_min_position.x, local_max_position.x) delta.y = clamp(delta.y, local_min_position.y, local_max_position.y) current_sliding_piece.position = current_origin + delta if event is InputEventScreenTouch: -# print("screen touch") if not event.pressed: # Touch released is_sliding = false if current_sliding_piece != null: var current_position = current_sliding_piece.position if current_position.distance_to(current_origin) > current_position.distance_to(current_goal): current_sliding_piece.position = current_goal - var origin_taquin_position = current_sliding_piece.taquin_index - swap(missing_piece, origin_taquin_position) - missing_piece = origin_taquin_position + commit_slide() else: - current_sliding_piece.position = current_origin + reset_position(current_sliding_piece) + reset_slide() func debug_print_direction(direction: int): match direction: @@ -192,7 +190,7 @@ func direction_for_angle(angle: float) -> int: return Direction.DOWN func sliding_piece_for_direction(direction) -> Piece: - var destination: Vector2 = missing_piece + var destination: Vector2 = missing_piece.taquin_index match direction: Direction.UP: destination.y += 1 @@ -207,26 +205,18 @@ func sliding_piece_for_direction(direction) -> Piece: || destination.y < 0 || destination.y >= rows): print("\/!\\ Impossible move") return null - return pieces[destination.x][destination.y] -func move_piece(direction) -> bool: - var destination: Vector2 = missing_piece - match direction: - Direction.UP: - destination.y -= 1 - Direction.DOWN: - destination.y += 1 - Direction.LEFT: - destination.x -= 1 - Direction.RIGHT: - destination.x += 1 + var piece = pieces[destination.x][destination.y] + current_origin = piece.position - if (destination.x < 0 || destination.x >= columns - || destination.y < 0 || destination.y >= rows): - print("impossible move") - return false + return piece + +func move_piece(direction) -> void: + current_sliding_piece = sliding_piece_for_direction(direction) + if current_sliding_piece == null: + reset_slide() + return - var moving_piece: Piece = pieces[destination.x][destination.y] var moving_piece_animation: Animation = $AnimationPlayer.get_animation("MovingPiece") assert(moving_piece_animation != null) @@ -236,33 +226,47 @@ func move_piece(direction) -> bool: assert(moving_piece_track_index != -1) - var new_animation_path: String = str($AnimationPlayer.get_parent().get_path_to(moving_piece), ":position") + var new_animation_path: String = str($AnimationPlayer.get_parent().get_path_to(current_sliding_piece), ":position") moving_piece_animation.track_set_path(moving_piece_track_index, new_animation_path) current_animation_path = new_animation_path - moving_piece_animation.track_set_key_value(moving_piece_track_index, 0, position_for_index(destination, moving_piece.size)) - moving_piece_animation.track_set_key_value(moving_piece_track_index, 1, position_for_index(missing_piece, moving_piece.size)) + moving_piece_animation.track_set_key_value(moving_piece_track_index, 0, current_sliding_piece.position) + moving_piece_animation.track_set_key_value(moving_piece_track_index, 1, missing_piece.position) $AnimationPlayer.play("MovingPiece") - swap(missing_piece, destination) - missing_piece = destination + commit_slide() update() - if check_solved(): - var game_state = get_node("/root/Main/GameState") as GameState - if game_state != null: - game_state.transition_to(GameState.State.WINNING) - - return true + check_solved() -func swap(src: Vector2, dst: Vector2) -> void: - var tmp: Piece = pieces[src.x][src.y] - pieces[src.x][src.y] = pieces[dst.x][dst.y] - pieces[src.x][src.y].taquin_index = src - pieces[dst.x][dst.y] = tmp - tmp.taquin_position = dst -# pieces[src.x][src.y].position = position_for_index(src, tmp.size) -# pieces[dst.x][dst.y].position = position_for_index(dst, tmp.size) +func commit_slide(): + assert(current_sliding_piece != null) + assert(current_origin != Vector2.ZERO) + + var x_delta = missing_piece.taquin_index.x - current_sliding_piece.taquin_index.x + var y_delta = missing_piece.taquin_index.y - current_sliding_piece.taquin_index.y + assert(abs(x_delta) + abs(y_delta) == 1) + + swap_pieces(missing_piece, current_sliding_piece) + reset_position(missing_piece) + + ensure_validity() + reset_slide() + check_solved() + +func reset_slide(): + current_sliding_piece = null + current_origin = Vector2.ZERO + +func reset_position(p: Piece): + p.position = position_for_index(p.taquin_index, p.size) + +func swap_pieces(a: Piece, b: Piece) -> void: + var a_index := a.taquin_index + a.taquin_index = b.taquin_index + pieces[b.taquin_index.x][b.taquin_index.y] = a + b.taquin_index = a_index + pieces[a_index.x][a_index.y] = b func shuffle(count: int) -> void: while count > 0: @@ -273,10 +277,22 @@ func shuffle(count: int) -> void: func check_solved() -> bool: for c in range(columns): for r in range(rows): - if pieces[c][r].number != 1 + c + r * columns: + if pieces[c][r].order != 1 + c + r * columns: return false + + var game_state = get_node_or_null("/root/Main/GameState") as GameState + if game_state != null: + game_state.transition_to(GameState.State.WINNING) + return true +func ensure_validity() -> void: + for c in range(columns): + for r in range(rows): + var piece = pieces[c][r] + assert(piece.taquin_index.x == c) + assert(piece.taquin_index.y == r) + func _on_GameState_state_changed(previous, current): match current: GameState.State.WINNING: diff --git a/game/src/Taquin.tscn b/game/src/Taquin.tscn index d8958aa..ecf997c 100644 --- a/game/src/Taquin.tscn +++ b/game/src/Taquin.tscn @@ -49,8 +49,8 @@ script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } -rows = 5 -columns = 5 +rows = 3 +columns = 3 difficulty = 0 [node name="Background" type="ColorRect" parent="."]