373 lines
8.5 KiB
C#
373 lines
8.5 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using Mirror;
|
|
public class GameManager : NetworkBehaviour
|
|
{
|
|
#region Singleton
|
|
public static GameManager instance;
|
|
|
|
private void Awake()
|
|
{
|
|
if (instance == null)
|
|
instance = this;
|
|
|
|
WinMenu.SetActive(false);
|
|
LoseMenu.SetActive(false);
|
|
levelsUI.SetActive(false);
|
|
sequenceBubbles = new List<Transform>();
|
|
connectedBubbles = new List<Transform>();
|
|
bubblesToDrop = new List<Transform>();
|
|
bubblesToDissolve = new List<Transform>();
|
|
DontDestroyOnLoad(gameObject);
|
|
}
|
|
#endregion
|
|
|
|
private const int SEQUENCE_SIZE = 3;
|
|
|
|
private List<Transform> sequenceBubbles;
|
|
private List<Transform> connectedBubbles;
|
|
private List<Transform> bubblesToDrop;
|
|
private List<Transform> bubblesToDissolve;
|
|
public Shooter shootScript_p1;
|
|
public Shooter shootScript_p2;
|
|
public GameObject explosionPrefab;
|
|
public GameObject WinMenu;
|
|
public GameObject LoseMenu;
|
|
public GameObject winScore;
|
|
public GameObject winThrows;
|
|
public GameObject volBtn;
|
|
public GameObject playBtn;
|
|
public GameObject homeVolBtn;
|
|
public GameObject startUI;
|
|
public GameObject levelsUI;
|
|
public GameObject LightObj;
|
|
public Transform bottomLimit;
|
|
public float dropSpeed = 50f;
|
|
public string gameState = "play";
|
|
private bool hitABomb = false;
|
|
public bool isDissolving = false;
|
|
public float dissolveSpeed = 2f;
|
|
public float RayDistance = 200f;
|
|
|
|
private void Update()
|
|
{
|
|
if (isDissolving)
|
|
{
|
|
foreach (Transform bubble in bubblesToDissolve)
|
|
{
|
|
|
|
if (bubble == null)
|
|
{
|
|
//make sure every bubble disappeared before ending the dissolve
|
|
if (bubblesToDissolve.IndexOf(bubble) == bubblesToDissolve.Count - 1)
|
|
{
|
|
isDissolving = false;
|
|
EmptyDissolveList();
|
|
break;
|
|
}
|
|
else continue;
|
|
}
|
|
|
|
Bubble bubbleScript = bubble.GetComponent<Bubble>();
|
|
float dissolveAmount = bubbleScript.GetDissolveAmount();
|
|
|
|
if (dissolveAmount >= 0.99f)
|
|
{
|
|
isDissolving = false;
|
|
EmptyDissolveList();
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
float newDissolve = dissolveAmount + dissolveSpeed * Time.deltaTime;
|
|
bubbleScript.SetDissolveAmount(newDissolve);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void EmptyDissolveList()
|
|
{
|
|
foreach (Transform bubble in bubblesToDissolve)
|
|
if (bubble != null) Destroy(bubble.gameObject);
|
|
|
|
bubblesToDissolve.Clear();
|
|
}
|
|
|
|
public void ToggleGameState()
|
|
{
|
|
if (gameState == "play")
|
|
{
|
|
playBtn.GetComponent<Image>().color = Color.gray;
|
|
gameState = "pause";
|
|
LightObj.GetComponent<UnityEngine.Rendering.Universal.Light2D>().intensity = 0.4f;
|
|
PauseGame();
|
|
}
|
|
else if (gameState == "pause")
|
|
{
|
|
playBtn.GetComponent<Image>().color = Color.white;
|
|
gameState = "play";
|
|
LightObj.GetComponent<UnityEngine.Rendering.Universal.Light2D>().intensity = 1;
|
|
ResumeGame();
|
|
}
|
|
}
|
|
|
|
public void RestartGame()
|
|
{
|
|
LevelManager.instance.ClearLevel();
|
|
shootScript_p1.canShoot = false;
|
|
shootScript_p2.canShoot = false;
|
|
startUI.SetActive(true);
|
|
gameState = "play";
|
|
}
|
|
|
|
public void PauseGame()
|
|
{
|
|
Time.timeScale = 0f;
|
|
}
|
|
|
|
public void ResumeGame()
|
|
{
|
|
Time.timeScale = 1f;
|
|
}
|
|
|
|
public void ToggleMute()
|
|
{
|
|
AudioManager.instance.ToggleMute();
|
|
if (AudioManager.instance.mute)
|
|
{
|
|
volBtn.GetComponent<Image>().color = Color.gray;
|
|
homeVolBtn.GetComponent<Image>().color = Color.gray;
|
|
}
|
|
else
|
|
{
|
|
volBtn.GetComponent<Image>().color = Color.white;
|
|
homeVolBtn.GetComponent<Image>().color = Color.white;
|
|
}
|
|
}
|
|
|
|
IEnumerator CheckSequence(Transform currentBubble)
|
|
{
|
|
yield return new WaitForSeconds(0.1f);
|
|
|
|
sequenceBubbles.Clear();
|
|
CheckBubbleSequence(currentBubble);
|
|
ProcessSpecialBubbles(currentBubble);
|
|
|
|
if ((sequenceBubbles.Count >= SEQUENCE_SIZE) || hitABomb)
|
|
{
|
|
ProcessBubblesInSequence();
|
|
ProcessDisconectedBubbles();
|
|
}
|
|
|
|
sequenceBubbles.Clear();
|
|
LevelManager.instance.UpdateListOfBubblesInScene();
|
|
hitABomb = false;
|
|
|
|
if (LevelManager.instance.bubblesInScene.Count == 0)
|
|
{
|
|
// ScoreManager man = ScoreManager.GetInstance();
|
|
// winScore.GetComponent<Text>().text = man.GetScore().ToString();
|
|
// winThrows.GetComponent<Text>().text = man.GetThrows().ToString();
|
|
// WinMenu.SetActive(true);
|
|
}
|
|
else
|
|
{
|
|
shootScript_p1.CreateNextBubble();
|
|
shootScript_p2.CreateNextBubble();
|
|
shootScript_p1.canShoot = true;
|
|
shootScript_p2.canShoot = true;
|
|
}
|
|
|
|
ProcessBottomLimit();
|
|
}
|
|
|
|
public void ProcessTurn(Transform currentBubble)
|
|
{
|
|
StartCoroutine(CheckSequence(currentBubble));
|
|
}
|
|
|
|
private void ProcessBottomLimit()
|
|
{
|
|
foreach (Transform t in LevelManager.instance.bubblesArea)
|
|
{
|
|
if (t.GetComponent<Bubble>().isConnected
|
|
&& t.position.y < bottomLimit.position.y)
|
|
{
|
|
LevelManager.instance.ClearLevel();
|
|
LoseMenu.SetActive(true);
|
|
shootScript_p1.canShoot = false;
|
|
shootScript_p2.canShoot = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CheckBubbleSequence(Transform currentBubble)
|
|
{
|
|
sequenceBubbles.Add(currentBubble);
|
|
|
|
Bubble bubbleScript = currentBubble.GetComponent<Bubble>();
|
|
List<Transform> neighbours = bubbleScript.GetNeighbours();
|
|
|
|
foreach (Transform t in neighbours)
|
|
{
|
|
if (!sequenceBubbles.Contains(t))
|
|
{
|
|
Bubble bScript = t.GetComponent<Bubble>();
|
|
|
|
if (bScript.bubbleColor == bubbleScript.bubbleColor)
|
|
{
|
|
CheckBubbleSequence(t);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ProcessSpecialBubbles(Transform currentBubble)
|
|
{
|
|
Bubble bubbleScript = currentBubble.GetComponent<Bubble>();
|
|
List<Transform> neighbours = bubbleScript.GetNeighbours();
|
|
|
|
foreach (Transform t in neighbours)
|
|
{
|
|
Bubble bScript = t.GetComponent<Bubble>();
|
|
|
|
if (bScript.bubbleColor == Bubble.BubbleColor.Bomb)
|
|
{
|
|
hitABomb = true;
|
|
|
|
//create explosion effect
|
|
GameObject explosion = Instantiate(explosionPrefab, t.position, Quaternion.identity);
|
|
NetworkServer.Spawn(explosion);
|
|
explosion.transform.localScale = new Vector3(25f, 25f, 1f);
|
|
Destroy(explosion, 0.5f);
|
|
|
|
//destroy the bomb
|
|
Destroy(t.gameObject);
|
|
|
|
//destroy the neighbours of bomb
|
|
foreach (Transform t2 in bScript.GetNeighbours())
|
|
{
|
|
if (sequenceBubbles.Contains(t2))
|
|
sequenceBubbles.Remove(t2);
|
|
|
|
Destroy(t2.gameObject);
|
|
}
|
|
|
|
ScoreManager.GetInstance().AddScore(10);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
private void ProcessBubblesInSequence()
|
|
{
|
|
if (hitABomb)
|
|
AudioManager.instance.PlaySound("explosion");
|
|
else
|
|
AudioManager.instance.PlaySound("destroy");
|
|
|
|
foreach (Transform t in sequenceBubbles)
|
|
{
|
|
if (!bubblesToDissolve.Contains(t))
|
|
{
|
|
ScoreManager.GetInstance().AddScore(1);
|
|
t.tag = "Untagged";
|
|
t.SetParent(null);
|
|
t.GetComponent<CircleCollider2D>().enabled = false;
|
|
bubblesToDissolve.Add(t);
|
|
}
|
|
}
|
|
isDissolving = true;
|
|
}
|
|
|
|
#region Drop Disconected Bubbles
|
|
|
|
private void ProcessDisconectedBubbles()
|
|
{
|
|
SetAllBubblesConnectionToFalse();
|
|
SetConnectedBubblesToTrue();
|
|
CheckDisconectedBubbles();
|
|
DropAll();
|
|
}
|
|
|
|
private void SetAllBubblesConnectionToFalse()
|
|
{
|
|
foreach (Transform bubble in LevelManager.instance.bubblesArea)
|
|
{
|
|
bubble.GetComponent<Bubble>().isConnected = false;
|
|
}
|
|
}
|
|
|
|
private void SetConnectedBubblesToTrue()
|
|
{
|
|
connectedBubbles.Clear();
|
|
|
|
RaycastHit2D[] hits = Physics2D.RaycastAll(transform.position, Vector2.right, RayDistance);
|
|
|
|
for (int i = 0; i < hits.Length; i++)
|
|
{
|
|
if (hits[i].transform.gameObject.tag.Equals("Bubble"))
|
|
SetNeighboursConnectionToTrue(hits[i].transform);
|
|
}
|
|
}
|
|
|
|
private void SetNeighboursConnectionToTrue(Transform bubble)
|
|
{
|
|
connectedBubbles.Add(bubble);
|
|
|
|
Bubble bubbleScript = bubble.GetComponent<Bubble>();
|
|
bubbleScript.isConnected = true;
|
|
|
|
foreach (Transform t in bubbleScript.GetNeighbours())
|
|
{
|
|
if (!connectedBubbles.Contains(t))
|
|
{
|
|
SetNeighboursConnectionToTrue(t);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CheckDisconectedBubbles()
|
|
{
|
|
foreach (Transform bubble in LevelManager.instance.bubblesArea)
|
|
{
|
|
Bubble bubbleScript = bubble.GetComponent<Bubble>();
|
|
if (!bubbleScript.isConnected)
|
|
{
|
|
if (!bubblesToDrop.Contains(bubble))
|
|
{
|
|
ScoreManager.GetInstance().AddScore(2);
|
|
bubble.tag = "Untagged";
|
|
bubblesToDrop.Add(bubble);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DropAll()
|
|
{
|
|
foreach (Transform bubble in bubblesToDrop)
|
|
{
|
|
bubble.SetParent(null);
|
|
//Destroy(bubble.gameObject);
|
|
bubble.gameObject.GetComponent<CircleCollider2D>().enabled = false;
|
|
if (!bubble.GetComponent<Rigidbody2D>())
|
|
{
|
|
Rigidbody2D rig = (Rigidbody2D)bubble.gameObject.AddComponent(typeof(Rigidbody2D));
|
|
rig.gravityScale = dropSpeed;
|
|
}
|
|
}
|
|
bubblesToDrop.Clear();
|
|
}
|
|
|
|
#endregion
|
|
public void OnDrawGizmosSelected()
|
|
{
|
|
Gizmos.color = Color.red;
|
|
Gizmos.DrawRay(transform.position, Vector2.right * RayDistance);
|
|
}
|
|
} |