diff --git a/rhythm_game/note/visual/hold/hold_note.gd b/rhythm_game/note/visual/hold/hold_note.gd new file mode 100644 index 0000000..515f39d --- /dev/null +++ b/rhythm_game/note/visual/hold/hold_note.gd @@ -0,0 +1,4 @@ +class_name HoldNote extends NoteVisual + +var start_id: int +var end_id: int diff --git a/rhythm_game/note/visual/hold/hold_note.gd.uid b/rhythm_game/note/visual/hold/hold_note.gd.uid new file mode 100644 index 0000000..5eae9a9 --- /dev/null +++ b/rhythm_game/note/visual/hold/hold_note.gd.uid @@ -0,0 +1 @@ +uid://cbsnb8bdby0d diff --git a/rhythm_game/note/visual/hold/hold_note.tscn b/rhythm_game/note/visual/hold/hold_note.tscn new file mode 100644 index 0000000..3506fc9 --- /dev/null +++ b/rhythm_game/note/visual/hold/hold_note.tscn @@ -0,0 +1,3 @@ +[gd_scene format=3 uid="uid://dq5ocf0272tet"] + +[node name="HoldNote" type="Node2D" unique_id=495232990] diff --git a/rhythm_game/note/visual/note_animator.gd b/rhythm_game/note/visual/note_animator.gd new file mode 100644 index 0000000..5753ef6 --- /dev/null +++ b/rhythm_game/note/visual/note_animator.gd @@ -0,0 +1,27 @@ +class_name NoteAnimator extends NoteView + +@export var pool: NotePool + +## TODO WARNING: This is currently only implemented for beat updates +## going forward in time. +func update_current_beat(beat: float) -> void: + var old_begin: int = _begin + var old_end: int = _end + super.update_current_beat(beat) # Update _begin and _end. + _update_note_visuals(old_begin, _begin) + _update_note_visuals(old_end, _end) + + +# ======== IMPLEMENTATION ======== # +var _note_map: Dictionary[int, NoteVisual] + +func _update_note_visuals(index_begin: int, index_end: int) -> void: + for i: int in range(index_begin, index_end): + # TODO: Either get or return node from pool, + # depending on if index_begin > or < than index_end. + pass + +func _set_notes(p_notes: NoteArray) -> void: + + notes = p_notes + _reset_view() diff --git a/rhythm_game/note/visual/note_animator.gd.uid b/rhythm_game/note/visual/note_animator.gd.uid new file mode 100644 index 0000000..13cefd4 --- /dev/null +++ b/rhythm_game/note/visual/note_animator.gd.uid @@ -0,0 +1 @@ +uid://dpu6645p40p43 diff --git a/rhythm_game/note/visual/note_pool.gd b/rhythm_game/note/visual/note_pool.gd new file mode 100644 index 0000000..f72859a --- /dev/null +++ b/rhythm_game/note/visual/note_pool.gd @@ -0,0 +1,84 @@ +class_name NotePool extends Node + +@export_group("Start") +## Tap notes to spawn on [method _ready]. +@export var tap_size: int = 30 + +## Hold notes to spawn on [method _ready]. +@export var hold_size: int = 10 + +@export_group("Skin") +## [StringName] of the tap note skin to use. +@export var tap_skin: StringName = "default" + +## [StringName] of the hold note skin to use. +@export var hold_skin: StringName = "default" + +func get_note(type: NoteVisual.TYPE) -> NoteVisual: + var note: NoteVisual + # TODO: Implement. + return note + +## Get a tap note. Instantiates one if no free nodes are available. +func get_tap() -> TapNote: + var tap: TapNote = _free_taps.pop_back() + if tap == null: + tap = _instantiate_tap() + _used_taps[tap] = true + return tap + +## Return a tap note. +func return_tap(tap: TapNote) -> void: + var parent: Node = tap.get_parent() + if parent: + parent.remove_child(tap) + + if not _used_taps.erase(tap): + push_warning( + "Returning tap note ", tap, + " that was not spawned by pool ", self, "." + ) + _free_taps.append(tap) + +## Get a hold note. Instantiates one if no free nodes are available. +func get_hold() -> HoldNote: + var hold: HoldNote = _free_holds.pop_back() + if hold == null: + hold = _instantiate_hold() + _used_holds[hold] = true + return hold + +## Return a hold note. +func return_hold(hold: HoldNote) -> void: + var parent: Node = hold.get_parent() + if parent: + parent.remove_child(hold) + + if not _used_holds.erase(hold): + push_warning( + "Returning hold note ", hold, + " that was not spawned by pool ", self, "." + ) + _free_holds.append(hold) + +## Spawn the given number of notes. +func reserve(taps: int, holds: int) -> void: + for i: int in range(taps): + _free_taps.append(_instantiate_tap()) + + for i: int in range(holds): + _free_holds.append(_instantiate_hold()) + + +# ========= IMPLEMENTATION ========= # +var _free_taps: Array[TapNote] +var _used_taps: Dictionary[TapNote, bool] + +var _free_holds: Array[HoldNote] +var _used_holds: Dictionary[HoldNote, bool] + +func _instantiate_tap() -> TapNote: + return NoteScenes.get_tap(tap_skin).instantiate() as TapNote + +func _instantiate_hold() -> HoldNote: + return NoteScenes.get_tap(tap_skin).instantiate() as HoldNote diff --git a/rhythm_game/note/visual/note_pool.gd.uid b/rhythm_game/note/visual/note_pool.gd.uid new file mode 100644 index 0000000..731fea7 --- /dev/null +++ b/rhythm_game/note/visual/note_pool.gd.uid @@ -0,0 +1 @@ +uid://clog51kfg2rsb diff --git a/rhythm_game/note/visual/note_scenes.gd b/rhythm_game/note/visual/note_scenes.gd new file mode 100644 index 0000000..d90e204 --- /dev/null +++ b/rhythm_game/note/visual/note_scenes.gd @@ -0,0 +1,26 @@ +## Static class that stores references to note scenes. +class_name NoteScenes extends Object + +static func get_tap(skin: StringName = "default") -> PackedScene: + if _tap_scenes.has(skin): + return _tap_scenes[skin] + else: + push_warning("Tap note skin [", skin, "] does not exist.") + return _tap_scenes["default"] + +static func get_hold(skin: StringName = "default") -> PackedScene: + if _hold_scenes.has(skin): + return _hold_scenes[skin] + else: + push_warning("Hold note skin [", skin, "] does not exist.") + return _hold_scenes["default"] + +# ======== IMPLEMENTATION ======== # + +static var _tap_scenes: Dictionary[StringName, PackedScene] = { + "default": load("uid://dq5ocf0272tet") +} + +static var _hold_scenes: Dictionary[StringName, PackedScene] = { + "default": load("uid://jbgxbhfpj806") +} diff --git a/rhythm_game/note/visual/note_scenes.gd.uid b/rhythm_game/note/visual/note_scenes.gd.uid new file mode 100644 index 0000000..85eafa8 --- /dev/null +++ b/rhythm_game/note/visual/note_scenes.gd.uid @@ -0,0 +1 @@ +uid://bftlqc7ysprwy diff --git a/rhythm_game/note/visual/note_visual.gd b/rhythm_game/note/visual/note_visual.gd new file mode 100644 index 0000000..9feb348 --- /dev/null +++ b/rhythm_game/note/visual/note_visual.gd @@ -0,0 +1,10 @@ +@abstract class_name NoteVisual extends Node2D + +enum TYPE { + TAP = 0, + HOLD = 1 +} + +@abstract func reset() -> void + +@abstract func in_use() -> bool diff --git a/rhythm_game/note/visual/note_visual.gd.uid b/rhythm_game/note/visual/note_visual.gd.uid new file mode 100644 index 0000000..6e0603e --- /dev/null +++ b/rhythm_game/note/visual/note_visual.gd.uid @@ -0,0 +1 @@ +uid://dle62fabvqhrc diff --git a/rhythm_game/note/visual/tap/tap_note.gd b/rhythm_game/note/visual/tap/tap_note.gd new file mode 100644 index 0000000..a3640b0 --- /dev/null +++ b/rhythm_game/note/visual/tap/tap_note.gd @@ -0,0 +1,9 @@ +class_name TapNote extends NoteVisual + +var id: int = -1 + +func reset() -> void: + id = -1 + +func in_use() -> bool: + return id >= 0 diff --git a/rhythm_game/note/visual/tap/tap_note.gd.uid b/rhythm_game/note/visual/tap/tap_note.gd.uid new file mode 100644 index 0000000..2cc8d0d --- /dev/null +++ b/rhythm_game/note/visual/tap/tap_note.gd.uid @@ -0,0 +1 @@ +uid://1qve2pqu1yr4 diff --git a/rhythm_game/note/visual/tap/tap_note.tscn b/rhythm_game/note/visual/tap/tap_note.tscn new file mode 100644 index 0000000..792ba52 --- /dev/null +++ b/rhythm_game/note/visual/tap/tap_note.tscn @@ -0,0 +1,21 @@ +[gd_scene format=3 uid="uid://jbgxbhfpj806"] + +[ext_resource type="Script" uid="uid://1qve2pqu1yr4" path="res://rhythm_game/note/visual/tap/tap_note.gd" id="1_kuk3o"] + +[node name="TapNote" type="Node2D" unique_id=1341974559] +script = ExtResource("1_kuk3o") +metadata/_custom_type_script = "uid://1qve2pqu1yr4" + +[node name="ColorRect" type="ColorRect" parent="." unique_id=743279305] +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -29.0 +offset_top = -6.0 +offset_right = 29.0 +offset_bottom = 6.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0.928887, 0.8138475, 0, 1) diff --git a/rhythm_game/rhythm_game.tscn b/rhythm_game/rhythm_game.tscn index d67f226..307f7a9 100644 --- a/rhythm_game/rhythm_game.tscn +++ b/rhythm_game/rhythm_game.tscn @@ -9,6 +9,7 @@ [ext_resource type="Script" uid="uid://bbpyym0kgujev" path="res://rhythm_game/metronome.gd" id="7_nsyv8"] [ext_resource type="Script" uid="uid://8isyo4pxyj1r" path="res://rhythm_game/note/array/note_array.gd" id="9_10cpq"] [ext_resource type="Script" uid="uid://c7h7ue6kjgoha" path="res://rhythm_game/note/view/note_view.gd" id="9_74aio"] +[ext_resource type="Script" uid="uid://clog51kfg2rsb" path="res://rhythm_game/note/visual/note_pool.gd" id="10_74aio"] [sub_resource type="Resource" id="Resource_10cpq"] script = ExtResource("5_nsyv8") @@ -40,4 +41,8 @@ script = ExtResource("9_74aio") notes = NodePath("../AllChartNotes") metadata/_custom_type_script = "uid://c7h7ue6kjgoha" +[node name="NotePool" type="Node" parent="." unique_id=621311008] +script = ExtResource("10_74aio") +metadata/_custom_type_script = "uid://clog51kfg2rsb" + [connection signal="ticked" from="Conductor" to="Metronome" method="on_conductor_ticked"]