using System; using System.Collections; using System.Collections.Generic; using ExitGames.Client.Photon; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; public class GameManager : MonoBehaviourPunCallbacks, IOnEventCallback { const int START_WAIT_TIME = 10; const byte GAME_START_CODE = 1; DateTime startedTime = DateTime.UnixEpoch; public bool gameStarted => startedTime != DateTime.UnixEpoch; RaiseEventOptions raiseEventOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; public SnakeController p1; public SnakeController p2; public TMP_Text mp_status_txt; public GameObject fruitPrefab; public List spawnedFruits = new List(); public int maxFruits = 10; public float fruitSpawnInterval = 5f; float fruitSpawnTimer = 0; void Awake(){ p1.gameObject.SetActive(false); p2.gameObject.SetActive(false); } void Start() { if(!PhotonNetwork.IsConnectedAndReady){ SceneManager.LoadScene(0); } spawnedFruits= new List(); } float startTimer = START_WAIT_TIME; void Update() { if (!gameStarted) { if(Input.GetKeyDown(KeyCode.P)){ StartGame(); } WaitForGameStart(); return; } if (PhotonNetwork.IsMasterClient) { p1.gameObject.SetActive(true); p2.gameObject.SetActive(false); SpawnFruits(); } else { p1.gameObject.SetActive(false); p2.gameObject.SetActive(true); } } void SpawnFruits(){ if(spawnedFruits.Count > maxFruits){return;} if(fruitSpawnTimer >0){ fruitSpawnTimer-=Time.deltaTime; return; } fruitSpawnTimer = fruitSpawnInterval; spawnedFruits.Add(PhotonNetwork.Instantiate(fruitPrefab.name, GetRandomPoint(),Quaternion.identity)); } void WaitForGameStart() { if (PhotonNetwork.CurrentRoom.PlayerCount >= 2) { if (startTimer > 0) { startTimer -= Time.deltaTime; mp_status_txt.text = $"Starting game in {startTimer.ToString("n0")} Seconds"; } else { if (PhotonNetwork.IsMasterClient) { StartGame(); } } } else { startTimer = START_WAIT_TIME; mp_status_txt.text = "Waiting for an opponent"; } } Vector2 GetRandomPoint(){ SnakeController p = (p1.gameObject.activeSelf) ? p1 : p2; float x = p.transform.position.x - (int)(UnityEngine.Random.Range(-p.fieldSize.x/2f, p.fieldSize.x/2f)); float y = p.transform.position.y - (int)(UnityEngine.Random.Range(-p.fieldSize.y/2f, p.fieldSize.y/2f)); return new Vector2(x, y); } void StartGame(){ Debug.Log("Sending Raise Event"); PhotonNetwork.RaiseEvent(GAME_START_CODE, 1, raiseEventOptions, SendOptions.SendReliable); startedTime = DateTime.Now; } public void DestroyFruit(Vector2 position){ if(PhotonNetwork.IsMasterClient){ destroyFruit(position); }else{ photonView.RPC("RpcDestroyFruit", RpcTarget.All, position); } } [PunRPC] void RpcDestroyFruit(Vector2 position){ if(PhotonNetwork.IsMasterClient){ destroyFruit(position); } } void destroyFruit(Vector2 position){ // Fruit[] fruits = FindObjectsOfType(); foreach(GameObject fruit in spawnedFruits){ if((Vector2)fruit.transform.position == position){ spawnedFruits.Remove(fruit); PhotonNetwork.Destroy(fruit.gameObject); break; } } } public void OnEvent(EventData photonEvent) { if (photonEvent.Code == GAME_START_CODE) { Debug.Log("Game Started"); startedTime = DateTime.Now; } } }