From 7c7458be65eef6d7d646399b435f2efdad69a9cc Mon Sep 17 00:00:00 2001 From: Rob Kelly Date: Mon, 18 Nov 2024 12:06:43 -0700 Subject: [PATCH] Life bar has damage lag --- asset_dev/UI/lifebar_patch.xcf | Bin 19831 -> 20980 bytes assets/ui/lifebar_fill_damage.png | 3 ++ assets/ui/lifebar_fill_damage.png.import | 34 +++++++++++++++++ src/game/game.gd | 10 ----- src/player/shot_setup/shot_setup.gd | 4 ++ src/ui/shot_hud/life_bar/life_bar.gd | 22 +++++++++++ src/ui/shot_hud/life_bar/life_bar.tscn | 46 +++++++++++++++++++++++ src/ui/shot_hud/shot_hud.gd | 38 +++++++++++++++++++ src/ui/shot_hud/shot_hud.tscn | 26 ++++++------- 9 files changed, 159 insertions(+), 24 deletions(-) create mode 100644 assets/ui/lifebar_fill_damage.png create mode 100644 assets/ui/lifebar_fill_damage.png.import create mode 100644 src/ui/shot_hud/life_bar/life_bar.gd create mode 100644 src/ui/shot_hud/life_bar/life_bar.tscn diff --git a/asset_dev/UI/lifebar_patch.xcf b/asset_dev/UI/lifebar_patch.xcf index 205fca5d86d00ff2af75a67d93ffee43e78bc2db..8154c88c21fc326288e2cd702838e92075bc2720 100644 GIT binary patch delta 547 zcmex9i}A~1#tBZ0IvbtE7%dkufB~C4gqE>{(AusL+I%a7wu*w#jvNr$wQO=1qr50@ zT4qj;f<|$EPG*WGNQMcBCkGf`5LAJvgON<@CmWhbaWP$n2(SrHekdU(!1NiyW$A{{ zlmFUfPO?t}qpZmj9AYPTJ0wAI?c|k=a+5=h6($=xu9-ZWiJytx5NsxUC`7Z2F33zS z_EHE}bob^DOah`{)oUd9nPi>7s%6t4(%P0_)v|36u7>AkMoCsakZM6@h!Bj_@c?Vo z$$49*KA~&;Z6T($Kv$;-|l@F|1Ux%Mb{WMs$`g@49u?|?Z20w(WduMZtPA)fC z^;`>nCKF4rYLi%qwCP2#YLi+hSAFv*i-n9})%Mo>OlG&is?GjGq;2ZKs?FsgT+8d5 zr&zCL1*?AR$j@Zk307^p79#EN7OdL#EQD*Hy4lG|orTHq8(5W-6hzoJ8?4I73c_{2 Kv3b3lD>ncH@>`Ao diff --git a/assets/ui/lifebar_fill_damage.png b/assets/ui/lifebar_fill_damage.png new file mode 100644 index 0000000..013bd53 --- /dev/null +++ b/assets/ui/lifebar_fill_damage.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:461dd962dd6fff2b30c9ce54985e2ac59fc219ce605d000e3a067778a80aafb8 +size 671 diff --git a/assets/ui/lifebar_fill_damage.png.import b/assets/ui/lifebar_fill_damage.png.import new file mode 100644 index 0000000..c9e27f1 --- /dev/null +++ b/assets/ui/lifebar_fill_damage.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dv8757eh7bgmm" +path="res://.godot/imported/lifebar_fill_damage.png-844591e686129d7c89c44d44c5c8df44.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/ui/lifebar_fill_damage.png" +dest_files=["res://.godot/imported/lifebar_fill_damage.png-844591e686129d7c89c44d44c5c8df44.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/src/game/game.gd b/src/game/game.gd index 0fb09ce..d62245b 100644 --- a/src/game/game.gd +++ b/src/game/game.gd @@ -79,16 +79,6 @@ func _finish_scene_load(instance: Node) -> void: func _process(_delta: float) -> void: - # REMOVEME - if Input.is_action_just_pressed("debug_1"): - viewport.hit_lag(1) - if Input.is_action_just_pressed("debug_2"): - viewport.hit_lag_small() - if Input.is_action_just_pressed("debug_3"): - viewport.hit_lag_big() - if Input.is_action_just_pressed("debug_4"): - viewport.hit_lag_huge() - if _loading_resources and not loading_screen.visible: loader_transition.play("fade_in") diff --git a/src/player/shot_setup/shot_setup.gd b/src/player/shot_setup/shot_setup.gd index 2ae8b89..3203580 100644 --- a/src/player/shot_setup/shot_setup.gd +++ b/src/player/shot_setup/shot_setup.gd @@ -31,6 +31,9 @@ const WASTED_BALL_RETURN_DELAY := 3.5 ## Shots above this threshold trigger a "big power" effect const BIG_POWER_THRESHOLD := 0.7 +## Amount of life lost when landing in water +const WATER_DAMAGE := 10.0 + ## In Driving Range mode, the ball can be retrieved in the shot phase. @export var driving_range := false @@ -500,6 +503,7 @@ func _on_ball_entered_water() -> void: if phase == Phase.SHOT: physics_ball.freeze = true hud.play_wasted_animation() + player.life -= WATER_DAMAGE ball_return_timer.start(WASTED_BALL_RETURN_DELAY) diff --git a/src/ui/shot_hud/life_bar/life_bar.gd b/src/ui/shot_hud/life_bar/life_bar.gd new file mode 100644 index 0000000..da5342e --- /dev/null +++ b/src/ui/shot_hud/life_bar/life_bar.gd @@ -0,0 +1,22 @@ +@tool +extends TextureProgressBar + +@export var damage_delay := 1.0 +@export var damage_tween_time := 0.4 + +@onready var damage_bar: TextureProgressBar = %DamageBar +@onready var damage_update_timer: Timer = $DamageUpdateTimer + + +func _on_value_changed(_value: float) -> void: + damage_update_timer.start(damage_delay) + + +func _on_damage_update_timer_timeout() -> void: + var tween := get_tree().create_tween() + ( + tween + . tween_property(damage_bar, "value", value, damage_tween_time) + . set_trans(Tween.TRANS_CUBIC) + . set_ease(Tween.EASE_OUT) + ) diff --git a/src/ui/shot_hud/life_bar/life_bar.tscn b/src/ui/shot_hud/life_bar/life_bar.tscn new file mode 100644 index 0000000..7637fa1 --- /dev/null +++ b/src/ui/shot_hud/life_bar/life_bar.tscn @@ -0,0 +1,46 @@ +[gd_scene load_steps=5 format=3 uid="uid://dmciuk3pbjsae"] + +[ext_resource type="Texture2D" uid="uid://dtdqninlnu10o" path="res://assets/ui/lifebar_fill_grey.png" id="1_nhls1"] +[ext_resource type="Script" path="res://src/ui/shot_hud/life_bar/life_bar.gd" id="2_6jpmf"] +[ext_resource type="Texture2D" uid="uid://bvwh0yunmvirp" path="res://assets/ui/lifebar_patch.png" id="3_8s5ot"] +[ext_resource type="Texture2D" uid="uid://dv8757eh7bgmm" path="res://assets/ui/lifebar_fill_damage.png" id="4_ohduq"] + +[node name="LifeBar" type="TextureProgressBar"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +step = 0.01 +nine_patch_stretch = true +stretch_margin_left = 32 +stretch_margin_top = 16 +stretch_margin_right = 32 +stretch_margin_bottom = 16 +texture_progress = ExtResource("1_nhls1") +script = ExtResource("2_6jpmf") +damage_tween_time = 0.6 + +[node name="DamageBar" type="TextureProgressBar" parent="."] +unique_name_in_owner = true +show_behind_parent = true +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +step = 0.01 +nine_patch_stretch = true +stretch_margin_left = 32 +stretch_margin_top = 16 +stretch_margin_right = 32 +stretch_margin_bottom = 16 +texture_under = ExtResource("3_8s5ot") +texture_progress = ExtResource("4_ohduq") +tint_progress = Color(0.9, 0, 0, 1) + +[node name="DamageUpdateTimer" type="Timer" parent="."] + +[connection signal="value_changed" from="." to="." method="_on_value_changed"] +[connection signal="timeout" from="DamageUpdateTimer" to="." method="_on_damage_update_timer_timeout"] diff --git a/src/ui/shot_hud/shot_hud.gd b/src/ui/shot_hud/shot_hud.gd index 1e0e9d9..fb77e21 100644 --- a/src/ui/shot_hud/shot_hud.gd +++ b/src/ui/shot_hud/shot_hud.gd @@ -1,6 +1,13 @@ class_name ShotHUD extends Control ## HUD for main gameplay loop +## Scale factor for the life bar rumble intensity on taking damage +const LIFE_BAR_DAMAGE_RUMBLE_SCALE := 0.2 +## Time it takes to dampen the life bar rumble on taking damage, in seconds +const LIFE_BAR_DAMAGE_RUMBLE_TIME := 0.2 + +var _life_signal: Signal + @onready var power_bar: TextureProgressBar = %PowerBar @onready var curve_bar: ProgressBar = %CurveBar @onready var life_bar: TextureProgressBar = %LifeBar @@ -17,6 +24,8 @@ class_name ShotHUD extends Control @onready var _player_name: Label = %PlayerName +@onready var _life_bar_rumbler: Rumbler = %LifeBarRumbler + @onready var _state: AnimationNodeStateMachinePlayback = hud_state_machine["parameters/playback"] @@ -28,6 +37,14 @@ func set_state_for_player(player: WorldPlayer) -> void: # TODO animate on life loss? life_bar.value = player.life life_bar.tint_progress = player.color + + # TODO this is soooooo wack... + # TODO we should just revert to having distinct ShotHUDs for each player + if _life_signal and _life_signal.is_connected(set_life_value): + _life_signal.disconnect(set_life_value) + _life_signal = player.on_life_changed + _life_signal.connect(set_life_value) + # TODO special equipment # TODO abilities @@ -70,3 +87,24 @@ func play_nice_animation() -> void: func play_wasted_animation() -> void: _wasted_animation.play("display") + + +## Set the value of the life bar, potentially playing some kind of effect in response. +## +## To set the life bar without triggering an effect, set it directly with `life_bar.value` +func set_life_value(new_value: float) -> void: + var difference := new_value - life_bar.value + if difference < 0: + # Taking damage + _life_bar_rumbler.intensity = LIFE_BAR_DAMAGE_RUMBLE_SCALE * abs(difference) + var tween := get_tree().create_tween() + ( + tween + . tween_property(_life_bar_rumbler, "intensity", 0, LIFE_BAR_DAMAGE_RUMBLE_TIME) + . set_trans(Tween.TRANS_CUBIC) + ) + elif difference > 0: + # Restoring health + # TODO: something for this? + pass + life_bar.value = new_value diff --git a/src/ui/shot_hud/shot_hud.tscn b/src/ui/shot_hud/shot_hud.tscn index af8c3e3..0c19b9e 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=34 format=3 uid="uid://c4ifdiohng830"] +[gd_scene load_steps=33 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"] @@ -8,8 +8,7 @@ [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="FontFile" uid="uid://dsa0oh7c0h4pu" path="res://assets/fonts/Racing_Sans_One/RacingSansOne-Regular.ttf" id="8_bejx4"] -[ext_resource type="Texture2D" uid="uid://bvwh0yunmvirp" path="res://assets/ui/lifebar_patch.png" id="9_4f1d7"] -[ext_resource type="Texture2D" uid="uid://dtdqninlnu10o" path="res://assets/ui/lifebar_fill_grey.png" id="10_130v7"] +[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"] resource_name = "RESET" @@ -276,7 +275,7 @@ _data = { [sub_resource type="ShaderMaterial" id="ShaderMaterial_afsun"] shader = ExtResource("1_ybxxp") shader_parameter/change_color_depth = true -shader_parameter/target_color_depth = 3 +shader_parameter/target_color_depth = 4 shader_parameter/dithering = true shader_parameter/scale_resolution = true shader_parameter/target_resolution_scale = 3 @@ -698,16 +697,15 @@ theme_override_fonts/font = ExtResource("8_bejx4") theme_override_font_sizes/font_size = 32 text = "PLAYER NAME" -[node name="LifeBar" type="TextureProgressBar" parent="SouthWest/VBoxContainer"] +[node name="MarginContainer" type="MarginContainer" parent="SouthWest/VBoxContainer"] +layout_mode = 2 + +[node name="LifeBarRumbler" type="Control" parent="SouthWest/VBoxContainer/MarginContainer"] unique_name_in_owner = true custom_minimum_size = Vector2(0, 48) layout_mode = 2 -min_value = -4.0 -step = 0.01 -nine_patch_stretch = true -stretch_margin_left = 32 -stretch_margin_top = 16 -stretch_margin_right = 32 -stretch_margin_bottom = 16 -texture_under = ExtResource("9_4f1d7") -texture_progress = ExtResource("10_130v7") +script = ExtResource("3_6groq") + +[node name="LifeBar" parent="SouthWest/VBoxContainer/MarginContainer/LifeBarRumbler" instance=ExtResource("9_w1fiw")] +unique_name_in_owner = true +layout_mode = 1