godot-shooter / commit
Added damage labels that pop up whenever ships are damaged, or when the player is healed by HP pick-ups.
actors/Enemy.gd | 8 +++ actors/Enemy.tscn | 4 +- actors/Player.gd | 9 +++ actors/Player.tscn | 4 +- effects/Damage.gd | 24 ++++++++ effects/Damage.tscn | 146 ++++++++++++++++++++++++++++++++++++++++++++++++ project.godot | 6 ++ themes/DamageTheme.tres | 14 +++++ themes/HealTheme.tres | 14 +++++ 9 files changed, 225 insertions(+), 4 deletions(-) diff --git a/actors/Enemy.gd b/actors/Enemy.gd index b48ad66..cb5137a 100644 --- a/actors/Enemy.gd +++ b/actors/Enemy.gd @@ -6,6 +6,7 @@ onready var damage_points = $DamagePoints const Utils = preload("res://utils/Utils.gd") const Explosion = preload("res://effects/Explosion.tscn") const Smoke = preload("res://effects/Smoke.tscn") +const Damage = preload("res://effects/Damage.tscn") const Constants = preload("res://utils/Constants.gd") export var move_speed = Constants.SPEED * 1.05 @@ -88,6 +89,7 @@ func hurt(damage: int = 1): if dead || is_invincible: return health -= damage + add_damage_label(damage) # add_child(smoke) _ensure_smoke_exists() if health <= 0: @@ -105,6 +107,12 @@ func kill(): z_index = -1 emit_signal("enemy_killed", global_position) +func add_damage_label(damage_amount: int = 5) -> void: + var damage_label: Damage = Damage.instance() + damage_label.value = -damage_amount + damage_label.position = self.position + get_tree().root.add_child(damage_label) + func teleport(dest: Vector2) -> void: $Graphics/Alive/Trails.clear() position = dest diff --git a/actors/Enemy.tscn b/actors/Enemy.tscn index c9d1778..f887843 100644 --- a/actors/Enemy.tscn +++ b/actors/Enemy.tscn @@ -116,8 +116,8 @@ gradient = SubResource( 4 ) margin_left = -50.0 margin_top = 45.0 margin_right = 50.0 -margin_bottom = 55.0 -rect_min_size = Vector2( 100, 10 ) +margin_bottom = 50.0 +rect_min_size = Vector2( 100, 5 ) custom_styles/fg = SubResource( 5 ) custom_styles/bg = SubResource( 6 ) value = 30.0 diff --git a/actors/Player.gd b/actors/Player.gd index 6bfe9a4..99cf0cf 100644 --- a/actors/Player.gd +++ b/actors/Player.gd @@ -1,6 +1,7 @@ extends KinematicBody2D class_name Player +const Damage = preload("res://effects/Damage.tscn") const Weapons = preload("res://weapons/Weapons.gd") const Constants = preload("res://utils/Constants.gd") @@ -136,6 +137,7 @@ func heal(amount: int = 1): if dead: return health += amount + add_damage_label(-amount) if health > max_health: health = max_health @@ -149,9 +151,16 @@ func hurt(damage_amount: int = 1): return else: health -= damage_amount + add_damage_label(damage_amount) if health <= 0: kill() +func add_damage_label(damage_amount: int = 5) -> void: + var damage_label: Damage = Damage.instance() + damage_label.value = -damage_amount + damage_label.position = self.position + get_tree().root.add_child(damage_label) + func turn_towards(dest: Vector2, _delta: float): var to_dir = (dest - global_position).normalized() var curr_dir = velocity.normalized() diff --git a/actors/Player.tscn b/actors/Player.tscn index 82df0f3..a8bea0d 100644 --- a/actors/Player.tscn +++ b/actors/Player.tscn @@ -89,8 +89,8 @@ offset = Vector2( 0, -300 ) margin_left = -50.0 margin_top = 45.0 margin_right = 50.0 -margin_bottom = 55.0 -rect_min_size = Vector2( 100, 10 ) +margin_bottom = 50.0 +rect_min_size = Vector2( 100, 5 ) custom_styles/fg = SubResource( 13 ) custom_styles/bg = SubResource( 14 ) value = 30.0 diff --git a/effects/Damage.gd b/effects/Damage.gd new file mode 100644 index 0000000..1dc6878 --- /dev/null +++ b/effects/Damage.gd @@ -0,0 +1,24 @@ +extends Node2D + +class_name Damage + +const HealTheme = preload("res://themes/HealTheme.tres") +const DamageTheme = preload("res://themes/DamageTheme.tres") +onready var animation_player = $AnimationPlayer +onready var damage_label = $DamageLabel +export var value: int = 5 + +func _ready() -> void: + animation_player.queue("fade_in") + animation_player.queue("fade_out") + +func _process(delta: float) -> void: + var value_sign = "+" + if self.value < 0: + value_sign = "-" + var abs_value = abs(self.value) + damage_label.text = "%s%s" % [value_sign, abs_value] + if self.value >= 0: + damage_label.theme = HealTheme + else: + damage_label.theme = DamageTheme diff --git a/effects/Damage.tscn b/effects/Damage.tscn new file mode 100644 index 0000000..978f0b8 --- /dev/null +++ b/effects/Damage.tscn @@ -0,0 +1,146 @@ +[gd_scene load_steps=6 format=2] + +[ext_resource path="res://themes/DamageTheme.tres" type="Theme" id=1] +[ext_resource path="res://effects/Damage.gd" type="Script" id=2] + +[sub_resource type="Animation" id=1] +length = 0.001 +tracks/0/type = "value" +tracks/0/path = NodePath(".:modulate") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 0, +"values": [ Color( 1, 1, 1, 0 ) ] +} +tracks/1/type = "value" +tracks/1/path = NodePath(".:scale") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 0, +"values": [ Vector2( 0.1, 0.1 ) ] +} +tracks/2/type = "value" +tracks/2/path = NodePath(".:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/keys = { +"times": PoolRealArray( 0 ), +"transitions": PoolRealArray( 1 ), +"update": 0, +"values": [ Vector2( 0, 100 ) ] +} + +[sub_resource type="Animation" id=2] +resource_name = "fade_in" +length = 0.25 +tracks/0/type = "value" +tracks/0/path = NodePath(".:modulate") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0, 0.2 ), +"transitions": PoolRealArray( 1, 1 ), +"update": 0, +"values": [ Color( 1, 1, 1, 0 ), Color( 1, 1, 1, 1 ) ] +} +tracks/1/type = "value" +tracks/1/path = NodePath(".:scale") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0, 0.2 ), +"transitions": PoolRealArray( 1, 1 ), +"update": 0, +"values": [ Vector2( 0.1, 0.1 ), Vector2( 1, 1 ) ] +} +tracks/2/type = "value" +tracks/2/path = NodePath(".:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/imported = false +tracks/2/enabled = false +tracks/2/keys = { +"times": PoolRealArray( 0, 0.2 ), +"transitions": PoolRealArray( 1, 1 ), +"update": 0, +"values": [ Vector2( 0, 100 ), Vector2( 0, 0 ) ] +} + +[sub_resource type="Animation" id=3] +resource_name = "fade_out" +length = 2.0 +tracks/0/type = "value" +tracks/0/path = NodePath(".:modulate") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0, 2 ), +"transitions": PoolRealArray( 1, 1 ), +"update": 0, +"values": [ Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ] +} +tracks/1/type = "value" +tracks/1/path = NodePath(".:scale") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/keys = { +"times": PoolRealArray( 0, 2 ), +"transitions": PoolRealArray( 1, 1 ), +"update": 0, +"values": [ Vector2( 1, 1 ), Vector2( 0.1, 0.1 ) ] +} +tracks/2/type = "method" +tracks/2/path = NodePath(".") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/keys = { +"times": PoolRealArray( 2 ), +"transitions": PoolRealArray( 1 ), +"values": [ { +"args": [ ], +"method": "queue_free" +} ] +} + +[node name="Damage" type="Node2D"] +modulate = Color( 1, 1, 1, 0 ) +position = Vector2( 0, 100 ) +scale = Vector2( 0.1, 0.1 ) +script = ExtResource( 2 ) + +[node name="DamageLabel" type="Label" parent="."] +margin_left = -20.0 +margin_top = -19.0 +margin_right = 20.0 +margin_bottom = 18.0 +theme = ExtResource( 1 ) +text = "5" +align = 1 +valign = 1 + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +anims/RESET = SubResource( 1 ) +anims/fade_in = SubResource( 2 ) +anims/fade_out = SubResource( 3 ) diff --git a/project.godot b/project.godot index 28fe087..23b7065 100644 --- a/project.godot +++ b/project.godot @@ -19,6 +19,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://items/ConstantItemGenerator.gd" }, { +"base": "Node2D", +"class": "Damage", +"language": "GDScript", +"path": "res://effects/Damage.gd" +}, { "base": "KinematicBody2D", "class": "Enemy", "language": "GDScript", @@ -62,6 +67,7 @@ _global_script_classes=[ { _global_script_class_icons={ "Bullet": "", "ConstantItemGenerator": "", +"Damage": "", "Enemy": "", "LevelItemGenerator": "", "Player": "", diff --git a/themes/DamageTheme.tres b/themes/DamageTheme.tres new file mode 100644 index 0000000..e2a85d5 --- /dev/null +++ b/themes/DamageTheme.tres @@ -0,0 +1,14 @@ +[gd_resource type="Theme" load_steps=3 format=2] + +[ext_resource path="res://assets/neuropolitical rg.otf" type="DynamicFontData" id=1] + +[sub_resource type="DynamicFont" id=1] +size = 30 +outline_size = 3 +outline_color = Color( 1, 0, 0, 1 ) +use_mipmaps = true +use_filter = true +font_data = ExtResource( 1 ) + +[resource] +default_font = SubResource( 1 ) diff --git a/themes/HealTheme.tres b/themes/HealTheme.tres new file mode 100644 index 0000000..9f6443a --- /dev/null +++ b/themes/HealTheme.tres @@ -0,0 +1,14 @@ +[gd_resource type="Theme" load_steps=3 format=2] + +[ext_resource path="res://assets/neuropolitical rg.otf" type="DynamicFontData" id=1] + +[sub_resource type="DynamicFont" id=1] +size = 30 +outline_size = 1 +outline_color = Color( 0.00392157, 0.686275, 0.0784314, 1 ) +use_mipmaps = true +use_filter = true +font_data = ExtResource( 1 ) + +[resource] +default_font = SubResource( 1 )