diff --git a/Scenes/Play.tscn b/Scenes/Play.tscn index 759047d..069df35 100644 --- a/Scenes/Play.tscn +++ b/Scenes/Play.tscn @@ -1,11 +1,10 @@ -[gd_scene load_steps=19 format=3 uid="uid://bqh00ot0csqmk"] +[gd_scene load_steps=18 format=3 uid="uid://bqh00ot0csqmk"] [ext_resource type="Script" path="res://Scripts/Scenes/Play/Play.cs" id="1_asytu"] [ext_resource type="PackedScene" uid="uid://cyetvgmwnoy8l" path="res://Things/Background.tscn" id="2_8g6gv"] [ext_resource type="Shader" path="res://Shaders/Cutout2D.gdshader" id="3_rjbyl"] [ext_resource type="Script" path="res://Scripts/Scenes/Play/Audio/BGM.cs" id="4_c2dke"] [ext_resource type="Script" path="res://Scripts/Scenes/Play/Audio/SFX.cs" id="5_owrd5"] -[ext_resource type="PackedScene" uid="uid://cyopljug0duaa" path="res://Things/TunnelObjects/Notes/NoteTouch.tscn" id="6_kjmqf"] [sub_resource type="Environment" id="Environment_nefjb"] ambient_light_source = 1 @@ -62,7 +61,7 @@ uv1_scale = Vector3(-1, 1, 1) [sub_resource type="ViewportTexture" id="ViewportTexture_w20vk"] viewport_path = NodePath("Mask") -[sub_resource type="ShaderMaterial" id="ShaderMaterial_nh4gy"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_7nje4"] resource_local_to_scene = true shader = ExtResource("3_rjbyl") shader_parameter/mask = SubResource("ViewportTexture_w20vk") @@ -141,7 +140,7 @@ anchor_mode = 0 editor_draw_screen = false [node name="Background" parent="2D Viewport/Viewport Control" instance=ExtResource("2_8g6gv")] -material = SubResource("ShaderMaterial_nh4gy") +material = SubResource("ShaderMaterial_7nje4") layout_mode = 1 offset_top = -1920.0 offset_right = 1920.0 @@ -249,8 +248,6 @@ anchor_top = 1.0 anchor_bottom = 1.0 grow_vertical = 0 -[node name="NoteTouch" parent="2D Viewport/Viewport Control/Scroll Anchor/Notes Scroll" instance=ExtResource("6_kjmqf")] - [node name="AudioStreamPlayer BGM" type="AudioStreamPlayer" parent="."] script = ExtResource("4_c2dke") diff --git a/Scripts/Data/Chart/Chart.cs b/Scripts/Data/Chart/Chart.cs index 1b3a265..c676a4a 100644 --- a/Scripts/Data/Chart/Chart.cs +++ b/Scripts/Data/Chart/Chart.cs @@ -18,7 +18,7 @@ namespace WacK.Data.Chart public SortedList> playNotes { get; private set; } public SortedList> timeSigChgs { get; private set; } public SortedList> tempoChgs { get; private set; } - public SortedList> events { get; private set; } + public SortedList>> events { get; private set; } public Chart(string chartPath) { @@ -244,7 +244,6 @@ namespace WacK.Data.Chart } else { - // only add notes that aren't part of the hold if (!playNotes.ContainsKey(curTime)) { playNotes[curTime] = new List(); @@ -270,11 +269,15 @@ namespace WacK.Data.Chart this.timeSigChgs[curTime] = neii; } - // NoteEvent + // NoteEvent -- BG Change var nei = curNote as NoteEvent; if (nei != null) { - this.events[curTime] = nei; + if (!events.ContainsKey(curTime)) + { + events[curTime] = new List>(); + } + events[curTime].Add(nei); } // update previous states diff --git a/Scripts/Scenes/Play/Play.cs b/Scripts/Scenes/Play/Play.cs index af3939e..667a41d 100644 --- a/Scripts/Scenes/Play/Play.cs +++ b/Scripts/Scenes/Play/Play.cs @@ -63,10 +63,14 @@ namespace WacK.Scenes public Viewport rightViewport; private Chart chart; + // Indices point to the NEXT thing to look for. We process that thing once + // the song time is at or later than the thing's time. + private int chordNextIdx = 0; + private int eventNextIdx = 0; // base scroll speed, which we can apply multipliers on public static readonly float BASE_PIXELS_PER_SECOND = 800; - public static float scrollPxPerSec + public static float ScrollPxPerSec { get { @@ -82,17 +86,19 @@ namespace WacK.Scenes // parse mer and create chart for current play chart = new(playParams.chartPath); - RealizeChart(); + InstantiateChartVisuals(); - // audio setup + // // audio setup bgmController.LoadFromUser(playParams.soundPath); bgmController.Play(); + + // TestBGAnim(); } /// /// Instantiates necessary notes onto noteDisplay for the player to see. /// - private void RealizeChart() + private void InstantiateChartVisuals() { foreach (var msNote in chart.playNotes) { @@ -128,21 +134,76 @@ namespace WacK.Scenes } nNote.Init(note); var nPos = nNote.Position; - nPos.Y = msNote.Key * -scrollPxPerSec; + nPos.Y = msNote.Key * -ScrollPxPerSec; nNote.Position = nPos; noteDisplay.AddChild(nNote); } } } - public override void _Process(double delta) - { - double time = bgmController.GetPlaybackPosition() + AudioServer.GetTimeSinceLastMix() - AudioServer.GetOutputLatency(); + /// + /// Process current game state. Should only run if playing a chart and unpaused. + /// + private void PlayLoop() + { + float time = bgmController.CurTime; + + // check next event + while (eventNextIdx < chart.events.Count && time >= chart.events.Keys[eventNextIdx]) + { + var t = chart.events.Keys[eventNextIdx]; + var l = chart.events[t]; + + foreach (var e in l) + { + GD.Print($"Passed event {e.type}(pos={e.pos},size={e.size}) at {t}"); + switch (e.type) + { + case NoteEventType.BGAdd: + background.SetSegments((int)e.pos, (int)e.size, true, (DrawDirection)e.value); + break; + case NoteEventType.BGRem: + background.SetSegments((int)e.pos, (int)e.size, false, (DrawDirection)e.value); + break; + } + } + + eventNextIdx++; + } + // set scroll var nPos = noteDisplay.Position; - nPos.Y = bgmController.CurTime * scrollPxPerSec; + nPos.Y = time * ScrollPxPerSec; noteDisplay.Position = nPos; scrollDisplay.Position = nPos; + } + + private async void TestBGAnim() + { + await ToSignal(GetTree().CreateTimer(1.5), SceneTreeTimer.SignalName.Timeout); + + // clockwise all + background.SetSegments(0, 60, true, DrawDirection.Clockwise); + await ToSignal(GetTree().CreateTimer(1.5), SceneTreeTimer.SignalName.Timeout); + background.SetSegments(0, 60, false, DrawDirection.Clockwise); + await ToSignal(GetTree().CreateTimer(1.5), SceneTreeTimer.SignalName.Timeout); + + // counterclockwise all + background.SetSegments(0, 60, true, DrawDirection.CounterClockwise); + await ToSignal(GetTree().CreateTimer(1.5), SceneTreeTimer.SignalName.Timeout); + background.SetSegments(0, 60, false, DrawDirection.CounterClockwise); + await ToSignal(GetTree().CreateTimer(1.5), SceneTreeTimer.SignalName.Timeout); + + // center all + background.SetSegments(0, 60, true, DrawDirection.Center); + await ToSignal(GetTree().CreateTimer(1.5), SceneTreeTimer.SignalName.Timeout); + background.SetSegments(0, 60, false, DrawDirection.Center); + await ToSignal(GetTree().CreateTimer(1.5), SceneTreeTimer.SignalName.Timeout); + } + + public override void _Process(double delta) + { + PlayLoop(); } private void OnDestroy() diff --git a/Scripts/Things/TunnelObjects/Background.cs b/Scripts/Things/TunnelObjects/Background.cs index 0e04346..7f15c7f 100644 --- a/Scripts/Things/TunnelObjects/Background.cs +++ b/Scripts/Things/TunnelObjects/Background.cs @@ -18,21 +18,22 @@ namespace WacK.Things.TunnelObjects public partial class Background : Node { [Export] - private ColorRect firstSegment; - private List segments = new(60); + private TextureRect firstSegment; + private List segments = new(60); // Called when the node enters the scene tree for the first time. public override void _Ready() { var segmentsNode = FindChild("Segment Masks"); + firstSegment.Visible = false; segments.Add(firstSegment); for (int i = 1; i < 60; ++i) { - var n = (ColorRect)firstSegment.Duplicate(); + var n = (TextureRect)firstSegment.Duplicate(); segmentsNode.AddChild(n); segments.Add(n); n.Name = i.ToString(); - n.SetPosition(new Vector2(i * Constants.BASE_2D_RESOLUTION / 60, 0)); + n.SetPosition(new Vector2(i * Constants.BASE_2D_RESOLUTION / 60, Constants.BASE_2D_RESOLUTION)); } } @@ -43,7 +44,7 @@ namespace WacK.Things.TunnelObjects // GD.Print($"{direction} = {state}. Even? {size % 2 == 0}"); double timer = 0; - double time = .5f; + double time = .1f; int centerSeg = pos + size/2; while (timer < time) @@ -79,6 +80,7 @@ namespace WacK.Things.TunnelObjects } await ToSignal(GetTree(), "process_frame"); } + GD.Print("Finished BG anim!"); } } } diff --git a/Scripts/Things/TunnelObjects/THNoteHold.cs b/Scripts/Things/TunnelObjects/THNoteHold.cs index 35d2c38..0adb10d 100644 --- a/Scripts/Things/TunnelObjects/THNoteHold.cs +++ b/Scripts/Things/TunnelObjects/THNoteHold.cs @@ -23,7 +23,7 @@ namespace WacK.Things.TunnelObjects { longThing = new Node2D(); holdScroll.AddChild(longThing); - longThing.Position = new Vector2(0, (float)-holdNoteData.time * Play.scrollPxPerSec); + longThing.Position = new Vector2(0, (float)-holdNoteData.time * Play.ScrollPxPerSec); if (holdNoteData.points.Count > 0) { @@ -31,7 +31,7 @@ namespace WacK.Things.TunnelObjects float segmentPos = 0; foreach (var (_, curNote) in holdNoteData.points) { - var curLength = Play.scrollPxPerSec * (float)(curNote.time - lastHold.time); + var curLength = Play.ScrollPxPerSec * (float)(curNote.time - lastHold.time); var segment = CreateSegment(lastHold, curNote); longThing.AddChild(segment); segment.Position = new Vector2(0, segmentPos); @@ -50,7 +50,7 @@ namespace WacK.Things.TunnelObjects { float minuteSize = Constants.BASE_2D_RESOLUTION / 60; - var length = Play.scrollPxPerSec * (float)(destination.time - origin.time); + var length = Play.ScrollPxPerSec * (float)(destination.time - origin.time); var verts = new Vector2[4]; int originPos; diff --git a/Shaders/Cutout2D.gdshader b/Shaders/Cutout2D.gdshader index a3a4291..405d8ab 100644 --- a/Shaders/Cutout2D.gdshader +++ b/Shaders/Cutout2D.gdshader @@ -7,9 +7,6 @@ void fragment( ) vec4 mask_color = texture(mask, UV).rgba; vec4 sprite_color = texture(TEXTURE, UV).rgba; - if (mask_color.a == 0.0) - { - sprite_color.a = 0.0; - } + sprite_color.a = mask_color.a; COLOR = sprite_color; } \ No newline at end of file diff --git a/Things/Background.tscn b/Things/Background.tscn index bb2d90a..662c76e 100644 --- a/Things/Background.tscn +++ b/Things/Background.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=10 format=3 uid="uid://cyetvgmwnoy8l"] +[gd_scene load_steps=12 format=3 uid="uid://cyetvgmwnoy8l"] [ext_resource type="Shader" path="res://Shaders/Cutout2D.gdshader" id="1_f6ion"] [ext_resource type="Texture2D" uid="uid://dkohutwp0yujj" path="res://_Assets/Textures/HitLine/BGLine.png" id="1_w0gbp"] @@ -22,12 +22,22 @@ shader_parameter/mask = SubResource("ViewportTexture_oigfv") [sub_resource type="Gradient" id="Gradient_djnn4"] offsets = PackedFloat32Array(0) -colors = PackedColorArray(0.0308856, 0.0596563, 0.141577, 0.894118) +colors = PackedColorArray(0.0313726, 0.0588235, 0.141176, 1) [sub_resource type="GradientTexture1D" id="GradientTexture1D_kn5i7"] gradient = SubResource("Gradient_djnn4") width = 2048 +[sub_resource type="Gradient" id="Gradient_n1451"] +interpolation_mode = 2 +interpolation_color_space = 2 +offsets = PackedFloat32Array(0, 0.376518) +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_pibib"] +gradient = SubResource("Gradient_n1451") +width = 1920 + [node name="Background" type="Control" node_paths=PackedStringArray("firstSegment")] material = SubResource("ShaderMaterial_h3xxm") custom_minimum_size = Vector2(1920, 1920) @@ -47,6 +57,7 @@ offset_right = 40.0 offset_bottom = 40.0 [node name="SubViewport" type="SubViewport" parent="FullBG"] +transparent_bg = true handle_input_locally = false size = Vector2i(1920, 1920) render_target_update_mode = 4 @@ -66,8 +77,11 @@ layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 +offset_top = 1920.0 +offset_bottom = 1920.0 grow_horizontal = 2 grow_vertical = 2 +rotation = -1.5708 texture = SubResource("GradientTexture1D_kn5i7") expand_mode = 1 @@ -114,6 +128,10 @@ expand_mode = 1 transparent_bg = true size = Vector2i(1920, 1920) -[node name="0" type="ColorRect" parent="Segment Masks"] -offset_right = 32.0 -offset_bottom = 1920.0 +[node name="0" type="TextureRect" parent="Segment Masks"] +anchors_preset = -1 +offset_top = 1920.0 +offset_right = 1920.0 +offset_bottom = 1952.0 +rotation = -1.5708 +texture = SubResource("GradientTexture1D_pibib")