diff --git a/asset_dev/balls/ball_icons.xcf b/asset_dev/balls/ball_icons.xcf new file mode 100644 index 0000000..d706fed Binary files /dev/null and b/asset_dev/balls/ball_icons.xcf differ diff --git a/assets/ui/ball_icons/basic_icon.png b/assets/ui/ball_icons/basic_icon.png new file mode 100644 index 0000000..4675760 --- /dev/null +++ b/assets/ui/ball_icons/basic_icon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f31c37793ded0f1d51ec4dba68a5d50602af6e0b18a2f6d7e50735cd29600f70 +size 2402 diff --git a/assets/ui/ball_icons/basic_icon.png.import b/assets/ui/ball_icons/basic_icon.png.import new file mode 100644 index 0000000..3b82c5b --- /dev/null +++ b/assets/ui/ball_icons/basic_icon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://tancoet1lih5" +path="res://.godot/imported/basic_icon.png-bc904292cc126e1d3e1fd0eb1ba5acc2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/ui/ball_icons/basic_icon.png" +dest_files=["res://.godot/imported/basic_icon.png-bc904292cc126e1d3e1fd0eb1ba5acc2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/project.godot b/project.godot index 6382ac2..2e9c7e3 100644 --- a/project.godot +++ b/project.godot @@ -182,6 +182,16 @@ pause={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } +ball_next={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194306,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +ball_previous={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":true,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194306,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} [layer_names] diff --git a/src/equipment/balls/physics_ball/game_ball.gd b/src/equipment/balls/physics_ball/game_ball.gd index 86a2b65..aaec4f7 100644 --- a/src/equipment/balls/physics_ball/game_ball.gd +++ b/src/equipment/balls/physics_ball/game_ball.gd @@ -4,6 +4,13 @@ class_name GameBall extends RigidBody3D ## Fired as soon as this ball enters a water hazard signal entered_water +## Types of game balls +enum Type { + NONE, + BASIC, + PLASMA, +} + const TERRAIN_DAMPING_EPSILON := 1e-6 const IRON_DAMPING := 9999.0 diff --git a/src/player/debug_player.tres b/src/player/debug_player.tres index 8eaef6f..9083234 100644 --- a/src/player/debug_player.tres +++ b/src/player/debug_player.tres @@ -8,9 +8,14 @@ [resource] script = ExtResource("4_8ybyj") -name = "DEBUG Gfolfer" life = 100.0 +name = "DEBUG Gfolfer" +color = Color(1, 0.439216, 0.439216, 1) driver = ExtResource("1_sn8fd") iron = ExtResource("2_piku2") wedge = ExtResource("5_wm4ae") putter = ExtResource("3_tytwr") +_balls = { +1: -1, +2: 5 +} diff --git a/src/player/shot_setup/ball_point.gd b/src/player/shot_setup/ball_point.gd index a82e423..318f2d6 100644 --- a/src/player/shot_setup/ball_point.gd +++ b/src/player/shot_setup/ball_point.gd @@ -4,17 +4,10 @@ class_name BallPoint extends Node3D ## Emitted when a new ball is placed. signal ball_changed(ball: GameBall) -## Types of game balls -enum Type { - NONE, - BASIC, - PLASMA, -} - ## Scenes for each type of ball. const SCENE_MAP: Dictionary = { - Type.BASIC: preload("res://src/equipment/balls/physics_ball/physics_ball.tscn"), - Type.PLASMA: preload("res://src/equipment/balls/plasma_ball/plasma_ball.tscn"), + GameBall.Type.BASIC: preload("res://src/equipment/balls/physics_ball/physics_ball.tscn"), + GameBall.Type.PLASMA: preload("res://src/equipment/balls/plasma_ball/plasma_ball.tscn"), } @export var ball: GameBall: @@ -25,7 +18,7 @@ const SCENE_MAP: Dictionary = { ## Get a new instance of a ball of the given type. ## Returns null if the type can't be instantiated (e.g. NONE type) -func get_instance(type: Type) -> GameBall: +func get_instance(type: GameBall.Type) -> GameBall: if type in SCENE_MAP: var scene: PackedScene = SCENE_MAP.get(type) return scene.instantiate() as GameBall @@ -33,7 +26,7 @@ func get_instance(type: Type) -> GameBall: ## Clear any existing ball, instantiate a new one of the given type, and place it at the ball point. -func spawn_ball(type: Type) -> void: +func spawn_ball(type: GameBall.Type) -> void: # Clear existing ball if is_instance_valid(ball): ball.queue_free() diff --git a/src/player/shot_setup/shot_setup.gd b/src/player/shot_setup/shot_setup.gd index 3c19d36..e4a4082 100644 --- a/src/player/shot_setup/shot_setup.gd +++ b/src/player/shot_setup/shot_setup.gd @@ -42,7 +42,7 @@ const WATER_DAMAGE := 10.0 @export var initial_club: Club.Type = Club.Type.DRIVER ## Initially-selected ball type -@export var initial_ball: BallPoint.Type = BallPoint.Type.BASIC +@export var initial_ball: GameBall.Type = GameBall.Type.BASIC @export_category("Shot Parameters") @export var base_power := 2.5 @@ -89,9 +89,10 @@ var club: Club.Type: _on_club_change(value) club = value -var ball_type: BallPoint.Type: +var ball_type: GameBall.Type: set(value): if value != ball_type: + hud.ball_selector.value = value ball_point.spawn_ball(value) ball_type = value @@ -237,6 +238,10 @@ func take_shot() -> void: game_ball.freeze = false game_ball.apply_central_impulse(impulse) + # Use a ball if a limited type is selected + if player.get_balls(ball_type) > 0: + player.mutate_balls(ball_type, -1) + ## Make the shot projection widget visible, with animated transition func _show_shot_projection() -> void: @@ -486,6 +491,12 @@ func _process(delta: float) -> void: if Input.is_action_just_pressed("select_putter"): club = Club.Type.PUTTER + # Ball select + if Input.is_action_just_pressed("ball_next"): + ball_type = player.next_ball(ball_type) + if Input.is_action_just_pressed("ball_previous"): + ball_type = player.prev_ball(ball_type) + # Switch to free cam if ( Input.is_action_just_pressed("camera_back") @@ -497,7 +508,10 @@ func _process(delta: float) -> void: # Advance to next phase if Input.is_action_just_pressed("shot_accept"): - phase = Phase.POWER_ADJUST + if player.get_balls(ball_type) != 0: + # Check that player has enough of the selected ball (<0 means unlimited) + phase = Phase.POWER_ADJUST + # TODO play UI bonk if player doesn't have balls (lmao) Phase.POWER_ADJUST: if Input.is_action_just_pressed("shot_accept"): # TODO set power gauge parameters if needed diff --git a/src/player/shot_setup/shot_setup.tscn b/src/player/shot_setup/shot_setup.tscn index 632bea7..8ba1607 100644 --- a/src/player/shot_setup/shot_setup.tscn +++ b/src/player/shot_setup/shot_setup.tscn @@ -323,14 +323,13 @@ visible = false transform = Transform3D(0.2, 0, 0, 0, -1.74846e-08, 0.2, 0, -0.4, -8.74228e-09, 0, 0, -1) loop_animation = 1 -[node name="ShotProjection" parent="ArrowPivot" node_paths=PackedStringArray("excluded_bodies") instance=ExtResource("4_ry2ho")] +[node name="ShotProjection" parent="ArrowPivot" instance=ExtResource("4_ry2ho")] unique_name_in_owner = true transform = Transform3D(1, 0, 0, 0, 0.707107, -0.707107, 0, 0.707107, 0.707107, 0, -0.02, 0) visible = false initial_speed = 50.0 time_step = 0.01 max_steps = 800 -excluded_bodies = [null] [node name="ProjectedTarget" parent="ArrowPivot/ShotProjection" instance=ExtResource("6_mynqj")] diff --git a/src/player/world_player.gd b/src/player/world_player.gd index ace2d5d..0b6df77 100644 --- a/src/player/world_player.gd +++ b/src/player/world_player.gd @@ -2,6 +2,7 @@ class_name WorldPlayer extends Resource ## Container for the state of the player within the world. signal on_life_changed(new_value: float) +signal on_balls_changed(type: GameBall.Type, new_value: int) @export_range(0, 100) var life: float = 100.0: set(value): @@ -21,6 +22,13 @@ signal on_life_changed(new_value: float) @export var putter: Club @export var special: Club +## Count of each type of ball the player possesses. +## A count of less than zero indicates unlimited quantity. +@export var _balls := { + GameBall.Type.BASIC: -1, + GameBall.Type.PLASMA: -1, +} + # TODO balls, pickups, etc var shot_setup: ShotSetup: @@ -48,6 +56,39 @@ func get_club(type: Club.Type) -> Club: return null +## Get the quantity of a ball type +func get_balls(type: GameBall.Type) -> int: + return _balls.get(type, 0) + + +## Set the quantity of a ball type +func set_balls(type: GameBall.Type, value: int) -> void: + _balls[type] = value + on_balls_changed.emit(type, value) + + +## Change the quantity of a ball type +func mutate_balls(type: GameBall.Type, delta: int) -> void: + _balls[type] = _balls.get(type, 0) + delta + on_balls_changed.emit(type, _balls[type]) + + +## Get next slotted ball type +func next_ball(type: GameBall.Type) -> GameBall.Type: + var keys := _balls.keys() + var i := keys.find(type) + var j := (i + 1) % len(keys) if i >= 0 else 0 + return keys[j] + + +## Get previous slotted ball type +func prev_ball(type: GameBall.Type) -> GameBall.Type: + var keys := _balls.keys() + var i := keys.find(type) + var j := (i - 1) % len(keys) if i >= 0 else 0 + return keys[j] + + ## Create a debug player instance static func create_debug() -> WorldPlayer: var instance := WorldPlayer.new() diff --git a/src/ui/main_theme.tres b/src/ui/main_theme.tres index 5d28770..3adf3ae 100644 --- a/src/ui/main_theme.tres +++ b/src/ui/main_theme.tres @@ -28,6 +28,11 @@ PauseMenuButton/colors/font_outline_color = Color(0, 0, 0, 1) PauseMenuButton/constants/outline_size = 6 PauseMenuButton/font_sizes/font_size = 32 PauseMenuButton/fonts/font = ExtResource("2_5ty6u") +QuantityLabel/base_type = &"Label" +QuantityLabel/colors/font_color = Color(0.819608, 0.196078, 0.196078, 1) +QuantityLabel/colors/font_outline_color = Color(1, 0.901961, 0.509804, 1) +QuantityLabel/constants/outline_size = 6 +QuantityLabel/font_sizes/font_size = 22 ShotFeedback/base_type = &"RichTextLabel" ShotFeedback/colors/font_shadow_color = Color(0, 0, 0, 1) ShotFeedback/constants/shadow_offset_x = 6 diff --git a/src/ui/shot_hud/ball_selector/ball_icon.gd b/src/ui/shot_hud/ball_selector/ball_icon.gd new file mode 100644 index 0000000..e363aaf --- /dev/null +++ b/src/ui/shot_hud/ball_selector/ball_icon.gd @@ -0,0 +1,51 @@ +@tool +class_name BallIcon extends Control +## HUD icon for a ball type + +const BASE_MODULATE := Color.WHITE +const EMPTY_MODULATE := Color.DIM_GRAY + +@export var text: String: + set(value): + text = value + if ball_label: + ball_label.text = value + +@export var quantity: int: + set = _set_quantity +@export var empty: bool: + set(value): + if value: + quantity = 0 + elif not quantity: + quantity = 1 + get: + return quantity == 0 +@export var unlimited: bool: + set(value): + quantity = -1 if value else 0 + get: + return quantity < 0 + +@onready var ball_label: Label = %BallLabel +@onready var quantity_container: HBoxContainer = %QuantityContainer +@onready var quantity_label: Label = %QuantityLabel + + +func _ready() -> void: + text = text + quantity = quantity + + +func _set_quantity(value: int) -> void: + # TODO play effect on gain/loss + quantity = value + if not quantity_label: + return + quantity_label.text = str(quantity) + + # Quantity is not visible if we're empty or unlimited + quantity_container.visible = quantity > 0 + + # Grey out when empty + ball_label.modulate = EMPTY_MODULATE if quantity == 0 else BASE_MODULATE diff --git a/src/ui/shot_hud/ball_selector/ball_icon.tscn b/src/ui/shot_hud/ball_selector/ball_icon.tscn new file mode 100644 index 0000000..7a92367 --- /dev/null +++ b/src/ui/shot_hud/ball_selector/ball_icon.tscn @@ -0,0 +1,68 @@ +[gd_scene load_steps=3 format=3 uid="uid://cc8a55ly7ybhy"] + +[ext_resource type="Script" path="res://src/ui/shot_hud/ball_selector/ball_icon.gd" id="1_p0p8j"] +[ext_resource type="FontFile" uid="uid://b6gxwgomstkgu" path="res://assets/fonts/Geo/Geo-Italic.ttf" id="2_bu42i"] + +[node name="BallIcon" type="Control"] +custom_minimum_size = Vector2(0, 27) +layout_mode = 3 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 4 +script = ExtResource("1_p0p8j") +quantity = -1 +unlimited = true + +[node name="BallLabel" type="Label" parent="."] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -46.5 +offset_top = -13.5 +offset_right = 46.5 +offset_bottom = 13.5 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/outline_size = 10 +theme_override_fonts/font = ExtResource("2_bu42i") +theme_override_font_sizes/font_size = 25 +horizontal_alignment = 2 + +[node name="QuantityContainer" type="HBoxContainer" parent="BallLabel"] +unique_name_in_owner = true +visible = false +layout_mode = 1 +anchors_preset = -1 +anchor_left = 1.0 +anchor_top = 0.8 +anchor_right = 1.0 +anchor_bottom = 0.8 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/separation = 0 + +[node name="Label" type="Label" parent="BallLabel/QuantityContainer"] +layout_mode = 2 +size_flags_horizontal = 8 +size_flags_vertical = 8 +theme_type_variation = &"QuantityLabel" +theme_override_font_sizes/font_size = 22 +text = "×" + +[node name="QuantityLabel" type="Label" parent="BallLabel/QuantityContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 8 +size_flags_vertical = 8 +theme_type_variation = &"QuantityLabel" +theme_override_font_sizes/font_size = 22 +text = "-1" diff --git a/src/ui/shot_hud/ball_selector/ball_selector.gd b/src/ui/shot_hud/ball_selector/ball_selector.gd new file mode 100644 index 0000000..bd7d292 --- /dev/null +++ b/src/ui/shot_hud/ball_selector/ball_selector.gd @@ -0,0 +1,54 @@ +@tool +class_name BallSelector extends Control + +const TWEEN_TIME := 0.2 + +const Y_OFFSET := { + GameBall.Type.NONE: 50, + GameBall.Type.BASIC: 18, + GameBall.Type.PLASMA: -14, +} + +@export var value: GameBall.Type: + set = _set_value + +@onready var ball_list: VBoxContainer = %BallList +@onready var basic_icon: BallIcon = %BasicIcon +@onready var plasma_icon: BallIcon = %PlasmaIcon + + +func _ready() -> void: + value = value + + +## Set ball quantities based on player's state +func set_state_for_player(player: WorldPlayer) -> void: + basic_icon.quantity = player.get_balls(GameBall.Type.BASIC) + plasma_icon.quantity = player.get_balls(GameBall.Type.PLASMA) + if player.shot_setup: + value = player.shot_setup.ball_type + player.on_balls_changed.connect(_set_quantity) + + +func _get_icon(type: GameBall.Type) -> BallIcon: + match type: + GameBall.Type.BASIC: + return basic_icon + GameBall.Type.PLASMA: + return plasma_icon + return null + + +func _set_value(new_value: GameBall.Type) -> void: + if not ball_list: + return + + var tween := get_tree().create_tween() + tween.tween_property(ball_list, "position:y", Y_OFFSET[new_value], TWEEN_TIME).set_trans( + Tween.TRANS_EXPO + ) + value = new_value + + +func _set_quantity(type: GameBall.Type, new_value: int) -> void: + _get_icon(type).quantity = new_value diff --git a/src/ui/shot_hud/ball_selector/ball_selector.tscn b/src/ui/shot_hud/ball_selector/ball_selector.tscn new file mode 100644 index 0000000..d8336f8 --- /dev/null +++ b/src/ui/shot_hud/ball_selector/ball_selector.tscn @@ -0,0 +1,66 @@ +[gd_scene load_steps=5 format=3 uid="uid://b0yr0w0xv8cm5"] + +[ext_resource type="PackedScene" uid="uid://cc8a55ly7ybhy" path="res://src/ui/shot_hud/ball_selector/ball_icon.tscn" id="1_1v8xg"] +[ext_resource type="Script" path="res://src/ui/shot_hud/ball_selector/ball_selector.gd" id="1_b7gkp"] + +[sub_resource type="Gradient" id="Gradient_3vqut"] +interpolation_mode = 2 +offsets = PackedFloat32Array(0, 0.382, 0.618, 1) +colors = PackedColorArray(0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) + +[sub_resource type="GradientTexture2D" id="GradientTexture2D_tm61r"] +gradient = SubResource("Gradient_3vqut") +fill_to = Vector2(0, 1) +metadata/_snap_enabled = true + +[node name="BallSelector" type="Control"] +custom_minimum_size = Vector2(120, 27) +layout_mode = 3 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -60.0 +offset_top = -13.5 +offset_right = 60.0 +offset_bottom = 13.5 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_b7gkp") + +[node name="GradientMask" type="TextureRect" parent="."] +clip_children = 1 +custom_minimum_size = Vector2(120, 32) +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +texture = SubResource("GradientTexture2D_tm61r") + +[node name="BallList" type="VBoxContainer" parent="GradientMask"] +unique_name_in_owner = true +custom_minimum_size = Vector2(120, 0) +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = 50.0 +offset_bottom = 50.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/separation = 5 + +[node name="BasicIcon" parent="GradientMask/BallList" instance=ExtResource("1_1v8xg")] +unique_name_in_owner = true +custom_minimum_size = Vector2(120, 27) +layout_mode = 2 +text = "BASIC" + +[node name="PlasmaIcon" parent="GradientMask/BallList" instance=ExtResource("1_1v8xg")] +unique_name_in_owner = true +custom_minimum_size = Vector2(120, 27) +layout_mode = 2 +text = "PLASMA" diff --git a/src/ui/shot_hud/shot_hud.gd b/src/ui/shot_hud/shot_hud.gd index 463e126..4098c8e 100644 --- a/src/ui/shot_hud/shot_hud.gd +++ b/src/ui/shot_hud/shot_hud.gd @@ -13,6 +13,7 @@ var player: WorldPlayer @onready var life_bar: TextureProgressBar = %LifeBar @onready var club_selector: ClubSelector = %ClubSelector +@onready var ball_selector: BallSelector = %BallSelector @onready var _curve_animation: AnimationPlayer = %CurveAnimation @onready var _power_animation: AnimationPlayer = %PowerAnimation @@ -32,6 +33,7 @@ static var scene: PackedScene = preload("res://src/ui/shot_hud/shot_hud.tscn") func _ready() -> void: club_selector.set_state_for_player(player) + ball_selector.set_state_for_player(player) _player_name.text = player.name life_bar.value = player.life life_bar.tint_progress = player.color diff --git a/src/ui/shot_hud/shot_hud.tscn b/src/ui/shot_hud/shot_hud.tscn index ef91dfc..c0359af 100644 --- a/src/ui/shot_hud/shot_hud.tscn +++ b/src/ui/shot_hud/shot_hud.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=32 format=3 uid="uid://c4ifdiohng830"] +[gd_scene load_steps=34 format=3 uid="uid://c4ifdiohng830"] [ext_resource type="Script" path="res://src/ui/shot_hud/shot_hud.gd" id="1_x5b4c"] [ext_resource type="Shader" path="res://src/shaders/canvas_retro.gdshader" id="1_ybxxp"] @@ -7,7 +7,9 @@ [ext_resource type="Texture2D" uid="uid://b5812y3pmmgg5" path="res://assets/ui/gauge_patch.png" id="4_5kcpe"] [ext_resource type="Texture2D" uid="uid://76fjx2ukavqe" path="res://assets/ui/power_gauge_fill.png" id="5_3i1yq"] [ext_resource type="Texture2D" uid="uid://4a8tvjgwegv3" path="res://assets/ui/power_gauge_tab.png" id="6_sw48q"] +[ext_resource type="PackedScene" uid="uid://b0yr0w0xv8cm5" path="res://src/ui/shot_hud/ball_selector/ball_selector.tscn" id="8_b2302"] [ext_resource type="FontFile" uid="uid://dsa0oh7c0h4pu" path="res://assets/fonts/Racing_Sans_One/RacingSansOne-Regular.ttf" id="8_bejx4"] +[ext_resource type="Texture2D" uid="uid://tancoet1lih5" path="res://assets/ui/ball_icons/basic_icon.png" id="8_tt8i3"] [ext_resource type="PackedScene" uid="uid://dmciuk3pbjsae" path="res://src/ui/shot_hud/life_bar/life_bar.tscn" id="9_w1fiw"] [sub_resource type="Animation" id="Animation_3xds6"] @@ -490,35 +492,6 @@ tracks/1/keys = { "values": [false] } -[sub_resource type="Animation" id="Animation_nicro"] -resource_name = "show_life_bar" -length = 0.4 -step = 0.02 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("SouthWest:position") -tracks/0/interp = 2 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0, 0.34, 0.4), -"transitions": PackedFloat32Array(1.618, 1.618, 1), -"update": 0, -"values": [Vector2(0, 1100), Vector2(0, 960), Vector2(0, 982)] -} -tracks/1/type = "value" -tracks/1/imported = false -tracks/1/enabled = true -tracks/1/path = NodePath("SouthWest:visible") -tracks/1/interp = 1 -tracks/1/loop_wrap = true -tracks/1/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [true] -} - [sub_resource type="Animation" id="Animation_jugqx"] resource_name = "peek" length = 2.4 @@ -548,6 +521,35 @@ tracks/1/keys = { "values": [true, false] } +[sub_resource type="Animation" id="Animation_nicro"] +resource_name = "show_life_bar" +length = 0.4 +step = 0.02 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("SouthWest:position") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.34, 0.4), +"transitions": PackedFloat32Array(1.618, 1.618, 1), +"update": 0, +"values": [Vector2(0, 1100), Vector2(0, 960), Vector2(0, 982)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("SouthWest:visible") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} + [sub_resource type="AnimationLibrary" id="AnimationLibrary_c3i4w"] _data = { "RESET": SubResource("Animation_3cn2c"), @@ -756,15 +758,30 @@ libraries = { "": SubResource("AnimationLibrary_5nauw") } +[node name="TextureRect" type="TextureRect" parent="ClubSelector"] +texture_filter = 1 +layout_mode = 0 +offset_right = 128.0 +offset_bottom = 128.0 +texture = ExtResource("8_tt8i3") + +[node name="BallSelector" parent="ClubSelector/TextureRect" instance=ExtResource("8_b2302")] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = -1 +anchor_left = 0.7 +anchor_right = 0.7 +offset_right = 108.0 +grow_horizontal = 1 + [node name="SouthWest" type="MarginContainer" parent="."] layout_mode = 1 anchors_preset = -1 anchor_top = 1.0 anchor_right = 0.333 anchor_bottom = 1.0 -offset_top = 20.0 +offset_top = -98.0 offset_right = 40.0 -offset_bottom = 118.0 grow_vertical = 0 theme_override_constants/margin_left = 16 theme_override_constants/margin_bottom = 16