Implement note spawner.

This commit is contained in:
2026-02-01 23:17:51 +08:00
parent 3a9d3046b2
commit 7bc4246375
8 changed files with 151 additions and 75 deletions

View File

@@ -1,27 +0,0 @@
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()

View File

@@ -15,9 +15,21 @@ class_name NotePool extends Node
@export var hold_skin: StringName = "default"
func get_note(type: NoteVisual.TYPE) -> NoteVisual:
var note: NoteVisual
# TODO: Implement.
return note
match type:
NoteVisual.TYPE.TAP:
return get_tap()
NoteVisual.TYPE.HOLD:
return get_hold()
_:
return null
func return_note(note: NoteVisual) -> void:
if note is TapNote:
note.reset()
return_tap(note as TapNote)
elif note is HoldNote:
note.reset()
return_hold(note as HoldNote)
## Get a tap note. Instantiates one if no free nodes are available.
func get_tap() -> TapNote:

View File

@@ -0,0 +1,91 @@
class_name NoteSpawner extends NoteView
signal notes_spawned(beat: float)
@export var lanes: Dictionary[int, Lane]
@export var pool: NotePool
## Spawn all the notes that should exist on this beat.
func update(beat: float) -> void:
var old_begin: int = _begin
var old_end: int = _end
_update_view_relative_to_notes(notes, beat) # Updates _begin and _end.
if _previous_beat <= beat:
_set_note_visuals(old_end, _end)
_remove_note_visuals(old_begin, _begin)
else:
_remove_note_visuals(_end, old_end)
_set_note_visuals(_begin, old_begin)
_previous_beat = beat
notes_spawned.emit(beat)
# ======== IMPLEMENTATION ======== #
var _note_visuals: Dictionary[int, NoteVisual] # [Note ID, Note Visual]
var _last_lane_holds: Dictionary[int, HoldNote]
func _set_notes(p_notes: NoteArray) -> void:
super._set_notes(p_notes)
for note in _note_visuals.values():
if note == null:
continue
pool.return_note(note)
# TODO Finish implementation.
# Spawn or delete nodes in the range.
func _set_note_visuals(index_begin: int, index_end: int) -> void:
for note_id: int in range(index_begin, index_end):
match notes.type_at(note_id):
Note.TYPE.TAP:
_set_visual_for_tap_at(note_id)
Note.TYPE.HOLD_START:
_set_visual_for_hold_start_at(note_id)
Note.TYPE.HOLD_END:
_set_visual_for_hold_end_at(note_id)
func _remove_note_visuals(index_begin: int, index_end: int) -> void:
for note_id: int in range(index_begin, index_end):
match notes.type_at(note_id):
Note.TYPE.TAP:
_remove_visual_for_tap_at(note_id)
Note.TYPE.HOLD_START:
_remove_visual_for_hold_start_at(note_id)
Note.TYPE.HOLD_END:
_remove_visual_for_hold_end_at(note_id)
func _set_visual_for_tap_at(note_id: int) -> void:
var lane_id: int = notes.lane_at(note_id)
var lane: Lane = lanes[lane_id]
var note: TapNote = pool.get_tap()
lane.add_child(note)
_note_visuals[note_id] = note
func _set_visual_for_hold_start_at(note_id: int) -> void:
var lane_id: int = notes.lane_at(note_id)
var lane: Lane = lanes[lane_id]
var note: HoldNote = pool.get_hold()
lane.add_child(note)
_note_visuals[note_id] = note
_last_lane_holds[lane_id] = note
func _set_visual_for_hold_end_at(note_id: int) -> void:
var lane_id: int = notes.lane_at(note_id)
var lane: Lane = lanes[lane_id]
var note: HoldNote = _last_lane_holds[lane_id]
if note == null:
note = pool.get_hold()
lane.add_child(note)
_note_visuals[note_id] = note
_last_lane_holds[lane_id] = null
func _remove_visual_for_tap_at(note_id: int) -> void:
pass
func _remove_visual_for_hold_start_at(note_id: int) -> void:
pass
func _remove_visual_for_hold_end_at(note_id: int) -> void:
pass