From 36c329b4b1e624cddfc1b7813ac9ccf4d458403e Mon Sep 17 00:00:00 2001 From: Guilherme Henrique Teixeira de Oliveira Date: Mon, 10 Dec 2018 15:50:57 -0200 Subject: [PATCH] Open and close animations added to CircularMenu Closes #73 --- .../interface/circular_menu/CircularButton.gd | 6 +- .../interface/circular_menu/CircularMenu.gd | 55 +++++++++++++++---- .../interface/circular_menu/CircularMenu.tscn | 22 ++++++++ 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/godot/combat/interface/circular_menu/CircularButton.gd b/godot/combat/interface/circular_menu/CircularButton.gd index bd591bd..9309d4d 100644 --- a/godot/combat/interface/circular_menu/CircularButton.gd +++ b/godot/combat/interface/circular_menu/CircularButton.gd @@ -6,9 +6,13 @@ onready var button_icon : = $Background/Icon as TextureRect var mouse_over : bool var active : bool +var target_position : Vector2 +var unfocused_scale : Vector2 func initialize(action : CombatAction, target_position : Vector2) -> void: - rect_position = target_position + unfocused_scale = rect_scale + rect_scale = Vector2() + self.target_position = target_position disabled = not action.can_use() if disabled: modulate = Color("#555555") diff --git a/godot/combat/interface/circular_menu/CircularMenu.gd b/godot/combat/interface/circular_menu/CircularMenu.gd index 22825ae..c7aaff2 100644 --- a/godot/combat/interface/circular_menu/CircularMenu.gd +++ b/godot/combat/interface/circular_menu/CircularMenu.gd @@ -4,9 +4,14 @@ signal action_selected(action) const ContextualAction = preload("CircularButton.tscn") +onready var tween : = $Tween as Tween +onready var buttons : = $Buttons as Control + export(float, 0.0, 300.0) var radius : float = 190 setget set_radius export(float, 0, 1.0) var spacing : float = 0.2 setget set_spacing export(float, -1.0, 1.0) var offset : float = -0.1 setget set_offset +export(float, 0.01, 0.1) var animation_offset : float = 0.08 +export(float, 0.1, 0.5) var animation_duration : float = 0.2 enum Layout { CENTERED = 0, CLOCKWISE = 1, COUNTER_CLOCKWISE = -1} export(Layout) var layout : int = CENTERED @@ -18,36 +23,64 @@ func initialize(actor : Battler) -> void: var actions = actor.actions.get_actions() for action in actions: var button = ContextualAction.instance() - add_child(button) + buttons.add_child(button) var target_position = _calculate_position(button, actions.size()) button.initialize(action, target_position) button.connect("pressed", self, "_on_CircularButton_pressed", [action]) -func open(): +func open() -> void: show() - var first_button = get_child(0) + for button_index in buttons.get_child_count(): + var button = buttons.get_child(button_index) + tween.interpolate_property(button, "rect_scale", Vector2(), button.unfocused_scale, animation_duration, Tween.TRANS_EXPO, Tween.EASE_IN_OUT, animation_offset * button_index) + tween.interpolate_property(button, "rect_position", Vector2(), button.target_position, animation_duration, Tween.TRANS_ELASTIC, Tween.EASE_IN_OUT, animation_offset * button_index) + tween.start() + yield(tween, "tween_completed") + var first_button = buttons.get_child(0) first_button.grab_focus() func _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("ui_right") or event.is_action_pressed("ui_focus_next"): - var next_button_index = (get_focus_owner().get_index() + 1) % get_child_count() - get_child(next_button_index).grab_focus() + if tween.is_active(): + cancel_animation() + var next_button_index = (get_focus_owner().get_index() + 1) % buttons.get_child_count() + buttons.get_child(next_button_index).grab_focus() accept_event() if event.is_action_pressed("ui_left") or event.is_action_pressed("ui_focus_prev"): - var next_button_index = (get_focus_owner().get_index() - 1 + get_child_count()) % get_child_count() - get_child(next_button_index).grab_focus() + if tween.is_active(): + cancel_animation() + var next_button_index = (get_focus_owner().get_index() - 1 + buttons.get_child_count()) % buttons.get_child_count() + buttons.get_child(next_button_index).grab_focus() accept_event() -func close(): +func close() -> void: + for button_index in buttons.get_child_count(): + var button = buttons.get_child(button_index) + button.animation_player.stop() + tween.interpolate_property(button, "rect_scale", button.rect_scale, Vector2(), animation_duration, Tween.TRANS_EXPO, Tween.EASE_IN_OUT, animation_offset * button_index) + tween.interpolate_property(button, "rect_position", button.rect_position, Vector2(), animation_duration, Tween.TRANS_ELASTIC, Tween.EASE_IN_OUT, animation_offset * button_index) + tween.start() + yield(tween, "tween_completed") queue_free() +func cancel_animation() -> void: + tween.stop_all() + for button_index in buttons.get_child_count(): + var button = buttons.get_child(button_index) + button.rect_scale = button.unfocused_scale + button.rect_position = button.target_position + var first_button = buttons.get_child(0) + first_button.grab_focus() + func _on_CircularButton_pressed(action): + yield(close(), "completed") emit_signal("action_selected", action) - close() func _update() -> void: - for button in get_children(): - button.rect_position = _calculate_position(button, get_child_count()) + if not is_inside_tree(): + return + for button in buttons.get_children(): + button.rect_position = _calculate_position(button, buttons.get_child_count()) func _calculate_position(button, buttons_count : int) -> Vector2: """ diff --git a/godot/combat/interface/circular_menu/CircularMenu.tscn b/godot/combat/interface/circular_menu/CircularMenu.tscn index 3a2de14..cfbd372 100644 --- a/godot/combat/interface/circular_menu/CircularMenu.tscn +++ b/godot/combat/interface/circular_menu/CircularMenu.tscn @@ -20,5 +20,27 @@ __meta__ = { radius = 190 spacing = 0.2 offset = -0.1 +animation_offset = 0.08 +animation_duration = 0.2 layout = 0 +[node name="Tween" type="Tween" parent="."] +repeat = false +playback_process_mode = 1 +playback_speed = 1.0 +playback/active = false +playback/repeat = false +playback/speed = 1.0 + +[node name="Buttons" type="Control" parent="."] +anchor_left = 0.0 +anchor_top = 0.0 +anchor_right = 0.0 +anchor_bottom = 0.0 +rect_pivot_offset = Vector2( 0, 0 ) +rect_clip_content = false +mouse_filter = 0 +mouse_default_cursor_shape = 0 +size_flags_horizontal = 1 +size_flags_vertical = 1 + -- GitLab