From 0e6bf1dcadd68f25fc2dd134f5cbf4c34e1b1200 Mon Sep 17 00:00:00 2001 From: CrbnsCat10n Date: Sun, 5 Apr 2026 00:07:28 +0800 Subject: [PATCH] new file: .editorconfig new file: .gitattributes new file: Charts/track.json new file: ProjectOnrinto.csproj new file: ProjectOnrinto.sln new file: Scenes/Audio/audio_stream_player.tscn new file: Scenes/Game/level.tscn new file: Scenes/Prefabs/beat.tscn new file: Scripts/Core/GameManager.cs new file: Scripts/Core/GameManager.cs.uid new file: Scripts/Core/MusicClock.cs new file: Scripts/Core/MusicClock.cs.uid new file: Scripts/Core/TrackGenerator.cs new file: Scripts/Core/TrackGenerator.cs.uid new file: Scripts/Data/ChartEvent.cs new file: Scripts/Data/ChartEvent.cs.uid new file: Scripts/Data/JsonConverter.cs new file: Scripts/Data/JsonConverter.cs.uid new file: Scripts/Data/TrackData.cs new file: Scripts/Data/TrackData.cs.uid new file: Scripts/GameObjects/NoteObject.cs new file: Scripts/GameObjects/NoteObject.cs.uid new file: icon.svg new file: icon.svg.import new file: project.godot --- .editorconfig | 4 + .gitattributes | 2 + Charts/track.json | 30 +++++++ ProjectOnrinto.csproj | 7 ++ ProjectOnrinto.sln | 19 ++++ Scenes/Audio/audio_stream_player.tscn | 6 ++ Scenes/Game/level.tscn | 11 +++ Scenes/Prefabs/beat.tscn | 12 +++ Scripts/Core/GameManager.cs | 71 +++++++++++++++ Scripts/Core/GameManager.cs.uid | 1 + Scripts/Core/MusicClock.cs | 26 ++++++ Scripts/Core/MusicClock.cs.uid | 1 + Scripts/Core/TrackGenerator.cs | 64 ++++++++++++++ Scripts/Core/TrackGenerator.cs.uid | 1 + Scripts/Data/ChartEvent.cs | 94 ++++++++++++++++++++ Scripts/Data/ChartEvent.cs.uid | 1 + Scripts/Data/JsonConverter.cs | 46 ++++++++++ Scripts/Data/JsonConverter.cs.uid | 1 + Scripts/Data/TrackData.cs | 119 ++++++++++++++++++++++++++ Scripts/Data/TrackData.cs.uid | 1 + Scripts/GameObjects/NoteObject.cs | 39 +++++++++ Scripts/GameObjects/NoteObject.cs.uid | 1 + icon.svg | 1 + icon.svg.import | 43 ++++++++++ project.godot | 33 +++++++ 25 files changed, 634 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 Charts/track.json create mode 100644 ProjectOnrinto.csproj create mode 100644 ProjectOnrinto.sln create mode 100644 Scenes/Audio/audio_stream_player.tscn create mode 100644 Scenes/Game/level.tscn create mode 100644 Scenes/Prefabs/beat.tscn create mode 100644 Scripts/Core/GameManager.cs create mode 100644 Scripts/Core/GameManager.cs.uid create mode 100644 Scripts/Core/MusicClock.cs create mode 100644 Scripts/Core/MusicClock.cs.uid create mode 100644 Scripts/Core/TrackGenerator.cs create mode 100644 Scripts/Core/TrackGenerator.cs.uid create mode 100644 Scripts/Data/ChartEvent.cs create mode 100644 Scripts/Data/ChartEvent.cs.uid create mode 100644 Scripts/Data/JsonConverter.cs create mode 100644 Scripts/Data/JsonConverter.cs.uid create mode 100644 Scripts/Data/TrackData.cs create mode 100644 Scripts/Data/TrackData.cs.uid create mode 100644 Scripts/GameObjects/NoteObject.cs create mode 100644 Scripts/GameObjects/NoteObject.cs.uid create mode 100644 icon.svg create mode 100644 icon.svg.import create mode 100644 project.godot diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f28239b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +charset = utf-8 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/Charts/track.json b/Charts/track.json new file mode 100644 index 0000000..2e189b9 --- /dev/null +++ b/Charts/track.json @@ -0,0 +1,30 @@ +{ + "BPM": 120, + "Offset": 0.5, + "TicksPerBeat": 480, + "Events": [ + { + "$type": "Onrinto.Chart.ChartEvent", + "Type": "Beat", + "Tick": 1000, + "Position": {"x": 1.0, "y": 0.0} + }, + { + "$type": "Onrinto.Chart.AnimatedEvent", + "Type": "Catch", + "Tick": 2000, + "Position": {"x": 0.0, "y": 0.0}, + "AniType": "Sin", + "In_Out": 1, + "AniStartTime": 1500, + "AniEndTime": 2000, + "RelativeSpeed": 1.5, + "StartPosition": {"x": -2.0, "y": 4.0}, + "EndPosition": {"x": 2.0, "y": 3.0} + } + ], + "RelativeSpeedPoints": [ + { "Tick": 0, "Speed": 1.0 , "IsLinear": false}, + { "Tick": 5000, "Speed": 2.0, "IsLinear": true } + ] +} \ No newline at end of file diff --git a/ProjectOnrinto.csproj b/ProjectOnrinto.csproj new file mode 100644 index 0000000..e457872 --- /dev/null +++ b/ProjectOnrinto.csproj @@ -0,0 +1,7 @@ + + + net8.0 + net9.0 + true + + \ No newline at end of file diff --git a/ProjectOnrinto.sln b/ProjectOnrinto.sln new file mode 100644 index 0000000..758885c --- /dev/null +++ b/ProjectOnrinto.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectOnrinto", "ProjectOnrinto.csproj", "{7F7FC90F-715A-4D55-98B9-182451D8EE09}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + ExportDebug|Any CPU = ExportDebug|Any CPU + ExportRelease|Any CPU = ExportRelease|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7F7FC90F-715A-4D55-98B9-182451D8EE09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7F7FC90F-715A-4D55-98B9-182451D8EE09}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7F7FC90F-715A-4D55-98B9-182451D8EE09}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU + {7F7FC90F-715A-4D55-98B9-182451D8EE09}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU + {7F7FC90F-715A-4D55-98B9-182451D8EE09}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU + {7F7FC90F-715A-4D55-98B9-182451D8EE09}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU + EndGlobalSection +EndGlobal diff --git a/Scenes/Audio/audio_stream_player.tscn b/Scenes/Audio/audio_stream_player.tscn new file mode 100644 index 0000000..a0f253a --- /dev/null +++ b/Scenes/Audio/audio_stream_player.tscn @@ -0,0 +1,6 @@ +[gd_scene format=3 uid="uid://n8na6nkfmnme"] + +[ext_resource type="Script" uid="uid://d1ct3oyh0fr1s" path="res://Scripts/Core/MusicClock.cs" id="1_g84o6"] + +[node name="AudioStreamPlayer" type="AudioStreamPlayer" unique_id=1188161767] +script = ExtResource("1_g84o6") diff --git a/Scenes/Game/level.tscn b/Scenes/Game/level.tscn new file mode 100644 index 0000000..5c26ba2 --- /dev/null +++ b/Scenes/Game/level.tscn @@ -0,0 +1,11 @@ +[gd_scene format=3 uid="uid://fg4ip37xbrhw"] + +[ext_resource type="PackedScene" uid="uid://n8na6nkfmnme" path="res://Scenes/Audio/audio_stream_player.tscn" id="1_5xcqo"] +[ext_resource type="Script" uid="uid://bmanbpeqbrkk1" path="res://Scripts/Core/TrackGenerator.cs" id="2_gayhk"] + +[node name="Level" type="Node3D" unique_id=2071595859] + +[node name="AudioStreamPlayer" parent="." unique_id=1188161767 instance=ExtResource("1_5xcqo")] + +[node name="Track" type="Node3D" parent="." unique_id=923723651] +script = ExtResource("2_gayhk") diff --git a/Scenes/Prefabs/beat.tscn b/Scenes/Prefabs/beat.tscn new file mode 100644 index 0000000..b5e1b5b --- /dev/null +++ b/Scenes/Prefabs/beat.tscn @@ -0,0 +1,12 @@ +[gd_scene format=3 uid="uid://dqp4hku6gudds"] + +[ext_resource type="Script" uid="uid://budeg56m55hkr" path="res://Scripts/GameObjects/NoteObject.cs" id="1_624vv"] + +[sub_resource type="BoxMesh" id="BoxMesh_26t3m"] +size = Vector3(0.8, 0.8, 0.8) + +[node name="Node3D" type="Node3D" unique_id=1476701000] +script = ExtResource("1_624vv") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=1691210492] +mesh = SubResource("BoxMesh_26t3m") diff --git a/Scripts/Core/GameManager.cs b/Scripts/Core/GameManager.cs new file mode 100644 index 0000000..4044e17 --- /dev/null +++ b/Scripts/Core/GameManager.cs @@ -0,0 +1,71 @@ +using Godot; +using Onrinto.Chart; + +public partial class GameManager : Node3D +{ + public TrackData CurrentTrack { get; private set; } + public static GameManager Instance { get; private set; } + + public float CurrentAbsoluteSpeed { get; private set; } + public float CurrentAbsZ { get; private set; } + + private int absoluteSpeedPointIndexArrow = 0; + + private void UpdateAbsoluteState(double time) + { + var points = CurrentTrack.AbsoluteSpeedPoints; + if(points == null || points.Count == 0) return; + + double firstPointTime = CurrentTrack.TickToSeconds(points[0].Tick); + if(time < firstPointTime) + { + CurrentAbsoluteSpeed = points[0].Speed; + return; + } + + for(int i = absoluteSpeedPointIndexArrow; i < points.Count - 1; i++) + { + double pointTime_from = CurrentTrack.TickToSeconds(points[i].Tick); + double pointTime_to = CurrentTrack.TickToSeconds(points[i + 1].Tick); + + if(time >= pointTime_from && time < pointTime_to) + { + absoluteSpeedPointIndexArrow = i; + + if(points[i].IsLinear) + { + double t = (time - pointTime_from) / (pointTime_to - pointTime_from); + CurrentAbsoluteSpeed = Mathf.Lerp(points[i].Speed, points[i + 1].Speed, (float)t); + } + else + { + CurrentAbsoluteSpeed = points[i].Speed; + } + return; + } + } + + absoluteSpeedPointIndexArrow = points.Count - 1; + CurrentAbsoluteSpeed = points[^1].Speed; + } + + // Called when the node enters the scene tree for the first time. + public override void _Ready() + { + if (Instance != null){ QueueFree(); return; } + Instance = this; + + ProcessPriority = -100; + } + + // Called every frame. 'delta' is the elapsed time since the previous frame. + public override void _Process(double delta) + { + double tNow = MusicClock.Instance.CurrentTime; + + if(CurrentTrack == null) return; + + UpdateAbsoluteState(tNow); + CurrentAbsZ = CurrentTrack.GetZ(tNow, CurrentTrack.RelativeSpeedPoints, CurrentTrack.RelativeZTable); + } +} \ No newline at end of file diff --git a/Scripts/Core/GameManager.cs.uid b/Scripts/Core/GameManager.cs.uid new file mode 100644 index 0000000..1db596a --- /dev/null +++ b/Scripts/Core/GameManager.cs.uid @@ -0,0 +1 @@ +uid://ch71v2vkldtbd diff --git a/Scripts/Core/MusicClock.cs b/Scripts/Core/MusicClock.cs new file mode 100644 index 0000000..efcf2fa --- /dev/null +++ b/Scripts/Core/MusicClock.cs @@ -0,0 +1,26 @@ +using Godot; + +public partial class MusicClock : AudioStreamPlayer +{ + public static MusicClock Instance {get; private set; } + + private double currentTime; + public double CurrentTime { get; private set; } + + public override void _Ready() + { + Instance = this; + if (Stream == null) GD.PrintErr("MusicClock: No Audio File?"); + } + + public override void _Process(double delta) + { + if(!Playing) return; + + double rawTime = GetPlaybackPosition(); + double delay = AudioServer.GetTimeSinceLastMix(); + double latency = AudioServer.GetOutputLatency(); + + CurrentTime = rawTime + delay - latency; + } +} diff --git a/Scripts/Core/MusicClock.cs.uid b/Scripts/Core/MusicClock.cs.uid new file mode 100644 index 0000000..930338e --- /dev/null +++ b/Scripts/Core/MusicClock.cs.uid @@ -0,0 +1 @@ +uid://d1ct3oyh0fr1s diff --git a/Scripts/Core/TrackGenerator.cs b/Scripts/Core/TrackGenerator.cs new file mode 100644 index 0000000..e2c561d --- /dev/null +++ b/Scripts/Core/TrackGenerator.cs @@ -0,0 +1,64 @@ +using Godot; +using System.Text.Json; +using Onrinto.Chart; +using System.Text.Json.Serialization; +using System.Linq; +using System.Collections.Generic; +using System.Security.Cryptography.X509Certificates; + +public partial class TrackGenerator : Node3D +{ + TrackData track = new TrackData(); + List _notes = new List(); + [Export] public PackedScene NotePrefab; + + // Called when the node enters the scene tree for the first time. + public override void _Ready() + { + //Load chart data. + string chart_path = "res://Charts/track.json"; + if (!FileAccess.FileExists(chart_path)) + { + GD.PrintErr($"Can't find chart file: {chart_path}"); + return; + } + + using var file = FileAccess.Open(chart_path, FileAccess.ModeFlags.Read); + string json = file.GetAsText(); + + var options = new JsonSerializerOptions { + PropertyNameCaseInsensitive = true, + Converters = { new JsonStringEnumConverter(), new Vector2Converter() } + }; + try { + track = JsonSerializer.Deserialize(json, options); + + // foreach (var e in track.Events) { + // GD.Print($"事件时间: {e.Tick}, 类型: {e.GetType().Name}"); + // if (e is AnimatedEvent ani) { + // GD.Print($" -> 这是一个动画音符开始位置: {ani.StartPosition}, 结束位置: {ani.EndPosition}"); + // } + // } + } catch (JsonException ex) { + GD.PrintErr("Failed to parse chart JSON: " + ex.Message); + } + + _notes = track.Events.OrderBy(e => e.Tick).ToList(); // Ensure events are sorted by time. + } + + private void spawnNote(ChartEvent e) { + var noteInstance = NotePrefab.Instantiate(); + + float speed = 20.0f; + double hitTime = (double)(e.Tick / track.TicksPerBeat * 60.0 / track.BPM); + float initialZ = (float)(hitTime * speed); + + noteInstance.Initialize(e, hitTime, initialZ); // Initial Z position + AddChild(noteInstance); + } + // Called every frame. 'delta' is the elapsed time since the previous frame. + public override void _Process(double delta) + { + + } +} diff --git a/Scripts/Core/TrackGenerator.cs.uid b/Scripts/Core/TrackGenerator.cs.uid new file mode 100644 index 0000000..85e9c5f --- /dev/null +++ b/Scripts/Core/TrackGenerator.cs.uid @@ -0,0 +1 @@ +uid://bmanbpeqbrkk1 diff --git a/Scripts/Data/ChartEvent.cs b/Scripts/Data/ChartEvent.cs new file mode 100644 index 0000000..36a02e0 --- /dev/null +++ b/Scripts/Data/ChartEvent.cs @@ -0,0 +1,94 @@ +using Godot; +using System; +using System.Text.Json.Serialization; + +namespace Onrinto.Chart; + +public enum EventType { Hole, Obstacle, Beat, Catch, Through, Jump, Dash, Float }; +public enum AnimationType { Linear, Sin, Back }; + +public class TempoPoint +{ + public double Tick { get; set; } + public float BPM { get; set; } + + [JsonConstructor] + public TempoPoint(double tick, float bpm, bool isLinear) + { + Tick = tick; + BPM = bpm; + } +} + +public class SpeedPoint +{ + public double Tick { get; set; } + public float Speed { get; set; } + public bool IsLinear { get; set; } + + [JsonConstructor] + public SpeedPoint(double tick, float speed, bool isLinear) + { + Tick = tick; + Speed = speed; + IsLinear = isLinear; + } +} + +[JsonPolymorphic(TypeDiscriminatorPropertyName = "$type")] +[JsonDerivedType(typeof(ChartEvent), typeDiscriminator: "Onrinto.Chart.ChartEvent")] +[JsonDerivedType(typeof(AnimatedEvent), typeDiscriminator: "Onrinto.Chart.AnimatedEvent")] +[Serializable] +public class ChartEvent +{ + + public EventType Type { get; set; } + public double Tick { get; set; } + public Vector2 Position { get; set; } + public double HitTime { get; set; } + public double HitAbsZ { get; set; } + + public ChartEvent(EventType type, double tick, Vector2 position) + { + Type = type; + Tick = tick; + Position = position; + } +} + +[Serializable] +public class AnimatedEvent : ChartEvent +{ + public AnimationType AniType { get; set; } + public int In_Out { get; set; } + + public double AniStartTime { get; set; } + public double AniEndTime { get; set; } + + public Vector2 StartPosition { get; set; } + public Vector2 EndPosition { get; set; } + + public float RelativeSpeed { get; set; } + + public AnimatedEvent( + EventType type, + double tick, + Vector2 position, + AnimationType aniType, + int in_Out, + double aniStartTime, + double aniEndTime, + float relativeSpeed, + Vector2 startPosition, + Vector2 endPosition + ) : base(type, tick, position) + { + AniType = aniType; + In_Out = in_Out; + AniStartTime = aniStartTime; + AniEndTime = aniEndTime; + RelativeSpeed = relativeSpeed; + StartPosition = startPosition; + EndPosition = endPosition; + } +} diff --git a/Scripts/Data/ChartEvent.cs.uid b/Scripts/Data/ChartEvent.cs.uid new file mode 100644 index 0000000..d0c7c49 --- /dev/null +++ b/Scripts/Data/ChartEvent.cs.uid @@ -0,0 +1 @@ +uid://bg6k051syuyb6 diff --git a/Scripts/Data/JsonConverter.cs b/Scripts/Data/JsonConverter.cs new file mode 100644 index 0000000..3604d7a --- /dev/null +++ b/Scripts/Data/JsonConverter.cs @@ -0,0 +1,46 @@ +using Godot; +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +//unread... + +namespace Onrinto.Chart; + +public class Vector2Converter : JsonConverter +{ + public override Vector2 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + // 预设默认值 + float x = 0; + float y = 0; + + if (reader.TokenType != JsonTokenType.StartObject) + throw new JsonException("预期一个对象来解析 Vector2"); + + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + return new Vector2(x, y); + + if (reader.TokenType == JsonTokenType.PropertyName) + { + string propertyName = reader.GetString()?.ToLower(); // 统一转小写处理 + reader.Read(); + + if (propertyName == "x") x = (float)reader.GetDouble(); + else if (propertyName == "y") y = (float)reader.GetDouble(); + } + } + + return new Vector2(x, y); + } + + public override void Write(Utf8JsonWriter writer, Vector2 value, JsonSerializerOptions options) + { + writer.WriteStartObject(); + writer.WriteNumber("x", value.X); + writer.WriteNumber("y", value.Y); + writer.WriteEndObject(); + } +} \ No newline at end of file diff --git a/Scripts/Data/JsonConverter.cs.uid b/Scripts/Data/JsonConverter.cs.uid new file mode 100644 index 0000000..7a102b0 --- /dev/null +++ b/Scripts/Data/JsonConverter.cs.uid @@ -0,0 +1 @@ +uid://25r22gy8t7ny diff --git a/Scripts/Data/TrackData.cs b/Scripts/Data/TrackData.cs new file mode 100644 index 0000000..d12c791 --- /dev/null +++ b/Scripts/Data/TrackData.cs @@ -0,0 +1,119 @@ +using System.Collections.Generic; +using System.Linq; +using Godot; + +namespace Onrinto.Chart; + +public class TrackData +{ + public int BPM { get; set; } + public double Offset { get; set; } + public double TicksPerBeat { get; set; } + public double BeatDuration => 60.0 / BPM; + public List Events { get; set; } = new List(); + public List TempoPoints { get; set; } = new List(); + public List RelativeSpeedPoints { get; set; } = new List(); + public List AbsoluteSpeedPoints { get; set; } = new List(); + + public List TempoSecondsTable { get; private set; } = new List(); + public List RelativeZTable { get; private set; } = new List(); + + public void Initialize() + { + InitializeTempoTable(); + InitializeRelativeZTable(RelativeSpeedPoints); + + foreach(var e in Events) + { + e.HitTime = TickToSeconds(e.Tick); + e.HitAbsZ = GetZ(e.HitTime, RelativeSpeedPoints, RelativeZTable); + } + } + + public void InitializeTempoTable() + { + TempoSecondsTable.Clear(); + if(TempoPoints == null || TempoPoints.Count == 0) return; + + TempoPoints = TempoPoints.OrderBy(tp => tp.Tick).ToList(); + double cachedSeconds = 0.0; + TempoSecondsTable.Add(cachedSeconds); + + for(int i = 0; i < TempoPoints.Count - 1; i++) + { + double ticksDelta = TempoPoints[i + 1].Tick - TempoPoints[i].Tick; + double secondsDelta = ticksDelta / TicksPerBeat * 60.0 / TempoPoints[i].BPM; + cachedSeconds += secondsDelta; + TempoSecondsTable.Add(cachedSeconds); + } + } + + public void InitializeRelativeZTable(List speedPoints) + { + RelativeZTable.Clear(); + if(speedPoints == null || speedPoints.Count == 0) return; + + speedPoints = speedPoints.OrderBy(sp => sp.Tick).ToList(); + float cachedZ = 0.0f; + RelativeZTable.Add(cachedZ); + + for(int i = 0; i < speedPoints.Count - 1; i++) + { + double timeDelta = TickToSeconds(speedPoints[i + 1].Tick) - TickToSeconds(speedPoints[i].Tick); + + if(speedPoints[i].IsLinear) + { + cachedZ += (float)timeDelta * (speedPoints[i].Speed + speedPoints[i + 1].Speed) * 0.5f; + } + else + { + cachedZ += (float)timeDelta * speedPoints[i].Speed; + } + RelativeZTable.Add(cachedZ); + } + } + + public double TickToSeconds(double tick) + { + if(TempoPoints == null || TempoPoints.Count == 0) + return tick / TicksPerBeat * 60.0 / BPM; + + int idx = 0; + for(int i = 0; i < TempoPoints.Count; i++) + { + if(tick >= TempoPoints[i].Tick) idx = i; + else break; + } + + return TempoSecondsTable[idx] + (tick - TempoPoints[idx].Tick) / TicksPerBeat * 60.0 / TempoPoints[idx].BPM; + } + + public float GetZ(double time, List speedPoints, List zTable) + { + if(speedPoints == null || speedPoints.Count == 0) return 0.0f; + + int idx = 0; + for(int i = 0; i < speedPoints.Count; i++) + { + if(time >= TickToSeconds(speedPoints[i].Tick)) idx = i; + else break; + } + + var point = speedPoints[idx]; + float cachedZ = zTable[idx]; + double pointTime = TickToSeconds(point.Tick); + double deltaTime = time - pointTime; + + if(point.IsLinear && idx < speedPoints.Count - 1) + { + double nextTime = TickToSeconds(speedPoints[idx + 1].Tick); + float t = (float)((time - pointTime) / (nextTime - pointTime)); + float currentSpeed = Mathf.Lerp(point.Speed, speedPoints[idx + 1].Speed, t); + return cachedZ + (float)deltaTime * (point.Speed + currentSpeed) * 0.5f; + } + else + { + return cachedZ + (float)deltaTime * point.Speed; + } + } +} \ No newline at end of file diff --git a/Scripts/Data/TrackData.cs.uid b/Scripts/Data/TrackData.cs.uid new file mode 100644 index 0000000..c94aea6 --- /dev/null +++ b/Scripts/Data/TrackData.cs.uid @@ -0,0 +1 @@ +uid://beb5iifgf08kg diff --git a/Scripts/GameObjects/NoteObject.cs b/Scripts/GameObjects/NoteObject.cs new file mode 100644 index 0000000..7fc144c --- /dev/null +++ b/Scripts/GameObjects/NoteObject.cs @@ -0,0 +1,39 @@ +using Godot; +using Onrinto.Chart; + +public partial class NoteObject : Node3D +{ + private double _hitSeconds; + private bool _isHit = false; + private bool _initialized = false; + + public void Initialize(ChartEvent chartEvent, double hitSeconds, float initialZ) + { + _hitSeconds = hitSeconds; + Position = new Vector3(chartEvent.Position.X, chartEvent.Position.Y, initialZ); + + _initialized = true; + } + + // Called when the node enters the scene tree for the first time. + public override void _Ready() + { + + } + + // Called every frame. 'delta' is the elapsed time since the previous frame. + public override void _Process(double delta) + { + if (!_initialized) return; + + float speed = 20.0f; // Scroll speed + + double _currentTime = MusicClock.Instance.CurrentTime; + + float newZ = (float)((_hitSeconds - _currentTime) * speed); + Position = new Vector3(Position.X, Position.Y, newZ); // Update Z position + + if(_hitSeconds - _currentTime < -0.5) QueueFree(); // Remove note + + } +} diff --git a/Scripts/GameObjects/NoteObject.cs.uid b/Scripts/GameObjects/NoteObject.cs.uid new file mode 100644 index 0000000..b993cfd --- /dev/null +++ b/Scripts/GameObjects/NoteObject.cs.uid @@ -0,0 +1 @@ +uid://budeg56m55hkr diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..c6bbb7d --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..565f1c6 --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bkl6uvoagfpkv" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..c3de5ec --- /dev/null +++ b/project.godot @@ -0,0 +1,33 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="ProjectOnrinto" +run/main_scene="uid://fg4ip37xbrhw" +config/features=PackedStringArray("4.6", "C#", "Forward Plus") +config/icon="res://icon.svg" + +[autoload] + +GlobalAudioStreamPlayer="*uid://n8na6nkfmnme" +GameManager="*uid://ch71v2vkldtbd" + +[dotnet] + +project/assembly_name="ProjectOnrinto" + +[physics] + +3d/physics_engine="Jolt Physics" + +[rendering] + +rendering_device/driver.windows="d3d12"