Files

322 lines
8.5 KiB
C#
Raw Permalink Normal View History

2026-08-25 22:24:07 -04:00
using UnityEngine;
using UnityEngine.InputSystem;
2026-08-27 14:41:40 -04:00
using UnityEngine.UI;
using System.Collections;
2026-08-25 22:24:07 -04:00
public class LevelEnder : MonoBehaviour
{
public WorldFiller worldFiller;
public BallSpawner ballSpawner;
public MultiplierSpawner multiplierSpawner;
public SharkSpawner sharkSpawner;
public CakeSpawner cakeSpawner;
public MusicManager musicManager;
public Player player;
public SpriteRenderer levelEndTally;
public SpriteRenderer levelEndTallyBackground;
public Animator levelEndTallyAnimator;
public AudioClip victory;
2026-08-27 14:41:40 -04:00
public AudioClip showBonus;
public AudioClip countBonus;
public AudioClip multiplierBonusSound;
public AudioClip multiplierPenaltySound;
public Text timeBonus;
public Text overachieverBonus;
public Text overachieverPercent;
public Text isolationBonus;
public Text isolationCount;
public Text multiplierBonus;
public Text totalBonus;
public SpriteRenderer overarchieverPercentLabel;
public SpriteRenderer isolationCountSingleLabel;
public SpriteRenderer isolationCountPluralLabel;
2026-08-25 22:24:07 -04:00
private AudioSource audioSource;
private bool levelEnded = false;
2026-08-27 15:06:29 -04:00
private bool tallyShown = false;
private bool addScoreToPlayer = false;
private int scoreTotal = 0;
private float addScoreTimer = 0.0f;
2026-08-25 22:24:07 -04:00
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
audioSource = GetComponent<AudioSource>();
}
// Update is called once per frame
void Update()
{
// Check for victory condition.
if (
player &&
player.percentCovered >= 80 &&
!levelEnded
)
{
musicManager.PauseMusic();
audioSource.PlayOneShot(victory);
levelEnded = true;
StartCoroutine(EndLevelAfterDelay());
}
if (
levelEnded &&
(
Mouse.current.leftButton.wasPressedThisFrame ||
Keyboard.current.anyKey.wasPressedThisFrame
)
)
{
2026-08-27 15:06:29 -04:00
addScoreToPlayer = true;
}
if (addScoreToPlayer && tallyShown)
{
addScoreTimer += Time.deltaTime;
if (addScoreTimer >= 0.02f && scoreTotal > 0)
{
addScoreTimer = 0.0f;
addScoreToPlayer = AddScore();
2026-08-27 15:34:06 -04:00
if (!addScoreToPlayer)
{
tallyShown = false;
StartCoroutine(ProceedToNextLevel());
}
2026-08-27 15:06:29 -04:00
}
2026-08-25 22:24:07 -04:00
}
}
public void EndLevel()
{
2026-08-27 15:06:29 -04:00
tallyShown = false;
2026-08-25 22:24:07 -04:00
// Stop all spawners.
ballSpawner.StopSpawning();
multiplierSpawner.StopSpawning();
sharkSpawner.StopSpawning();
cakeSpawner.StopSpawning();
// Show the level end tally.
musicManager.PlayVictoryMusic();
levelEndTally.enabled = true;
levelEndTallyBackground.enabled = true;
levelEndTallyAnimator.ResetTrigger("replay");
levelEndTallyAnimator.SetTrigger("replay");
// Destroy all objects other than the player.
ClearBoard();
}
private void ClearBoard()
{
// Clear the game board by destroying all objects except the player.
var yummies = GameObject.FindGameObjectsWithTag("Yummy");
var multipliers = GameObject.FindGameObjectsWithTag("Multiplier");
var shark = GameObject.FindGameObjectWithTag("Shark");
var notifications = GameObject.FindGameObjectsWithTag("Notification");
2026-08-25 22:24:07 -04:00
foreach (var yummy in yummies)
{
Destroy(yummy);
}
foreach (var notification in notifications)
{
Destroy(notification);
}
2026-08-25 22:24:07 -04:00
foreach (var multiplier in multipliers)
{
Destroy(multiplier);
}
if (shark != null)
{
Destroy(shark);
}
worldFiller.ClearSpawnedWalls();
}
2026-08-27 15:06:29 -04:00
private bool AddScore()
{
audioSource.PlayOneShot(countBonus);
int scoreToAdd = scoreTotal > 100 ? 100 : scoreTotal;
scoreTotal -= 100;
scoreTotal = Mathf.Max(scoreTotal, 0);
player.score += scoreToAdd;
ShowBonus(totalBonus, scoreTotal, null, null, null, showBonus);
if (scoreTotal <= 0)
{
audioSource.PlayOneShot(showBonus);
return false;
}
return true;
}
2026-08-27 14:41:40 -04:00
private void ShowBonus(Text bonusText, int bonusValue, int? bonusCount, Text countLabel, SpriteRenderer bonusLabel, AudioClip bonusSound)
{
bonusText.text = $"{bonusValue}";
if (bonusCount.HasValue)
{
countLabel.text = $"{bonusCount.Value}";
}
if (bonusLabel)
{
bonusLabel.enabled = true;
}
audioSource.PlayOneShot(bonusSound);
}
2026-08-25 22:24:07 -04:00
private IEnumerator EndLevelAfterDelay()
{
yield return new WaitForSeconds(victory.length);
EndLevel();
2026-08-27 14:41:40 -04:00
// Wait a moment before showing the bonus tally.
yield return new WaitForSeconds(1.5f);
2026-08-27 15:06:29 -04:00
scoreTotal = player.bonus;
2026-08-27 14:41:40 -04:00
ShowBonus(timeBonus, player.bonus, null, null, null, showBonus);
2026-08-27 15:06:29 -04:00
ShowBonus(totalBonus, scoreTotal, null, null, null, showBonus);
2026-08-27 14:41:40 -04:00
// Calculate and show the overachiever bonus.
yield return new WaitForSeconds(0.75f);
int overachieverBonusCount = 20 - (100 - player.percentCovered);
int overachieverBonusValue = 100 * overachieverBonusCount;
2026-08-27 15:06:29 -04:00
scoreTotal += overachieverBonusValue;
2026-08-27 14:41:40 -04:00
ShowBonus(
overachieverBonus,
overachieverBonusValue,
overachieverBonusCount,
overachieverPercent,
overarchieverPercentLabel,
showBonus
);
2026-08-27 15:06:29 -04:00
ShowBonus(totalBonus, scoreTotal, null, null, null, showBonus);
2026-08-27 14:41:40 -04:00
// Calculate and show the isolation bonus.
yield return new WaitForSeconds(0.75f);
int isolationBonusCount = 0;
int isolationBonusValue = 100 * isolationBonusCount;
2026-08-27 15:06:29 -04:00
scoreTotal += isolationBonusValue;
2026-08-27 14:41:40 -04:00
ShowBonus(
isolationBonus,
isolationBonusValue,
isolationBonusCount,
isolationCount,
isolationBonusCount == 1 ? isolationCountSingleLabel : isolationCountPluralLabel,
showBonus
);
2026-08-27 15:06:29 -04:00
ShowBonus(totalBonus, scoreTotal, null, null, null, showBonus);
2026-08-27 14:41:40 -04:00
// Calculate and show the multiplier bonus if applicable.
if (player.multiplier != 1.0f)
{
yield return new WaitForSeconds(0.75f);
int multiplierValue = player.multiplier == 0.5f ? 1 : (int)(player.multiplier);
2026-08-27 15:06:29 -04:00
scoreTotal = (int)(scoreTotal * player.multiplier);
2026-08-27 14:41:40 -04:00
ShowBonus(
multiplierBonus,
multiplierValue,
null,
null,
null,
multiplierValue == 1 ? multiplierPenaltySound : multiplierBonusSound
);
2026-08-27 15:06:29 -04:00
ShowBonus(totalBonus, scoreTotal, null, null, null, showBonus);
2026-08-27 14:41:40 -04:00
}
2026-08-27 15:06:29 -04:00
tallyShown = true;
yield return new WaitForSeconds(7.3f - 3.0f - (player.multiplier != 1.0f ? 0.75f : 0.0f));
addScoreToPlayer = true;
2026-08-25 22:24:07 -04:00
}
2026-08-27 15:34:06 -04:00
private IEnumerator ProceedToNextLevel()
{
musicManager.PauseMusic();
yield return new WaitForSeconds(1.0f);
// Reenable spawners.
multiplierSpawner.StartSpawning();
sharkSpawner.StartSpawning();
cakeSpawner.StartSpawning();
ballSpawner.StartSpawning();
2026-08-27 17:14:18 -04:00
multiplierSpawner.Reset();
2026-08-28 14:04:01 -04:00
sharkSpawner.Reset();
2026-08-27 15:34:06 -04:00
// Reset state.
levelEnded = false;
tallyShown = false;
addScoreToPlayer = false;
scoreTotal = 0;
addScoreTimer = 0.0f;
// Clear text labels.
timeBonus.text = "";
totalBonus.text = "";
isolationBonus.text = "";
overachieverBonus.text = "";
isolationCount.text = "";
overachieverPercent.text = "";
multiplierBonus.text = "";
overarchieverPercentLabel.enabled = false;
isolationCountSingleLabel.enabled = false;
isolationCountPluralLabel.enabled = false;
// Hide score tally.
levelEndTally.enabled = false;
levelEndTallyBackground.enabled = false;
2026-08-27 16:12:47 -04:00
// Reset.
player.OnLevelEnd();
ballSpawner.ResetBalls();
worldFiller.ClearWalls();
2026-08-27 15:34:06 -04:00
// Restart music.
musicManager.ResumeMusic();
}
2026-08-25 22:24:07 -04:00
}