Compare commits
3 Commits
dfac4bbfa5
...
7bc4246375
| Author | SHA1 | Date | |
|---|---|---|---|
| 7bc4246375 | |||
| 3a9d3046b2 | |||
| 72f9b8eea5 |
@@ -4,6 +4,6 @@ class_name Lane extends Node2D
|
|||||||
func get_hit_pos() -> Vector2:
|
func get_hit_pos() -> Vector2:
|
||||||
return position
|
return position
|
||||||
|
|
||||||
|
## Should be connected to [signal NoteSpawner.notes_spawned].
|
||||||
func update(_beat: BeatUpdate) -> void:
|
func update(beat: float) -> void:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ class_name LaneView extends NoteView
|
|||||||
func get_data() -> NoteSubset:
|
func get_data() -> NoteSubset:
|
||||||
return _lane_notes
|
return _lane_notes
|
||||||
|
|
||||||
func update_current_beat(beat: float) -> void:
|
func update(beat: float) -> void:
|
||||||
_current_beat = beat
|
_update_view_relative_to_notes(_lane_notes, beat)
|
||||||
_update_view_relative_to_notes(_lane_notes)
|
_previous_beat = beat
|
||||||
|
|
||||||
# ======== Implementation ======== #
|
# ======== Implementation ======== #
|
||||||
var _lane_notes: NoteSubset
|
var _lane_notes: NoteSubset
|
||||||
@@ -18,4 +18,4 @@ var _lane_notes: NoteSubset
|
|||||||
func _set_data(p_notes: NoteArray) -> void:
|
func _set_data(p_notes: NoteArray) -> void:
|
||||||
notes = p_notes
|
notes = p_notes
|
||||||
_lane_notes = NoteSubset.get_notes_in_lane(p_notes, lane)
|
_lane_notes = NoteSubset.get_notes_in_lane(p_notes, lane)
|
||||||
_reset_view()
|
reset_view()
|
||||||
|
|||||||
@@ -8,12 +8,41 @@ class_name NoteView extends View
|
|||||||
func get_data() -> NoteArray:
|
func get_data() -> NoteArray:
|
||||||
return notes
|
return notes
|
||||||
|
|
||||||
func update_current_beat(beat: float) -> void:
|
func update(beat: float) -> void:
|
||||||
_current_beat = beat
|
_update_view_relative_to_notes(notes, beat)
|
||||||
_update_view_relative_to_notes(notes)
|
_previous_beat = beat
|
||||||
|
|
||||||
|
func reset_view() -> void:
|
||||||
|
super.reset_view()
|
||||||
|
_previous_beat = -999.0
|
||||||
|
|
||||||
# ======= IMPLEMENTATION ======= #
|
# ======= IMPLEMENTATION ======= #
|
||||||
|
var _previous_beat: float = -999.0
|
||||||
|
|
||||||
func _set_notes(p_notes: NoteArray) -> void:
|
func _set_notes(p_notes: NoteArray) -> void:
|
||||||
notes = p_notes
|
notes = p_notes
|
||||||
_reset_view()
|
reset_view()
|
||||||
|
|
||||||
|
## Update the view to match _current_beat.
|
||||||
|
func _update_view_relative_to_notes(p_notes: NoteArray, new_beat: float) -> void:
|
||||||
|
var new_begin = _begin
|
||||||
|
var new_end = _end
|
||||||
|
if new_beat > _previous_beat:
|
||||||
|
# Update forward.
|
||||||
|
while(new_begin < p_notes.size()) and (p_notes.beat_at(new_begin) < new_beat + offset_begin):
|
||||||
|
new_begin += 1
|
||||||
|
while(new_end < p_notes.size()) and (p_notes.beat_at(new_end) <= new_beat + offset_end):
|
||||||
|
new_end += 1
|
||||||
|
elif new_beat < _previous_beat:
|
||||||
|
# Update backward.
|
||||||
|
while(new_begin >= 0) and (p_notes.beat_at(new_begin) >= new_beat + offset_begin):
|
||||||
|
_begin -= 1
|
||||||
|
while(new_end >= 0) and (p_notes.beat_at(new_end) > new_beat + offset_end):
|
||||||
|
new_end -= 1
|
||||||
|
if(new_begin != _begin):
|
||||||
|
new_begin += 1
|
||||||
|
if(new_end != _end):
|
||||||
|
new_end += 1
|
||||||
|
|
||||||
|
_begin = new_begin
|
||||||
|
_end = new_end
|
||||||
|
|||||||
@@ -7,7 +7,12 @@
|
|||||||
|
|
||||||
## Update the view to be relative to beat.
|
## Update the view to be relative to beat.
|
||||||
## Can be connected to a beat update signal.
|
## Can be connected to a beat update signal.
|
||||||
@abstract func update_current_beat(beat: float) -> void
|
@abstract func update(beat: float) -> void
|
||||||
|
|
||||||
|
## Reset the view.
|
||||||
|
func reset_view() -> void:
|
||||||
|
_begin = -1
|
||||||
|
_end = -1
|
||||||
|
|
||||||
## Beginning of the range relative to te current beat where notes will be visible.
|
## Beginning of the range relative to te current beat where notes will be visible.
|
||||||
## Any notes where (hit_beat < current_beat + offset_begin) will NOT be visible.
|
## Any notes where (hit_beat < current_beat + offset_begin) will NOT be visible.
|
||||||
@@ -32,37 +37,3 @@ func size() -> int:
|
|||||||
# ======= IMPLEMENETATION ======= #
|
# ======= IMPLEMENETATION ======= #
|
||||||
var _begin: int = -1
|
var _begin: int = -1
|
||||||
var _end: int = -1
|
var _end: int = -1
|
||||||
|
|
||||||
var _current_beat: float = -999
|
|
||||||
var _previous_beat: float = -999
|
|
||||||
|
|
||||||
func _reset_view() -> void:
|
|
||||||
_begin = -1
|
|
||||||
_end = -1
|
|
||||||
_current_beat = -999
|
|
||||||
_previous_beat = -999
|
|
||||||
|
|
||||||
## Update the view to match _current_beat.
|
|
||||||
func _update_view_relative_to_notes(notes: NoteArray) -> void:
|
|
||||||
var new_begin = _begin
|
|
||||||
var new_end = _end
|
|
||||||
if _current_beat > _previous_beat:
|
|
||||||
# Update forward.
|
|
||||||
while(new_begin < notes.size()) and (notes.beat_at(new_begin) < _current_beat + offset_begin):
|
|
||||||
new_begin += 1
|
|
||||||
while(new_end < notes.size()) and (notes.beat_at(new_end) <= _current_beat + offset_end):
|
|
||||||
new_end += 1
|
|
||||||
elif _current_beat < _previous_beat:
|
|
||||||
# Update backward.
|
|
||||||
while(new_begin >= 0) and (notes.beat_at(new_begin) >= _current_beat + offset_begin):
|
|
||||||
_begin -= 1
|
|
||||||
while(new_end >= 0) and (notes.beat_at(new_end) > _current_beat + offset_end):
|
|
||||||
new_end -= 1
|
|
||||||
if(new_begin != _begin):
|
|
||||||
new_begin += 1
|
|
||||||
if(new_end != _end):
|
|
||||||
new_end += 1
|
|
||||||
|
|
||||||
_begin = new_begin
|
|
||||||
_end = new_end
|
|
||||||
_previous_beat = _current_beat
|
|
||||||
|
|||||||
@@ -1,4 +1,18 @@
|
|||||||
class_name HoldNote extends NoteVisual
|
class_name HoldNote extends NoteVisual
|
||||||
|
|
||||||
|
@export var start: Node2D
|
||||||
|
|
||||||
|
@export var end: Node2D
|
||||||
|
|
||||||
var start_id: int
|
var start_id: int
|
||||||
var end_id: int
|
var end_id: int
|
||||||
|
|
||||||
|
func reset() -> void:
|
||||||
|
start_id = -1
|
||||||
|
end_id = -1
|
||||||
|
|
||||||
|
func in_use() -> bool:
|
||||||
|
return start_id >= 0 or end_id >= 0
|
||||||
|
|
||||||
|
func update(beat: float) -> void:
|
||||||
|
pass
|
||||||
|
|||||||
@@ -1,3 +1,39 @@
|
|||||||
[gd_scene format=3 uid="uid://dq5ocf0272tet"]
|
[gd_scene format=3 uid="uid://dq5ocf0272tet"]
|
||||||
|
|
||||||
[node name="HoldNote" type="Node2D" unique_id=495232990]
|
[ext_resource type="Script" uid="uid://cbsnb8bdby0d" path="res://rhythm_game/note/visual/hold/hold_note.gd" id="1_5cv34"]
|
||||||
|
|
||||||
|
[node name="HoldNote" type="Node2D" unique_id=320259211]
|
||||||
|
script = ExtResource("1_5cv34")
|
||||||
|
metadata/_custom_type_script = "uid://cbsnb8bdby0d"
|
||||||
|
|
||||||
|
[node name="NoteStart" type="Node2D" parent="." unique_id=1911676927]
|
||||||
|
|
||||||
|
[node name="ColorRect" type="ColorRect" parent="NoteStart" unique_id=1232591431]
|
||||||
|
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.93, 0, 0, 1)
|
||||||
|
|
||||||
|
[node name="NoteEnd" type="Node2D" parent="." unique_id=2007025807]
|
||||||
|
|
||||||
|
[node name="ColorRect" type="ColorRect" parent="NoteEnd" unique_id=1179831333]
|
||||||
|
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.93, 0, 0, 1)
|
||||||
|
|||||||
@@ -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()
|
|
||||||
@@ -15,9 +15,21 @@ class_name NotePool extends Node
|
|||||||
@export var hold_skin: StringName = "default"
|
@export var hold_skin: StringName = "default"
|
||||||
|
|
||||||
func get_note(type: NoteVisual.TYPE) -> NoteVisual:
|
func get_note(type: NoteVisual.TYPE) -> NoteVisual:
|
||||||
var note: NoteVisual
|
match type:
|
||||||
# TODO: Implement.
|
NoteVisual.TYPE.TAP:
|
||||||
return note
|
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.
|
## Get a tap note. Instantiates one if no free nodes are available.
|
||||||
func get_tap() -> TapNote:
|
func get_tap() -> TapNote:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
## Static class that stores references to note scenes.
|
## Static class that stores references to note scenes.
|
||||||
class_name NoteScenes extends Object
|
@abstract class_name NoteScenes extends Object
|
||||||
|
|
||||||
static func get_tap(skin: StringName = "default") -> PackedScene:
|
static func get_tap(skin: StringName = "default") -> PackedScene:
|
||||||
if _tap_scenes.has(skin):
|
if _tap_scenes.has(skin):
|
||||||
|
|||||||
91
rhythm_game/note/visual/note_spawner.gd
Normal file
91
rhythm_game/note/visual/note_spawner.gd
Normal 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
|
||||||
@@ -8,3 +8,15 @@ enum TYPE {
|
|||||||
@abstract func reset() -> void
|
@abstract func reset() -> void
|
||||||
|
|
||||||
@abstract func in_use() -> bool
|
@abstract func in_use() -> bool
|
||||||
|
|
||||||
|
@abstract func update(beat: float) -> void
|
||||||
|
|
||||||
|
# ======= IMPLEMENTATION ======= #
|
||||||
|
var _lane: Lane = null
|
||||||
|
|
||||||
|
func _notification(what: int) -> void:
|
||||||
|
match what:
|
||||||
|
NOTIFICATION_PARENTED:
|
||||||
|
_lane = get_parent() as Lane
|
||||||
|
NOTIFICATION_UNPARENTED:
|
||||||
|
_lane = null
|
||||||
|
|||||||
@@ -2,8 +2,13 @@ class_name TapNote extends NoteVisual
|
|||||||
|
|
||||||
var id: int = -1
|
var id: int = -1
|
||||||
|
|
||||||
|
#TODO: Add all the members needed so a note can be updated.
|
||||||
|
|
||||||
func reset() -> void:
|
func reset() -> void:
|
||||||
id = -1
|
id = -1
|
||||||
|
|
||||||
func in_use() -> bool:
|
func in_use() -> bool:
|
||||||
return id >= 0
|
return id >= 0
|
||||||
|
|
||||||
|
func update(beat: float) -> void:
|
||||||
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user