diff --git a/entities/game/card_collider/scripts/CardCollider.gd b/entities/game/card_collider/scripts/CardCollider.gd index 09bd0bf..f24c35d 100644 --- a/entities/game/card_collider/scripts/CardCollider.gd +++ b/entities/game/card_collider/scripts/CardCollider.gd @@ -3,25 +3,24 @@ class_name CardCollider extends Node2D signal set_shape(shape: RectangleShape2D) signal mouse_enter(grid: Vector2i) signal mouse_left(grid: Vector2i) -signal clicked(grid: Vector2i) +signal clicked(grid: Vector2i, card: MemoryCardResource) var _grid_coordinate: Vector2i = Vector2i.ZERO var _shape: CollisionShape2D = null var _mouse_inside: bool = false var _active_state: bool = false -var _card_id: int = -1 +var _card_data: MemoryCardResource = null func _ready() -> void: _shape = get_node("%CollisionShape") -func set_card_id(id: int) -> void: - if _card_id != -1: - return - _card_id = id +func set_data(data: MemoryCardResource) -> void: + + _card_data = data func get_card_id() -> int: - return _card_id + return _card_data.id func set_size(size: Vector2) -> void: var shape: RectangleShape2D = RectangleShape2D.new() @@ -63,6 +62,9 @@ func input_event(_viewport: Node, event: InputEvent, _shape_idx: int) -> void: return if event is InputEventMouseButton: if event.pressed and event.button_index == MouseButton.MOUSE_BUTTON_LEFT: - clicked.emit(_grid_coordinate) - disable_collider() - is_clicked() + activate() + +func activate() -> void: + disable_collider() + is_clicked() + clicked.emit(_grid_coordinate, _card_data) \ No newline at end of file diff --git a/entities/game/card_template/scenes/CardTemplate.tscn b/entities/game/card_template/scenes/CardTemplate.tscn index 8a4afad..a584723 100644 --- a/entities/game/card_template/scenes/CardTemplate.tscn +++ b/entities/game/card_template/scenes/CardTemplate.tscn @@ -209,19 +209,13 @@ volume = -15.0 [connection signal="about_to_get_delete" from="." to="CardContentGroup" method="animate_destruction"] [connection signal="about_to_get_delete" from="." to="CardBack" method="remove_from_board"] [connection signal="about_to_get_delete" from="." to="MatchingFoundEffect" method="trigger"] -[connection signal="card_in_focus" from="." to="CardContentGroup/DropShadow" method="got_focus"] -[connection signal="card_in_focus" from="." to="CardBack" method="is_focused"] -[connection signal="card_in_focus" from="." to="FocusEffect" method="trigger_random_effect"] -[connection signal="card_lost_focus" from="." to="CardContentGroup/DropShadow" method="lost_focus"] -[connection signal="card_lost_focus" from="." to="CardBack" method="lost_focus"] [connection signal="card_text_changed" from="." to="CardContentGroup/CardNameBackground/CardName" method="set_card_text"] [connection signal="card_tooltip_changed" from="." to="CardContentGroup/CardNameBackground/CardName" method="set_tooltip"] [connection signal="deck_changed" from="." to="CardContentGroup/DropShadow" method="deck_changed"] [connection signal="deck_changed" from="." to="CardBack" method="deck_changed"] +[connection signal="focus_changed" from="." to="CardBack" method="focus_changed"] [connection signal="hide_card" from="." to="CardContentGroup/CardNameBackground/CardName" method="card_hidden"] [connection signal="hide_card" from="." to="CardBack" method="toggle_on"] -[connection signal="input_active" from="." to="CardBack" method="input_active"] -[connection signal="input_active" from="." to="FocusEffect" method="toggle_state"] [connection signal="remove_requested" from="." to="CardBack" method="removal_planed"] [connection signal="show_card" from="." to="CardContentGroup" method="show_card_content"] [connection signal="show_card" from="." to="CardBack" method="toggle_off"] diff --git a/entities/game/card_template/scripts/CardTemplate.gd b/entities/game/card_template/scripts/CardTemplate.gd index 849d003..cc5b47b 100644 --- a/entities/game/card_template/scripts/CardTemplate.gd +++ b/entities/game/card_template/scripts/CardTemplate.gd @@ -8,19 +8,27 @@ signal show_card() signal fully_hidden() ## The process of showing has ended, the card is fully visible now signal fully_shown() -signal card_triggered(card: CardTemplate) -signal card_in_focus() -signal card_lost_focus() -signal mouse_was_used() + +signal remove_requested() + +signal animation_done() + +## Signals to manage the visual card state + ## The card is now queued to be freed signal about_to_get_delete() -signal input_active(is_active: bool) +## The card text was changed signal card_text_changed(new_text: String) + +## The card tooltip was changed signal card_tooltip_changed(new_tooltip: String) + +## The card deck was changed signal deck_changed(deck: MemoryDeckResource) -signal remove_requested() +signal focus_changed(new_state: bool) + @export var is_ghost: bool = false @@ -103,25 +111,23 @@ func _setup_timer() -> void: _timer_for_hide_delay.timeout.connect(hide_card_now) add_child(_timer_for_hide_delay) -func _enter_tree() -> void: - if is_ghost: - return - var parent_node: MemoryGame = get_parent().get_node("%World").get_parent() as MemoryGame - if parent_node == null: - printerr("No parent node was found!") +func change_focus(new_state: bool) -> void: + focus_changed.emit(new_state) func toggle_card_on() -> void: var time_range: float = card_flip_animation_max_time_delay - card_flip_animation_min_time_delay var delay: float = randf() * time_range + card_flip_animation_min_time_delay - _timer_for_hide_delay.wait_time = delay - _timer_for_hide_delay.start() + await get_tree().create_timer(delay).timeout + hide_card_now() + #_timer_for_hide_delay.wait_time = delay + #_timer_for_hide_delay.start() func hide_card_now() -> void: if back_side == null or back_side.is_hidden(): return _was_clicked = false hide_card.emit() - lost_focus() + _playing_animation = true play_card_turn_sound() func get_height() -> float: @@ -131,7 +137,6 @@ func freeze_card() -> void: if back_side == null: return _card_frozen = true - lost_focus() func unfreeze_card() -> void: if back_side == null: @@ -154,14 +159,13 @@ func force_reveal_card() -> void: if _was_clicked or not _valid_game_state: return _was_clicked = true + _playing_animation = true freeze_card() play_card_turn_sound() if back_side == null or back_side.is_queued_for_deletion(): return back_side.toggle_off() show_card.emit() - - card_triggered.emit(self) func play_card_turn_sound() -> void: GlobalSoundManager.play_sound_effect(flip_effects.pick_random()) @@ -237,6 +241,7 @@ func _trigger_remove() -> void: for group: String in get_groups(): remove_from_group(group) _playing_animation = false + animation_done.emit() about_to_get_delete.emit() func is_playing_animation() -> bool: @@ -245,9 +250,6 @@ func is_playing_animation() -> bool: func is_getting_removed() -> bool: return _getting_removed -func destory_now() -> void: - queue_free() - func card_is_hidden() -> bool: if back_side == null: return true @@ -263,31 +265,19 @@ func card_is_focused() -> bool: return true return back_side.is_currently_in_focus() -func got_focus() -> void: - if _was_clicked or _card_frozen: - return - card_in_focus.emit() - -func lost_focus() -> void: - if _was_clicked: - return - card_lost_focus.emit() - -func selected_by_mouse() -> void: - mouse_was_used.emit() - func play_sound(audio: AudioStream) -> void: if audio == null: return GlobalSoundManager.play_sound_effect(audio) -func input_allowed(allowed: bool) -> void: - input_active.emit(allowed) - func signal_repeater_fully_shown() -> void: + _playing_animation = false + animation_done.emit() fully_shown.emit() func signal_repeater_fully_hidden() -> void: + _playing_animation = false + animation_done.emit() fully_hidden.emit() func game_state_changed(new_state: GameEnum.State) -> void: diff --git a/entities/game/card_template/scripts/ToggleCardVisibility.gd b/entities/game/card_template/scripts/ToggleCardVisibility.gd index 0e2049a..907bf80 100644 --- a/entities/game/card_template/scripts/ToggleCardVisibility.gd +++ b/entities/game/card_template/scripts/ToggleCardVisibility.gd @@ -24,7 +24,8 @@ enum VisibilityEnum var _internal_toggle_material: ShaderMaterial var _internal_focus_material: ShaderMaterial -var currently_in_focus: bool = false +## The card is the current focus of the player +var _current_focus: bool = false var removal_requested: bool = false var can_remove: bool = false @@ -51,9 +52,8 @@ func deck_changed(deck: MemoryDeckResource) -> void: texture = real_texture return -# This method will hide a fully shown card +## This method will hide a fully shown card func toggle_on() -> void: - print("toggle on") can_remove = false if is_hidden(): return @@ -68,23 +68,20 @@ func toggle_on() -> void: visibility = VisibilityEnum.TRANSITION animation_tween.tween_method(update_toggle_material, 1.0, 0.0, animation_time) animation_tween.finished.connect(func() -> void: _animation_finished(true)) - if currently_in_focus: + if _current_focus: set_shader_material(_internal_toggle_material) func _animation_finished(should_hide: bool) -> void: if should_hide: fully_hidden.emit() visibility = VisibilityEnum.HIDDEN - print("hidden") if not should_hide: fully_shown.emit() visibility = VisibilityEnum.SHOWN can_remove = true - print("shown") -# This method will show a fully hidden card +## This method will show a fully hidden card func toggle_off() -> void: - print("toggle off") if animation_tween != null: animation_tween.kill() if material is ShaderMaterial: @@ -93,28 +90,31 @@ func toggle_off() -> void: visibility = VisibilityEnum.TRANSITION animation_tween.tween_method(update_toggle_material, 0.0, 1.0, animation_time) animation_tween.finished.connect(func() -> void: _animation_finished(false)) - if currently_in_focus: + if _current_focus: set_shader_material(_internal_toggle_material) func update_toggle_material(progress: float) -> void: if material is ShaderMaterial: material.set_shader_parameter("threshold", progress) +func focus_changed(new_focus: bool) -> void: + if new_focus: + is_focused() + else: + lost_focus() + func is_focused() -> void: if animation_tween != null && animation_tween.is_running(): return if visibility == VisibilityEnum.TRANSITION: return - for card: Node in get_tree().get_nodes_in_group("game_card"): - if card is CardTemplate and card.card_is_focused(): - card.lost_focus() - currently_in_focus = true + _current_focus = true set_shader_material(_internal_focus_material) _animate_focus(focus_scale) func lost_focus() -> void: - currently_in_focus = false + _current_focus = false set_shader_material(_internal_toggle_material) _animate_focus(1.0) @@ -133,7 +133,7 @@ func is_fully_shown() -> bool: return visibility == VisibilityEnum.SHOWN func is_currently_in_focus() -> bool: - return currently_in_focus + return _current_focus func remove_from_board() -> void: removal_requested = true diff --git a/entities/game/memory_game/scenes/MemoryGame.tscn b/entities/game/memory_game/scenes/MemoryGame.tscn index 5c0a980..c17e9c3 100644 --- a/entities/game/memory_game/scenes/MemoryGame.tscn +++ b/entities/game/memory_game/scenes/MemoryGame.tscn @@ -281,17 +281,10 @@ debug_functions = Array[ExtResource("34_4hsit")]([SubResource("Resource_8rpam")] [connection signal="player_has_changed" from="Systems/NetworkHandlerSystem" to="Systems/PlayerSystem" method="set_player_by_id"] [connection signal="player_has_scored" from="Systems/NetworkHandlerSystem" to="Systems/PlayerSystem" method="set_player_score"] [connection signal="remove_card" from="Systems/NetworkHandlerSystem" to="World/CardBoard" method="remove_card_from_board"] -[connection signal="all_matching_cards_removed" from="World/CardBoard" to="." method="all_cards_removed"] -[connection signal="all_matching_cards_removed" from="World/CardBoard" to="Systems/GameStateSystem" method="matches_found"] -[connection signal="all_matching_cards_removed" from="World/CardBoard" to="Systems/TutorialStateSystem" method="matching_card_found"] -[connection signal="all_matching_cards_removed" from="World/CardBoard" to="Systems/PlayerSystem" method="player_scored"] +[connection signal="animations_finished" from="World/CardBoard" to="Systems/GameStateSystem" method="animation_cleared"] +[connection signal="animations_finished" from="World/CardBoard" to="Systems/PlayerSystem" method="card_animations_completed"] [connection signal="board_ready" from="World/CardBoard" to="Systems/GameStateSystem" method="board_ready"] -[connection signal="card_activated" from="World/CardBoard" to="Systems/GameStateSystem" method="card_was_clicked"] -[connection signal="card_activated" from="World/CardBoard" to="Systems/TutorialStateSystem" method="card_triggered"] -[connection signal="card_removed" from="World/CardBoard" to="World/CardBoard/CardInteractionField" method="remove_card"] -[connection signal="card_triggered" from="World/CardBoard" to="Systems/AiAgentSystem" method="card_was_triggered"] -[connection signal="identical_cards" from="World/CardBoard" to="Systems/AiAgentSystem" method="card_was_identically"] -[connection signal="no_matches_found" from="World/CardBoard" to="Systems/GameStateSystem" method="no_matches"] +[connection signal="ai_information_card_clicked" from="World/CardBoard/CardInteractionField" to="Systems/AiAgentSystem" method="card_was_triggered"] [connection signal="board_area" from="World/CardBoard/CardInteractionField" to="World/Camera2D" method="adjust_zoom_and_position_to_play_area"] [connection signal="board_build" from="World/CardBoard/CardInteractionField" to="Systems/GameStateSystem" method="game_field_ready"] [connection signal="board_build" from="World/CardBoard/CardInteractionField" to="UI/PauseMenuButton" method="show_button_if_valid"] @@ -299,8 +292,15 @@ debug_functions = Array[ExtResource("34_4hsit")]([SubResource("Resource_8rpam")] [connection signal="board_build" from="World/CardBoard/CardInteractionField" to="UI/ZoomButtons/ZoomIn" method="show_button_if_valid"] [connection signal="board_build" from="World/CardBoard/CardInteractionField" to="UI/ZoomButtons/ZoomOut" method="show_button_if_valid"] [connection signal="board_empty" from="World/CardBoard/CardInteractionField" to="Systems/GameStateSystem" method="board_empty"] +[connection signal="card_activated" from="World/CardBoard/CardInteractionField" to="Systems/TutorialStateSystem" method="card_triggered"] [connection signal="clicked" from="World/CardBoard/CardInteractionField" to="World/CardBoard" method="trigger_card_at_position"] +[connection signal="match_found" from="World/CardBoard/CardInteractionField" to="Systems/GameStateSystem" method="matches_found"] +[connection signal="match_found" from="World/CardBoard/CardInteractionField" to="Systems/TutorialStateSystem" method="matching_card_found"] +[connection signal="match_found" from="World/CardBoard/CardInteractionField" to="Systems/PlayerSystem" method="player_scored"] [connection signal="mouse_enter" from="World/CardBoard/CardInteractionField" to="World/CardBoard" method="select_card_at_position"] [connection signal="place_card" from="World/CardBoard/CardInteractionField" to="World/CardBoard" method="place_card"] +[connection signal="remove_card_at" from="World/CardBoard/CardInteractionField" to="Systems/AiAgentSystem" method="remove_card_to_all_ais"] +[connection signal="remove_cards_at" from="World/CardBoard/CardInteractionField" to="World/CardBoard" method="remove_cards_from_board"] +[connection signal="turn_ended" from="World/CardBoard/CardInteractionField" to="Systems/GameStateSystem" method="no_matches"] [connection signal="touch_used" from="World/Camera2D" to="World/CardBoard" method="disable_card_effects"] [connection signal="pressed" from="UI/PauseMenuButton" to="." method="show_game_menu"] diff --git a/entities/game/memory_game/scripts/CardInteractionField.gd b/entities/game/memory_game/scripts/CardInteractionField.gd index 40ce260..778f03c 100644 --- a/entities/game/memory_game/scripts/CardInteractionField.gd +++ b/entities/game/memory_game/scripts/CardInteractionField.gd @@ -3,14 +3,28 @@ class_name CardInteractionField extends Node2D signal mouse_enter(grid: Vector2i) signal mouse_left(grid: Vector2i) signal clicked(grid: Vector2i) +signal card_activated() +signal remove_cards_at(cards: Array[Vector2i]) +signal ai_information_card_clicked(grid: Vector2i, card: MemoryCardResource) signal place_card(card: MemoryCardResource, grid_position: Vector2i, world_position: Vector2) signal board_area(area: Rect2) signal board_build() +# Methods to manage game flow + +signal remove_card_at(grid_coordinate: Vector2i) + ## The whole board is empty now signal board_empty() +## Player turn did end +signal turn_ended() + +## A match was found +signal match_found() + + enum Axis {X, Y} @export var default_texture_size: Vector2 = Vector2(499, 550) @@ -36,6 +50,9 @@ var possible_movements: Array[Vector2] = [ Vector2.UP ] +func _init(): + remove_card_at.connect(remove_card) + func _reset_grid_position() -> void: _selected_grid_position = -Vector2i.ONE @@ -99,7 +116,7 @@ func build_field(cards: Array[MemoryCardResource]) -> void: template.set_size(_card_size) template.position = _offset + additional_offset + Vector2i(x_addition, y_addition) template.set_grid_coordinate(Vector2i(x, y)) - template.set_card_id(card.id) + template.set_data(card) _connect_card_interaction(template) _placed_cards.set(Vector2i(x, y), template) add_child(template) @@ -273,17 +290,58 @@ func _connect_card_interaction(collider: CardCollider) -> void: collider.mouse_enter.connect(_mouse_movement_was_made) collider.mouse_left.connect(mouse_has_left) collider.mouse_left.connect(_mouse_movement_was_made) - collider.clicked.connect(mouse_has_clicked) + collider.clicked.connect(card_was_clicked) func _mouse_movement_was_made(_grid_position: Vector2i) -> void: _controller_input_was_made = false Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) -func mouse_has_clicked(grid_position: Vector2i) -> void: +func card_was_clicked(grid_position: Vector2i, data: MemoryCardResource) -> void: clicked.emit(grid_position) - for collider: CardCollider in get_children(): - if collider.get_grid_coordinate() == grid_position: - collider.is_clicked() + ai_information_card_clicked.emit(grid_position, data) + + _check_board_state() + +func _check_board_state() -> void: + var cards: Array[CardCollider] = _placed_cards.values().filter(func(card: CardCollider) -> bool: return not card.is_active()) + if cards.size() < 2: + return + if _check_for_matching(cards): + match_found.emit() + return + + turn_ended.emit() + +func _check_for_matching(cards: Array[CardCollider]) -> bool: + if cards.size() != 2: + return false + if cards[0].get_card_id() == cards[1].get_card_id(): + var grid_positions: Array[Vector2i] = [] + + for card: CardCollider in cards: + grid_positions.append(card.get_grid_coordinate()) + remove_cards_at.emit(grid_positions) + remove_card_at.emit(grid_positions[0]) + remove_card_at.emit(grid_positions[1]) + return true + return false + +func mouse_has_clicked(grid_position: Vector2i) -> void: + if not _placed_cards.has(grid_position): + return + + var card: CardCollider = _placed_cards.get(grid_position) + if not card.is_active(): + return + card.activate() + card_activated.emit() + + _reset_player_selection() + +func _reset_player_selection() -> void: + if _is_ai_player: + return + if not _controller_input_was_made: _reset_grid_position() return diff --git a/entities/game/memory_game/scripts/GameCardGrid.gd b/entities/game/memory_game/scripts/GameCardGrid.gd index df718dd..ce82d08 100644 --- a/entities/game/memory_game/scripts/GameCardGrid.gd +++ b/entities/game/memory_game/scripts/GameCardGrid.gd @@ -1,13 +1,8 @@ class_name GameCardGrid extends Node2D -signal card_removed(grid_position: Vector2i) -signal all_matching_cards_removed() -signal card_triggered(CardTemplate: CardTemplate) -signal identical_cards(first_card_Vector2i: Vector2i, set_icon_modulated_card_Vector2i: Vector2i) -signal no_matches_found() signal board_ready() -signal board_empty() -signal card_activated() + +signal animations_finished() @export var state_machine: GameStateSystem @export var matching_card_sound_effect: AudioStream @@ -20,11 +15,8 @@ var current_card: CardTemplate var controller_input_was_made: bool = false var currently_ai_player: bool = false -var number_of_triggered_cards: int = 0 - -var _game_completed: bool = false - var _deck: MemoryDeckResource = null +var _cards: Dictionary[Vector2i, CardTemplate] = {} enum Axis {X, Y} @@ -40,31 +32,33 @@ func trigger_card_at_position(grid_position: Vector2i) -> void: func remove_cards_from_board(grid_positions: Array[Vector2i]) -> void: for grid_position: Vector2i in grid_positions: remove_card_from_board(grid_position) - for card: CardTemplate in _get_game_card_templates(): - if card.is_playing_animation(): - await card.about_to_get_delete - all_matching_cards_removed.emit() + + await animations_finished GlobalSoundManager.play_sound_effect(matching_card_sound_effect) func remove_card_from_board(grid_position: Vector2i) -> void: - for child: CardTemplate in _get_game_card_templates_children(): - if child.grid_position == grid_position: - child.remove_from_board(currently_ai_player) - card_removed.emit(child.grid_position) + if _cards.has(grid_position): + var card: CardTemplate = _cards.get(grid_position) + _cards.erase(grid_position) + card.remove_from_board(currently_ai_player) + +func _await_animations_finished() -> void: + ## This search must be done on the visual node as the card is already remove from the + ## dictionary track + for card: Node in visual_card_node.get_children(): + if card != null and card is CardTemplate and card.is_playing_animation(): + await card.animation_done func select_card_at_position(grid_position: Vector2i) -> bool: var found_card: bool = false - var initial_card: CardTemplate = current_card - for card: CardTemplate in _get_game_card_templates_children(): - card.lost_focus() - if grid_position == card.grid_position: - card.got_focus() - current_card = card - found_card = true - - if !found_card and current_card != null: - current_card = initial_card - current_card.got_focus() + if _cards.has(grid_position): + for card: CardTemplate in _cards.values(): + card.change_focus(false) + + var card: CardTemplate = _cards.get(grid_position) + card.change_focus(true) + current_card = card + found_card = true return found_card func round_frozen() -> void: @@ -72,64 +66,30 @@ func round_frozen() -> void: func game_state_changed(game_state: GameEnum.State) -> void: match game_state: - GameEnum.State.TURN_START: - if _get_game_card_templates().size() == 0: - _announce_empty_board() - GameEnum.State.TURN_FREEZE: round_frozen() - GameEnum.State.TURN_COMPLETED: - _validate_grid() GameEnum.State.PREPARE_TURN_END: _prepare_turn_complete() - -func _announce_empty_board() -> void: - if _game_completed: - return - _game_completed = true - board_empty.emit() - -func _validate_grid() -> void: - for card: CardTemplate in _get_game_card_templates(): - if card == null or card.is_queued_for_deletion(): - continue - if card.is_turned() and not card.card_is_fully_shown(): - await card.fully_shown - if _any_matching(): - var card_positions: Array[Vector2i] = [] - for card: CardTemplate in _get_game_card_templates(): - if card.is_turned(): - card_positions.append(card.grid_position) - identical_cards.emit(card_positions[0], card_positions[1]) - remove_cards_from_board(card_positions) - var count: int = _get_game_card_templates().filter(func (card: CardTemplate) -> bool: return not card.is_getting_removed()).size() - if count == 0: - _announce_empty_board() + GameEnum.State.WAIT_FOR_ANIMATION_FINISH: + await wait_for_animations() + animations_finished.emit() - return - - - no_matches_found.emit() +func wait_for_animations() -> void: + await _await_animations_finished() func _prepare_turn_complete() -> void: - for card: CardTemplate in _get_game_card_templates(): + for card: CardTemplate in _cards.values(): if card == null or card.is_queued_for_deletion(): continue if not card.card_is_hidden(): print ("wait hidden card") await card.fully_hidden - - print ("continue prepare turn complete") - var all_cards: Array[CardTemplate] = _get_game_card_templates() - if all_cards.size() == 0: - _announce_empty_board() - return - board_ready.emit() + #board_ready.emit() func _any_matching() -> bool: var first_found: CardTemplate = null - for card: CardTemplate in _get_game_card_templates(): + for card: CardTemplate in _cards.values(): if not card.is_turned(): continue if first_found == null: @@ -139,18 +99,9 @@ func _any_matching() -> bool: return true return false -func get_all_card_positions(get_turned: bool = false) -> Array[Vector2i]: - var return_data: Array[Vector2i] = [] - for card: CardTemplate in _get_game_card_templates_children(): - if card.is_getting_removed(): - continue - if get_turned or !card.is_turned(): - return_data.append(card.grid_position) - return return_data - func get_all_cards_currently_turned() -> Array[Vector2i]: var return_data: Array[Vector2i] = [] - for card: CardTemplate in _get_game_card_templates_children(): + for card: CardTemplate in _cards.values(): if card.is_turned(): return_data.append(card.grid_position) return return_data @@ -160,31 +111,6 @@ func player_changed(current_player:PlayerResource) -> void: if multiplayer.get_peers().size() > 0 and current_player.id != multiplayer.get_unique_id(): currently_ai_player = true -func disable_card_effects() -> void: - for card: CardTemplate in _get_game_card_templates(): - card.lost_focus() - -func _get_game_card_templates_children() -> Array[CardTemplate]: - var return_data: Array[CardTemplate] - for template: CardTemplate in visual_card_node.get_children().filter(func(data: Node) -> bool: return data is CardTemplate): - return_data.append(template) - return return_data - -func _get_game_card_templates() -> Array[CardTemplate]: - var return_data: Array[CardTemplate] - for template: CardTemplate in get_tree().get_nodes_in_group("game_card").filter(func(card: Node) -> bool: return card is CardTemplate): - return_data.append(template) - return return_data - -func prevent_input(prevent: bool) -> void: - for card: CardTemplate in _get_game_card_templates_children(): - card.input_allowed(!prevent) - -# remove -func card_was_placed(card: CardTemplate) -> void: - card.card_triggered.connect(card_triggered_hook) - state_machine.state_changed.connect(card.game_state_changed) - func place_card(card: MemoryCardResource, grid_position: Vector2i, world_position: Vector2) -> void: var card_template_node: CardTemplate = card_template.instantiate() as CardTemplate card_template_node.memory_card = card @@ -193,12 +119,6 @@ func place_card(card: MemoryCardResource, grid_position: Vector2i, world_positio card_template_node.card_deck = _deck visual_card_node.add_child(card_template_node) + _cards.set(grid_position, card_template_node) - ## Should be changed - card_template_node.card_triggered.connect(card_triggered_hook) state_machine.state_changed.connect(card_template_node.game_state_changed) - -func card_triggered_hook(card: CardTemplate) -> void: - select_card_at_position(card.grid_position) - card_triggered.emit(card) - card_activated.emit() diff --git a/entities/game/memory_game/scripts/systems/AiAgentSystem.gd b/entities/game/memory_game/scripts/systems/AiAgentSystem.gd index bf3d537..f23f4ac 100644 --- a/entities/game/memory_game/scripts/systems/AiAgentSystem.gd +++ b/entities/game/memory_game/scripts/systems/AiAgentSystem.gd @@ -19,8 +19,8 @@ var should_play_round: bool = false var current_player_data: PlayerResource = null var last_card: MemoryCardResource = null -func card_was_triggered(card: CardTemplate) -> void: - add_card_to_all_ais(card.grid_position, card.memory_card) +func card_was_triggered(grid: Vector2i, card: MemoryCardResource) -> void: + add_card_to_all_ais(grid, card) func card_was_identically(first_card_position: Vector2i, second_card_position: Vector2i) -> void: remove_card_to_all_ais(first_card_position) @@ -30,7 +30,9 @@ func card_was_identically(first_card_position: Vector2i, second_card_position: V func game_state_changed(game_state: GameEnum.State) -> void: if should_play_round and game_state == GameEnum.State.TURN_START: + await get_tree().physics_frame print("ai turn start") + triggered_cards = 0 prepare_and_start_timer() if game_state == GameEnum.State.PREPARE_TURN_END or game_state == GameEnum.State.TURN_FREEZE: diff --git a/entities/game/memory_game/scripts/systems/GameStateSystem.gd b/entities/game/memory_game/scripts/systems/GameStateSystem.gd index 29c7aec..8b0efeb 100644 --- a/entities/game/memory_game/scripts/systems/GameStateSystem.gd +++ b/entities/game/memory_game/scripts/systems/GameStateSystem.gd @@ -5,6 +5,8 @@ signal request_popup(window: PopupWindow) signal force_close_popup(id: int) signal game_has_ended() +signal _animations_done() + @export var round_end_message: TextTranslation @export var round_end_message_no_auto_complete: TextTranslation @@ -12,8 +14,6 @@ var message_banner: PackedScene = preload("res://entities/game/bottom_message_ba var _current_state: GameEnum.State = GameEnum.State.GAME_INIT -var _cards_per_turn: int = 2 -var _clicked_card_amount: int = 0 var _popup_id: int = -1 func _ready() -> void: @@ -32,23 +32,24 @@ func game_field_ready() -> void: if _current_state == GameEnum.State.GAME_INIT: _change_state(GameEnum.State.TURN_START) -func card_was_clicked() -> void: - print("card clicked") - _clicked_card_amount += 1 - if _clicked_card_amount >= _cards_per_turn: - _change_state(GameEnum.State.TURN_FREEZE) - _change_state(GameEnum.State.TURN_COMPLETED) - _clicked_card_amount = 0 - func matches_found() -> void: print("match found") + _change_state(GameEnum.State.TURN_FREEZE) + _change_state(GameEnum.State.TURN_COMPLETED) if _current_state == GameEnum.State.GAME_END: animation_cleared() + + _change_state(GameEnum.State.WAIT_FOR_ANIMATION_FINISH) + await _animations_done _change_state(GameEnum.State.TURN_START) func no_matches() -> void: print("no matches") + _change_state(GameEnum.State.TURN_FREEZE) + _change_state(GameEnum.State.TURN_COMPLETED) _change_state(GameEnum.State.PREPARE_TURN_END) + _change_state(GameEnum.State.WAIT_FOR_ANIMATION_FINISH) + await _animations_done _show_round_ended_banner() func board_ready() -> void: @@ -67,6 +68,9 @@ func board_empty() -> void: emergency_timer.start(2) func animation_cleared() -> void: + if _current_state == GameEnum.State.WAIT_FOR_ANIMATION_FINISH: + _animations_done.emit() + if _current_state != GameEnum.State.GAME_END: return _change_state(GameEnum.State.ANIMATION_CLEARED) @@ -94,5 +98,5 @@ func force_end_round() -> void: func _begin_new_round() -> void: _change_state(GameEnum.State.TURN_END) - _clicked_card_amount = 0 - _popup_id = -1 \ No newline at end of file + _popup_id = -1 + _change_state(GameEnum.State.TURN_START) \ No newline at end of file diff --git a/entities/game/memory_game/scripts/systems/PlayerInputSystem.gd b/entities/game/memory_game/scripts/systems/PlayerInputSystem.gd index fd74515..22058ec 100644 --- a/entities/game/memory_game/scripts/systems/PlayerInputSystem.gd +++ b/entities/game/memory_game/scripts/systems/PlayerInputSystem.gd @@ -4,7 +4,6 @@ signal game_menu_requested() signal end_current_round() signal confirm_current_card() signal card_movement(information: Vector2) -#signal disable_input() @export var frames_to_skip_after_pause: int = 2 @@ -42,8 +41,6 @@ func player_changed(current_player:PlayerResource) -> void: current_ai_player = current_player.is_ai() if multiplayer.get_peers().size() > 0 and current_player.id != multiplayer.get_unique_id(): current_ai_player = true - #if current_ai_player: - #disable_input.emit() func prevent_input(prevent: bool) -> void: _prevent_input = prevent @@ -57,7 +54,6 @@ func _handle_special_player_actions() -> void: Input.action_release("back") game_menu_requested.emit() if Input.is_action_just_pressed("next_round") and can_end_round: - can_end_round = false end_current_round.emit() func _handle_player_input_actions() -> void: diff --git a/entities/game/memory_game/scripts/systems/PlayerSystem.gd b/entities/game/memory_game/scripts/systems/PlayerSystem.gd index 3b7cff6..9d783a4 100644 --- a/entities/game/memory_game/scripts/systems/PlayerSystem.gd +++ b/entities/game/memory_game/scripts/systems/PlayerSystem.gd @@ -5,6 +5,8 @@ signal player_resource_changed(current_player: PlayerResource) signal player_added(player: PlayerResource) signal player_score_changed(player_id: int, score: int) +signal _remove_card_animation_completed() + var players: Array[PlayerResource] var current_player_index: int @@ -37,6 +39,7 @@ func next_player() -> void: func player_scored() -> void: if get_current_player() == null: return + await _remove_card_animation_completed set_player_score(get_current_player().id, get_current_player().score + 1) func game_state_changed(game_state: GameEnum.State) -> void: @@ -60,4 +63,7 @@ func set_player_score(id: int, score: int) -> void: if index == -1: return players[index].score = score - player_score_changed.emit(players[index].id, players[index].score) \ No newline at end of file + player_score_changed.emit(players[index].id, players[index].score) + +func card_animations_completed() -> void: + _remove_card_animation_completed.emit() \ No newline at end of file diff --git a/project.godot b/project.godot index 5ec7584..1cafad3 100644 --- a/project.godot +++ b/project.godot @@ -15,7 +15,7 @@ compatibility/default_parent_skeleton_in_mesh_instance_3d=true [application] config/name="Samory" -config/version="0.20.2" +config/version="0.20.3" config/tags=PackedStringArray("public") run/main_scene="res://shared/global_entities/game_manager/scenes/GameManager.tscn" config/features=PackedStringArray("4.7", "GL Compatibility") diff --git a/shared/entities/game_state/scripts/GameStateEnum.gd b/shared/entities/game_state/scripts/GameStateEnum.gd index 0c719ec..829e690 100644 --- a/shared/entities/game_state/scripts/GameStateEnum.gd +++ b/shared/entities/game_state/scripts/GameStateEnum.gd @@ -6,6 +6,7 @@ enum State { TURN_FREEZE = 20, # Can go to turn completed turn completed TURN_COMPLETED = 30, # Can only go to prepare turn end or turn start PREPARE_TURN_END = 40, # Can go to turn end or end game + WAIT_FOR_ANIMATION_FINISH = 45, TURN_END = 50, # Can go to turn start GAME_END = 1000, ANIMATION_CLEARED = 10000 diff --git a/shared/global_entities/game_manager/scripts/GameManager.gd b/shared/global_entities/game_manager/scripts/GameManager.gd index 2fc485d..f1a0ee2 100644 --- a/shared/global_entities/game_manager/scripts/GameManager.gd +++ b/shared/global_entities/game_manager/scripts/GameManager.gd @@ -85,7 +85,7 @@ func reload_system_decks() -> void: if not _deck_reload_connected: _deck_reload_connected = true GlobalSystemDeckManager.loading_system_decks_done.connect(loading_data_done) - GlobalSystemDeckManager.reload_system_decks() + await GlobalSystemDeckManager.reload_system_decks() func initial_settings_setup() -> void: var settings: SettingsResource = SettingsRepository.load_settings()