using Com.LuisPedroFonseca.ProCamera2D; using System.Collections; using System.Collections.Generic; using UnityEngine; public class PLIGameController : MonoBehaviour { [SerializeField] public int score = 0; [SerializeField] int level = 1; [SerializeField] int lives = 3; [SerializeField] public int power = 0; [SerializeField] int extraLifePoints = 50000; [SerializeField] int bonusBase = 1000; [SerializeField] List enemyWave1; [SerializeField] List enemyWave2; [SerializeField] List bosses; [SerializeField] float deathWaitTime = 5f; // seconds [SerializeField] AudioClip startLevelClip; [SerializeField] AudioClip endLevelClip; [SerializeField] AudioClip ohBabyClip; [SerializeField] AudioClip ohYeahClip; [SerializeField] AudioClip extraLifeClip; [SerializeField] GameObject lifeCounter; [SerializeField] GameObject lifeIcon; [SerializeField] TMPro.TextMeshProUGUI scoreTMPro; [SerializeField] TMPro.TextMeshProUGUI levelTMPro; [SerializeField] TMPro.TextMeshProUGUI currentLevelTMPro; [SerializeField] ParticleSystem particles; [SerializeField] AudioSource music; [SerializeField] AudioClip bossSong; [SerializeField] List songs; [SerializeField] GameObject player; AudioSource audioSource; ProCamera2DShake cameraShaker; int enemyCount = 0; int border = 32; int wavelength = 10; // todo: implement int[] nlp = { 25000, 50000, 100000, 250000, 500000, 1000000, 1500000, 2000000, 3000000, 4500000, 6000000, 7500000, 10000000 }; int nextLifePoints; // Start is called before the first frame update void Start() { cameraShaker = GameObject.FindGameObjectWithTag("MainCamera").GetComponent(); audioSource = GetComponent(); nextLifePoints = extraLifePoints; StartCoroutine(StartTestLevelLogic()); for (int i = 0; i < lives; i++) { GameObject l = Instantiate(lifeIcon); l.transform.SetParent(lifeCounter.transform); } } public void ShakeCamera() { cameraShaker.Shake(1); } void CycleMusic() { if (level%5 == 0 || level%wavelength == 1 || !music.isPlaying) { music.Stop(); if (level%wavelength == 0) { music.clip = bossSong; } else { music.clip = songs[(level / 5) % songs.Count]; } music.loop = true; music.Play(); } } public void Score(int points) { score += points; if (score >= nextLifePoints) { nextLifePoints += extraLifePoints; lives += 1; GameObject l = Instantiate(lifeIcon); l.transform.SetParent(lifeCounter.transform); audioSource.PlayOneShot(extraLifeClip); } } IEnumerator StartTestLevelLogic() { var main = particles.main; while (true) { power = Mathf.Max(0, (level - 1) / wavelength); yield return new WaitForSeconds(3.0f); CycleMusic(); main.simulationSpeed = 5; // TODO: Show level text Debug.Log("Level " + level.ToString()); audioSource.PlayOneShot(startLevelClip); levelTMPro.SetText("Level " + level.ToString()); yield return new WaitForSeconds(3.0f); main.simulationSpeed = 1; levelTMPro.SetText(""); enemyCount = 0; if (level == wavelength) { // Spawn a boss! SpawnBoss(); } else if (level == 2*wavelength) { bool left = true; while (enemyCount < 5) { enemyCount++; SpawnBoss2(left); left = !left; yield return new WaitForSeconds(10.0f); } } else if (level < wavelength) { // Spawn a bunch of enemies while (enemyCount < 5 + level * 4) { enemyCount += 1; SpawnWave1(); yield return new WaitForSeconds(20.0f / (level + 10)); } } else if (level < 2*wavelength) { while (enemyCount < 5 + (level) * 4) { enemyCount += 1; SpawnWave2(); yield return new WaitForSeconds(20.0f / (level + 12)); } } // Check every 2 seconds to make sure all enemies are dead while (GameObject.FindGameObjectsWithTag("PegLegIoEnemy").Length > 0) { yield return new WaitForSeconds(2.0f); } audioSource.PlayOneShot(endLevelClip); levelTMPro.SetText("Level Complete"); yield return new WaitForSeconds(3.0f); int bonus = lives * bonusBase; if (bonus >= 10000) { audioSource.PlayOneShot(ohBabyClip); } else { audioSource.PlayOneShot(endLevelClip); } levelTMPro.SetText("Bonus\n" + bonus.ToString()); Score(bonus); yield return new WaitForSeconds(3.0f); if (level >= 2*wavelength) { levelTMPro.SetText("Mission Complete"); break; } if (level%wavelength == 0) { audioSource.PlayOneShot(ohYeahClip); levelTMPro.SetText("Power Up"); yield return new WaitForSeconds(3.0f); } levelTMPro.SetText(""); level += 1; } } void SpawnBoss() { GameObject b = Instantiate(bosses[0]); b.transform.position = new Vector2(0.0f, 180f); } void SpawnBoss2(bool left) { GameObject b = Instantiate(bosses[1]); b.transform.position = new Vector2(((left)?-1:1) * 320.0f, 100f); } void SpawnWave1() { int choice = (enemyCount % enemyWave1.Count) % (level / 3 + 1); if (choice == 1) { GameObject e = Instantiate(enemyWave1[1]); e.transform.position = new Vector2( Random.Range(-180f, 180f), 150f); } else if (choice == 2) { GameObject e = Instantiate(enemyWave1[2]); e.transform.position = new Vector2( Random.Range(-180f, 180f), 50f); } else if (choice == 3) { GameObject e = Instantiate(enemyWave1[3]); if (Random.Range(0.0f, 1.0f) > 0.5f) { e.transform.position = new Vector2(-480 / 2 - 24, Random.Range(0, 100)); } else { e.transform.position = new Vector2(480 / 2 + 24, Random.Range(0, 100)); } } else { GameObject e = Instantiate(enemyWave1[0]); if (Random.Range(0.0f, 1.0f) > 0.5f) { e.transform.position = new Vector2(-480 / 2 - 24, Random.Range(-270 / 4 + border, 270 / 2 - border)); } else { e.transform.position = new Vector2(480 / 2 + 24, Random.Range(-270 / 4 + border, 270 / 2 - border)); } } } void SpawnWave2() { int choice; if (enemyCount % (25 - level) == 0) { // Spawn Dummies sometimes, more often at higher levels choice = 0; } else if (level > 3*wavelength-3 && enemyCount % 5 == 0) { // Spawn Shooters often at higher levels choice = 3; } else { // Pick between jumpers and bubbles choice = 1 + (enemyCount % 2); } if (choice == 1) { GameObject e = Instantiate(enemyWave2[1]); e.transform.position = new Vector2( Random.Range(-180f, 180f), 150f); } else if (choice == 2) { GameObject e = Instantiate(enemyWave2[2]); e.transform.position = new Vector2( Random.Range(-180f, 180f), 50f); } else if (choice == 3) { GameObject e = Instantiate(enemyWave2[3]); if (Random.Range(0.0f, 1.0f) > 0.5f) { e.transform.position = new Vector2(-480 / 2 - 24, Random.Range(0, 100)); } else { e.transform.position = new Vector2(480 / 2 + 24, Random.Range(0, 100)); } } else { GameObject e = Instantiate(enemyWave2[0]); if (Random.Range(0.0f, 1.0f) > 0.5f) { e.transform.position = new Vector2(-480 / 2 - 24, Random.Range(-270 / 4 + border, 270 / 2 - border)); } else { e.transform.position = new Vector2(480 / 2 + 24, Random.Range(-270 / 4 + border, 270 / 2 - border)); } } } public IEnumerator PlayerDie() { lives -= 1; Destroy(lifeCounter.transform.GetChild(0).gameObject); yield return new WaitForSeconds(deathWaitTime); if (lives > 0) { GameObject p = Instantiate(player); p.transform.position = new Vector2(0f, -180f); } else { levelTMPro.SetText("Game Over!"); Debug.Log("Game Over!"); // TODO: Scoreboard } } // Update is called once per frame void LateUpdate() { scoreTMPro.SetText(score.ToString()); currentLevelTMPro.SetText(level.ToString()); } }