Skip to content

Commit 38c5ff1

Browse files
authored
Merge pull request #27 from Project-Funk-Engine/S1-ChartLooping
S1 chart looping Merge into Sprint-1 working branch
2 parents 8fed186 + f20cedb commit 38c5ff1

19 files changed

Lines changed: 501 additions & 232 deletions

Classes/Note.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using Godot;
3+
4+
/**
5+
* @class Note
6+
* @brief Data structure class for holding data and methods for a battle time note. WIP
7+
*/
8+
public partial class Note : Resource
9+
{
10+
public int Beat;
11+
public NoteArrow.ArrowType Type;
12+
13+
public Note(NoteArrow.ArrowType type = NoteArrow.ArrowType.Up, int beat = 0)
14+
{
15+
Beat = beat;
16+
Type = type;
17+
}
18+
}

project.godot

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ config_version=5
1111
[application]
1212

1313
config/name="Funk Engine"
14-
run/main_scene="res://scenes/main.tscn"
14+
run/main_scene="res://scenes/ChartViewport/test_scene.tscn"
1515
config/features=PackedStringArray("4.3", "C#", "Forward Plus")
1616
config/icon="res://icon.svg"
1717

@@ -56,3 +56,7 @@ arrowRight={
5656
[rendering]
5757

5858
textures/canvas_textures/default_texture_filter=0
59+
60+
[threading]
61+
62+
worker_pool/canvas_textures/default_texture_filter=1
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System;
2+
using Godot;
3+
4+
/**
5+
* @class BattleDirector
6+
* @brief Higher priority director to manage battle effects. Can directly access managers, which should signal up to Director WIP
7+
*/
8+
public partial class BattleDirector : Node2D
9+
{
10+
[Export]
11+
public ChartManager CM;
12+
13+
[Export]
14+
public NoteManager NM;
15+
16+
//TODO: Slowly add data based on what it needs.
17+
public struct SongData
18+
{
19+
public int Bpm;
20+
public double SongLength;
21+
public int NumLoops;
22+
}
23+
24+
private SongData _curSong;
25+
private Note[] _notes;
26+
27+
public override void _Ready()
28+
{
29+
AddExampleNote();
30+
31+
CM.PrepChart(_curSong, _notes);
32+
//TODO: Hook up signals
33+
}
34+
35+
private void AddExampleNote()
36+
{
37+
//Create Dummy Song Data
38+
_curSong = new SongData
39+
{
40+
Bpm = 120,
41+
SongLength = 160,
42+
NumLoops = 5,
43+
};
44+
//Add note
45+
_notes = new Note[1];
46+
_notes[0] = new Note(NoteArrow.ArrowType.Left, 32);
47+
}
48+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
using System;
2+
using Godot;
3+
using ArrowType = NoteArrow.ArrowType;
4+
5+
/*
6+
//Lets say this inits all the initial notes and manages the chart BG.
7+
8+
//What does this do?
9+
//Input, visual looping, timing, battle stuff, combo, note creation
10+
11+
//Focus on the looping
12+
This should manage creating sprites for notes???
13+
This should manage subview camera pos and zoom.
14+
15+
Movement should primarily be done from a parent node
16+
!!Backgrounds need to be big enough/notes and beats spaced enough that when a note goes off screen, it can be teleported in position offscreen
17+
BackGround probably needs 2 sprites or parallax:
18+
Get a set length, based on viewport and loop/song length (Const PLAYWIDTH)
19+
Once one BG hits a certain left pos return it to the right pos
20+
21+
Notes are similar, but only need 1 representation.
22+
Once hits left bounds return to right bounds
23+
(Something else should probably manage refreshing, input, etc)
24+
Can probably use an object pool
25+
26+
If timing based input checking:
27+
This is enough, notes are visually just sprites
28+
Collision based - This might need to manage that, or have a sister manager that does, notes need more stuff on their own
29+
*/
30+
31+
/**
32+
* @class ChartManager
33+
* @brief Chart Manager is meant to handle the visual aspects of a battle. Setting up the chart background, initial notes, and handle looping. WIP
34+
*/
35+
public partial class ChartManager : SubViewportContainer
36+
{
37+
//Nodes from scene
38+
[Export]
39+
public NoteManager NM;
40+
41+
[Export]
42+
public CanvasGroup ChartLoopables;
43+
44+
public BattleDirector.SongData SongData; //TODO: Maybe. Make settable from outside, but readonly
45+
46+
//Arbitrary vars, play with these
47+
private const double ChartLength = 1400; //Might move this to be song specific?
48+
49+
//Speed that chart objs should move at, to be synced to song, in theory
50+
private double _rateOfChart;
51+
private double _loopLen; //secs
52+
private int _beatsPerLoop;
53+
54+
private void InitBackgrounds()
55+
{
56+
//TODO: Get better visual for BG's, and/or create BG's on demand. Though we should only ever need 2.
57+
int i = 0;
58+
foreach (Node child in ChartLoopables.GetChildren())
59+
{
60+
if (child is Loopable)
61+
{
62+
Loopable loopable = (Loopable)child;
63+
//TODO: Consolidate
64+
loopable.SetSize(new Vector2((float)ChartLength / 2 + 1, Size.Y));
65+
loopable.SetPosition(new Vector2((float)ChartLength / 2 * i, 0));
66+
loopable.Bounds = (float)ChartLength / 2;
67+
loopable.Speed = (float)_rateOfChart;
68+
69+
i++;
70+
}
71+
}
72+
}
73+
74+
private void InitNotes(Note[] notes)
75+
{
76+
foreach (Note noteData in notes)
77+
{
78+
CreateNote(noteData.Type, noteData.Beat);
79+
}
80+
}
81+
82+
public void PrepChart(BattleDirector.SongData songData, Note[] notes)
83+
{
84+
SongData = songData;
85+
86+
_loopLen = SongData.SongLength / SongData.NumLoops;
87+
_beatsPerLoop = (int)(_loopLen / (60f / SongData.Bpm));
88+
89+
_rateOfChart = 700 / _loopLen; //px/s
90+
91+
InitBackgrounds();
92+
InitNotes(notes);
93+
}
94+
95+
//TODO: Rework these
96+
public NoteArrow CreateNote(ArrowType arrow, int beat = 0)
97+
{
98+
var newNote = CreateNote(NM.Arrows[arrow]);
99+
newNote.Bounds =
100+
(float)((double)beat / _beatsPerLoop * (ChartLength / 2)) - newNote.Size.X / 2; //eww
101+
newNote.Position += Vector2.Right * newNote.Bounds;
102+
return newNote;
103+
}
104+
105+
private NoteArrow CreateNote(NoteManager.ArrowData arrowData)
106+
{
107+
var noteScene = ResourceLoader.Load<PackedScene>("res://scenes/NoteManager/note.tscn");
108+
var note = noteScene.Instantiate<NoteArrow>();
109+
110+
note.Init(arrowData, (float)_rateOfChart, -1);
111+
112+
ChartLoopables.AddChild(note);
113+
return note;
114+
}
115+
116+
//TODO: Queue next notes. Needs Timing System
117+
/*The logic:
118+
*Spawn in pos is a proportion (intended beat/beats per loop) = (intended pos/track length in px) ->
119+
* intended pos = intended beat / bpl * track length
120+
*
121+
* Respawn (probably obj pool, or for now new instantiation)
122+
* When a note's pos is at its intended initial pos, queue up and spawn the next note of its beat at intended pos + track length
123+
*/
124+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[gd_scene load_steps=5 format=3 uid="uid://dfevfib11kou1"]
2+
3+
[ext_resource type="Texture2D" uid="uid://b0tvsewgnf2x7" path="res://icon.svg" id="1_0wnka"]
4+
[ext_resource type="Script" path="res://scenes/ChartViewport/ChartManager.cs" id="1_ruh2l"]
5+
[ext_resource type="Script" path="res://scenes/ChartViewport/Loopable.cs" id="3_5u57h"]
6+
[ext_resource type="PackedScene" uid="uid://bn8txx53xlguw" path="res://scenes/NoteManager/note_manager.tscn" id="4_fd5fw"]
7+
8+
[node name="VPContainer" type="SubViewportContainer" node_paths=PackedStringArray("NM", "ChartLoopables")]
9+
offset_right = 480.0
10+
offset_bottom = 220.0
11+
script = ExtResource("1_ruh2l")
12+
NM = NodePath("SubViewport/noteManager")
13+
ChartLoopables = NodePath("SubViewport/ChartLoopables")
14+
15+
[node name="SubViewport" type="SubViewport" parent="."]
16+
handle_input_locally = false
17+
size = Vector2i(480, 220)
18+
render_target_update_mode = 4
19+
20+
[node name="Camera2D" type="Camera2D" parent="SubViewport"]
21+
position = Vector2(240, 110)
22+
23+
[node name="ChartLoopables" type="CanvasGroup" parent="SubViewport"]
24+
unique_name_in_owner = true
25+
26+
[node name="ChartBG1" type="TextureRect" parent="SubViewport/ChartLoopables"]
27+
modulate = Color(2, 2, 2, 1)
28+
offset_top = -46.0
29+
offset_right = 701.0
30+
offset_bottom = 254.0
31+
texture = ExtResource("1_0wnka")
32+
script = ExtResource("3_5u57h")
33+
34+
[node name="ChartBG2" type="TextureRect" parent="SubViewport/ChartLoopables"]
35+
modulate = Color(2, 2, 2, 1)
36+
offset_left = 700.0
37+
offset_top = -46.0
38+
offset_right = 1401.0
39+
offset_bottom = 254.0
40+
texture = ExtResource("1_0wnka")
41+
script = ExtResource("3_5u57h")
42+
43+
[node name="noteManager" parent="SubViewport" instance=ExtResource("4_fd5fw")]

scenes/ChartViewport/Loopable.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using Godot;
3+
4+
/**
5+
* @class Loopable
6+
* @brief A general class fo textures on the chart which should have a position at which point they loop. WIP
7+
*/
8+
public partial class Loopable : TextureRect
9+
{
10+
public float Bounds = 700f; //px Pos to loop or do something at.
11+
public float Speed = 5; //px/s
12+
13+
// Called every frame. 'delta' is the elapsed time since the previous frame.
14+
public override void _Process(double delta)
15+
{
16+
if (Position.X <= -Bounds)
17+
{
18+
Loop();
19+
}
20+
Position += Speed * Vector2.Left * (float)delta;
21+
}
22+
23+
public virtual void Loop()
24+
{
25+
Position = new Vector2(Bounds, Position.Y);
26+
}
27+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[gd_scene load_steps=3 format=3 uid="uid://b0mrgr7h0ty1y"]
2+
3+
[ext_resource type="PackedScene" uid="uid://dfevfib11kou1" path="res://scenes/ChartViewport/ChartViewport.tscn" id="1_1vh1u"]
4+
[ext_resource type="Script" path="res://scenes/ChartViewport/BattleDirector.cs" id="1_jbxt1"]
5+
6+
[node name="ProtoBattleDirector" type="Node2D" node_paths=PackedStringArray("CM", "NM")]
7+
script = ExtResource("1_jbxt1")
8+
CM = NodePath("SubViewport")
9+
NM = NodePath("SubViewport/SubViewport/noteManager")
10+
11+
[node name="SubViewport" parent="." instance=ExtResource("1_1vh1u")]
12+
offset_left = 80.0
13+
offset_top = 140.0
14+
offset_right = 560.0
15+
offset_bottom = 360.0
16+
17+
[node name="ColorRect" type="ColorRect" parent="."]
18+
z_index = -1
19+
offset_left = -70.0
20+
offset_top = -34.0
21+
offset_right = 673.0
22+
offset_bottom = 393.0
23+
color = Color(0.147672, 0.147672, 0.147672, 1)

scripts/noteSystem/assets/right-arrow.png.import renamed to scenes/NoteManager/assets/right-arrow.png.import

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
importer="texture"
44
type="CompressedTexture2D"
55
uid="uid://bucvj4fquqpkr"
6-
path="res://.godot/imported/right-arrow.png-8f579df18e1ada04d965b123ceaf76a0.ctex"
6+
path="res://.godot/imported/right-arrow.png-b3005485b42777a77a9d39fbba48875d.ctex"
77
metadata={
88
"vram_texture": false
99
}
1010

1111
[deps]
1212

13-
source_file="res://scripts/noteSystem/assets/right-arrow.png"
14-
dest_files=["res://.godot/imported/right-arrow.png-8f579df18e1ada04d965b123ceaf76a0.ctex"]
13+
source_file="res://scenes/NoteManager/assets/right-arrow.png"
14+
dest_files=["res://.godot/imported/right-arrow.png-b3005485b42777a77a9d39fbba48875d.ctex"]
1515

1616
[params]
1717

scenes/NoteManager/note.tscn

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[gd_scene load_steps=3 format=3 uid="uid://ck3bfqy30rjbq"]
2+
3+
[ext_resource type="Texture2D" uid="uid://bucvj4fquqpkr" path="res://scenes/NoteManager/assets/right-arrow.png" id="1_kubiy"]
4+
[ext_resource type="Script" path="res://scenes/NoteManager/scripts/NoteArrow.cs" id="2_lbl4b"]
5+
6+
[node name="Right-arrow" type="TextureRect"]
7+
offset_right = 38.0
8+
offset_bottom = 38.0
9+
texture = ExtResource("1_kubiy")
10+
expand_mode = 1
11+
script = ExtResource("2_lbl4b")

0 commit comments

Comments
 (0)