Bouncy Road improvements (#944)
* Add custom notes to Bouncy Road + fix swing animations * Add simple tap controls to Bouncy Road * Add blank pole sounds + volume panning to Bouncy Road
This commit is contained in:
parent
a72a5f73bb
commit
4e39d6f52b
BIN
Assets/Resources/Sfx/games/bouncyRoad/leftBlank.ogg
Normal file
BIN
Assets/Resources/Sfx/games/bouncyRoad/leftBlank.ogg
Normal file
Binary file not shown.
22
Assets/Resources/Sfx/games/bouncyRoad/leftBlank.ogg.meta
Normal file
22
Assets/Resources/Sfx/games/bouncyRoad/leftBlank.ogg.meta
Normal file
|
@ -0,0 +1,22 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9b584037609d9084aa8a838607884dcc
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 6
|
||||
defaultSettings:
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
preloadAudioData: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
Assets/Resources/Sfx/games/bouncyRoad/rightBlank.ogg
Normal file
BIN
Assets/Resources/Sfx/games/bouncyRoad/rightBlank.ogg
Normal file
Binary file not shown.
22
Assets/Resources/Sfx/games/bouncyRoad/rightBlank.ogg.meta
Normal file
22
Assets/Resources/Sfx/games/bouncyRoad/rightBlank.ogg.meta
Normal file
|
@ -0,0 +1,22 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c0997440911c8a543b05babc2e2ed806
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 6
|
||||
defaultSettings:
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 1
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 0
|
||||
normalize: 1
|
||||
preloadAudioData: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -15,6 +15,12 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
|||
|
||||
public Color color;
|
||||
[System.NonSerialized] public bool goal;
|
||||
[System.NonSerialized] public bool useCustomNotes;
|
||||
[System.NonSerialized] public int[] bounceNotes;
|
||||
[System.NonSerialized] public int bounceNote;
|
||||
[System.NonSerialized] public int rightNote;
|
||||
[System.NonSerialized] public int leftNote;
|
||||
[System.NonSerialized] public int goalNote;
|
||||
|
||||
private bool isMiss;
|
||||
|
||||
|
@ -33,9 +39,9 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
|||
|
||||
if (currentCurve is not null)
|
||||
{
|
||||
float curveProg = cond.GetPositionFromBeat(currentBeat, lengthBeat);
|
||||
float curveProg = cond.GetPositionFromBeat(currentBeat, lengthBeat, ignoreSwing: false);
|
||||
if (isMiss) {
|
||||
curveProg = cond.GetPositionFromBeat(currentBeat, lengthBeat/2);
|
||||
curveProg = cond.GetPositionFromBeat(currentBeat, lengthBeat/2, ignoreSwing: false);
|
||||
} else {
|
||||
// curveProg /= (float)(1 + BouncyRoad.ngLateTime);
|
||||
if (curveProg >= 1) curveProg = 1;
|
||||
|
@ -44,9 +50,19 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
|||
}
|
||||
}
|
||||
|
||||
private void Bounce()
|
||||
private void Bounce() {
|
||||
float[] pitches = null;
|
||||
if (bounceNotes != null)
|
||||
{
|
||||
game.PlayBounceSound(startBeat, lengthBeat);
|
||||
pitches = new float[12];
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
|
||||
pitches[i] = GetPitch(bounceNotes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
game.PlayBounceSound(startBeat, lengthBeat, pitches, GetPitch(bounceNote));
|
||||
|
||||
var actions = new List<BeatAction.Action>();
|
||||
|
||||
|
@ -70,7 +86,7 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
|||
|
||||
public void RightSuccess(PlayerActionEvent caller, float state)
|
||||
{
|
||||
SoundByte.PlayOneShotGame("bouncyRoad/ballRight");
|
||||
SoundByte.PlayOneShotGame("bouncyRoad/ballRight", pitch: GetPitch(rightNote));
|
||||
game.ThingsAnim[12].Play("podium", 0, 0);
|
||||
currentCurve = curve[1+12];
|
||||
currentBeat = startBeat + 12 * lengthBeat;
|
||||
|
@ -80,7 +96,7 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
|||
|
||||
public void RightMiss(PlayerActionEvent caller)
|
||||
{
|
||||
SoundByte.PlayOneShotGame("bouncyRoad/ballBounce");
|
||||
SoundByte.PlayOneShotGame("bouncyRoad/ballBounce", pitch: GetPitch(bounceNote));
|
||||
currentCurve = curve[^2];
|
||||
currentBeat = Conductor.instance.songPositionInBeats;
|
||||
isMiss = true;
|
||||
|
@ -95,12 +111,12 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
|||
|
||||
public void LeftSuccess(PlayerActionEvent caller, float state)
|
||||
{
|
||||
SoundByte.PlayOneShotGame("bouncyRoad/ballLeft");
|
||||
SoundByte.PlayOneShotGame("bouncyRoad/ballLeft", pitch: GetPitch(leftNote));
|
||||
game.ThingsAnim[13].Play("podium", 0, 0);
|
||||
currentCurve = curve[1+13];
|
||||
currentBeat = startBeat + 13 * lengthBeat;
|
||||
|
||||
if (goal) SoundByte.PlayOneShotGame("bouncyRoad/goal", startBeat + 14 * lengthBeat);
|
||||
if (goal) SoundByte.PlayOneShotGame("bouncyRoad/goal", startBeat + 14 * lengthBeat, pitch: GetPitch(goalNote));
|
||||
BeatAction.New(game, new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(startBeat + 14 * lengthBeat, delegate
|
||||
|
@ -118,7 +134,7 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
|||
|
||||
public void LeftMiss(PlayerActionEvent caller)
|
||||
{
|
||||
SoundByte.PlayOneShotGame("bouncyRoad/ballBounce");
|
||||
SoundByte.PlayOneShotGame("bouncyRoad/ballBounce", pitch: GetPitch(bounceNote));
|
||||
currentCurve = curve[^1];
|
||||
currentBeat = Conductor.instance.songPositionInBeats;
|
||||
isMiss = true;
|
||||
|
@ -132,5 +148,10 @@ namespace HeavenStudio.Games.Scripts_BouncyRoad
|
|||
}
|
||||
|
||||
public void Empty(PlayerActionEvent caller) { }
|
||||
|
||||
private float GetPitch(int semitones)
|
||||
{
|
||||
return useCustomNotes ? SoundByte.GetPitchFromSemiTones(semitones, true) : 1;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,6 +24,29 @@ namespace HeavenStudio.Games.Loaders
|
|||
{
|
||||
new Param("goal", true, "Play Goal Sound"),
|
||||
new Param("color", Color.white, "Color", "Choose the color of the ball."),
|
||||
new Param("useCustomNotes", false, "Custom Notes", "Toggle if the ball should use custom notes.", new List<Param.CollapseParam>()
|
||||
{
|
||||
new Param.CollapseParam((x, _) => (bool)x, new string[] { "bounceNote", "rightNote", "leftNote", "goalNote", "separateBounceNotes"})
|
||||
}),
|
||||
new Param("separateBounceNotes", false, "Separate Bounce Notes", "Toggle if the ball should use separate notes for the each of the first 12 poles.", new List<Param.CollapseParam>()
|
||||
{
|
||||
new Param.CollapseParam((x, _) => (bool)x, new string[] { "bounceNote2", "bounceNote3", "bounceNote4", "bounceNote5", "bounceNote6", "bounceNote7", "bounceNote8", "bounceNote9", "bounceNote10", "bounceNote11", "bounceNote12" })
|
||||
}),
|
||||
new Param("bounceNote", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note", "Choose the note the ball plays when bouncing on the first 12 poles or the first pole if using custom notes."),
|
||||
new Param("bounceNote2", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 2", "Choose the note the ball plays when bouncing on the second pole."),
|
||||
new Param("bounceNote3", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 3", "Choose the note the ball plays when bouncing on the third pole."),
|
||||
new Param("bounceNote4", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 4", "Choose the note the ball plays when bouncing on the fourth pole."),
|
||||
new Param("bounceNote5", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 5", "Choose the note the ball plays when bouncing on the fifth pole."),
|
||||
new Param("bounceNote6", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 6", "Choose the note the ball plays when bouncing on the sixth pole."),
|
||||
new Param("bounceNote7", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 7", "Choose the note the ball plays when bouncing on the seventh pole."),
|
||||
new Param("bounceNote8", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 8", "Choose the note the ball plays when bouncing on the eighth pole."),
|
||||
new Param("bounceNote9", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 9", "Choose the note the ball plays when bouncing on the ninth pole."),
|
||||
new Param("bounceNote10", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 10", "Choose the note the ball plays when bouncing on the tenth pole."),
|
||||
new Param("bounceNote11", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 11", "Choose the note the ball plays when bouncing on the eleventh pole."),
|
||||
new Param("bounceNote12", new EntityTypes.Note(0, 7, 4, "bouncyRoad/ballBounce"), "Bounce Note 12", "Choose the note the ball plays when bouncing on the twelfth pole."),
|
||||
new Param("rightNote", new EntityTypes.Note(0, 3, 4, "bouncyRoad/ballRight"), "A Note", "Choose the note the ball plays when it bounces on the A pole."),
|
||||
new Param("leftNote", new EntityTypes.Note(0, 10, 4, "bouncyRoad/ballLeft"), "+ Note", "Choose the note the ball plays when it bounces on the + pole."),
|
||||
new Param("goalNote", new EntityTypes.Note(0, 3, 5, "bouncyRoad/goal"), "Goal Note", "Choose the note the ball plays when it bounces on the last pole."),
|
||||
}
|
||||
},
|
||||
new GameAction("background appearance", "Background Appearance")
|
||||
|
@ -87,12 +110,20 @@ namespace HeavenStudio.Games
|
|||
private ColorEase[] colorEases = new ColorEase[2];
|
||||
|
||||
const double BALL_SEEK_TIME = 1.0;
|
||||
private struct ScheduledBall
|
||||
|
||||
public struct ScheduledBall
|
||||
{
|
||||
public double beat;
|
||||
public double length;
|
||||
public bool goal;
|
||||
public Color color;
|
||||
public bool useCustomNotes;
|
||||
public bool seperateBounceNotes;
|
||||
public int[] bounceNotes;
|
||||
public int bounceNote;
|
||||
public int rightNote;
|
||||
public int leftNote;
|
||||
public int goalNote;
|
||||
}
|
||||
List<ScheduledBall> scheduledBalls = new();
|
||||
int ballIndex;
|
||||
|
@ -111,16 +142,18 @@ namespace HeavenStudio.Games
|
|||
}
|
||||
protected static bool IA_TouchLeft(out double dt)
|
||||
{
|
||||
return PlayerInput.GetTouchDown(InputController.ActionsTouch.Left, out dt);
|
||||
return PlayerInput.GetTouchDown(InputController.ActionsTouch.Tap, out dt) && instance.IsExpectingInputNow(InputAction_Left);
|
||||
}
|
||||
|
||||
protected static bool IA_PadRight(out double dt)
|
||||
{
|
||||
return PlayerInput.GetPadDown(InputController.ActionsPad.East, out dt);
|
||||
}
|
||||
protected static bool IA_TouchRight(out double dt)
|
||||
{
|
||||
return PlayerInput.GetTouchDown(InputController.ActionsTouch.Right, out dt);
|
||||
protected static bool IA_TouchRight(out double dt) {
|
||||
return PlayerInput.GetTouchDown(InputController.ActionsTouch.Tap, out dt)
|
||||
&& (instance.IsExpectingInputNow(InputAction_Right)
|
||||
|| (!instance.IsExpectingInputNow(InputAction_Left) && !instance.IsExpectingInputNow(InputAction_Right)));
|
||||
|
||||
}
|
||||
|
||||
public static PlayerInput.InputAction InputAction_Left =
|
||||
|
@ -204,12 +237,30 @@ namespace HeavenStudio.Games
|
|||
foreach (var e in events)
|
||||
{
|
||||
if (e.length == 0) continue;
|
||||
|
||||
int[] bounceNotes = null;
|
||||
if (e["separateBounceNotes"]) {
|
||||
bounceNotes = new int[12];
|
||||
bounceNotes[0] = e["bounceNote"];
|
||||
for (int i = 1; i < 12; i++)
|
||||
{
|
||||
bounceNotes[i] = e[$"bounceNote{i+1}"];
|
||||
}
|
||||
}
|
||||
|
||||
var ball = new ScheduledBall
|
||||
{
|
||||
beat = e.beat,
|
||||
length = e.length,
|
||||
goal = e["goal"],
|
||||
color = e["color"],
|
||||
useCustomNotes = e["useCustomNotes"],
|
||||
seperateBounceNotes = e["separateBounceNotes"],
|
||||
bounceNotes = bounceNotes,
|
||||
bounceNote = e["bounceNote"],
|
||||
rightNote = e["rightNote"],
|
||||
leftNote = e["leftNote"],
|
||||
goalNote = e["goalNote"],
|
||||
};
|
||||
scheduledBalls.Add(ball);
|
||||
}
|
||||
|
@ -228,10 +279,12 @@ namespace HeavenStudio.Games
|
|||
if (PlayerInput.GetIsAction(InputAction_Right) && !IsExpectingInputNow(InputAction_Right))
|
||||
{
|
||||
ThingsAnim[12].Play("podium", 0, 0);
|
||||
SoundByte.PlayOneShotGame("bouncyRoad/rightBlank", volume: .5f);
|
||||
}
|
||||
if (PlayerInput.GetIsAction(InputAction_Left) && !IsExpectingInputNow(InputAction_Left))
|
||||
{
|
||||
ThingsAnim[13].Play("podium", 0, 0);
|
||||
SoundByte.PlayOneShotGame("bouncyRoad/leftBlank", volume: .5f);
|
||||
}
|
||||
|
||||
UpdateBalls();
|
||||
|
@ -246,7 +299,7 @@ namespace HeavenStudio.Games
|
|||
var ball = scheduledBalls[ballIndex];
|
||||
if (ball.beat - ball.length < beat + BALL_SEEK_TIME)
|
||||
{
|
||||
SpawnBall(ball.beat, ball.length, ball.goal, ball.color);
|
||||
SpawnBall(ball);
|
||||
ballIndex++;
|
||||
}
|
||||
else
|
||||
|
@ -256,20 +309,26 @@ namespace HeavenStudio.Games
|
|||
}
|
||||
}
|
||||
|
||||
public void SpawnBall(double beat, double length, bool goal, Color color)
|
||||
public void SpawnBall(ScheduledBall scheduledBall)
|
||||
{
|
||||
var newBall = Instantiate(baseBall, transform).GetComponent<Ball>();
|
||||
|
||||
newBall.startBeat = beat;
|
||||
newBall.lengthBeat = length;
|
||||
newBall.goal = goal;
|
||||
newBall.color = color;
|
||||
newBall.startBeat = scheduledBall.beat;
|
||||
newBall.lengthBeat = scheduledBall.length;
|
||||
newBall.goal = scheduledBall.goal;
|
||||
newBall.color = scheduledBall.color;
|
||||
newBall.useCustomNotes = scheduledBall.useCustomNotes;
|
||||
newBall.bounceNotes = scheduledBall.bounceNotes;
|
||||
newBall.bounceNote = scheduledBall.bounceNote;
|
||||
newBall.rightNote = scheduledBall.rightNote;
|
||||
newBall.leftNote = scheduledBall.leftNote;
|
||||
newBall.goalNote = scheduledBall.goalNote;
|
||||
|
||||
newBall.curve = GetHeightCurve((float)length);
|
||||
newBall.curve = GetHeightCurve((float)scheduledBall.length);
|
||||
|
||||
BeatAction.New(instance, new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(beat - length, delegate
|
||||
new BeatAction.Action(scheduledBall.beat - scheduledBall.length, delegate
|
||||
{
|
||||
newBall.Init();
|
||||
newBall.gameObject.SetActive(true);
|
||||
|
@ -278,13 +337,18 @@ namespace HeavenStudio.Games
|
|||
}
|
||||
|
||||
List<double> bounceBeats = new();
|
||||
public void PlayBounceSound(double beat, double length)
|
||||
public void PlayBounceSound(double beat, double length, float[] pitches, float singlePitch)
|
||||
{
|
||||
var sounds = new List<MultiSound.Sound>();
|
||||
for (int i = 0; i < 12 ; i++)
|
||||
{
|
||||
float volume = .65f;
|
||||
for (int i = 0; i < 12 ; i++) {
|
||||
if (i >= 6) volume += .059f;
|
||||
|
||||
var bounceBeat = beat + i * length;
|
||||
if (!bounceBeats.Contains(bounceBeat)) sounds.Add(new MultiSound.Sound("bouncyRoad/ballBounce", bounceBeat));
|
||||
if (!bounceBeats.Contains(bounceBeat)) {
|
||||
float pitch = pitches == null ? singlePitch : pitches[i];
|
||||
sounds.Add(new MultiSound.Sound("bouncyRoad/ballBounce", bounceBeat, pitch, volume));
|
||||
}
|
||||
bounceBeats.Add(bounceBeat);
|
||||
}
|
||||
MultiSound.Play(sounds.ToArray());
|
||||
|
|
Loading…
Reference in a new issue