BeatClock
namespace Griff.Scenes;
public sealed class BeatClock : ComponentKeeps time with the music: counts its beats and bars as they’re heard (allowing for the sound card’s delay and the player’s own audio offset, Game.AudioOffset, which a Calibration measures), and sends BeatMessage on every beat and BarMessage on the first beat of every bar, so sound players, counters, scripts and BeatPulses can follow along, and Spawners, Shooters, Movers and Switches with Beats set step to it. It follows whatever music is playing (a BackgroundMusic’s, a room’s or a script’s) and waits while there’s none. Music made with Audio > New Music says its own tempo; for other music, set Tempo.
This is a component: its saved properties are on its component page.
Properties
Section titled “Properties”public int Bar { get; }The bar it’s on, counting from 0.
BarMessage
Section titled “BarMessage”public string? BarMessage { get; set; }Sent on the first beat of every bar, with the bar’s number (0 for the first). Empty sends nothing.
public int Beat { get; }The beat it’s on, counting from 0; -1 before the first.
BeatInBar
Section titled “BeatInBar”public int BeatInBar { get; }Which beat of the bar it’s on, from 0 (the bar’s first, the downbeat) to BeatsPerBar - 1.
BeatMessage
Section titled “BeatMessage”public string? BeatMessage { get; set; }Sent on every beat, with the beat’s number (0 for the first) as its data. Empty sends nothing.
public float Beats { get; }Beats heard since the first, with how far through this one: 8.5 is halfway through beat 8 (the ninth). It counts on as the music loops, and is below 0 before the first beat.
BeatsPerBar
Section titled “BeatsPerBar”public int BeatsPerBar { get; set; }Beats in a bar: 4 for most music, 3 for a waltz.
CurrentTempo
Section titled “CurrentTempo”public float CurrentTempo { get; }The tempo it counts at: its Tempo, or the music’s.
IsPlaying
Section titled “IsPlaying”public bool IsPlaying { get; }True while there’s music to keep time with.
Offset
Section titled “Offset”public float Offset { get; set; }Seconds into the music of its first beat: for music with a lead-in, or to nudge the beat later (more) or earlier (less) until it sits right. It’s the music’s, the same for everyone; how late a player’s own speakers are is their audio offset (Game.AudioOffset), which the clock allows for on top.
public float Phase { get; }How far through the beat it is, from 0 (on it) to almost 1 (the next is due).
Position
Section titled “Position”public float Position { get; }Seconds into the music that have been heard (less the player’s audio offset), back to 0 each time it loops.
SecondsFromBeat
Section titled “SecondsFromBeat”public float SecondsFromBeat { get; }How far it is from the nearest beat, in seconds: negative just before it, positive just after. For timing a press to the music: if (Math.Abs(clock.SecondsFromBeat) < 0.1f) Perfect(); The player’s audio offset is allowed for, so a press on the beat as they hear it is 0.
SecondsPerBeat
Section titled “SecondsPerBeat”public float SecondsPerBeat { get; }How long a beat lasts, in seconds.
public double Shown { get; }The beats drawn: those counted, ahead by the player’s visual offset, for what shows the beat.
ShownBeats
Section titled “ShownBeats”public float ShownBeats { get; }The beats to draw now: Beats ahead by the player’s visual offset (Game.VisualOffset, how late their screen shows things), so what’s drawn to the beat (a BeatPulse, notes coming down a lane) is seen just as the beat is heard. Only drawing goes by it.
public float Tempo { get; set; }Beats a minute. 0 takes the music’s own, when it says (music made with Audio > New Music does), and otherwise counts 120.
Methods
Section titled “Methods”OnBeat
Section titled “OnBeat”public bool OnBeat(int every = 1, int offset = 0)True in the frame a beat lands that’s one of every every, counting from the first, or from offset beats later: what Spawners, Shooters, Movers and Switches with Beats set step on. For a script: if (clock.OnBeat(2)) Jump();
SecondsFrom
Section titled “SecondsFrom”public float SecondsFrom(double beat)How far the music heard is past beat (counted as Beats are, so 16.5 is halfway through the seventeenth), in seconds: negative before it, positive after. The player’s audio offset is allowed for, so a press as they hear the beat reads 0: what a hit judgment compares with its windows, for a note on that beat. if (Math.Abs(clock.SecondsFrom(note)) < 0.05f) Perfect();
Events
Section titled “Events”BarStarted
Section titled “BarStarted”public event Action<int>? BarStartedRaised on the first beat of every bar, with the bar’s number.
BeatStarted
Section titled “BeatStarted”public event Action<int>? BeatStartedRaised on every beat, with its number.