From d553492e00743b540fd27c5ab5b4ce93687a0ee7 Mon Sep 17 00:00:00 2001 From: Hamcha Date: Mon, 6 May 2019 23:18:04 +0200 Subject: [PATCH] Cards now tween and don't overlap as badly --- Scenes/Board.tscn | 2 -- Scenes/Components/Card.gd | 37 +++++++++++++++++++++++++------------ Scenes/Components/Card.tscn | 3 +++ Scenes/Scripts/Board.gd | 27 ++++++++++++++++++--------- Scenes/Scripts/BoardUI.gd | 24 +++++++++++++++++++++--- 5 files changed, 67 insertions(+), 26 deletions(-) diff --git a/Scenes/Board.tscn b/Scenes/Board.tscn index 691a3d2..f6412bb 100644 --- a/Scenes/Board.tscn +++ b/Scenes/Board.tscn @@ -31,5 +31,3 @@ material/0 = null [node name="BoardUI" parent="." instance=ExtResource( 4 )] [node name="Cards" type="Spatial" parent="."] - -[node name="Tween" type="Tween" parent="."] diff --git a/Scenes/Components/Card.gd b/Scenes/Components/Card.gd index 3b0c5e0..5b04639 100644 --- a/Scenes/Components/Card.gd +++ b/Scenes/Components/Card.gd @@ -6,6 +6,7 @@ signal card_selected() signal card_unselected() signal card_picked() signal card_dropped() +signal card_dropped_anim() signal card_menu() var clicked := false @@ -28,19 +29,18 @@ func _input_event(camera, event, click_position, click_normal, shape_idx): # Mouse motion if clicked and event is InputEventMouseMotion: if not lifted: - animation.play("lift") - if inHand: - animation.advance(1.0) emit_signal("card_picked") lifted = true var origin: Vector3 = camera.project_ray_origin(event.position) var direction: Vector3 = camera.project_ray_normal(event.position) if inHand: - transform.origin = Vector3.ZERO + Vector3.RIGHT * direction * 3.0 + translation = Vector3(direction.x * 3.0, 0.25, -0.25) + # Fix rotation if coming from hand + rotation = Vector3.ZERO else: var denom := Vector3.UP.dot(direction) var t: float = (-camera.transform.origin).dot(Vector3.UP) / denom; - transform.origin = origin + direction * t + translation = origin + direction * t # Right click if event is InputEventMouseButton and event.pressed and event.button_index == BUTTON_RIGHT: # Show menu @@ -52,15 +52,11 @@ func _input_event(camera, event, click_position, click_normal, shape_idx): # Check for card dropped if not clicked and lifted: - if inHand: - animation.play("drop") - else: - animation.play_backwards("lift") emit_signal("card_dropped") lifted = false # Check double click - if event.doubleclick and not lifted and not animation.is_playing(): + if event.doubleclick and not inHand and not lifted and not animation.is_playing(): if exhausted: animation.play_backwards("tap") exhausted = false @@ -69,7 +65,7 @@ func _input_event(camera, event, click_position, click_normal, shape_idx): exhausted = true func reset_transform(): - $Border.transform.origin = Vector3.ZERO + $Border.translation = Vector3.ZERO func _menu_action(id: int): match id: @@ -79,4 +75,21 @@ func _menu_action(id: int): flipped = false else: animation.play("flip") - flipped = true \ No newline at end of file + flipped = true + +func _check_drop_anim(anim_name): + if anim_name == "drop": + emit_signal("card_dropped_anim") + +func tween_move_to(targetPos: Vector3, duration: float = 0.1): + $Tween.interpolate_property(self, "translation", + translation, targetPos, duration, + Tween.TRANS_CUBIC, Tween.EASE_IN_OUT) + +func tween_rotate(targetRot: Vector3, duration: float = 0.1): + $Tween.interpolate_property(self, "rotation", + rotation, targetRot, duration, + Tween.TRANS_CUBIC, Tween.EASE_IN_OUT) + +func tween(): + $Tween.start() \ No newline at end of file diff --git a/Scenes/Components/Card.tscn b/Scenes/Components/Card.tscn index 4a3e8a5..43e14ef 100644 --- a/Scenes/Components/Card.tscn +++ b/Scenes/Components/Card.tscn @@ -169,6 +169,9 @@ anims/tap = SubResource( 7 ) transform = Transform( 0.318962, 0, 0, 0, 1, 0, 0, 0, 0.450381, 0, 0.007, 0 ) mesh = SubResource( 8 ) material/0 = SubResource( 9 ) + +[node name="Tween" type="Tween" parent="."] [connection signal="input_event" from="." to="." method="_input_event"] [connection signal="mouse_entered" from="." to="." method="_mouse_hover"] [connection signal="mouse_exited" from="." to="." method="_mouse_blur"] +[connection signal="animation_finished" from="Border/AnimationPlayer" to="." method="_check_drop_anim"] diff --git a/Scenes/Scripts/Board.gd b/Scenes/Scripts/Board.gd index 95e5eca..3f2f0f2 100644 --- a/Scenes/Scripts/Board.gd +++ b/Scenes/Scripts/Board.gd @@ -9,7 +9,7 @@ onready var hand := $Camera/Hand onready var ui := $BoardUI onready var cards := $Cards -export var mouseHandThreshold = 0.9 +export var mouseHandThreshold = 0.85 var holdingCard: Card = null var focusedCard: Card = null @@ -63,13 +63,14 @@ func _process(delta: float): func _card_picked(card: Card): holdingCard = card - # Fix rotation if coming from hand - if holdingCard.inHand: - holdingCard.rotation = Vector3.ZERO + holdingCard.animation.play("lift") func _card_dropped(card: Card): + if card.inHand: + card.animation.play("drop") + else: + card.animation.play_backwards("lift") holdingCard = null - reorder_hand() func _card_selected(card: Card): if card.inHand and focusedCard == null: @@ -98,6 +99,7 @@ func add_card(cardID: String, playerID: int, inHand: bool): card.connect("card_unselected", ui, "_card_unselected", [card]) card.connect("card_selected", self, "_card_selected", [card]) card.connect("card_unselected", self, "_card_unselected", [card]) + card.connect("card_dropped_anim", self, "check_hand_drop", [card]) card.connect("card_menu", ui, "show_card_menu", [card]) if inHand: # TODO if player != me, put in opponent's hand @@ -105,8 +107,14 @@ func add_card(cardID: String, playerID: int, inHand: bool): else: cards.add_child(card) +func check_hand_drop(card: Card): + # Re-order hand as soon as the animation is over + if card.inHand: + card.reset_transform() + reorder_hand() + const MAX_CARD_DISTANCE := 0.5 -const HAND_SCREEN_PERC := 0.8 +const HAND_SCREEN_PERC := 0.6 const CARD_ROTATION := 0.03 const UNITSPERPX := 0.003 @@ -121,17 +129,18 @@ func reorder_hand(): # want them to go offscreen, therefore a "maximum screen %" is used to determine # how to fit all the cards within a % of the viewport's width var distancePerc := get_viewport().size.x * HAND_SCREEN_PERC * UNITSPERPX / size - var distance := distancePerc#max(distancePerc, MAX_CARD_DISTANCE) + var distance := min(distancePerc, MAX_CARD_DISTANCE) var totalWidth := distance * (size-1) var minX := -totalWidth/2 # Iterate over all items, keep track of the index var i := 0 for child in cardsInHand: - child.transform.origin = Vector3(minX + distance * i, 0.02*i, 0) - child.rotation = Vector3(0, CARD_ROTATION * (size - i - 1), 0) + child.tween_move_to(Vector3(minX + distance * i, 0.02*i, -0.005*i)) + child.tween_rotate(Vector3(0, CARD_ROTATION * (size/2.0 - i), 0)) i += 1 child.reset_transform() + child.tween() class TransformSorter: static func sort(a, b): diff --git a/Scenes/Scripts/BoardUI.gd b/Scenes/Scripts/BoardUI.gd index a616f68..53b7495 100644 --- a/Scenes/Scripts/BoardUI.gd +++ b/Scenes/Scripts/BoardUI.gd @@ -2,6 +2,8 @@ extends Control onready var animation = $AnimationPlayer +var menu: PopupMenu = null + func _card_selected(card: Card): animation.play("fade ui card") @@ -9,8 +11,24 @@ func _card_unselected(card: Card): animation.play_backwards("fade ui card") func show_card_menu(card): - var menu := PopupMenu.new() - menu.add_item("Flip", 0) + # Close any open menus + if menu != null: + menu.queue_free() + remove_child(menu) + menu = PopupMenu.new() + if card.inHand: + menu.add_separator("Hand actions") + menu.add_item("Reveal card", 3) + menu.add_item("Discard card", 4) + menu.add_item("Banish card", 5) + else: + menu.add_separator("Card actions") + menu.add_item("Flip card", 0) + menu.add_separator("Counters & status") + menu.add_item("Set Pumped", 1) + menu.add_item("Set Cutie-Marked", 2) + menu.add_item("Add color", 3) + menu.add_item("Add marker", 4) menu.connect("id_pressed", card, "_menu_action") add_child(menu) - menu.popup(Rect2(get_viewport().get_mouse_position(), Vector2(100,10))) \ No newline at end of file + menu.popup(Rect2(get_viewport().get_mouse_position(), Vector2(150,10))) \ No newline at end of file