mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-12 13:47:38 +02:00
Playable lockstep + Mr. Upbeat fix! (Lockstep is missing recolorable switchsteppers, many of them, and bach portraits) (#227)
* Added sfx, sprites and folders neccesary. And also made an empty game object for working dough * Started work on the background * Implemented all unanimated sprites * Added Init * Added Prefabs * Added Jumping and Idle Animatins for the Dough Dudes * SmallFix * Start Interval Event Implemented * Added Audio and Small and Big Ball events * Code Improvement + starting making the balls * Added bezier curves * Added First Rendition of Balls * Added NPC Balls and starting doing small transporting animations * SmallFixes * SmallSoundChanges * Implemented Audio and prefunction, not done with it though * In process of fixing set interval * Added more prefunction stuff and also started working on player input * Tried adding player balls, not done, many bugs to fix * Reverted trying to make the playerenterdoughball handle inputs, gonna do it through the main script instead * Sat up input code for later * Input works now! Need to add barely and wrong input animations and fix bugs * Tiny fix * Added first draft of wronginput animations * Finished all input anims, trying to fix bugs * Added finished Spaceship animations * Added Mr Game and Watch WIP and lifting dough dudes * Finished GANDW, fixed some bugs and still fixing bugs, almost done! * DONE * Begun development on tambourine * Working Dough Polish * Added many animations for tambourine * Added Events * Inputs added, near completion * Miss Anims * Animation changes * DONE * fix * FIXED??? * FIXED FOR REAL * Begun fixing lockstep, just needs small fixes and features * Smol fix-ish * Started work on mr upbeat * MrUpbeat fixed, finishing up lockstep * Added BG to lockstep * Added bg colour change * Done with my part
This commit is contained in:
@ -15,23 +15,22 @@ namespace HeavenStudio.Games.Loaders
|
||||
public static Minigame AddGame(EventCaller eventCaller) {
|
||||
return new Minigame("mrUpbeat", "Mr. Upbeat", "FFFFFF", false, false, new List<GameAction>()
|
||||
{
|
||||
new GameAction("prepare", "Prepare")
|
||||
new GameAction("stepping", "Start Stepping")
|
||||
{
|
||||
function = delegate { MrUpbeat.instance.SetInterval(eventCaller.currentEntity.beat); },
|
||||
defaultLength = 0.5f,
|
||||
resizable = true,
|
||||
inactiveFunction = delegate { MrUpbeat.Beep(eventCaller.currentEntity.beat, eventCaller.currentEntity.length); }
|
||||
},
|
||||
new GameAction("go", "Start Stepping")
|
||||
{
|
||||
function = delegate { MrUpbeat.instance.Go(eventCaller.currentEntity.beat); },
|
||||
defaultLength = 4f,
|
||||
preFunction = delegate {var e = eventCaller.currentEntity; MrUpbeat.Stepping(e.beat, e.length); },
|
||||
defaultLength = 4f,
|
||||
resizable = true
|
||||
},
|
||||
new GameAction("ding!", "Finish Stepping")
|
||||
new GameAction("blipping", "Beeping")
|
||||
{
|
||||
function = delegate {var e = eventCaller.currentEntity; MrUpbeat.instance.Blipping(e.beat, e.length); },
|
||||
defaultLength = 4f,
|
||||
resizable = true
|
||||
},
|
||||
new GameAction("ding!", "Ding!")
|
||||
{
|
||||
function = delegate { MrUpbeat.instance.Ding(eventCaller.currentEntity["toggle"]); },
|
||||
defaultLength = 0.5f,
|
||||
defaultLength = 0.5f,
|
||||
parameters = new List<Param>()
|
||||
{
|
||||
new Param("toggle", false, "Applause")
|
||||
@ -49,148 +48,144 @@ namespace HeavenStudio.Games
|
||||
public class MrUpbeat : Minigame
|
||||
{
|
||||
[Header("References")]
|
||||
public GameObject metronome;
|
||||
public Animator metronomeAnim;
|
||||
public UpbeatMan man;
|
||||
public GameObject bt;
|
||||
private static MultiSound beeps; //only used when this game isn't active.
|
||||
|
||||
public GameEvent beat = new GameEvent();
|
||||
public bool canGo = false;
|
||||
public int beatCount = 0;
|
||||
|
||||
public float beatOffset = 0f;
|
||||
[Header("Properties")]
|
||||
static List<queuedUpbeatInputs> queuedInputs = new List<queuedUpbeatInputs>();
|
||||
public struct queuedUpbeatInputs
|
||||
{
|
||||
public float beat;
|
||||
public bool goRight;
|
||||
}
|
||||
|
||||
public static MrUpbeat instance;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
instance = this;
|
||||
canGo = false;
|
||||
man.stepTimes = 0;
|
||||
SetInterval(0);
|
||||
var pos = Conductor.instance.songPositionInBeats;
|
||||
StartCoroutine(Upbeat(pos - Mathf.Round(pos)));
|
||||
}
|
||||
|
||||
List<float> gos = GameManager.instance.Beatmap.entities.FindAll(c => c.datamodel == "mrUpbeat/go").Select(c => c.beat).ToList();
|
||||
|
||||
if (gos.Count > 0)
|
||||
void OnDestroy()
|
||||
{
|
||||
if (!Conductor.instance.isPlaying || Conductor.instance.isPaused)
|
||||
{
|
||||
var nextInterval = gos.IndexOf(Mathp.GetClosestInList(gos, Conductor.instance.songPositionInBeats));
|
||||
beatOffset = gos[nextInterval];
|
||||
if (queuedInputs.Count > 0) queuedInputs.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
public void Update()
|
||||
{
|
||||
List<DynamicBeatmap.DynamicEntity> gos = GameManager.instance.Beatmap.entities.FindAll(c => c.datamodel == "mrUpbeat/go");
|
||||
for (int i = 0; i < gos.Count; i++)
|
||||
var cond = Conductor.instance;
|
||||
if (cond.isPlaying && !cond.isPaused)
|
||||
{
|
||||
if ((gos[i].beat - 0.15f) <= Conductor.instance.songPositionInBeats && (gos[i].beat + gos[i].length) - 0.15f > Conductor.instance.songPositionInBeats)
|
||||
if (queuedInputs.Count > 0)
|
||||
{
|
||||
canGo = true;
|
||||
break;
|
||||
} else
|
||||
{
|
||||
canGo = false;
|
||||
foreach (var input in queuedInputs)
|
||||
{
|
||||
ScheduleInput(cond.songPositionInBeats, input.beat - cond.songPositionInBeats, InputType.STANDARD_DOWN, Success, Miss, Nothing);
|
||||
if (input.goRight)
|
||||
{
|
||||
BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(input.beat - 0.5f, delegate { MrUpbeat.instance.metronomeAnim.DoScaledAnimationAsync("MetronomeGoLeft", 0.5f); }),
|
||||
new BeatAction.Action(input.beat - 0.5f, delegate { Jukebox.PlayOneShotGame("mrUpbeat/metronomeRight"); }),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(input.beat - 0.5f, delegate { MrUpbeat.instance.metronomeAnim.DoScaledAnimationAsync("MetronomeGoRight", 0.5f); }),
|
||||
new BeatAction.Action(input.beat - 0.5f, delegate { Jukebox.PlayOneShotGame("mrUpbeat/metronomeLeft"); }),
|
||||
});
|
||||
}
|
||||
}
|
||||
queuedInputs.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (canGo)
|
||||
{
|
||||
var songPos = Conductor.instance.songPositionInBeats - beatOffset;
|
||||
metronome.transform.eulerAngles = new Vector3(0, 0, 270 - Mathf.Cos(Mathf.PI * songPos) * 60);
|
||||
}
|
||||
|
||||
if (Conductor.instance.ReportBeat(ref beat.lastReportedBeat))
|
||||
{
|
||||
StartCoroutine(Upbeat());
|
||||
if (canGo)
|
||||
{
|
||||
if (beatCount % 2 == 0)
|
||||
Jukebox.PlayOneShotGame("mrUpbeat/metronomeRight");
|
||||
else
|
||||
Jukebox.PlayOneShotGame("mrUpbeat/metronomeLeft");
|
||||
|
||||
Beat(Mathf.Round(Conductor.instance.songPositionInBeats));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGameSwitch(float beat)
|
||||
{
|
||||
foreach (var entity in GameManager.instance.Beatmap.entities)
|
||||
{
|
||||
if (entity.beat > beat) //the list is sorted based on the beat of the entity, so this should work fine.
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (entity.datamodel != "mrUpbeat/prepare" || entity.beat + entity.length < beat) //check for prepares that happen before the switch
|
||||
{
|
||||
continue;
|
||||
}
|
||||
SetInterval(entity.beat);
|
||||
break;
|
||||
}
|
||||
if(beeps != null)
|
||||
{
|
||||
beeps.Delete(); //the beeps are only for when the game isn't active
|
||||
beeps = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetInterval(float beat)
|
||||
{
|
||||
beatCount = 0;
|
||||
man.targetBeat = beat + 320f;
|
||||
man.Idle();
|
||||
}
|
||||
|
||||
public void Go(float beat)
|
||||
{
|
||||
beatCount = 0;
|
||||
}
|
||||
|
||||
public void Ding(bool applause)
|
||||
{
|
||||
Jukebox.PlayOneShotGame("mrUpbeat/ding");
|
||||
if (applause)
|
||||
Jukebox.PlayOneShot("applause");
|
||||
if (applause) Jukebox.PlayOneShot("applause");
|
||||
}
|
||||
|
||||
public void Beat(float beat)
|
||||
public void Blipping(float beat, float length)
|
||||
{
|
||||
beatCount++;
|
||||
|
||||
GameObject _beat = Instantiate(bt);
|
||||
_beat.transform.parent = bt.transform.parent;
|
||||
_beat.SetActive(true);
|
||||
UpbeatStep s = _beat.GetComponent<UpbeatStep>();
|
||||
s.startBeat = beat;
|
||||
s.beatOffset = beatOffset;
|
||||
for (int i = 0; i < length + 1; i++)
|
||||
{
|
||||
BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(beat + i, delegate { man.Blip(); }),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator Upbeat(float offset = 0)
|
||||
public static void Stepping(float beat, float length)
|
||||
{
|
||||
yield return new WaitForSeconds(Conductor.instance.secPerBeat * 0.5f - offset);
|
||||
man.Blip();
|
||||
if (GameManager.instance.currentGame == "mrUpbeat")
|
||||
{
|
||||
float offSet = 0;
|
||||
if (!MrUpbeat.instance.isPlaying(MrUpbeat.instance.metronomeAnim, "MetronomeIdle") && !MrUpbeat.instance.isPlaying(MrUpbeat.instance.metronomeAnim, "MetronomeGoRight"))
|
||||
{
|
||||
offSet = 1;
|
||||
}
|
||||
for (int i = 0; i < length + 1; i++)
|
||||
{
|
||||
MrUpbeat.instance.ScheduleInput(beat - 1, 1 + i, InputType.STANDARD_DOWN, MrUpbeat.instance.Success, MrUpbeat.instance.Miss, MrUpbeat.instance.Nothing);
|
||||
if ((i + offSet) % 2 == 0)
|
||||
{
|
||||
BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(beat + i - 0.5f, delegate { MrUpbeat.instance.metronomeAnim.DoScaledAnimationAsync("MetronomeGoLeft", 0.5f); }),
|
||||
new BeatAction.Action(beat + i - 0.5f, delegate { Jukebox.PlayOneShotGame("mrUpbeat/metronomeRight"); }),
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
BeatAction.New(instance.gameObject, new List<BeatAction.Action>()
|
||||
{
|
||||
new BeatAction.Action(beat + i - 0.5f, delegate { MrUpbeat.instance.metronomeAnim.DoScaledAnimationAsync("MetronomeGoRight", 0.5f); }),
|
||||
new BeatAction.Action(beat + i - 0.5f, delegate { Jukebox.PlayOneShotGame("mrUpbeat/metronomeLeft"); }),
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < length + 1; i++)
|
||||
{
|
||||
queuedInputs.Add(new queuedUpbeatInputs
|
||||
{
|
||||
beat = beat + i,
|
||||
goRight = i % 2 == 0
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Beep(float beat, float length)
|
||||
public void Success(PlayerActionEvent caller, float state)
|
||||
{
|
||||
if(GameManager.instance.currentGame == "mrUpbeat") //this function is only meant for making beeps while the game is inactive
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (beeps != null)
|
||||
{
|
||||
beeps.Delete();
|
||||
}
|
||||
MultiSound.Sound[] beepSounds = new MultiSound.Sound[Mathf.CeilToInt(length)];
|
||||
for(int i = 0; i < beepSounds.Length; i++)
|
||||
{
|
||||
beepSounds[i] = new MultiSound.Sound("mrUpbeat/blip", beat + 0.5f + i);
|
||||
}
|
||||
beeps = MultiSound.Play(beepSounds, forcePlay:true);
|
||||
man.Step();
|
||||
}
|
||||
|
||||
public void Miss(PlayerActionEvent caller)
|
||||
{
|
||||
man.Fall();
|
||||
}
|
||||
|
||||
bool isPlaying(Animator anim, string stateName)
|
||||
{
|
||||
if (anim.GetCurrentAnimatorStateInfo(0).IsName(stateName) &&
|
||||
anim.GetCurrentAnimatorStateInfo(0).normalizedTime < 1.0f)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Nothing(PlayerActionEvent caller) {}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user