Separated time sequences

This commit is contained in:
2025-12-14 16:50:47 +01:00
parent a2a576a0c9
commit 8cf3f95af9
30 changed files with 1034 additions and 886 deletions

View File

@@ -15,12 +15,12 @@ MonoBehaviour:
serializedUdonProgramAsset: {fileID: 11400000, guid: ff2ee01d710668d489ec69b41b7dd764, type: 2}
udonAssembly:
assemblyError:
sourceCsScript: {fileID: 11500000, guid: 88e88d9bfa304c8448489e53fc031f74, type: 3}
sourceCsScript: {fileID: 11500000, guid: 501bd6c4adad10344a5e5dc0598e0b24, type: 3}
scriptVersion: 2
compiledVersion: 2
behaviourSyncMode: 0
hasInteractEvent: 0
scriptID: 666638420973985565
scriptID: -3120331848572677586
serializationData:
SerializedFormat: 2
SerializedBytes:

View File

@@ -11,7 +11,7 @@ namespace Marro.PacManUdon
using VRC.Udon.Common.Interfaces;
using VRC.SDK3.Data;
public class GameManager : UdonSharpBehaviour
public partial class GameManager : UdonSharpBehaviour
{
[Header("Static game components")]
[SerializeField] private Maze[] mazes;
@@ -468,7 +468,10 @@ namespace Marro.PacManUdon
}
#region TIME SEQUENCE BEHAVIOUR
// This was supposed to be a separate class, right until the moment I realized Udon doesn't support instantiating classes...
// A note about the quality of the code here:
// I intended to write this using proper classes, right until I realized Udon does not support instantiating classes.
// While I'm not a big fan of the partial class solution that I ended up doing (static classes would still be neater, or perhaps separate UdonSharpBehaviour instances),
// I'm not redoing this unless I get instantiatable classes before I wrap up this project.
bool currentlyInTimeSequence;
PacManTimeSequence currentTimeSequence;
@@ -659,818 +662,6 @@ namespace Marro.PacManUdon
return absolute;
}
private void TimeSequenceStepAttractScreenIntroduction(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
SetGameState(PacManGameState.AttractMode);
// Initialize
soundManager.SuppressSound(true);
RestartLevel();
HideEverything();
SetFrozen(true);
attractScreen.gameObject.SetActive(true);
attractScreen.Initialize();
for (int i = 0; i <= 15; i++)
{
// Debug.Log($"{gameObject} TimeSequenceAttractScreen deactivating with iteration i");
attractScreenElements[i].SetActive(false);
}
attractScreen.SetPowerPelletsBlink(false);
break;
case 1:
// show "Character / Nickname"
attractScreenElements[0].SetActive(true);
break;
case 2:
// Show blinky sprite
attractScreenElements[1].SetActive(true);
break;
case 3:
// Show blinky character
attractScreenElements[2].SetActive(true);
break;
case 4:
// Show blinky nickname
attractScreenElements[3].SetActive(true);
break;
case 5:
// Show pinky sprite
attractScreenElements[4].SetActive(true);
break;
case 6:
// Show pinky character
attractScreenElements[5].SetActive(true);
break;
case 7:
// Show pinky nickname
attractScreenElements[6].SetActive(true);
break;
case 8:
// Show inky sprite
attractScreenElements[7].SetActive(true);
break;
case 9:
// Show inky character
attractScreenElements[8].SetActive(true);
break;
case 10:
// Show inky nickname
attractScreenElements[9].SetActive(true);
break;
case 11:
// Show clyde sprite
attractScreenElements[10].SetActive(true);
break;
case 12:
// Show clyde character
attractScreenElements[11].SetActive(true);
break;
case 13:
// Show clyde nickname
attractScreenElements[12].SetActive(true);
break;
case 14:
// Show pellet point values
attractScreenElements[13].SetActive(true);
break;
case 15:
// Show copyright message, setup pellet demonstration
attractScreenElements[14].SetActive(true);
attractScreenElements[15].SetActive(true);
pacMan.SetLevel(1);
pacMan.Reset();
pacMan.SetKinematic(true);
pacMan.SetActive(true);
pacMan.SetPosition(attractScreenElements[16].transform.localPosition);
pacMan.SetDirection(Vector2.left);
ghostManager.SetLevel(2);
ghostManager.Reset();
ghostManager.SetKinematic(true);
ghostManager.SetActive(true);
Ghost[] ghosts = ghostManager.Ghosts;
for (int i = 0; i < ghosts.Length; i++)
{
ghosts[i].SetPosition(attractScreenElements[17 + i].transform.localPosition);
ghosts[i].SetDirection(Vector2.left);
ghosts[i].SetState(PacManGhostState.Normal);
}
break;
case 16:
attractScreen.SetPowerPelletsBlink(true);
SetFrozen(false);
break;
case 17:
ghostManager.SetPowerPellet(true);
pacMan.SetPowerPellet(true);
attractScreenElements[15].SetActive(false);
break;
case 18:
// Turn PacMan around after eating power pellet
pacMan.SetDirection(Vector2.right);
pacMan.SetTargetDirection(Vector2.right);
break;
case 19:
ghostManager.Ghosts[0].Caught(200);
pacMan.SetActive(false);
SetFrozen(true);
break;
case 20:
ghostManager.Ghosts[0].ReturnHome();
ghostManager.Ghosts[0].SetActive(false);
pacMan.SetActive(true);
SetFrozen(false);
break;
case 21:
ghostManager.Ghosts[1].Caught(400);
pacMan.SetActive(false);
SetFrozen(true);
break;
case 22:
ghostManager.Ghosts[1].ReturnHome();
ghostManager.Ghosts[1].SetActive(false);
pacMan.SetActive(true);
SetFrozen(false);
break;
case 23:
ghostManager.Ghosts[2].Caught(800);
pacMan.SetActive(false);
SetFrozen(true);
break;
case 24:
ghostManager.Ghosts[2].ReturnHome();
ghostManager.Ghosts[2].SetActive(false);
pacMan.SetActive(true);
SetFrozen(false);
break;
case 25:
ghostManager.Ghosts[3].Caught(1600);
pacMan.SetActive(false);
SetFrozen(true);
break;
case 26:
ghostManager.Ghosts[3].ReturnHome();
ghostManager.Ghosts[3].SetActive(false);
// Hide elements, start demo
attractScreen.gameObject.SetActive(false);
if (!hasTimeSequenceQueued)
{
StartTimeSequence(PacManTimeSequence.AttractScreenDemo);
}
break;
}
}
private void TimeSequenceStepAttractScreenDemo(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
SetGameState(PacManGameState.AttractModeDemo);
HideEverything();
SetFrozen(true);
break;
case 1:
InitializeLevel();
SetMazeActive(true);
SetMazeVisible(true);
SetLevel(1);
break;
case 2:
// Reset ghosts
RestartLevel();
ghostManager.Ghosts[0].SetPredefinedPath(new Vector2[]{ // Blinky
Vector2.down,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.zero,
Vector2.zero,
Vector2.up,
Vector2.right,
Vector2.down,
Vector2.zero,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.up,
Vector2.zero,
Vector2.left,
Vector2.down,
Vector2.zero,
Vector2.left,
Vector2.down,
Vector2.right,
// Goes through tunnel
Vector2.zero,
Vector2.up,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.zero,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.up,
Vector2.left,
// Gets eaten
Vector2.zero,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
});
ghostManager.Ghosts[1].SetPredefinedPath(new Vector2[]{ // Pinky
Vector2.down,
Vector2.left,
Vector2.up,
Vector2.zero,
Vector2.zero,
Vector2.left,
Vector2.down,
Vector2.right,
// Pellet starts
Vector2.up,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.up,
Vector2.right,
// Pellet ends
Vector2.zero,
Vector2.down,
// Pellet starts
Vector2.left,
Vector2.down,
Vector2.zero,
Vector2.left,
// Caught
Vector2.up,
Vector2.right,
Vector2.zero,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.right,
// Home
Vector2.down,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.down,
Vector2.zero,
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.zero,
Vector2.down,
Vector2.left,
// Power pellet active
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.up,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.up
});
ghostManager.Ghosts[2].SetPredefinedPath(new Vector2[]{ // Inky
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.zero,
Vector2.zero,
Vector2.down,
Vector2.right,
// Pellet starts
Vector2.up,
Vector2.right,
Vector2.up,
// Caught
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.up,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.zero,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.zero,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.up,
Vector2.left
});
ghostManager.Ghosts[3].SetPredefinedPath(new Vector2[]{ // Clyde
Vector2.down,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.down,
Vector2.zero,
Vector2.left,
Vector2.zero,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.up,
Vector2.right,
Vector2.zero,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.up,
Vector2.right,
Vector2.zero,
Vector2.up,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.up,
Vector2.right
});
pacMan.SetPredefinedPath(new Vector2[]{
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.zero,
Vector2.up,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.zero,
Vector2.up,
Vector2.zero,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.up,
Vector2.zero,
Vector2.zero,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.zero,
Vector2.up,
Vector2.left,
Vector2.down,
Vector2.zero,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.zero,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.down,
Vector2.zero,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.zero,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.zero,
Vector2.down,
Vector2.right,
Vector2.up,
Vector2.right,
Vector2.zero,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.zero,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.up,
Vector2.right,
});
break;
case 3:
SetPelletsActive(true);
pelletManager.RestoreAllPellets();
statusDisplay.SetGameOverTextVisible(true);
break;
case 4:
// Show pacman, show ghosts
SetPacManActive(true);
SetGhostsActive(true);
break;
case 5:
// Unfreeze
SetFrozen(false);
break;
// case 6:
// if (!hasTimeSequenceQueued)
// {
// StartTimeSequence(PacManTimeSequence.AttractScreenWaitForStart);
// }
// break;
}
}
private void TimeSequenceStepWaitForStart(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
SetGameState(PacManGameState.WaitForStart);
HideEverything();
soundManager.SuppressSound(false);
soundManager.PlayCoinSound();
break;
case 1:
SetPressStartButtonScreenVisible(true);
if (playerInput.active == false && hasTimeSequenceQueued == false)
{
StartTimeSequence(PacManTimeSequence.WaitForStartTimeout);
}
break;
}
}
private void TimeSequenceStepWaitForStartTimeout(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
break;
case 1:
if (playerInput.active == false && hasTimeSequenceQueued == false)
{
StartAttractMode();
}
break;
}
}
private void TimeSequenceStepStartNewGame(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
// Prepare new game, hide everything except score bar
gameState = PacManGameState.InGame;
HideEverything();
SetMazeActive(true);
InitializeNewGame();
InitializeLevel();
RestartLevel();
SetFrozen(true);
soundManager.SuppressSound(false);
soundManager.PlayGameStartSound();
break;
case 1:
// Show maze, lives indicator, level indicator, player 1 and ready text
// SOMEWHERE IN HERE UNITY (EDITOR) APPEARS TO HAVE A SMALL RANDOM CHANCE OF CRASHING !!
Debug.Log("Log dump in case of crash");
Debug.Log("Setting pellets visible");
SetPelletsActive(true);
Debug.Log("Setting maze visible");
SetMazeVisible(true);
Debug.Log("Setting extra lives display visible");
statusDisplay.SetExtraLivesDisplayVisible(true);
Debug.Log("Setting level display visible");
statusDisplay.SetLevelDisplayVisible(true);
Debug.Log("Setting player 1 text visible");
statusDisplay.SetPlayer1TextVisible(true);
Debug.Log("Setting ready text visible");
statusDisplay.SetReadyTextVisible(true);
Debug.Log("Starting 1UP blink");
statusDisplay.SetLabel1UPTextBlinking(true);
break;
case 2:
// Subtract a life
DecrementLives();
break;
case 3:
// Remove Player 1 text
statusDisplay.SetPlayer1TextVisible(false);
break;
case 4:
// Show ghosts and pacman
SetGhostsActive(true);
SetPacManActive(true);
break;
case 5:
// Remove ready text
statusDisplay.SetReadyTextVisible(false);
break;
case 6:
// Start game, end sequence
soundManager.StartGhostSound();
SetFrozen(false);
break;
}
}
private void TimeSequenceStepBoardClear(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
// Freeze
SetFrozen(true);
soundManager.StopAllSound();
break;
case 1:
// Start board blinking, hide pellets in case of rack test
BoardClearAnimation();
SetPelletsActive(false);
break;
case 2:
// Hide ghosts
SetGhostsActive(false);
break;
case 3:
// Hide maze, lives indicator, level indicator
SetMazeVisible(false);
statusDisplay.SetExtraLivesDisplayVisible(false);
statusDisplay.SetLevelDisplayVisible(false);
break;
case 4:
// Hide score bar
statusDisplay.SetScoreDisplayVisible(false);
break;
case 5:
// Hide pacman, show level indicator with old level
SetPacManActive(false);
statusDisplay.SetLevelDisplayVisible(true);
break;
case 6:
// Call handler for what should happen next
InsertTimeSequence(PacManTimeSequence.StartNewLevel);
break;
}
}
private void TimeSequenceStepStartNewLevel(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
// Reset, show maze and score display
InitializeLevel();
RestartLevel();
SetMazeVisible(true);
statusDisplay.SetScoreDisplayVisible(true);
soundManager.SuppressSound(false);
break;
case 1:
// Increment level, show ready, show pellets, show lives indicators
IncrementLevel();
statusDisplay.SetExtraLivesDisplayVisible(true);
statusDisplay.SetReadyTextVisible(true);
SetPelletsActive(true);
break;
case 2:
// Show pacman, show ghosts
SetPacManActive(true);
SetGhostsActive(true);
break;
case 3:
// Hide ready
statusDisplay.SetReadyTextVisible(false);
break;
case 4:
// Unfreeze
SetFrozen(false);
soundManager.StartGhostSound();
break;
}
}
private void TimeSequenceStepGhostCaught(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
// Freeze and hide pacman, but let ghosts already in the caught animation continue
SetFrozen(true, ghostIgnoreIfCaught: true);
SetPacManActive(false);
soundManager.PlayGhostEatSound();
break;
case 1:
// Unfreeze and reveal pacman
SetPacManActive(true);
SetFrozen(false);
ghostManager.GhostCaughtContinue();
soundManager.SetGhostRetreat(true);
break;
}
}
private void TimeSequenceStepPacManCaught(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
// Freeze (except for the ghost animations)
SetFrozen(true, ghostKeepAnimating: true);
soundManager.StopAllSound();
break;
case 1:
// Hide ghosts, start pacman death animation
SetGhostsActive(false);
pacMan.SetDead(true);
break;
case 2:
// Start playing death sound
soundManager.PlayDeathSound();
break;
case 3:
// Hide pacman, start next state
SetPacManActive(false);
if (gameState == PacManGameState.AttractModeDemo)
{
break;
}
if (extraLives > 0)
{
InsertTimeSequence(PacManTimeSequence.RestartLevel);
break;
}
InsertTimeSequence(PacManTimeSequence.GameOver);
break;
case 4:
if (gameState == PacManGameState.AttractModeDemo)
{
#if RECORDING_DEMO
// recorder.gameObject.SetActive(false);
#endif
InsertTimeSequence(PacManTimeSequence.AttractScreenIntroduction);
}
break;
}
}
private void TimeSequenceStepRestartLevel(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
// Hide playfield and pellets
SetMazeVisible(false);
SetPelletsActive(false);
break;
case 1:
// Make maze visible
RestartLevel();
SetMazeVisible(true);
break;
case 2:
// Take life, show ready, show pellets
DecrementLives();
statusDisplay.SetReadyTextVisible(true);
SetPelletsActive(true);
break;
case 3:
// Show pacman, show ghosts
SetPacManActive(true);
SetGhostsActive(true);
break;
case 4:
// Hide ready
statusDisplay.SetReadyTextVisible(false);
break;
case 5:
// Unfreeze
SetFrozen(false);
soundManager.SuppressSound(false);
soundManager.StartGhostSound();
soundManager.UpdatePelletCount(pelletCountRemaining);
break;
}
}
private void TimeSequenceStepGameOver(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
// Show game over text, freeze power pellet blink
statusDisplay.SetGameOverTextVisible(true);
pelletManager.FreezePowerPelletsBlink(true);
break;
case 1:
// Stop text blinking, transition to attract screen
statusDisplay.SetLabel1UPTextBlinking(false);
StartAttractMode();
break;
}
}
public int TimeSequenceProgress
{
get => timeSequenceProgress;

View File

@@ -1,69 +0,0 @@
// // Silly me for wanting to make the code neat, forgot this was Udon :)
// using System.Collections;
// using System.Collections.Generic;
// using UdonSharp;
// using UnityEngine;
// public class GameStartSequence : TimeSequence
// {
// GameStateManager gameStateManager;
// StatusDisplay statusDisplay;
// public GameStartSequence(GameStateManager gameStateManager, StatusDisplay statusDisplay) : base(DeltaToAbsolute(new float[]
// {0, 0.016f, 2.2f, 0.032f, 0.032f, 1.92f, 0.032f}
// ))
// {
// this.gameStateManager = gameStateManager;
// this.statusDisplay = statusDisplay;
// }
// protected override void SequenceStep(int sequneceProgress)
// {
// switch (SequenceProgress)
// {
// case 0:
// // Prepare new game, hide everything except score bar
// gameStateManager.SetFrozen(true);
// gameStateManager.StartNewGame();
// gameStateManager.SetPelletsVisible(false);
// gameStateManager.SetMazeVisible(false);
// gameStateManager.SetGhostsVisible(false);
// gameStateManager.SetPacManVisible(false);
// statusDisplay.SetExtraLivesDisplayVisible(false);
// statusDisplay.SetLevelDisplayVisible(false);
// break;
// case 1:
// // Show maze, lives indicator, level indicator, player 1 and ready text
// gameStateManager.SetPelletsVisible(true);
// gameStateManager.SetMazeVisible(true);
// statusDisplay.SetExtraLivesDisplayVisible(true);
// statusDisplay.SetLevelDisplayVisible(true);
// statusDisplay.SetPlayer1TextVisible(true);
// statusDisplay.SetReadyTextVisible(true);
// break;
// case 2:
// // Subtract a life
// gameStateManager.DecrementLives();
// break;
// case 3:
// // Remove Player 1 text
// statusDisplay.SetPlayer1TextVisible(false);
// break;
// case 4:
// // Show ghosts and pacman
// gameStateManager.SetGhostsVisible(true);
// gameStateManager.SetPacManVisible(true);
// break;
// case 5:
// // Remove ready text
// statusDisplay.SetReadyTextVisible(true);
// break;
// case 6:
// // Start game, end sequence
// gameStateManager.SetFrozen(false);
// break;
// }
// }
// }

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1b2004a68b8de65489915c49e9d6cf8b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,350 @@
using UnityEngine;
namespace Marro.PacManUdon
{
public partial class GameManager
{
private void TimeSequenceStepAttractScreenDemo(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
SetGameState(PacManGameState.AttractModeDemo);
HideEverything();
SetFrozen(true);
break;
case 1:
InitializeLevel();
SetMazeActive(true);
SetMazeVisible(true);
SetLevel(1);
break;
case 2:
// Reset ghosts
RestartLevel();
ghostManager.Ghosts[0].SetPredefinedPath(new Vector2[]{ // Blinky
Vector2.down,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.zero,
Vector2.zero,
Vector2.up,
Vector2.right,
Vector2.down,
Vector2.zero,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.up,
Vector2.zero,
Vector2.left,
Vector2.down,
Vector2.zero,
Vector2.left,
Vector2.down,
Vector2.right,
// Goes through tunnel
Vector2.zero,
Vector2.up,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.zero,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.up,
Vector2.left,
// Gets eaten
Vector2.zero,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
});
ghostManager.Ghosts[1].SetPredefinedPath(new Vector2[]{ // Pinky
Vector2.down,
Vector2.left,
Vector2.up,
Vector2.zero,
Vector2.zero,
Vector2.left,
Vector2.down,
Vector2.right,
// Pellet starts
Vector2.up,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.up,
Vector2.right,
// Pellet ends
Vector2.zero,
Vector2.down,
// Pellet starts
Vector2.left,
Vector2.down,
Vector2.zero,
Vector2.left,
// Caught
Vector2.up,
Vector2.right,
Vector2.zero,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.right,
// Home
Vector2.down,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.down,
Vector2.zero,
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.zero,
Vector2.down,
Vector2.left,
// Power pellet active
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.up,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.up
});
ghostManager.Ghosts[2].SetPredefinedPath(new Vector2[]{ // Inky
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.zero,
Vector2.zero,
Vector2.down,
Vector2.right,
// Pellet starts
Vector2.up,
Vector2.right,
Vector2.up,
// Caught
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.up,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.zero,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.zero,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.up,
Vector2.left
});
ghostManager.Ghosts[3].SetPredefinedPath(new Vector2[]{ // Clyde
Vector2.down,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.down,
Vector2.zero,
Vector2.left,
Vector2.zero,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.up,
Vector2.right,
Vector2.zero,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.up,
Vector2.right,
Vector2.zero,
Vector2.up,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.up,
Vector2.right
});
pacMan.SetPredefinedPath(new Vector2[]{
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.right,
Vector2.zero,
Vector2.up,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.zero,
Vector2.up,
Vector2.zero,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.up,
Vector2.zero,
Vector2.zero,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.zero,
Vector2.up,
Vector2.left,
Vector2.down,
Vector2.zero,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.zero,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.down,
Vector2.zero,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.zero,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.up,
Vector2.right,
Vector2.zero,
Vector2.down,
Vector2.right,
Vector2.up,
Vector2.right,
Vector2.zero,
Vector2.down,
Vector2.left,
Vector2.down,
Vector2.right,
Vector2.down,
Vector2.left,
Vector2.zero,
Vector2.zero,
Vector2.up,
Vector2.right,
Vector2.up,
Vector2.left,
Vector2.up,
Vector2.right,
});
break;
case 3:
SetPelletsActive(true);
pelletManager.RestoreAllPellets();
statusDisplay.SetGameOverTextVisible(true);
break;
case 4:
// Show pacman, show ghosts
SetPacManActive(true);
SetGhostsActive(true);
break;
case 5:
// Unfreeze
SetFrozen(false);
break;
// case 6:
// if (!hasTimeSequenceQueued)
// {
// StartTimeSequence(PacManTimeSequence.AttractScreenWaitForStart);
// }
// break;
}
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 6e99011c9b7c5824fa22a5dc4b5bb735
guid: c021fd7df80d25746b58cf4c48c6d95a
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,179 @@
using UnityEngine;
namespace Marro.PacManUdon
{
public partial class GameManager
{
private void TimeSequenceStepAttractScreenIntroduction(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
SetGameState(PacManGameState.AttractMode);
// Initialize
soundManager.SuppressSound(true);
RestartLevel();
HideEverything();
SetFrozen(true);
attractScreen.gameObject.SetActive(true);
attractScreen.Initialize();
for (int i = 0; i <= 15; i++)
{
// Debug.Log($"{gameObject} TimeSequenceAttractScreen deactivating with iteration i");
attractScreenElements[i].SetActive(false);
}
attractScreen.SetPowerPelletsBlink(false);
break;
case 1:
// show "Character / Nickname"
attractScreenElements[0].SetActive(true);
break;
case 2:
// Show blinky sprite
attractScreenElements[1].SetActive(true);
break;
case 3:
// Show blinky character
attractScreenElements[2].SetActive(true);
break;
case 4:
// Show blinky nickname
attractScreenElements[3].SetActive(true);
break;
case 5:
// Show pinky sprite
attractScreenElements[4].SetActive(true);
break;
case 6:
// Show pinky character
attractScreenElements[5].SetActive(true);
break;
case 7:
// Show pinky nickname
attractScreenElements[6].SetActive(true);
break;
case 8:
// Show inky sprite
attractScreenElements[7].SetActive(true);
break;
case 9:
// Show inky character
attractScreenElements[8].SetActive(true);
break;
case 10:
// Show inky nickname
attractScreenElements[9].SetActive(true);
break;
case 11:
// Show clyde sprite
attractScreenElements[10].SetActive(true);
break;
case 12:
// Show clyde character
attractScreenElements[11].SetActive(true);
break;
case 13:
// Show clyde nickname
attractScreenElements[12].SetActive(true);
break;
case 14:
// Show pellet point values
attractScreenElements[13].SetActive(true);
break;
case 15:
// Show copyright message, setup pellet demonstration
attractScreenElements[14].SetActive(true);
attractScreenElements[15].SetActive(true);
pacMan.SetLevel(1);
pacMan.Reset();
pacMan.SetKinematic(true);
pacMan.SetActive(true);
pacMan.SetPosition(attractScreenElements[16].transform.localPosition);
pacMan.SetDirection(Vector2.left);
ghostManager.SetLevel(2);
ghostManager.Reset();
ghostManager.SetKinematic(true);
ghostManager.SetActive(true);
Ghost[] ghosts = ghostManager.Ghosts;
for (int i = 0; i < ghosts.Length; i++)
{
ghosts[i].SetPosition(attractScreenElements[17 + i].transform.localPosition);
ghosts[i].SetDirection(Vector2.left);
ghosts[i].SetState(PacManGhostState.Normal);
}
break;
case 16:
attractScreen.SetPowerPelletsBlink(true);
SetFrozen(false);
break;
case 17:
ghostManager.SetPowerPellet(true);
pacMan.SetPowerPellet(true);
attractScreenElements[15].SetActive(false);
break;
case 18:
// Turn PacMan around after eating power pellet
pacMan.SetDirection(Vector2.right);
pacMan.SetTargetDirection(Vector2.right);
break;
case 19:
ghostManager.Ghosts[0].Caught(200);
pacMan.SetActive(false);
SetFrozen(true);
break;
case 20:
ghostManager.Ghosts[0].ReturnHome();
ghostManager.Ghosts[0].SetActive(false);
pacMan.SetActive(true);
SetFrozen(false);
break;
case 21:
ghostManager.Ghosts[1].Caught(400);
pacMan.SetActive(false);
SetFrozen(true);
break;
case 22:
ghostManager.Ghosts[1].ReturnHome();
ghostManager.Ghosts[1].SetActive(false);
pacMan.SetActive(true);
SetFrozen(false);
break;
case 23:
ghostManager.Ghosts[2].Caught(800);
pacMan.SetActive(false);
SetFrozen(true);
break;
case 24:
ghostManager.Ghosts[2].ReturnHome();
ghostManager.Ghosts[2].SetActive(false);
pacMan.SetActive(true);
SetFrozen(false);
break;
case 25:
ghostManager.Ghosts[3].Caught(1600);
pacMan.SetActive(false);
SetFrozen(true);
break;
case 26:
ghostManager.Ghosts[3].ReturnHome();
ghostManager.Ghosts[3].SetActive(false);
// Hide elements, start demo
attractScreen.gameObject.SetActive(false);
if (!hasTimeSequenceQueued)
{
StartTimeSequence(PacManTimeSequence.AttractScreenDemo);
}
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e68e4d7063d5ae3439ad77dde2ff4d8b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
namespace Marro.PacManUdon
{
public partial class GameManager
{
private void TimeSequenceStepBoardClear(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
// Freeze
SetFrozen(true);
soundManager.StopAllSound();
break;
case 1:
// Start board blinking, hide pellets in case of rack test
BoardClearAnimation();
SetPelletsActive(false);
break;
case 2:
// Hide ghosts
SetGhostsActive(false);
break;
case 3:
// Hide maze, lives indicator, level indicator
SetMazeVisible(false);
statusDisplay.SetExtraLivesDisplayVisible(false);
statusDisplay.SetLevelDisplayVisible(false);
break;
case 4:
// Hide score bar
statusDisplay.SetScoreDisplayVisible(false);
break;
case 5:
// Hide pacman, show level indicator with old level
SetPacManActive(false);
statusDisplay.SetLevelDisplayVisible(true);
break;
case 6:
// Call handler for what should happen next
InsertTimeSequence(PacManTimeSequence.StartNewLevel);
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dfb426d2ba016fe4f994057627f457f9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,22 @@
namespace Marro.PacManUdon
{
public partial class GameManager
{
private void TimeSequenceStepGameOver(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
// Show game over text, freeze power pellet blink
statusDisplay.SetGameOverTextVisible(true);
pelletManager.FreezePowerPelletsBlink(true);
break;
case 1:
// Stop text blinking, transition to attract screen
statusDisplay.SetLabel1UPTextBlinking(false);
StartAttractMode();
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8b7f368ee62421d44a31d95b0e18ef5a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,25 @@
namespace Marro.PacManUdon
{
public partial class GameManager
{
private void TimeSequenceStepGhostCaught(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
// Freeze and hide pacman, but let ghosts already in the caught animation continue
SetFrozen(true, ghostIgnoreIfCaught: true);
SetPacManActive(false);
soundManager.PlayGhostEatSound();
break;
case 1:
// Unfreeze and reveal pacman
SetPacManActive(true);
SetFrozen(false);
ghostManager.GhostCaughtContinue();
soundManager.SetGhostRetreat(true);
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7289f833229ba214487c6752af911043
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,50 @@
namespace Marro.PacManUdon
{
public partial class GameManager
{
private void TimeSequenceStepPacManCaught(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
// Freeze (except for the ghost animations)
SetFrozen(true, ghostKeepAnimating: true);
soundManager.StopAllSound();
break;
case 1:
// Hide ghosts, start pacman death animation
SetGhostsActive(false);
pacMan.SetDead(true);
break;
case 2:
// Start playing death sound
soundManager.PlayDeathSound();
break;
case 3:
// Hide pacman, start next state
SetPacManActive(false);
if (gameState == PacManGameState.AttractModeDemo)
{
break;
}
if (extraLives > 0)
{
InsertTimeSequence(PacManTimeSequence.RestartLevel);
break;
}
InsertTimeSequence(PacManTimeSequence.GameOver);
break;
case 4:
if (gameState == PacManGameState.AttractModeDemo)
{
#if RECORDING_DEMO
// recorder.gameObject.SetActive(false);
#endif
InsertTimeSequence(PacManTimeSequence.AttractScreenIntroduction);
}
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 44ac2b1481d4fb14fa9ba70526ae9a11
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,44 @@
namespace Marro.PacManUdon
{
public partial class GameManager
{
private void TimeSequenceStepRestartLevel(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
// Hide playfield and pellets
SetMazeVisible(false);
SetPelletsActive(false);
break;
case 1:
// Make maze visible
RestartLevel();
SetMazeVisible(true);
break;
case 2:
// Take life, show ready, show pellets
DecrementLives();
statusDisplay.SetReadyTextVisible(true);
SetPelletsActive(true);
break;
case 3:
// Show pacman, show ghosts
SetPacManActive(true);
SetGhostsActive(true);
break;
case 4:
// Hide ready
statusDisplay.SetReadyTextVisible(false);
break;
case 5:
// Unfreeze
SetFrozen(false);
soundManager.SuppressSound(false);
soundManager.StartGhostSound();
soundManager.UpdatePelletCount(pelletCountRemaining);
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5afb156778fca6c449652276697f346a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,71 @@
using UnityEngine;
namespace Marro.PacManUdon
{
public partial class GameManager
{
private void TimeSequenceStepStartNewGame(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
// Prepare new game, hide everything except score bar
gameState = PacManGameState.InGame;
HideEverything();
SetMazeActive(true);
InitializeNewGame();
InitializeLevel();
RestartLevel();
SetFrozen(true);
soundManager.SuppressSound(false);
soundManager.PlayGameStartSound();
break;
case 1:
// Show maze, lives indicator, level indicator, player 1 and ready text
// SOMEWHERE IN HERE UNITY (EDITOR) APPEARS TO HAVE A SMALL RANDOM CHANCE OF CRASHING !!
Debug.Log("Log dump in case of crash");
Debug.Log("Setting pellets visible");
SetPelletsActive(true);
Debug.Log("Setting maze visible");
SetMazeVisible(true);
Debug.Log("Setting extra lives display visible");
statusDisplay.SetExtraLivesDisplayVisible(true);
Debug.Log("Setting level display visible");
statusDisplay.SetLevelDisplayVisible(true);
Debug.Log("Setting player 1 text visible");
statusDisplay.SetPlayer1TextVisible(true);
Debug.Log("Setting ready text visible");
statusDisplay.SetReadyTextVisible(true);
Debug.Log("Starting 1UP blink");
statusDisplay.SetLabel1UPTextBlinking(true);
break;
case 2:
// Subtract a life
DecrementLives();
break;
case 3:
// Remove Player 1 text
statusDisplay.SetPlayer1TextVisible(false);
break;
case 4:
// Show ghosts and pacman
SetGhostsActive(true);
SetPacManActive(true);
break;
case 5:
// Remove ready text
statusDisplay.SetReadyTextVisible(false);
break;
case 6:
// Start game, end sequence
soundManager.StartGhostSound();
SetFrozen(false);
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: db81dd1c2ea086643af71ac8484c2fa5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
namespace Marro.PacManUdon
{
public partial class GameManager
{
private void TimeSequenceStepStartNewLevel(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
// Reset, show maze and score display
InitializeLevel();
RestartLevel();
SetMazeVisible(true);
statusDisplay.SetScoreDisplayVisible(true);
soundManager.SuppressSound(false);
break;
case 1:
// Increment level, show ready, show pellets, show lives indicators
IncrementLevel();
statusDisplay.SetExtraLivesDisplayVisible(true);
statusDisplay.SetReadyTextVisible(true);
SetPelletsActive(true);
break;
case 2:
// Show pacman, show ghosts
SetPacManActive(true);
SetGhostsActive(true);
break;
case 3:
// Hide ready
statusDisplay.SetReadyTextVisible(false);
break;
case 4:
// Unfreeze
SetFrozen(false);
soundManager.StartGhostSound();
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7bdc932910f22bf49b3de1b3883359d0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,25 @@
namespace Marro.PacManUdon
{
public partial class GameManager
{
private void TimeSequenceStepWaitForStart(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
SetGameState(PacManGameState.WaitForStart);
HideEverything();
soundManager.SuppressSound(false);
soundManager.PlayCoinSound();
break;
case 1:
SetPressStartButtonScreenVisible(true);
if (playerInput.active == false && hasTimeSequenceQueued == false)
{
StartTimeSequence(PacManTimeSequence.WaitForStartTimeout);
}
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b977750eeccea07469ed2ed566ad0b4c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
namespace Marro.PacManUdon
{
public partial class GameManager
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 07078a284b77f1345b55f46089841280
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
namespace Marro.PacManUdon
{
public partial class GameManager
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a584f98f4d7e35146ae110c947f41176
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,20 @@
namespace Marro.PacManUdon
{
public partial class GameManager
{
private void TimeSequenceStepWaitForStartTimeout(int sequenceProgress)
{
switch (sequenceProgress)
{
case 0:
break;
case 1:
if (playerInput.active == false && hasTimeSequenceQueued == false)
{
StartAttractMode();
}
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ac77c2211d465d445934f6bf7398f743
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: