Take damage/Screen shake

This commit is contained in:
2025-11-30 22:35:26 -08:00
parent 8f8cc217dc
commit 4ee4e02a51
5 changed files with 131 additions and 12 deletions

View File

@@ -0,0 +1,45 @@
using Godot;
public partial class ShakeCamera : Camera3D
{
[Export] private double _shakeIntensity = 1.0;
[Export] private double _maxX = 10;
[Export] private double _maxY = 10;
[Export] private double _maxZ = 5;
[Export] private FastNoiseLite _noise;
[Export] private double _noiseSpeed = 50.0;
private double _shake = 0.0;
private double _time = 0.0;
private Vector3 _initialRotation;
public override void _Ready()
{
_initialRotation = RotationDegrees;
}
public override void _Process(double delta)
{
_time += delta;
_shake = Mathf.Max(_shake - delta * _shakeIntensity, 0.0);
RotationDegrees = new Vector3(
(float)(_initialRotation.X + _maxX * Mathf.Pow(_shake, 2) * GetNoiseFromSeed(0)),
(float)(_initialRotation.Y + _maxY * Mathf.Pow(_shake, 2) * GetNoiseFromSeed(1)),
(float)(_initialRotation.Z + _maxZ * Mathf.Pow(_shake, 2) * GetNoiseFromSeed(2)));
}
public void AddShake(float shakeAmount)
{
_shake = Mathf.Clamp(_shake + shakeAmount, 0.0, 1.0);
}
private double GetNoiseFromSeed(int seed)
{
_noise.Seed = seed;
return _noise.GetNoise1D((float)(_time * _noiseSpeed));
}
}

View File

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

View File

@@ -0,0 +1,20 @@
[gd_scene load_steps=3 format=3 uid="uid://didc6vnf5ftlg"]
[ext_resource type="Script" uid="uid://bb36q1wpe0tlw" path="res://src/camera/ShakeCamera.cs" id="1_ubmds"]
[sub_resource type="FastNoiseLite" id="FastNoiseLite_ubmds"]
frequency = 0.08
fractal_octaves = 4
[node name="Camera3D" type="Camera3D"]
cull_mask = 1048569
doppler_tracking = 1
fov = 52.0
near = 0.01
far = 9000.0
script = ExtResource("1_ubmds")
_shakeIntensity = 1.8
_maxX = 0.0
_maxY = 5.0
_noise = SubResource("FastNoiseLite_ubmds")
_noiseSpeed = 40.0

View File

@@ -76,6 +76,8 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
[Node] private IAnimationPlayer PlayerFXAnimations { get; set; } = default!; [Node] private IAnimationPlayer PlayerFXAnimations { get; set; } = default!;
[Node] private IAnimationPlayer TakeDamageAnimationPlayer { get; set; } = default!;
[Node] private Area3D Hitbox { get; set; } = default!; [Node] private Area3D Hitbox { get; set; } = default!;
[Node] private Area3D CollisionDetector { get; set; } = default!; [Node] private Area3D CollisionDetector { get; set; } = default!;
@@ -87,6 +89,8 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
[Node] private AudioStreamPlayer3D WalkSFX { get; set; } = default!; [Node] private AudioStreamPlayer3D WalkSFX { get; set; } = default!;
[Node] private CollisionShape3D MainCollision { get; set; } = default!; [Node] private CollisionShape3D MainCollision { get; set; } = default!;
[Node] private ShakeCamera _camera3D { get; set; } = default!;
#endregion #endregion
@@ -168,7 +172,6 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
public void Activate() public void Activate()
{ {
MainCollision.Disabled = false;
SetProcessInput(true); SetProcessInput(true);
SetPhysicsProcess(true); SetPhysicsProcess(true);
SetHealthTimerStatus(HealthTimerIsActive); SetHealthTimerStatus(HealthTimerIsActive);
@@ -176,7 +179,6 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
public void Deactivate() public void Deactivate()
{ {
MainCollision.Disabled = true;
SetProcessInput(false); SetProcessInput(false);
SetPhysicsProcess(false); SetPhysicsProcess(false);
SetHealthTimerStatus(false); SetHealthTimerStatus(false);
@@ -197,6 +199,8 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
public void TakeDamage(AttackData damage) public void TakeDamage(AttackData damage)
{ {
_camera3D.AddShake(1.0f);
TakeDamageAnimationPlayer.Play("take_damage");
var damageReceived = DamageCalculator.CalculateDamage(damage, DefenseComponent.CurrentDefense.Value + EquipmentComponent.BonusDefense, EquipmentComponent.ElementalResistance); var damageReceived = DamageCalculator.CalculateDamage(damage, DefenseComponent.CurrentDefense.Value + EquipmentComponent.BonusDefense, EquipmentComponent.ElementalResistance);
HealthComponent.Damage(damageReceived); HealthComponent.Damage(damageReceived);
SfxDatabase.Instance.Play(SoundEffect.TakeDamage); SfxDatabase.Instance.Play(SoundEffect.TakeDamage);

View File

@@ -1,6 +1,7 @@
[gd_scene load_steps=59 format=3 uid="uid://cfecvvav8kkp6"] [gd_scene load_steps=63 format=3 uid="uid://cfecvvav8kkp6"]
[ext_resource type="Script" uid="uid://yxmiqy7i0t7r" path="res://src/player/Player.cs" id="1_xcol5"] [ext_resource type="Script" uid="uid://yxmiqy7i0t7r" path="res://src/player/Player.cs" id="1_xcol5"]
[ext_resource type="PackedScene" uid="uid://didc6vnf5ftlg" path="res://src/camera/ShakeCamera.tscn" id="2_jtmj1"]
[ext_resource type="AudioStream" uid="uid://cth2xgoqhdf0m" path="res://src/audio/sfx/player_hit_wall.ogg" id="3_565yv"] [ext_resource type="AudioStream" uid="uid://cth2xgoqhdf0m" path="res://src/audio/sfx/player_hit_wall.ogg" id="3_565yv"]
[ext_resource type="Texture2D" uid="uid://c4ps26w7h3vpq" path="res://src/minimap/textures/player_map_icon.png" id="4_3ojaj"] [ext_resource type="Texture2D" uid="uid://c4ps26w7h3vpq" path="res://src/minimap/textures/player_map_icon.png" id="4_3ojaj"]
[ext_resource type="Shader" uid="uid://dfk3eps71yyyl" path="res://src/player/InvertColors.gdshader" id="4_v5qoq"] [ext_resource type="Shader" uid="uid://dfk3eps71yyyl" path="res://src/player/InvertColors.gdshader" id="4_v5qoq"]
@@ -14,7 +15,7 @@ height = 3.07596
[sub_resource type="ShaderMaterial" id="ShaderMaterial_jtmj1"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_jtmj1"]
[sub_resource type="QuadMesh" id="QuadMesh_v7rlw"] [sub_resource type="QuadMesh" id="QuadMesh_ebyyx"]
material = SubResource("ShaderMaterial_jtmj1") material = SubResource("ShaderMaterial_jtmj1")
flip_faces = true flip_faces = true
size = Vector2(2, 2) size = Vector2(2, 2)
@@ -353,6 +354,43 @@ _data = {
&"normal_attack": SubResource("Animation_v5qoq") &"normal_attack": SubResource("Animation_v5qoq")
} }
[sub_resource type="Animation" id="Animation_g183x"]
resource_name = "take_damage"
length = 0.1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("SubViewportContainer/SubViewport/ColorRect:color")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.0333333, 0.0666667),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 0.623529), Color(1, 1, 1, 0)]
}
[sub_resource type="Animation" id="Animation_ojh85"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("SubViewportContainer/SubViewport/ColorRect:color")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(1, 1, 1, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_ojh85"]
_data = {
&"RESET": SubResource("Animation_ojh85"),
&"take_damage": SubResource("Animation_g183x")
}
[sub_resource type="AtlasTexture" id="AtlasTexture_v5qoq"] [sub_resource type="AtlasTexture" id="AtlasTexture_v5qoq"]
atlas = ExtResource("4_v7rlw") atlas = ExtResource("4_v7rlw")
region = Rect2(0, 0, 512, 512) region = Rect2(0, 0, 512, 512)
@@ -637,17 +675,14 @@ wait_time = 3.0
[node name="Camera" type="Node3D" parent="."] [node name="Camera" type="Node3D" parent="."]
[node name="Camera3D" type="Camera3D" parent="Camera"] [node name="Camera3D" parent="Camera" instance=ExtResource("2_jtmj1")]
transform = Transform3D(1, 6.69803e-05, 0.000118449, -6.06525e-05, 0.998614, -0.052638, -0.000121811, 0.052638, 0.998614, 0.003, 1.2, -0.01) unique_name_in_owner = true
cull_mask = 1048569 transform = Transform3D(1, 6.69803e-05, 0.00011845, -6.06525e-05, 0.998614, -0.052638, -0.000121811, 0.052638, 0.998614, 0.003, 1.2, -0.01)
doppler_tracking = 1 current = true
fov = 52.0
near = 0.01
far = 9000.0
[node name="MeshInstance3D" type="MeshInstance3D" parent="Camera/Camera3D"] [node name="MeshInstance3D" type="MeshInstance3D" parent="Camera/Camera3D"]
extra_cull_margin = 16384.0 extra_cull_margin = 16384.0
mesh = SubResource("QuadMesh_v7rlw") mesh = SubResource("QuadMesh_ebyyx")
[node name="player_model" type="Node3D" parent="Camera"] [node name="player_model" type="Node3D" parent="Camera"]
transform = Transform3D(-0.015, 0, -2.26494e-09, 0, 0.015, 0, 2.26494e-09, 0, -0.015, 0, -0.268445, -0.00941753) transform = Transform3D(-0.015, 0, -2.26494e-09, 0, 0.015, 0, 2.26494e-09, 0, -0.015, 0, -0.268445, -0.00941753)
@@ -741,6 +776,12 @@ libraries = {
&"": SubResource("AnimationLibrary_ebyyx") &"": SubResource("AnimationLibrary_ebyyx")
} }
[node name="TakeDamageAnimationPlayer" type="AnimationPlayer" parent="ScreenFX"]
unique_name_in_owner = true
libraries = {
&"": SubResource("AnimationLibrary_ojh85")
}
[node name="SubViewportContainer" type="SubViewportContainer" parent="ScreenFX"] [node name="SubViewportContainer" type="SubViewportContainer" parent="ScreenFX"]
custom_minimum_size = Vector2(1440, 1080) custom_minimum_size = Vector2(1440, 1080)
anchors_preset = -1 anchors_preset = -1
@@ -767,6 +808,14 @@ scale = Vector2(36.5, 36.5)
sprite_frames = SubResource("SpriteFrames_ebyyx") sprite_frames = SubResource("SpriteFrames_ebyyx")
animation = &"sample" animation = &"sample"
[node name="ColorRect" type="ColorRect" parent="ScreenFX/SubViewportContainer/SubViewport"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(1, 1, 1, 0)
[node name="HitWallSound" type="AudioStreamPlayer" parent="."] [node name="HitWallSound" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true unique_name_in_owner = true
bus = &"SFX" bus = &"SFX"