Added player health and health bar
This commit is contained in:
@@ -2,6 +2,13 @@ class_name Player
|
||||
extends CharacterBody2D
|
||||
|
||||
|
||||
signal health_changed(value: float)
|
||||
signal dead()
|
||||
|
||||
|
||||
const MAX_HEALTH = 100.0
|
||||
|
||||
|
||||
@export_group("Movement", "move")
|
||||
@export_range(0.0, 1000.0) var move_max_speed_normal := 350
|
||||
@export_range(0.0, 1000.0) var move_max_speed_slowed := 250
|
||||
@@ -28,6 +35,11 @@ var _slow_down_tween: Tween
|
||||
|
||||
var _last_wall_normal: = 0.0
|
||||
|
||||
var _current_health: = MAX_HEALTH:
|
||||
set(value):
|
||||
_current_health = value
|
||||
health_changed.emit(_current_health)
|
||||
|
||||
|
||||
@onready var player_sprite : AnimatedSprite2D = $PlayerSprite
|
||||
@onready var blade_sprite : AnimatedSprite2D = $BladeSprite
|
||||
@@ -126,6 +138,13 @@ func _input(event: InputEvent) -> void:
|
||||
_attack()
|
||||
|
||||
|
||||
func deal_damage(value: float) -> void:
|
||||
_current_health -= value
|
||||
health_changed.emit(_current_health)
|
||||
if _current_health < 0.0 or is_zero_approx(_current_health):
|
||||
dead.emit()
|
||||
|
||||
|
||||
func _attack() -> void:
|
||||
var sprite := attack_left_sprite if velocity.x <= 0.0 else attack_right_sprite
|
||||
sprite.show()
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
class_name HealthBar
|
||||
extends Node2D
|
||||
|
||||
const ANIMATION_ALERT = "alert"
|
||||
|
||||
const SHADER_MAX_VALUE = "shader_parameter/max_value"
|
||||
const SHADER_CURRENT_VALUE = "shader_parameter/current_value"
|
||||
const SHADER_OLD_VALUE = "shader_parameter/old_value"
|
||||
|
||||
|
||||
const OLD_VALUE_DECRETION_RATE = 25.0
|
||||
|
||||
|
||||
var _max_value := 0.0:
|
||||
set(value):
|
||||
_max_value = value
|
||||
if is_node_ready():
|
||||
health_sprite.material.set(SHADER_MAX_VALUE, _max_value)
|
||||
|
||||
var _current_value := 0.0:
|
||||
set(value):
|
||||
_current_value = value
|
||||
if is_node_ready():
|
||||
health_sprite.material.set(SHADER_CURRENT_VALUE, _current_value)
|
||||
|
||||
var _old_value := 0.0:
|
||||
set(value):
|
||||
_old_value = value
|
||||
if is_node_ready():
|
||||
health_sprite.material.set(SHADER_OLD_VALUE, _old_value)
|
||||
|
||||
var _old_value_tween : Tween
|
||||
|
||||
var _is_animation_needed := false
|
||||
|
||||
|
||||
@onready var background_sprite : Sprite2D = $BackgroundSprite
|
||||
@onready var alert_sprite : Sprite2D = $AlertSprite
|
||||
@onready var health_sprite : Sprite2D = $HealthSprite
|
||||
|
||||
@onready var animation_player : AnimationPlayer = $AnimationPlayer
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
alert_sprite.hide()
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if _is_animation_needed and not animation_player.is_playing():
|
||||
animation_player.play(ANIMATION_ALERT)
|
||||
_is_animation_needed = false
|
||||
|
||||
|
||||
func initialize(max_value: float, value: float) -> void:
|
||||
_max_value = max_value
|
||||
_current_value = value
|
||||
_old_value = value
|
||||
|
||||
|
||||
func set_current_value(value: float) -> void:
|
||||
if value < _current_value:
|
||||
_is_animation_needed = true
|
||||
|
||||
_current_value = value
|
||||
var time := (_old_value - _current_value)/OLD_VALUE_DECRETION_RATE
|
||||
|
||||
if _old_value_tween and _old_value_tween.is_running():
|
||||
_old_value_tween.kill()
|
||||
|
||||
_old_value_tween = create_tween()
|
||||
_old_value_tween.tween_property(self, "_old_value", _current_value, abs(time))
|
||||
@@ -0,0 +1 @@
|
||||
uid://nkpolcm0u4dw
|
||||
@@ -0,0 +1,79 @@
|
||||
[gd_scene format=3 uid="uid://b1x0tmnf7hx7h"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://nkpolcm0u4dw" path="res://game/hud/health_bar.gd" id="1_2bnd8"]
|
||||
[ext_resource type="Texture2D" uid="uid://bud580fp54qdi" path="res://images/hud/health_bar.png" id="2_hc5qd"]
|
||||
[ext_resource type="Shader" uid="uid://cdo2tw14pkf6n" path="res://game/shaders/health_bar.gdshader" id="3_vrpsd"]
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_2bnd8"]
|
||||
atlas = ExtResource("2_hc5qd")
|
||||
region = Rect2(0, 16, 80, 16)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_hc5qd"]
|
||||
atlas = ExtResource("2_hc5qd")
|
||||
region = Rect2(0, 0, 80, 16)
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_hc5qd"]
|
||||
shader = ExtResource("3_vrpsd")
|
||||
shader_parameter/max_value = 0.0
|
||||
shader_parameter/current_value = 0.0
|
||||
shader_parameter/old_value = 0.0
|
||||
shader_parameter/health_color = Color(0.36862746, 0.99215686, 0.5529412, 1)
|
||||
shader_parameter/depletion_color = Color(0.32941177, 0.6509804, 0.41568628, 1)
|
||||
shader_parameter/restoration_color = Color(1, 1, 1, 1)
|
||||
shader_parameter/background_color = Color(0, 0, 0, 0)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_vrpsd"]
|
||||
atlas = ExtResource("2_hc5qd")
|
||||
region = Rect2(2, 32, 76, 16)
|
||||
|
||||
[sub_resource type="Animation" id="Animation_hc5qd"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("AlertSprite:visible")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [true]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_vrpsd"]
|
||||
resource_name = "alert"
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("AlertSprite:visible")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
|
||||
"update": 1,
|
||||
"values": [true, false, true, false, true, false]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_5m3x1"]
|
||||
_data = {
|
||||
&"RESET": SubResource("Animation_hc5qd"),
|
||||
&"alert": SubResource("Animation_vrpsd")
|
||||
}
|
||||
|
||||
[node name="HealthBar" type="Node2D" unique_id=256637218]
|
||||
script = ExtResource("1_2bnd8")
|
||||
|
||||
[node name="BackgroundSprite" type="Sprite2D" parent="." unique_id=92025763]
|
||||
texture = SubResource("AtlasTexture_2bnd8")
|
||||
|
||||
[node name="AlertSprite" type="Sprite2D" parent="." unique_id=434583744]
|
||||
texture = SubResource("AtlasTexture_hc5qd")
|
||||
|
||||
[node name="HealthSprite" type="Sprite2D" parent="." unique_id=1962337283]
|
||||
material = SubResource("ShaderMaterial_hc5qd")
|
||||
texture = SubResource("AtlasTexture_vrpsd")
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=1840862293]
|
||||
libraries/ = SubResource("AnimationLibrary_5m3x1")
|
||||
@@ -2,6 +2,9 @@ class_name AbstractLevel
|
||||
extends Node2D
|
||||
|
||||
|
||||
const CORRUPTION_DAMAGE = 10.0
|
||||
|
||||
|
||||
@export var initial_corruption_x := 0.0
|
||||
@export var corruption_speed := 0.0
|
||||
|
||||
@@ -11,6 +14,9 @@ var _corruption_x: float
|
||||
|
||||
@onready var player : Player = $Player
|
||||
@onready var pause_menu : PauseMenu = $%PauseMenu
|
||||
@onready var health_bar : HealthBar = $%HealthBar
|
||||
|
||||
@onready var corruption_timer : Timer = $CorruptionTimer
|
||||
|
||||
@onready var level_material : ShaderMaterial = $%LevelColorRect.material
|
||||
|
||||
@@ -18,21 +24,35 @@ var _corruption_x: float
|
||||
func _ready() -> void:
|
||||
_corruption_x = initial_corruption_x
|
||||
pause_menu.hide()
|
||||
health_bar.initialize(player.MAX_HEALTH, player.MAX_HEALTH)
|
||||
player.health_changed.connect(health_bar.set_current_value)
|
||||
|
||||
#TODO Add gameplay music
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
_corruption_x += corruption_speed * delta
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
var screen_to_world := player.camera.get_canvas_transform().affine_inverse()
|
||||
level_material.set_shader_parameter("screen_to_world", screen_to_world)
|
||||
level_material.set_shader_parameter("corruption_x", _corruption_x)
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
_corruption_x += corruption_speed * delta
|
||||
|
||||
if player.position.x < _corruption_x:
|
||||
if corruption_timer.is_stopped():
|
||||
corruption_timer.start()
|
||||
else:
|
||||
corruption_timer.stop()
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("pause"):
|
||||
SoundManager.play_ui_stream(SoundManager.ui_stream_accept)
|
||||
get_tree().paused = true
|
||||
pause_menu.show()
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
|
||||
|
||||
func _on_corruption_timer_timeout() -> void:
|
||||
player.deal_damage(CORRUPTION_DAMAGE)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[ext_resource type="PackedScene" uid="uid://0e3xvmn36j5b" path="res://game/menu/pause_menu.tscn" id="3_fnnmn"]
|
||||
[ext_resource type="Shader" uid="uid://brudtlwas6x66" path="res://game/shaders/glitch.gdshader" id="4_6b8cu"]
|
||||
[ext_resource type="Texture2D" uid="uid://b8rm1kxgci4l1" path="res://images/level/beams.png" id="4_pi5fd"]
|
||||
[ext_resource type="PackedScene" uid="uid://b1x0tmnf7hx7h" path="res://game/hud/health_bar.tscn" id="6_x8k35"]
|
||||
|
||||
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_6b8cu"]
|
||||
resource_name = "Beams"
|
||||
@@ -1195,3 +1196,11 @@ offset_bottom = 360.0
|
||||
[node name="PauseMenu" parent="CanvasLayer" unique_id=1815975678 instance=ExtResource("3_fnnmn")]
|
||||
unique_name_in_owner = true
|
||||
process_mode = 2
|
||||
|
||||
[node name="HealthBar" parent="CanvasLayer" unique_id=256637218 instance=ExtResource("6_x8k35")]
|
||||
unique_name_in_owner = true
|
||||
position = Vector2(51, 19)
|
||||
|
||||
[node name="CorruptionTimer" type="Timer" parent="." unique_id=783383429]
|
||||
|
||||
[connection signal="timeout" from="CorruptionTimer" to="." method="_on_corruption_timer_timeout"]
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform float max_value;
|
||||
uniform float current_value;
|
||||
uniform float old_value;
|
||||
|
||||
uniform vec4 health_color : source_color = vec4(0.0, 0.65, 0.0, 1.0);
|
||||
uniform vec4 depletion_color : source_color = vec4(0.0, 0.3, 0.0, 1.0);
|
||||
uniform vec4 restoration_color : source_color = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
uniform vec4 background_color : source_color = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
void fragment() {
|
||||
float fill = current_value / max_value;
|
||||
float old_fill = old_value / max_value;
|
||||
|
||||
vec4 color;
|
||||
|
||||
if (current_value <= old_value) {
|
||||
if (UV.x < fill) {
|
||||
color = health_color;
|
||||
} else if (UV.x < old_fill) {
|
||||
color = depletion_color;
|
||||
} else {
|
||||
color = background_color;
|
||||
}
|
||||
} else {
|
||||
if (UV.x < old_fill) {
|
||||
color = health_color;
|
||||
} else if (UV.x < fill) {
|
||||
color = restoration_color;
|
||||
} else {
|
||||
color = background_color;
|
||||
}
|
||||
}
|
||||
|
||||
COLOR = vec4(color.rgb, color.a * COLOR.a);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://cdo2tw14pkf6n
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bud580fp54qdi"
|
||||
path="res://.godot/imported/health_bar.png-dcd0e5acd727c0d7b2bc135b358ef446.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://images/hud/health_bar.png"
|
||||
dest_files=["res://.godot/imported/health_bar.png-dcd0e5acd727c0d7b2bc135b358ef446.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
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/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
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
|
||||
Reference in New Issue
Block a user