VS-4/player-health-system (#11)

UPDATED TO GODOT 4.4!!!

Added:

an open source font just to have something different than Godot's default

Semblance of a framework for the UI

a health bar

a label that shows your time in seconds. Should probably make it show minutes and seconds

a menu that appears in the player's death state that shows the amount of time the player lived and their kill count. Also has a working quit button and non-working try again button.

a button that instantly kills you, which is "T."

Co-authored-by: ysandler <ysandler@tzed.io>
Reviewed-on: #11
Reviewed-by: Yehoshua Sandler <ysandler@beitzah.net>
This commit is contained in:
Travis Gatlin 2025-03-23 07:18:43 -05:00
parent da46fd1db7
commit 37b0069108
17 changed files with 306 additions and 30 deletions

View File

@ -167,7 +167,7 @@ texture = ExtResource("1_o4wx4")
5:10/0 = 0
5:10/0/terrain_set = 0
5:10/0/terrain = 1
5:10/0/occlusion_layer_0/polygon = SubResource("OccluderPolygon2D_kbfo3")
5:10/0/occlusion_layer_0/polygon_0/polygon = SubResource("OccluderPolygon2D_kbfo3")
5:10/0/terrains_peering_bit/right_side = 1
5:10/0/terrains_peering_bit/bottom_right_corner = 1
5:10/0/terrains_peering_bit/bottom_side = 1

View File

@ -0,0 +1 @@
uid://da6en7riwhwxg

6
assets/UI/UI Theme.tres Normal file
View File

@ -0,0 +1,6 @@
[gd_resource type="Theme" load_steps=2 format=3 uid="uid://dm1k0046nkiw7"]
[ext_resource type="FontFile" uid="uid://dyqn86y567nun" path="res://assets/UI/fonts/OstrichSans-Heavy.otf" id="1_i7gdq"]
[resource]
default_font = ExtResource("1_i7gdq")

35
assets/UI/death_menu.gd Normal file
View File

@ -0,0 +1,35 @@
extends PanelContainer
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
func _on_ui_death_menu(time: Variant, kills: Variant) -> void:
self.call_deferred("set_visible",true)
var gameTimeString:String
if time < 60.0:
gameTimeString = "Time: "+str(time)+" seconds."
elif time > 60.0:
var minutes = floori(time/60)
var seconds = time - minutes*60
if time >120.0:
gameTimeString = "Time: "+str(minutes)+" minutes and "+str(seconds)+ " seconds."
else:
gameTimeString = "Time: "+str(minutes)+" minute and "+str(seconds)+ " seconds."
$"panel/stats/game time".text = gameTimeString
$"panel/stats/killcount".text = "Kills: "+str(kills)
func _on_quit_pressed() -> void:
get_tree().quit()
func _on_try_again_pressed() -> void:
$"panel/controls/Label".call_deferred("set_visible",true)

View File

@ -0,0 +1 @@
uid://csfa25g8x57ab

Binary file not shown.

View File

@ -0,0 +1,35 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://dyqn86y567nun"
path="res://.godot/imported/OstrichSans-Heavy.otf-75da62584a7db5199732cc8d7d0872a4.fontdata"
[deps]
source_file="res://assets/UI/fonts/OstrichSans-Heavy.otf"
dest_files=["res://.godot/imported/OstrichSans-Heavy.otf-75da62584a7db5199732cc8d7d0872a4.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

View File

@ -0,0 +1,11 @@
[gd_resource type="GradientTexture2D" load_steps=2 format=3 uid="uid://dhs4m6d2y6o3o"]
[sub_resource type="Gradient" id="Gradient_c1s24"]
offsets = PackedFloat32Array(0, 0.514085, 1)
colors = PackedColorArray(0.269386, 0.277436, 0.261329, 1, 0.627249, 0.638787, 0.615777, 1, 0.269386, 0.277436, 0.261329, 1)
[resource]
gradient = SubResource("Gradient_c1s24")
width = 128
height = 20
fill_from = Vector2(1, 1)

29
assets/UI/ui.gd Normal file
View File

@ -0,0 +1,29 @@
extends Control
@onready var global = $"/root/Player"
var countingGameTime:bool
var gameTimer = 0.0
var killCount = 0
signal deathMenu(time,kills)
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
global.connect("playerHealth",updateHealthBar)
global.connect("playerDeath",playerDeath)
countingGameTime = true
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
if countingGameTime == true:
gameTimer += delta
$"topLeft/debug".text = str(snappedf(gameTimer,0.1))
func updateHealthBar(health):
var healthBarTween = get_tree().create_tween()
healthBarTween.set_trans(Tween.TRANS_EXPO)
healthBarTween.tween_property($"topLeft/health","value",health,0.1)
$"topLeft/health/healthText".text = str(health)
func playerDeath():
deathMenu.emit(snappedf(gameTimer,0.1),killCount)
gameTimer = 0.0
killCount = 0
countingGameTime = false

1
assets/UI/ui.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://co1m2vw7jpvey

1
camera.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://cmcp6ldln7rdb

171
demo.tscn

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,8 @@
extends Node
signal playerPosition(pos)
signal playerHealth(healthAmount)
signal playerDeath()
signal enemyKill()
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.

1
globals/player.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://bndhuubg5acwg

View File

@ -1,15 +1,25 @@
extends CharacterBody2D
@onready var global = $"/root/Player"
var playerHealth = 100.0
var dead = false
const SPEED = 350.0
var charAngle = 0.0
func _physics_process(delta: float) -> void:
global.emit_signal("playerPosition",self.global_position)
movement()
if dead != true:
movement()
func _process(delta: float) -> void:
if dead != false:
setAnimation("Death")
if Input.is_action_just_pressed("test"):
playerDamage(100)
func setAnimation(anim):
if $"Birb".animation != anim:
$Birb.animation = anim
$"Birb".play()
func animation():
pass
func movement():
var vertical = Input.get_axis("up","down")
var horizontal = Input.get_axis("left","right")
@ -24,4 +34,12 @@ func movement():
velocity.y = SPEED * vertical
velocity.x = SPEED * horizontal
move_and_slide()
$"../Camera2D/Label".text = (str(charAngle*180/PI))
#$"../UI/Label".text = (str(charAngle*180/PI))
func playerDamage(amount):
if dead == false:
playerHealth -= amount
global.emit_signal("playerHealth",playerHealth)
if playerHealth <= 0 and dead == false:
dead = true
global.emit_signal("playerDeath")

1
main character.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://y1jnx0p2rq46

View File

@ -12,7 +12,7 @@ config_version=5
config/name="birb"
run/main_scene="res://demo.tscn"
config/features=PackedStringArray("4.3", "GL Compatibility")
config/features=PackedStringArray("4.4", "GL Compatibility")
config/icon="res://icon.svg"
[autoload]
@ -59,6 +59,11 @@ right={
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null)
]
}
test={
"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":84,"key_label":0,"unicode":116,"location":0,"echo":false,"script":null)
]
}
[rendering]