diff --git a/Assets/Fonts/alagard.ttf b/Assets/Fonts/alagard.ttf new file mode 100644 index 0000000..c7ed1d9 Binary files /dev/null and b/Assets/Fonts/alagard.ttf differ diff --git a/Assets/Fonts/alagard.ttf.import b/Assets/Fonts/alagard.ttf.import new file mode 100644 index 0000000..94f50ea --- /dev/null +++ b/Assets/Fonts/alagard.ttf.import @@ -0,0 +1,32 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://cgwa8bjiyv534" +path="res://.godot/imported/alagard.ttf-ed7015ed0e84e70ec06fd3d65515ce04.fontdata" + +[deps] + +source_file="res://Assets/Fonts/alagard.ttf" +dest_files=["res://.godot/imported/alagard.ttf-ed7015ed0e84e70ec06fd3d65515ce04.fontdata"] + +[params] + +Rendering=null +antialiasing=0 +generate_mipmaps=false +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +force_autohinter=false +hinting=1 +subpixel_positioning=1 +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/Sprites/Characters/forsen.ase b/Assets/Sprites/Characters/forsen.ase similarity index 100% rename from Sprites/Characters/forsen.ase rename to Assets/Sprites/Characters/forsen.ase diff --git a/Sprites/Characters/forsen.png b/Assets/Sprites/Characters/forsen.png similarity index 100% rename from Sprites/Characters/forsen.png rename to Assets/Sprites/Characters/forsen.png diff --git a/Sprites/Characters/forsen.png.import b/Assets/Sprites/Characters/forsen.png.import similarity index 71% rename from Sprites/Characters/forsen.png.import rename to Assets/Sprites/Characters/forsen.png.import index 7ce2853..edd70e7 100644 --- a/Sprites/Characters/forsen.png.import +++ b/Assets/Sprites/Characters/forsen.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://dxymfduyrbuvx" -path="res://.godot/imported/forsen.png-fce73bdb02d4ae9ad3a1c7a29f120a10.ctex" +path="res://.godot/imported/forsen.png-c75844516d35dfe104cf50cd521a7820.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://Sprites/Characters/forsen.png" -dest_files=["res://.godot/imported/forsen.png-fce73bdb02d4ae9ad3a1c7a29f120a10.ctex"] +source_file="res://Assets/Sprites/Characters/forsen.png" +dest_files=["res://.godot/imported/forsen.png-c75844516d35dfe104cf50cd521a7820.ctex"] [params] diff --git a/Sprites/figure.ase b/Assets/Sprites/figure.ase similarity index 100% rename from Sprites/figure.ase rename to Assets/Sprites/figure.ase diff --git a/Sprites/knife.ase b/Assets/Sprites/knife.ase similarity index 100% rename from Sprites/knife.ase rename to Assets/Sprites/knife.ase diff --git a/Sprites/knife.png b/Assets/Sprites/knife.png similarity index 100% rename from Sprites/knife.png rename to Assets/Sprites/knife.png diff --git a/Sprites/knife.png.import b/Assets/Sprites/knife.png.import similarity index 72% rename from Sprites/knife.png.import rename to Assets/Sprites/knife.png.import index e44bffb..f139fae 100644 --- a/Sprites/knife.png.import +++ b/Assets/Sprites/knife.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://dt6u8p4h6g7le" -path="res://.godot/imported/knife.png-95e39b161a14477923b7daae97a5ccae.ctex" +path="res://.godot/imported/knife.png-29bc4ddc148b964cb9b086eec2187a96.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://Sprites/knife.png" -dest_files=["res://.godot/imported/knife.png-95e39b161a14477923b7daae97a5ccae.ctex"] +source_file="res://Assets/Sprites/knife.png" +dest_files=["res://.godot/imported/knife.png-29bc4ddc148b964cb9b086eec2187a96.ctex"] [params] diff --git a/Assets/Sprites/sword-swing.ase b/Assets/Sprites/sword-swing.ase new file mode 100644 index 0000000..c08ca0e Binary files /dev/null and b/Assets/Sprites/sword-swing.ase differ diff --git a/Assets/Sprites/sword-swing.png b/Assets/Sprites/sword-swing.png new file mode 100644 index 0000000..7d1124f Binary files /dev/null and b/Assets/Sprites/sword-swing.png differ diff --git a/Assets/Sprites/sword-swing.png.import b/Assets/Sprites/sword-swing.png.import new file mode 100644 index 0000000..5f6a5ad --- /dev/null +++ b/Assets/Sprites/sword-swing.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://do1bui3bblkk7" +path="res://.godot/imported/sword-swing.png-b3fe38b6ad54820f8f9984baa9ea79b7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/sword-swing.png" +dest_files=["res://.godot/imported/sword-swing.png-b3fe38b6ad54820f8f9984baa9ea79b7.ctex"] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/bptc_ldr=0 +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/Sprites/tileset.png b/Assets/Sprites/tileset.png similarity index 100% rename from Sprites/tileset.png rename to Assets/Sprites/tileset.png diff --git a/Sprites/tileset.png.import b/Assets/Sprites/tileset.png.import similarity index 72% rename from Sprites/tileset.png.import rename to Assets/Sprites/tileset.png.import index 5e7275e..ec98ab9 100644 --- a/Sprites/tileset.png.import +++ b/Assets/Sprites/tileset.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://gm2pcnfg7h8j" -path="res://.godot/imported/tileset.png-c259079e18121438fd392d302e3ca0d5.ctex" +path="res://.godot/imported/tileset.png-f52e8e44f74a535dd898a49592afe6d9.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://Sprites/tileset.png" -dest_files=["res://.godot/imported/tileset.png-c259079e18121438fd392d302e3ca0d5.ctex"] +source_file="res://Assets/Sprites/tileset.png" +dest_files=["res://.godot/imported/tileset.png-f52e8e44f74a535dd898a49592afe6d9.ctex"] [params] diff --git a/BoundingBoxes/BoundingBox.cs b/BoundingBoxes/BoundingBox.cs new file mode 100644 index 0000000..cbd20cb --- /dev/null +++ b/BoundingBoxes/BoundingBox.cs @@ -0,0 +1,11 @@ +using Godot; +using SupaLidlGame.Utils; + +namespace SupaLidlGame.BoundingBoxes +{ + public abstract partial class BoundingBox : Area2D, IFaction + { + [Export] + public ushort Faction { get; set; } + } +} diff --git a/BoundingBoxes/Hitbox.cs b/BoundingBoxes/Hitbox.cs index 8556dc3..04cee97 100644 --- a/BoundingBoxes/Hitbox.cs +++ b/BoundingBoxes/Hitbox.cs @@ -1,13 +1,17 @@ using System.Collections.Generic; +using System.Linq; using Godot; using SupaLidlGame.Characters; -using SupaLidlGame.Utils; +using SupaLidlGame.Items; namespace SupaLidlGame.BoundingBoxes { - public partial class Hitbox : Area2D, IFaction + public partial class Hitbox : BoundingBox { - private HashSet _ignoreList = new HashSet(); + private HashSet _ignoreList = new HashSet(); + + [Signal] + public delegate void HitEventHandler(BoundingBox box); [Export] public float Damage { get; set; } @@ -19,40 +23,76 @@ namespace SupaLidlGame.BoundingBoxes public bool IsDisabled { get => _collisionShape.Disabled; - set => _collisionShape.Disabled = value; + set + { + _collisionShape.Disabled = value; + if (value) + { + DamageStartTime = Time.GetTicksMsec(); + } + } } [Export] public float Knockback { get; set; } - [Export] - public ushort Faction { get; set; } - public Character Inflictor { get; set; } + public ulong DamageStartTime { get; set; } + private CollisionShape2D _collisionShape; + private bool _isParrying = false; + public override void _Ready() { _collisionShape = GetNode("CollisionShape2D"); } + private bool ShouldParry(Hitbox box) + { + Node parent = GetParent(); + + // if this hitbox does not even belong to a weapon, skip + if (parent is not Weapon) + { + return false; + } + + var weapon = parent as Weapon; + + // if we hit a hitbox, we can parry if it can be parried + if (box.GetParent() is Weapon other) + { + return weapon.IsParryable && other.IsParryable; + } + + return false; + } + public void _on_area_entered(Area2D area) { - if (area is Hurtbox hurtbox) + if (area is BoundingBox box) { // we don't want to hurt teammates - if (Faction != hurtbox.Faction) + if (Faction != box.Faction) { - if (!_ignoreList.Contains(hurtbox)) + if (!_ignoreList.Contains(box)) { - _ignoreList.Add(hurtbox); - hurtbox.InflictDamage(Damage, Inflictor, Knockback); + _ignoreList.Add(box); + EmitSignal(SignalName.Hit, box); } } } } public void ResetIgnoreList() => _ignoreList.Clear(); + + public bool HasHit(BoundingBox box) => _ignoreList.Contains(box); + + public HashSet Hits + { + get => _ignoreList; + } } } diff --git a/BoundingBoxes/Hitbox.tscn b/BoundingBoxes/Hitbox.tscn index e9a60a2..975e4f2 100644 --- a/BoundingBoxes/Hitbox.tscn +++ b/BoundingBoxes/Hitbox.tscn @@ -5,6 +5,7 @@ [sub_resource type="RectangleShape2D" id="RectangleShape2D_3w20g"] [node name="Hitbox" type="Area2D"] +priority = 5.0 script = ExtResource("1_44i8j") [node name="CollisionShape2D" type="CollisionShape2D" parent="."] diff --git a/BoundingBoxes/Hurtbox.cs b/BoundingBoxes/Hurtbox.cs index 7917ba9..470175e 100644 --- a/BoundingBoxes/Hurtbox.cs +++ b/BoundingBoxes/Hurtbox.cs @@ -4,7 +4,7 @@ using SupaLidlGame.Utils; namespace SupaLidlGame.BoundingBoxes { - public partial class Hurtbox : Area2D, IFaction + public partial class Hurtbox : BoundingBox, IFaction { [Signal] public delegate void ReceivedDamageEventHandler( @@ -14,9 +14,6 @@ namespace SupaLidlGame.BoundingBoxes Vector2 knockbackOrigin = default, Vector2 knockbackVector = default); - [Export] - public ushort Faction { get; set; } - public override void _Ready() { if (Faction == default && GetParent() is IFaction factionEntity) diff --git a/Characters/Character.cs b/Characters/Character.cs index 936dffa..4f4c7ae 100644 --- a/Characters/Character.cs +++ b/Characters/Character.cs @@ -1,4 +1,5 @@ using Godot; +using SupaLidlGame.Extensions; using SupaLidlGame.Items; using SupaLidlGame.Utils; @@ -9,6 +10,9 @@ namespace SupaLidlGame.Characters [Export] public float Speed { get; protected set; } = 32.0f; + [Export] + public float Friction { get; protected set; } = 4.0f; + [Export] public float Mass { @@ -28,10 +32,13 @@ namespace SupaLidlGame.Characters public Vector2 Acceleration => Direction * AccelerationMagnitude; + public Vector2 NetImpulse { get; set; } = Vector2.Zero; + public Vector2 Direction { get; set; } = Vector2.Zero; public Vector2 Target { get; set; } = Vector2.Zero; + [Export] public float Health { get => _health; @@ -51,9 +58,11 @@ namespace SupaLidlGame.Characters } } + public bool IsAlive => Health > 0; + protected float _health = 100f; - public bool IsAlive => Health > 0; + public double StunTime { get; set; } [Export] public AnimatedSprite2D Sprite { get; set; } @@ -99,7 +108,10 @@ namespace SupaLidlGame.Characters /// public virtual void ModifyVelocity() { - + if (StunTime > 0) + { + Velocity *= 0.25f; + } } public virtual void Die() @@ -113,7 +125,12 @@ namespace SupaLidlGame.Characters // delta p = F delta t if (resetVelocity) Velocity = Vector2.Zero; - Velocity += impulse / Mass; + NetImpulse += impulse / Mass; + } + + public virtual void Stun(float time) + { + StunTime += time; } protected void DrawTarget() @@ -134,6 +151,20 @@ namespace SupaLidlGame.Characters Inventory.Rotation = angle; } + public void UseCurrentItem() + { + if (StunTime > 0) + { + GD.Print("tried to use weapon but stunned"); + return; + } + + if (Inventory.SelectedItem is Weapon weapon) + { + weapon.Use(); + } + } + public void _on_hurtbox_received_damage(float damage, Character inflictor, float knockback, @@ -141,7 +172,13 @@ namespace SupaLidlGame.Characters Vector2 knockbackVector = default) { Health -= damage; - /* + + var textScene = GD.Load("res://UI/FloatingText.tscn"); + var instance = textScene.Instantiate(); + instance.Text = Mathf.Round(damage).ToString(); + instance.GlobalPosition = GlobalPosition; + this.GetAncestor().AddChild(instance); + Vector2 knockbackDir = knockbackVector; if (knockbackDir == default) { @@ -153,8 +190,14 @@ namespace SupaLidlGame.Characters knockbackDir = knockbackOrigin.DirectionTo(GlobalPosition); } - ApplyImpulse(knockback.) - */ + var player = GetNode("FlashAnimation"); + if (player != null) + { + player.Stop(); + player.Play("Hurt"); + } + + ApplyImpulse(knockbackDir.Normalized() * knockback); } } } diff --git a/Characters/ExampleEnemy.tscn b/Characters/ExampleEnemy.tscn index 785d6a4..c8f133d 100644 --- a/Characters/ExampleEnemy.tscn +++ b/Characters/ExampleEnemy.tscn @@ -1,40 +1,47 @@ -[gd_scene load_steps=19 format=3 uid="uid://dymwd5ihpwyqm"] +[gd_scene load_steps=24 format=3 uid="uid://ddcf6bfv212wj"] [ext_resource type="Script" path="res://Characters/Enemy.cs" id="1_2yopk"] -[ext_resource type="Texture2D" uid="uid://dxymfduyrbuvx" path="res://Sprites/Characters/forsen.png" id="2_jfku3"] +[ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="1_fx1w5"] [ext_resource type="Script" path="res://Characters/States/Machine.cs" id="3_k4ypw"] +[ext_resource type="Texture2D" uid="uid://dxymfduyrbuvx" path="res://Assets/Sprites/Characters/forsen.png" id="3_oxsgl"] [ext_resource type="Script" path="res://Characters/States/NPCIdleState.cs" id="4_8r2qn"] [ext_resource type="Script" path="res://Characters/States/NPCMoveState.cs" id="5_utogm"] [ext_resource type="PackedScene" uid="uid://cjgxyhgcyvsv7" path="res://BoundingBoxes/Hurtbox.tscn" id="6_jo0cg"] [ext_resource type="Script" path="res://Items/Inventory.cs" id="7_43gq8"] -[ext_resource type="PackedScene" uid="uid://cajlwb67xenfy" path="res://Items/Weapons/Sword.tscn" id="8_s3c8r"] +[ext_resource type="PackedScene" uid="uid://d72ehtv1ks0e" path="res://Items/Weapons/Sword.tscn" id="8_s3c8r"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_8jbxb"] +resource_local_to_scene = true +shader = ExtResource("1_fx1w5") +shader_parameter/color = null +shader_parameter/intensity = 0.0 [sub_resource type="AtlasTexture" id="AtlasTexture_6d2tf"] -atlas = ExtResource("2_jfku3") +atlas = ExtResource("3_oxsgl") region = Rect2(0, 0, 24, 24) [sub_resource type="AtlasTexture" id="AtlasTexture_bdyma"] -atlas = ExtResource("2_jfku3") +atlas = ExtResource("3_oxsgl") region = Rect2(24, 0, 24, 24) [sub_resource type="AtlasTexture" id="AtlasTexture_0dwbr"] -atlas = ExtResource("2_jfku3") +atlas = ExtResource("3_oxsgl") region = Rect2(48, 0, 24, 24) [sub_resource type="AtlasTexture" id="AtlasTexture_r7fn6"] -atlas = ExtResource("2_jfku3") +atlas = ExtResource("3_oxsgl") region = Rect2(72, 0, 24, 24) [sub_resource type="AtlasTexture" id="AtlasTexture_py8k0"] -atlas = ExtResource("2_jfku3") +atlas = ExtResource("3_oxsgl") region = Rect2(96, 0, 24, 24) [sub_resource type="AtlasTexture" id="AtlasTexture_g3nb2"] -atlas = ExtResource("2_jfku3") +atlas = ExtResource("3_oxsgl") region = Rect2(120, 0, 24, 24) [sub_resource type="AtlasTexture" id="AtlasTexture_jauql"] -atlas = ExtResource("2_jfku3") +atlas = ExtResource("3_oxsgl") region = Rect2(144, 0, 24, 24) [sub_resource type="SpriteFrames" id="SpriteFrames_4tm2b"] @@ -56,16 +63,57 @@ size = Vector2(16, 8) [sub_resource type="RectangleShape2D" id="RectangleShape2D_8lxmf"] size = Vector2(16, 24) +[sub_resource type="Animation" id="Animation_dxevc"] +resource_name = "Hurt" +length = 0.6 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:material:shader_parameter/intensity") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6), +"transitions": PackedFloat32Array(4, 4, 4, 4, 4, 4, 4), +"update": 0, +"values": [0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0] +} + +[sub_resource type="Animation" id="Animation_k6l16"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:material:shader_parameter/intensity") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_xe5eq"] +_data = { +"Hurt": SubResource("Animation_dxevc"), +"RESET": SubResource("Animation_k6l16") +} + [node name="ExampleEnemy" type="CharacterBody2D" node_paths=PackedStringArray("Sprite", "Inventory", "StateMachine")] texture_filter = 3 +material = SubResource("ShaderMaterial_8jbxb") y_sort_enabled = true +collision_layer = 2 script = ExtResource("1_2yopk") +Health = 50.0 Sprite = NodePath("Sprite") Inventory = NodePath("Inventory") StateMachine = NodePath("StateMachine") Faction = 2 [node name="Sprite" type="AnimatedSprite2D" parent="."] +use_parent_material = true frames = SubResource("SpriteFrames_4tm2b") animation = &"move" playing = true @@ -98,6 +146,12 @@ y_sort_enabled = true script = ExtResource("7_43gq8") [node name="Sword" parent="Inventory" instance=ExtResource("8_s3c8r")] +Knockback = 40.0 + +[node name="FlashAnimation" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_xe5eq") +} [connection signal="ReceivedDamage" from="Hurtbox" to="." method="_on_hurtbox_received_damage"] diff --git a/Characters/NPC.cs b/Characters/NPC.cs index 62b7213..024b79b 100644 --- a/Characters/NPC.cs +++ b/Characters/NPC.cs @@ -47,6 +47,7 @@ namespace SupaLidlGame.Characters public override void _Draw() { + #if DEBUG for (int i = 0; i < 16; i++) { Vector2 vec = _weightDirs[i] * _weights[i] * 128; @@ -62,6 +63,7 @@ namespace SupaLidlGame.Characters } DrawLine(Vector2.Zero, vec, c); } + #endif base._Draw(); } @@ -93,7 +95,8 @@ namespace SupaLidlGame.Characters Think(); } - Direction = _weightDirs[_bestWeightIdx]; + Direction = Target; + //Direction = _weightDirs[_bestWeightIdx]; } protected virtual void Think() @@ -105,14 +108,13 @@ namespace SupaLidlGame.Characters if (Target.LengthSquared() < 1024) { - GD.Print("lol"); if (Inventory.SelectedItem is Weapon weapon) { - GD.Print("use"); - weapon.Use(); + UseCurrentItem(); } } + #if DEBUGs for (int i = 0; i < 16; i++) { float directDot = _weightDirs[i].Dot(dir); @@ -203,6 +205,7 @@ namespace SupaLidlGame.Characters } QueueRedraw(); + #endif } } } diff --git a/Characters/Player.cs b/Characters/Player.cs index 9b94b8c..256e83d 100644 --- a/Characters/Player.cs +++ b/Characters/Player.cs @@ -1,5 +1,4 @@ using Godot; -using SupaLidlGame.Items; namespace SupaLidlGame.Characters { @@ -43,21 +42,18 @@ namespace SupaLidlGame.Characters Velocity *= 2; } - if (Inventory.SelectedItem is Weapon weapon) - { - /*if (weapon is Sword sword) - { - if (sword.IsAttacking) - { - Velocity *= 0.5f; - } - } - else*/ - if (weapon.IsUsing) - { - Velocity *= 0.75f; - } - } + base.ModifyVelocity(); + } + + public override void Stun(float time) + { + base.Stun(time); + // TODO: implement visual effects for stun + } + + public override void Die() + { + //base.Die(); } } } diff --git a/Characters/Player.tscn b/Characters/Player.tscn index 789082e..64158a7 100644 --- a/Characters/Player.tscn +++ b/Characters/Player.tscn @@ -1,42 +1,47 @@ -[gd_scene load_steps=22 format=3 uid="uid://bncaar8vp3b84"] +[gd_scene load_steps=26 format=3 uid="uid://b2254pup8k161"] [ext_resource type="Script" path="res://Characters/Player.cs" id="1_flygr"] -[ext_resource type="Texture2D" uid="uid://dxymfduyrbuvx" path="res://Sprites/Characters/forsen.png" id="2_swjho"] +[ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="2_ngsgt"] +[ext_resource type="Texture2D" uid="uid://dxymfduyrbuvx" path="res://Assets/Sprites/Characters/forsen.png" id="3_ig4hs"] [ext_resource type="Script" path="res://Characters/States/Machine.cs" id="3_npkjp"] [ext_resource type="Script" path="res://Characters/States/PlayerIdleState.cs" id="4_4k4mb"] [ext_resource type="Script" path="res://Characters/States/PlayerMoveState.cs" id="5_tx5rw"] [ext_resource type="Script" path="res://Characters/States/PlayerRollState.cs" id="6_6bgrj"] -[ext_resource type="Script" path="res://Characters/States/PlayerAttackState.cs" id="7_4cuhw"] -[ext_resource type="PackedScene" uid="uid://cajlwb67xenfy" path="res://Items/Weapons/Sword.tscn" id="7_4rxuv"] +[ext_resource type="PackedScene" uid="uid://d72ehtv1ks0e" path="res://Items/Weapons/Sword.tscn" id="7_4rxuv"] [ext_resource type="Script" path="res://Items/Inventory.cs" id="7_xyenu"] [ext_resource type="PackedScene" uid="uid://cjgxyhgcyvsv7" path="res://BoundingBoxes/Hurtbox.tscn" id="9_avyu4"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_h78y7"] +shader = ExtResource("2_ngsgt") +shader_parameter/color = null +shader_parameter/intensity = 0.0 + [sub_resource type="AtlasTexture" id="AtlasTexture_us1ce"] -atlas = ExtResource("2_swjho") +atlas = ExtResource("3_ig4hs") region = Rect2(0, 0, 24, 24) [sub_resource type="AtlasTexture" id="AtlasTexture_hn4kf"] -atlas = ExtResource("2_swjho") +atlas = ExtResource("3_ig4hs") region = Rect2(24, 0, 24, 24) [sub_resource type="AtlasTexture" id="AtlasTexture_wfbeq"] -atlas = ExtResource("2_swjho") +atlas = ExtResource("3_ig4hs") region = Rect2(48, 0, 24, 24) [sub_resource type="AtlasTexture" id="AtlasTexture_qlmwk"] -atlas = ExtResource("2_swjho") +atlas = ExtResource("3_ig4hs") region = Rect2(72, 0, 24, 24) [sub_resource type="AtlasTexture" id="AtlasTexture_l1vgu"] -atlas = ExtResource("2_swjho") +atlas = ExtResource("3_ig4hs") region = Rect2(96, 0, 24, 24) [sub_resource type="AtlasTexture" id="AtlasTexture_ytlaa"] -atlas = ExtResource("2_swjho") +atlas = ExtResource("3_ig4hs") region = Rect2(120, 0, 24, 24) [sub_resource type="AtlasTexture" id="AtlasTexture_1q30d"] -atlas = ExtResource("2_swjho") +atlas = ExtResource("3_ig4hs") region = Rect2(144, 0, 24, 24) [sub_resource type="SpriteFrames" id="SpriteFrames_2h7cf"] @@ -61,18 +66,59 @@ font_size = 24 [sub_resource type="RectangleShape2D" id="RectangleShape2D_cjk6b"] size = Vector2(16, 24) +[sub_resource type="Animation" id="Animation_dxevc"] +resource_name = "Hurt" +length = 0.6 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:material:shader_parameter/intensity") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6), +"transitions": PackedFloat32Array(4, 4, 4, 4, 4, 4, 4), +"update": 0, +"values": [0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0] +} + +[sub_resource type="Animation" id="Animation_k6l16"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:material:shader_parameter/intensity") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_xe5eq"] +_data = { +"Hurt": SubResource("Animation_dxevc"), +"RESET": SubResource("Animation_k6l16") +} + [node name="Player" type="CharacterBody2D" node_paths=PackedStringArray("Sprite", "Inventory", "StateMachine")] texture_filter = 3 +material = SubResource("ShaderMaterial_h78y7") y_sort_enabled = true +collision_layer = 2 script = ExtResource("1_flygr") Speed = 64.0 Mass = 1.0 +Health = 100.0 Sprite = NodePath("Sprite") Inventory = NodePath("Inventory") StateMachine = NodePath("StateMachine") Faction = 1 [node name="Sprite" type="AnimatedSprite2D" parent="."] +use_parent_material = true frames = SubResource("SpriteFrames_2h7cf") animation = &"move" playing = true @@ -105,10 +151,6 @@ IdleState = NodePath("../Idle") script = ExtResource("6_6bgrj") IdleState = NodePath("../Idle") -[node name="Attack" type="Node" parent="StateMachine" node_paths=PackedStringArray("IdleState")] -script = ExtResource("7_4cuhw") -IdleState = NodePath("../Idle") - [node name="Debug" type="Control" parent="."] layout_mode = 3 anchors_preset = 0 @@ -136,6 +178,11 @@ Faction = 1 [node name="CollisionShape2D" parent="Hurtbox" index="0"] shape = SubResource("RectangleShape2D_cjk6b") +[node name="FlashAnimation" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_xe5eq") +} + [connection signal="ReceivedDamage" from="Hurtbox" to="." method="_on_hurtbox_received_damage"] [editable path="Hurtbox"] diff --git a/Characters/States/CharacterState.cs b/Characters/States/CharacterState.cs index 185a6d0..37f8608 100644 --- a/Characters/States/CharacterState.cs +++ b/Characters/States/CharacterState.cs @@ -22,13 +22,32 @@ namespace SupaLidlGame.Characters.State /// public virtual void Exit(CharacterState nextState) { } - public virtual CharacterState Process(double delta) => null; + public virtual CharacterState Process(double delta) + { + if (Character.StunTime > 0) + { + Character.StunTime -= delta; + } + return null; + } public virtual CharacterState PhysicsProcess(double delta) { - Character.Velocity = Character.Direction * Character.Speed; + Character.Velocity = Character.NetImpulse; + + if (Character.NetImpulse.LengthSquared() < Mathf.Pow(Character.Speed, 2)) + { + Character.Velocity += Character.Direction.Normalized() + * Character.Speed; + } + + Character.NetImpulse = Character.NetImpulse.MoveToward( + Vector2.Zero, + (float)delta * Character.Speed * Character.Friction); + Character.ModifyVelocity(); Character.MoveAndSlide(); + return null; } diff --git a/Characters/States/PlayerState.cs b/Characters/States/PlayerState.cs index b15283f..a5cdf2c 100644 --- a/Characters/States/PlayerState.cs +++ b/Characters/States/PlayerState.cs @@ -32,7 +32,8 @@ namespace SupaLidlGame.Characters.State { if (Character.Inventory.SelectedItem is not null) { - Character.Inventory.SelectedItem.Use(); + Character.UseCurrentItem(); + //Character.Inventory.SelectedItem.Use(); //return AttackState; } } @@ -61,6 +62,7 @@ namespace SupaLidlGame.Characters.State Character.Target = dirToMouse; } } + return base.Process(delta); } } diff --git a/Extensions/Node.cs b/Extensions/Node.cs new file mode 100644 index 0000000..c8bd05c --- /dev/null +++ b/Extensions/Node.cs @@ -0,0 +1,28 @@ +using Godot; + +namespace SupaLidlGame.Extensions +{ + public static class NodeExtensions + { + /// + /// Iterates through each ancestor until it finds an ancestor of type + /// T + /// + public static T GetAncestor(this Node node) where T : Node + { + Node parent; + + while ((parent = node.GetParent()) != null) + { + if (parent is T t) + { + return t; + } + + node = parent; + } + + return null; + } + } +} diff --git a/Items/Weapon.cs b/Items/Weapon.cs index 1c6619a..bdac648 100644 --- a/Items/Weapon.cs +++ b/Items/Weapon.cs @@ -1,4 +1,5 @@ using Godot; +using SupaLidlGame.BoundingBoxes; using SupaLidlGame.Characters; namespace SupaLidlGame.Items @@ -34,6 +35,16 @@ namespace SupaLidlGame.Items [Export] public float InitialVelocity { get; set; } = 0; + /// + /// Whether or not the weapon can parry other weapons and is + /// parryable by other weapons. + /// + public virtual bool IsParryable { get; protected set; } = false; + + public bool IsParried { get; set; } + + public ulong ParryTimeOrigin { get; protected set; } + public Character Character { get; set; } public override void Equip(Character character) @@ -66,5 +77,13 @@ namespace SupaLidlGame.Items } } } + + public virtual void _on_hitbox_hit(BoundingBox box) + { + if (box is Hurtbox hurtbox) + { + hurtbox.InflictDamage(Damage, Character, Knockback); + } + } } } diff --git a/Items/Weapons/Sword.cs b/Items/Weapons/Sword.cs index b6c115f..012666d 100644 --- a/Items/Weapons/Sword.cs +++ b/Items/Weapons/Sword.cs @@ -1,14 +1,13 @@ using Godot; using SupaLidlGame.BoundingBoxes; using SupaLidlGame.Characters; +using SupaLidlGame.Extensions; namespace SupaLidlGame.Items.Weapons { public partial class Sword : Weapon { - public double RemainingAttackTime { get; protected set; } = 0; - - public bool IsAttacking => RemainingAttackTime > 0; + public bool IsAttacking { get; protected set; } [Export] public Hitbox Hitbox { get; set; } @@ -26,6 +25,11 @@ namespace SupaLidlGame.Items.Weapons [Export] public double AttackTime { get; set; } = 0; + [Export] + public CPUParticles2D ParryParticles { get; set; } + + public override bool IsParryable { get; protected set; } + public override void Equip(Character character) { Visible = true; @@ -46,24 +50,46 @@ namespace SupaLidlGame.Items.Weapons return; } - RemainingAttackTime = AttackTime; + IsParried = false; + + AnimationPlayer.Stop(); + + if (GetNode("Anchor").Rotation < Mathf.DegToRad(50)) + { + AnimationPlayer.Play("use"); + } + else + { + AnimationPlayer.Play("use2"); + } - AnimationPlayer.Play("use"); - Hitbox.IsDisabled = false; base.Use(); } public override void Deuse() { - AnimationPlayer.Stop(); + //AnimationPlayer.Stop(); Deattack(); base.Deuse(); } - protected void Deattack() + public void Attack() { + ParryTimeOrigin = Time.GetTicksMsec(); + IsParryable = true; + //RemainingAttackTime = AttackTime; + IsAttacking = true; + Hitbox.IsDisabled = false; + } + + public void Deattack() + { + IsAttacking = false; + IsParryable = false; Hitbox.IsDisabled = true; + ProcessHits(); Hitbox.ResetIgnoreList(); + AnimationPlayer.PlaybackSpeed = 1; } public override void _Ready() @@ -73,6 +99,7 @@ namespace SupaLidlGame.Items.Weapons public override void _Process(double delta) { + /* if (RemainingAttackTime > 0) { if ((RemainingAttackTime -= delta) <= 0) @@ -80,7 +107,73 @@ namespace SupaLidlGame.Items.Weapons Deattack(); } } + */ base._Process(delta); } + + public void ProcessHits() + { + if (IsParried) + { + return; + } + + foreach (BoundingBox box in Hitbox.Hits) + { + GD.Print("processing hit"); + if (box is Hurtbox hurtbox) + { + hurtbox.InflictDamage(Damage, Character, Knockback); + } + } + } + + public void AttemptParry(Weapon otherWeapon) + { + if (IsParryable && otherWeapon.IsParryable) + { + ParryParticles.Emitting = true; + if (ParryTimeOrigin < otherWeapon.ParryTimeOrigin) + { + // our character was parried + IsParried = true; + AnimationPlayer.PlaybackSpeed = 0.25f; + Character.Stun(1.5f); + } + } + //this.GetAncestor().AddChild(instance); + } + + public override void _on_hitbox_hit(BoundingBox box) + { + if (IsParried) + { + return; + } + + if (box is Hitbox hb) + { + Weapon w = hb.GetAncestor(); + if (w is not null) + { + //Vector2 a = new Vector2(2, 2) * new Vector2(5, 2); + AttemptParry(w); + } + } + + if (box is Hurtbox hurt) + { + if (hurt.GetParent() is Character c) + { + var item = c.Inventory.SelectedItem; + if (item is Weapon w) + { + AttemptParry(w); + } + } + } + + //base._on_hitbox_hit(box); + } } } diff --git a/Items/Weapons/Sword.tscn b/Items/Weapons/Sword.tscn index f6496dc..cee317b 100644 --- a/Items/Weapons/Sword.tscn +++ b/Items/Weapons/Sword.tscn @@ -1,13 +1,14 @@ -[gd_scene load_steps=13 format=3 uid="uid://cajlwb67xenfy"] +[gd_scene load_steps=16 format=3 uid="uid://d72ehtv1ks0e"] [ext_resource type="Script" path="res://Items/Weapons/Sword.cs" id="1_mlo73"] -[ext_resource type="Texture2D" uid="uid://dt6u8p4h6g7le" path="res://Sprites/knife.png" id="2_dmsp2"] +[ext_resource type="Texture2D" uid="uid://dt6u8p4h6g7le" path="res://Assets/Sprites/knife.png" id="2_rnfo4"] [ext_resource type="PackedScene" uid="uid://du5vhccg75nrq" path="res://BoundingBoxes/Hitbox.tscn" id="3_up3ob"] [ext_resource type="PackedScene" uid="uid://cojxmcin13ihm" path="res://Utils/Trail.tscn" id="4_pt6lq"] +[ext_resource type="Texture2D" uid="uid://do1bui3bblkk7" path="res://Assets/Sprites/sword-swing.png" id="5_pywek"] -[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_yln58"] -radius = 8.0 -height = 32.0 +[sub_resource type="Gradient" id="Gradient_jjxq2"] +offsets = PackedFloat32Array(0, 0.945312) +colors = PackedColorArray(1, 1, 1, 1, 0.687215, 0.687215, 0.687215, 0) [sub_resource type="Curve" id="Curve_4cxtp"] _data = [Vector2(0.00687286, 1), 0.0, 0.0, 0, 0, Vector2(0.879725, 0.190909), -2.93145, -2.93145, 0, 0, Vector2(1, 0.0454545), 0.0483926, 0.0, 0, 0] @@ -29,31 +30,19 @@ tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 0, -"values": [-0.785398] +"values": [-1.0472] } tracks/1/type = "value" tracks/1/imported = false tracks/1/enabled = true -tracks/1/path = NodePath("Anchor/Sprite2D:rotation") +tracks/1/path = NodePath("SwingSprite:frame") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), -"update": 0, -"values": [-1.19209e-07] -} -tracks/2/type = "value" -tracks/2/imported = false -tracks/2/enabled = true -tracks/2/path = NodePath("Anchor/Sprite2D:position") -tracks/2/interp = 1 -tracks/2/loop_wrap = true -tracks/2/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Vector2(8, 1)] +"update": 1, +"values": [0] } [sub_resource type="Animation" id="Animation_mv7y2"] @@ -61,8 +50,7 @@ resource_name = "idle" [sub_resource type="Animation" id="Animation_orc8t"] resource_name = "use" -length = 0.5 -loop_mode = 1 +length = 0.75 step = 0.05 tracks/0/type = "value" tracks/0/imported = false @@ -71,77 +59,142 @@ tracks/0/path = NodePath("Anchor:rotation") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { -"times": PackedFloat32Array(0, 0.1, 0.3, 0.5), -"transitions": PackedFloat32Array(1, 1, 1, 1), +"times": PackedFloat32Array(0.05, 0.1, 0.2, 0.4, 0.75), +"transitions": PackedFloat32Array(1, 4, 1, 2, 1), "update": 0, -"values": [-0.785398, 1.5708, 1.5708, -0.785398] +"values": [-0.610865, -0.959931, 3.92699, 3.92699, 3.75246] } -tracks/1/type = "value" +tracks/1/type = "method" tracks/1/imported = false tracks/1/enabled = true -tracks/1/path = NodePath("Anchor/Sprite2D:rotation") +tracks/1/path = NodePath(".") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { -"times": PackedFloat32Array(0, 0.1, 0.3, 0.5), -"transitions": PackedFloat32Array(1, 1, 1, 1), -"update": 0, -"values": [-1.19209e-07, 0.785398, 0.785398, -1.19209e-07] +"times": PackedFloat32Array(0.05, 0.25), +"transitions": PackedFloat32Array(1, 1), +"values": [{ +"args": [], +"method": &"Attack" +}, { +"args": [], +"method": &"Deattack" +}] } tracks/2/type = "value" tracks/2/imported = false tracks/2/enabled = true -tracks/2/path = NodePath("Anchor/Sprite2D:position") +tracks/2/path = NodePath("SwingSprite:frame") tracks/2/interp = 1 tracks/2/loop_wrap = true tracks/2/keys = { -"times": PackedFloat32Array(0, 0.1, 0.3, 0.5), +"times": PackedFloat32Array(0, 0.2, 0.3, 0.4), "transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 1, +"values": [0, 1, 2, 0] +} + +[sub_resource type="Animation" id="Animation_y4mj3"] +resource_name = "use2" +length = 0.75 +step = 0.05 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Anchor:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0.05, 0.1, 0.2, 0.4, 0.75), +"transitions": PackedFloat32Array(1, 4, 1, 2, 1), "update": 0, -"values": [Vector2(8, 1), Vector2(12, -1), Vector2(12, -1), Vector2(8, 1)] +"values": [3.75246, 4.10152, -0.785398, -0.785398, -0.610865] +} +tracks/1/type = "method" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath(".") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0.05, 0.25), +"transitions": PackedFloat32Array(1, 1), +"values": [{ +"args": [], +"method": &"Attack" +}, { +"args": [], +"method": &"Deattack" +}] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("SwingSprite:frame") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3, 0.4), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 1, +"values": [0, 1, 3, 0] } [sub_resource type="AnimationLibrary" id="AnimationLibrary_tao4k"] _data = { "RESET": SubResource("Animation_b7327"), "idle": SubResource("Animation_mv7y2"), -"use": SubResource("Animation_orc8t") +"use": SubResource("Animation_orc8t"), +"use2": SubResource("Animation_y4mj3") } [sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_1lid1"] -[node name="Sword" type="Node2D" node_paths=PackedStringArray("Hitbox", "AnimationPlayer")] +[sub_resource type="ConvexPolygonShape2D" id="ConvexPolygonShape2D_tv0o2"] +points = PackedVector2Array(-11.314, -11.314, 0, -16, 11.314, -11.314, 16, 0, 11.314, 11.314, 0, 16, -11.314, 11.314, 0, 0) + +[node name="Sword" type="Node2D" node_paths=PackedStringArray("Hitbox", "AnimationPlayer", "ParryParticles")] texture_filter = 3 y_sort_enabled = true script = ExtResource("1_mlo73") -Hitbox = NodePath("Anchor/Sprite2D/Hitbox") +Hitbox = NodePath("Hitbox") AnimationPlayer = NodePath("AnimationPlayer") AttackTime = 0.1 -Damage = 20.0 -UseTime = 0.5 +ParryParticles = NodePath("Anchor/Sprite2D/ParryParticles") +Damage = 30.0 +UseTime = 0.8 +Knockback = 80.0 Description = "A basic sword." [node name="Anchor" type="Node2D" parent="."] -rotation = -0.785398 +rotation = -1.0472 y_sort_enabled = true [node name="Sprite2D" type="Sprite2D" parent="Anchor"] -position = Vector2(8, 1) +position = Vector2(0, -8) y_sort_enabled = true -texture = ExtResource("2_dmsp2") +texture = ExtResource("2_rnfo4") -[node name="Hitbox" parent="Anchor/Sprite2D" instance=ExtResource("3_up3ob")] -IsDisabled = true - -[node name="CollisionShape2D" parent="Anchor/Sprite2D/Hitbox" index="0"] -position = Vector2(0, -4) -shape = SubResource("CapsuleShape2D_yln58") -disabled = true +[node name="ParryParticles" type="CPUParticles2D" parent="Anchor/Sprite2D"] +position = Vector2(-0.221825, -3.12132) +rotation = 0.785398 +emitting = false +amount = 12 +lifetime = 0.4 +one_shot = true +explosiveness = 1.0 +emission_shape = 1 +emission_sphere_radius = 4.0 +direction = Vector2(0, -1) +spread = 180.0 +gravity = Vector2(0, 200) +initial_velocity_min = 8.0 +initial_velocity_max = 64.0 +color_ramp = SubResource("Gradient_jjxq2") [node name="Trail" parent="Anchor" node_paths=PackedStringArray("Tracking") instance=ExtResource("4_pt6lq")] position = Vector2(2.40734, -0.55655) rotation = 0.945464 -scale = Vector2(1, 1) width_curve = SubResource("Curve_4cxtp") gradient = SubResource("Gradient_2ablm") Tracking = NodePath("../Sprite2D") @@ -156,4 +209,21 @@ tree_root = SubResource("AnimationNodeAnimation_1lid1") anim_player = NodePath("../AnimationPlayer") active = true -[editable path="Anchor/Sprite2D/Hitbox"] +[node name="Hitbox" parent="." instance=ExtResource("3_up3ob")] +IsDisabled = true + +[node name="CollisionShape2D" parent="Hitbox" index="0"] +shape = SubResource("ConvexPolygonShape2D_tv0o2") +disabled = true + +[node name="SwingSprite" type="Sprite2D" parent="."] +texture = ExtResource("5_pywek") +hframes = 4 + +[node name="SwingSound" type="AudioStreamPlayer2D" parent="."] + +[node name="ParrySound" type="AudioStreamPlayer2D" parent="."] + +[connection signal="Hit" from="Hitbox" to="." method="_on_hitbox_hit"] + +[editable path="Hitbox"] diff --git a/Scenes/Level.tscn b/Scenes/Level.tscn index 2603503..9f8040e 100644 --- a/Scenes/Level.tscn +++ b/Scenes/Level.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=6 format=3 uid="uid://cbsosmpnenfwu"] +[gd_scene load_steps=8 format=3 uid="uid://dd6xy1y0m8smm"] -[ext_resource type="Texture2D" uid="uid://gm2pcnfg7h8j" path="res://Sprites/tileset.png" id="1_k6myx"] -[ext_resource type="PackedScene" uid="uid://bncaar8vp3b84" path="res://Characters/Player.tscn" id="1_m35hr"] -[ext_resource type="PackedScene" uid="uid://dymwd5ihpwyqm" path="res://Characters/ExampleEnemy.tscn" id="2_uti3y"] +[ext_resource type="Texture2D" uid="uid://gm2pcnfg7h8j" path="res://Assets/Sprites/tileset.png" id="1_k6myx"] +[ext_resource type="PackedScene" uid="uid://b2254pup8k161" path="res://Characters/Player.tscn" id="1_m35hr"] +[ext_resource type="PackedScene" uid="uid://ddcf6bfv212wj" path="res://Characters/ExampleEnemy.tscn" id="2_uti3y"] +[ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="4_056cf"] [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_1pa1q"] texture = ExtResource("1_k6myx") @@ -1100,6 +1101,12 @@ texture = ExtResource("1_k6myx") physics_layer_0/collision_layer = 1 sources/0 = SubResource("TileSetAtlasSource_1pa1q") +[sub_resource type="ShaderMaterial" id="ShaderMaterial_mq5wa"] +resource_local_to_scene = true +shader = ExtResource("4_056cf") +shader_parameter/color = null +shader_parameter/intensity = 0.0 + [node name="Level" type="Node2D"] [node name="TileMap" type="TileMap" parent="."] @@ -1137,13 +1144,11 @@ position = Vector2(-81, -34) motion_mode = 1 [node name="ExampleEnemy" parent="TileMap" instance=ExtResource("2_uti3y")] +material = SubResource("ShaderMaterial_mq5wa") position = Vector2(38, 42) scale = Vector2(1.00571, 1) [node name="ExampleEnemy2" parent="TileMap" instance=ExtResource("2_uti3y")] -position = Vector2(156, 58) -scale = Vector2(1.00571, 1) - -[node name="ExampleEnemy3" parent="TileMap" instance=ExtResource("2_uti3y")] -position = Vector2(175, -15) +material = SubResource("ShaderMaterial_mq5wa") +position = Vector2(190, 99) scale = Vector2(1.00571, 1) diff --git a/Shaders/Flash.gdshader b/Shaders/Flash.gdshader new file mode 100644 index 0000000..46a0666 --- /dev/null +++ b/Shaders/Flash.gdshader @@ -0,0 +1,10 @@ +shader_type canvas_item; + +uniform vec4 color = vec4(1.0); +uniform float intensity : hint_range(0.0, 1.0) = 0.0; + +void fragment() { + vec4 tex = texture(TEXTURE, UV); + tex.rgb = mix(tex.rgb, color.rgb, intensity); + COLOR = tex; +} \ No newline at end of file diff --git a/UI/FloatingText.cs b/UI/FloatingText.cs new file mode 100644 index 0000000..b36c31c --- /dev/null +++ b/UI/FloatingText.cs @@ -0,0 +1,51 @@ +using Godot; +using System; + +namespace SupaLidlGame.UI +{ + public partial class FloatingText : Node2D + { + private Label _label; + + [Export] + public string Text { get; set; } + + public override void _Ready() + { + _label = GetNode