diff --git a/Scenes/Scanline.tres b/Scenes/Scanline.tres new file mode 100644 index 00000000..4fca427d --- /dev/null +++ b/Scenes/Scanline.tres @@ -0,0 +1,169 @@ +[gd_resource type="VisualShader" load_steps=15 format=3 uid="uid://bjp77nc6cbjfa"] + +[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_lj28b"] +default_input_values = [0, 0.0, 1, 20.0] +operator = 2 + +[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_3u088"] + +[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_4dkgw"] +default_input_values = [0, 0.0, 1, 5.0] +operator = 2 + +[sub_resource type="VisualShaderNodeFloatFunc" id="VisualShaderNodeFloatFunc_uxvhh"] +function = 0 + +[sub_resource type="VisualShaderNodeRemap" id="VisualShaderNodeRemap_81uiw"] +default_input_values = [1, 0.0, 2, 1.0, 3, 0.2, 4, 0.7] + +[sub_resource type="VisualShaderNodeRemap" id="VisualShaderNodeRemap_8lgdt"] + +[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_gga1y"] +input_name = "uv" + +[sub_resource type="VisualShaderNodeVectorDecompose" id="VisualShaderNodeVectorDecompose_drjer"] +default_input_values = [0, Vector2(0, 0)] +op_type = 0 + +[sub_resource type="VisualShaderNodeFloatOp" id="VisualShaderNodeFloatOp_yticp"] +default_input_values = [0, 0.0, 1, 300.0] +operator = 2 + +[sub_resource type="VisualShaderNodeFloatFunc" id="VisualShaderNodeFloatFunc_ddbac"] +function = 0 + +[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_xhnjp"] +input_name = "texture" + +[sub_resource type="VisualShaderNodeTexture" id="VisualShaderNodeTexture_07hhb"] +expanded_output_ports = [0] +source = 5 + +[sub_resource type="VisualShaderNodeMix" id="VisualShaderNodeMix_kljpx"] + +[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_hxwd7"] +input_name = "time" + +[resource] +code = "shader_type canvas_item; +render_mode blend_mix; + + + + +void fragment() { +// Input:2 + vec2 n_out2p0 = UV; + + +// VectorDecompose:3 + float n_out3p0 = n_out2p0.x; + float n_out3p1 = n_out2p0.y; + + +// FloatOp:4 + float n_in4p1 = 300.00000; + float n_out4p0 = n_out3p1 * n_in4p1; + + +// Input:9 + float n_out9p0 = TIME; + + +// FloatOp:10 + float n_in10p1 = 20.00000; + float n_out10p0 = n_out9p0 * n_in10p1; + + +// FloatOp:11 + float n_out11p0 = n_out4p0 + n_out10p0; + + +// FloatFunc:5 + float n_out5p0 = sin(n_out11p0); + + +// FloatOp:12 + float n_in12p1 = 5.00000; + float n_out12p0 = n_out9p0 * n_in12p1; + + +// FloatFunc:13 + float n_out13p0 = sin(n_out12p0); + + + float n_out14p0; +// Remap:14 + float n_in14p1 = 0.00000; + float n_in14p2 = 1.00000; + float n_in14p3 = 0.20000; + float n_in14p4 = 0.70000; + { + float __input_range = n_in14p2 - n_in14p1; + float __output_range = n_in14p4 - n_in14p3; + n_out14p0 = n_in14p3 + __output_range * ((n_out13p0 - n_in14p1) / __input_range); + } + + + float n_out15p0; +// Remap:15 + float n_in15p1 = 0.00000; + float n_in15p2 = 1.00000; + float n_in15p4 = 1.00000; + { + float __input_range = n_in15p2 - n_in15p1; + float __output_range = n_in15p4 - n_out14p0; + n_out15p0 = n_out14p0 + __output_range * ((n_out5p0 - n_in15p1) / __input_range); + } + + + vec4 n_out7p0; +// Texture2D:7 + n_out7p0 = texture(TEXTURE, UV); + float n_out7p4 = n_out7p0.a; + + +// Mix:8 + float n_in8p0 = 0.00000; + float n_out8p0 = mix(n_in8p0, n_out15p0, n_out7p4); + + +// Output:0 + COLOR.a = n_out8p0; + + +} +" +graph_offset = Vector2(-6.8877, 111.307) +mode = 1 +flags/light_only = false +nodes/fragment/0/position = Vector2(2960, 500) +nodes/fragment/2/node = SubResource("VisualShaderNodeInput_gga1y") +nodes/fragment/2/position = Vector2(60, 240) +nodes/fragment/3/node = SubResource("VisualShaderNodeVectorDecompose_drjer") +nodes/fragment/3/position = Vector2(540, 80) +nodes/fragment/4/node = SubResource("VisualShaderNodeFloatOp_yticp") +nodes/fragment/4/position = Vector2(860, 220) +nodes/fragment/5/node = SubResource("VisualShaderNodeFloatFunc_ddbac") +nodes/fragment/5/position = Vector2(1620, 520) +nodes/fragment/6/node = SubResource("VisualShaderNodeInput_xhnjp") +nodes/fragment/6/position = Vector2(320, 1000) +nodes/fragment/7/node = SubResource("VisualShaderNodeTexture_07hhb") +nodes/fragment/7/position = Vector2(1620, 1000) +nodes/fragment/8/node = SubResource("VisualShaderNodeMix_kljpx") +nodes/fragment/8/position = Vector2(2380, 740) +nodes/fragment/9/node = SubResource("VisualShaderNodeInput_hxwd7") +nodes/fragment/9/position = Vector2(840, 80) +nodes/fragment/10/node = SubResource("VisualShaderNodeFloatOp_lj28b") +nodes/fragment/10/position = Vector2(1380, 80) +nodes/fragment/11/node = SubResource("VisualShaderNodeFloatOp_3u088") +nodes/fragment/11/position = Vector2(1200, 500) +nodes/fragment/12/node = SubResource("VisualShaderNodeFloatOp_4dkgw") +nodes/fragment/12/position = Vector2(1740, -20) +nodes/fragment/13/node = SubResource("VisualShaderNodeFloatFunc_uxvhh") +nodes/fragment/13/position = Vector2(2040, 40) +nodes/fragment/14/node = SubResource("VisualShaderNodeRemap_81uiw") +nodes/fragment/14/position = Vector2(2540, 160) +nodes/fragment/15/node = SubResource("VisualShaderNodeRemap_8lgdt") +nodes/fragment/15/position = Vector2(2020, 360) +nodes/fragment/connections = PackedInt32Array(2, 0, 3, 0, 3, 1, 4, 0, 6, 0, 7, 2, 7, 4, 8, 2, 9, 0, 10, 0, 8, 0, 0, 1, 10, 0, 11, 1, 4, 0, 11, 0, 11, 0, 5, 0, 9, 0, 12, 0, 12, 0, 13, 0, 13, 0, 14, 0, 5, 0, 15, 0, 14, 0, 15, 3, 15, 0, 8, 1) diff --git a/Scenes/player.tscn b/Scenes/player.tscn index 9652a5b2..5e1e5c7a 100644 --- a/Scenes/player.tscn +++ b/Scenes/player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=36 format=3 uid="uid://bghghp5ep4w2j"] +[gd_scene load_steps=38 format=3 uid="uid://bghghp5ep4w2j"] [ext_resource type="Script" path="res://Scripts/PlayerMovement.cs" id="1_m27vu"] [ext_resource type="Texture2D" uid="uid://la06powu57hu" path="res://Sprites/Cirno_Big.png" id="2_bwf6x"] @@ -9,6 +9,7 @@ [ext_resource type="Script" path="res://addons/smoothing/smoothing_2d.gd" id="4_j4xhu"] [ext_resource type="Texture2D" uid="uid://ddwhrlrgj6i00" path="res://Sprites/Actors/Cirno.png" id="5_hq878"] [ext_resource type="PackedScene" uid="uid://cfb3nsay84xdb" path="res://Scenes/Weapons/crosshair.tscn" id="6_l43rf"] +[ext_resource type="Shader" path="res://Shaders/Blink.gdshader" id="6_xugve"] [ext_resource type="Texture2D" uid="uid://bf37ce6jskdel" path="res://Sprites/SmallHitbox.png" id="7_msn8i"] [ext_resource type="Script" path="res://Scenes/InteractionController.cs" id="7_uvgjg"] [ext_resource type="Texture2D" uid="uid://bwjrdlnysft15" path="res://Sprites/Actors/Focus_Circle.png" id="8_1og8b"] @@ -23,6 +24,14 @@ size = Vector2(6, 6) atlas = ExtResource("2_bwf6x") region = Rect2(0, 0, 8, 16) +[sub_resource type="ShaderMaterial" id="ShaderMaterial_s7co1"] +resource_local_to_scene = true +shader = ExtResource("6_xugve") +shader_parameter/blink_color = Color(1, 1, 1, 1) +shader_parameter/blink_intensity = 0.0 +shader_parameter/teleport_progress = 0.0 +shader_parameter/scanline_density = 0.0 + [sub_resource type="AtlasTexture" id="AtlasTexture_6tpxx"] atlas = ExtResource("5_hq878") region = Rect2(0, 0, 16, 16) @@ -175,6 +184,7 @@ SelectorScene = ExtResource("3_8wt6s") GameOverScene = "res://Scenes/GameOver.tscn" WingsSprite = ExtResource("3_ul15q") Muzzle = NodePath("Muzzle") +BlinkShader = ExtResource("6_xugve") HitboxSprite = NodePath("Smoothing2D/HitboxSprite") _deathParticles = ExtResource("4_1bl4h") metadata/_edit_group_ = true @@ -200,6 +210,7 @@ frame = 1 [node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="Smoothing2D" groups=["player_sprite"]] y_sort_enabled = true +material = SubResource("ShaderMaterial_s7co1") sprite_frames = SubResource("SpriteFrames_q0rt3") animation = &"walk_up" frame = 1 diff --git a/Scenes/test.tscn b/Scenes/test.tscn index c34829ef..493c7f82 100644 --- a/Scenes/test.tscn +++ b/Scenes/test.tscn @@ -138,7 +138,7 @@ ActivationType = 0 Targets = Array[NodePath]([NodePath("../Rumia")]) WaitForCompletion = true -[sub_resource type="Resource" id="Resource_cxaaj"] +[sub_resource type="Resource" id="Resource_tel42"] resource_local_to_scene = true script = ExtResource("49_0si7g") Target = NodePath(".") @@ -652,7 +652,7 @@ Events = Array[Object]([SubResource("Resource_068l7"), SubResource("Resource_l3n [node name="BossBattleStartScript" parent="." instance=ExtResource("43_kf3qc")] position = Vector2(-1487, -396) -Events = Array[Object]([SubResource("Resource_4f4id"), SubResource("Resource_s2o7m"), SubResource("Resource_b1dht"), SubResource("Resource_xrgpy"), SubResource("Resource_cxaaj")]) +Events = Array[Object]([SubResource("Resource_4f4id"), SubResource("Resource_s2o7m"), SubResource("Resource_b1dht"), SubResource("Resource_xrgpy"), SubResource("Resource_tel42")]) [node name="Enemy8" parent="." instance=ExtResource("47_u1ve6")] position = Vector2(-968, 206) diff --git a/Scripts/Activables/LevelTeleporter.cs b/Scripts/Activables/LevelTeleporter.cs index a2dfd0bf..3e2ef697 100644 --- a/Scripts/Activables/LevelTeleporter.cs +++ b/Scripts/Activables/LevelTeleporter.cs @@ -19,6 +19,8 @@ public partial class LevelTeleporter : Teleporter _particles.Emitting = true; + await player.Teleport(); + await Task.Delay((int)(TeleportAnimationLength * 1000)); GlobalState.Instance.GotoScene(LevelPath); diff --git a/Scripts/Activables/Teleporter.cs b/Scripts/Activables/Teleporter.cs index d86b5f64..0805115e 100644 --- a/Scripts/Activables/Teleporter.cs +++ b/Scripts/Activables/Teleporter.cs @@ -131,12 +131,17 @@ public partial class Teleporter : Activable await TweenPlayer(player); - Target.PrepareForReceiving(); + _particles.Emitting = true; + + await player.Teleport(); await Task.Delay((int)(TeleportAnimationLength * 1000)); + Target.PrepareForReceiving(); player.GlobalPosition = Target.GlobalPosition + TeleportOffset; + + await player.UnTeleport(); player.RequestMovementDisable(false); } diff --git a/Scripts/GameManager.cs b/Scripts/GameManager.cs index d80d26b3..5fc07ba3 100644 --- a/Scripts/GameManager.cs +++ b/Scripts/GameManager.cs @@ -165,6 +165,7 @@ public partial class GameManager : Node2D //_player.GlobalPosition = PlayerSpawnMarker.Position; CameraTargetPlayer(); + // // if (_cameraTarget != null) // { diff --git a/Scripts/PlayerMovement.cs b/Scripts/PlayerMovement.cs index 4586de9d..7f2aac45 100644 --- a/Scripts/PlayerMovement.cs +++ b/Scripts/PlayerMovement.cs @@ -7,6 +7,7 @@ using Cirno.Scripts.Components; using Cirno.Scripts.Components.Actors; using Cirno.Scripts.Resources; using Godot.Collections; +using System.Threading.Tasks; public partial class PlayerMovement : CharacterBody2D, IDestructible { @@ -49,6 +50,8 @@ public partial class PlayerMovement : CharacterBody2D, IDestructible [Export] public float MaxHealth = 32f; [Export] public float MaxShield = 32f; + [Export] public Shader BlinkShader {get;set;} + [ExportGroup("Action Names")] [Export] private string _shootActionName = "shoot"; [ExportGroup("Action Names")] @@ -182,6 +185,8 @@ public partial class PlayerMovement : CharacterBody2D, IDestructible } _lastCheckPointPosition = GlobalPosition; + + _ = UnTeleport(); } private void GameManagerOnGameStateChange(GameState state) @@ -483,12 +488,62 @@ public partial class PlayerMovement : CharacterBody2D, IDestructible } } + // Blink + //_animatedSprite + if (BlinkShader != null) + { + _ = Blink(); + } + if (!(CurrentHealth <= 0)) return; _isDestroyed = true; Explode(); } - + private async Task Blink() + { + ((ShaderMaterial)_animatedSprite.Material).Shader = BlinkShader; + + Tween tween = GetTree().CreateTween(); + tween.TweenMethod(Callable.From((float value) => SetShaderBlinkIntensity(value)), 1f, 0, 0.5); + await ToSignal(tween, "finished"); + } + + public async Task Teleport() + { + ((ShaderMaterial)_animatedSprite.Material).Shader = BlinkShader; + + Tween tween = GetTree().CreateTween(); + tween.TweenMethod(Callable.From((float value) => SetShaderScanlineDensity(value)), 0f, 50f, 0.5); + tween.Parallel().TweenMethod(Callable.From((float value) => SetShaderTeleportProgress(value)), 0f, 1f, 0.5); + await ToSignal(tween, "finished"); + } + + public async Task UnTeleport() + { + ((ShaderMaterial)_animatedSprite.Material).Shader = BlinkShader; + + Tween tween = GetTree().CreateTween(); + tween.TweenMethod(Callable.From((float value) => SetShaderTeleportProgress(value)), 1f, 0f, 0.5); + tween.Parallel().TweenMethod(Callable.From((float value) => SetShaderScanlineDensity(value)), 50f, 0f, 0.5); + await ToSignal(tween, "finished"); + } + + private void SetShaderTeleportProgress(float value) + { + ((ShaderMaterial)_animatedSprite.Material).SetShaderParameter("teleport_progress", value); + } + + private void SetShaderScanlineDensity(float value) + { + ((ShaderMaterial)_animatedSprite.Material).SetShaderParameter("scanline_density", value); + } + + private void SetShaderBlinkIntensity(float newValue) + { + ((ShaderMaterial)_animatedSprite.Material).SetShaderParameter("blink_intensity", newValue); + } + public bool IsDestroyed() { diff --git a/Shaders/Blink.gdshader b/Shaders/Blink.gdshader new file mode 100644 index 00000000..90a2f496 --- /dev/null +++ b/Shaders/Blink.gdshader @@ -0,0 +1,21 @@ +shader_type canvas_item; + +uniform vec4 blink_color: source_color; +uniform float blink_intensity = 0.0; +uniform float teleport_progress = 0.0; // 0 = fully visible, 1 = fully gone +uniform float scanline_density = 50.0; // Controls the number of scanlines + +void fragment() { + vec4 color = texture(TEXTURE, UV); + color = mix(color, blink_color, blink_intensity * color.a); + + // Generate scanline effect based on teleport_progress + float scanline = mod(UV.y * scanline_density, 1.0); // Creates scanline pattern + float cutoff = smoothstep(0.0, 1.0, UV.y - teleport_progress); // Controls disappearance + + // Mix scanline effect with cutoff to make it gradually disappear + float alpha_multiplier = step(scanline, cutoff); + color.a *= alpha_multiplier; + + COLOR = color; +} \ No newline at end of file