Skip to content

Commit

Permalink
Added on_beat_hit and on_step_hit to MusicBeatScene
Browse files Browse the repository at this point in the history
Closes #3
  • Loading branch information
Square789 committed Sep 27, 2021
1 parent e8c47aa commit 2988772
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 3 deletions.
39 changes: 39 additions & 0 deletions pyday_night_funkin/conductor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@

import typing as t


class BPMChangeEvent():
__slots__ = ("step_time", "song_time", "bpm")

def __init__(self, step_time: float, song_time: float, bpm: float) -> None:
self.step_time = step_time
self.song_time = song_time
self.bpm = bpm


# The tiniest conductor
class Conductor():
# https://ninjamuffin99.newgrounds.com/news/post/1124589
Expand All @@ -13,6 +23,7 @@ def __init__(self) -> None:
self.beat_duration = None
self.step_duration = None
self.song_position = 0.0
self._bpm_changes: t.List[BPMChangeEvent] = []

@property
def bpm(self) -> t.Optional[float]:
Expand All @@ -30,3 +41,31 @@ def bpm(self, new_bpm: float) -> None:
# step is just a quarter beat duration
# idk about music this probably has a reason
self.step_duration = self.beat_duration / 4.0

@property
def last_bpm_change(self) -> BPMChangeEvent:
r = BPMChangeEvent(0.0, 0.0, 0.0)
# NOTE: pretty intensive loop, could be kept track of way easier by
# adding a song_position property
for change in self._bpm_changes:
if self.song_position >= change.song_time:
r = change
else:
break
return r

def load_bpm_changes(self, song_data) -> None:
bpm_changes = []
cur_bpm = song_data["song"]["bpm"]
total_steps = 0
total_pos = 0.0
for section in song_data["song"]["notes"]:
if "changeBPM" in section and section["changeBPM"] and section["bpm"] != cur_bpm:
cur_bpm = section["bpm"]
bpm_changes.append(BPMChangeEvent(total_steps, total_pos, cur_bpm))

step_delta = section["lengthInSteps"]
total_steps += step_delta
total_pos += (15000.0 / cur_bpm) * step_delta

self._bpm_changes = bpm_changes
2 changes: 0 additions & 2 deletions pyday_night_funkin/graphics/pnf_sprite.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,6 @@ def __init__(
self.current_animation: t.Optional[str] = None
self.camera = camera

self.asdfdebug = False

self._x = x
self._y = y

Expand Down
5 changes: 5 additions & 0 deletions pyday_night_funkin/scenes/in_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ def load_song(self) -> t.Dict:
self.voice_player.queue(voices)

self.conductor.bpm = song_data["song"]["bpm"]
self.conductor.load_bpm_changes(song_data)
self.note_handler.feed_song_data(song_data)

def start_song(self) -> None:
Expand Down Expand Up @@ -124,3 +125,7 @@ def process_input(self, dt: float) -> None:
handled here.
"""
pass

def on_beat_hit(self) -> None:
super().on_beat_hit()
logger.debug("beat hit")
20 changes: 19 additions & 1 deletion pyday_night_funkin/scenes/music_beat.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@

from math import floor

from pyday_night_funkin.conductor import Conductor
from pyday_night_funkin.scenes._base import BaseScene


class MusicBeatScene(BaseScene):

def __init__(self, *args, **kwargs) -> None:
Expand All @@ -14,5 +17,20 @@ def __init__(self, *args, **kwargs) -> None:
def update(self, dt: float) -> None:
super().update(dt)

# TODO: beat hit stuff
old_step = self.cur_step

lc = self.conductor.last_bpm_change
self.cur_step = lc.step_time + floor(
(self.conductor.song_position - lc.song_time) / self.conductor.step_duration
)
self.cur_beat = floor(self.cur_step / 4)

if old_step != self.cur_step:
self.on_step_hit()

def on_beat_hit(self) -> None:
pass

def on_step_hit(self) -> None:
if self.cur_step % 4 == 0:
self.on_beat_hit()

0 comments on commit 2988772

Please sign in to comment.