snakes_mp/Assets/Scripts/GameManager.cs
2025-03-25 11:35:44 +05:30

163 lines
4.1 KiB
C#

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<GameObject> spawnedFruits = new List<GameObject>();
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<GameObject>();
}
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<Fruit>();
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;
}
}
}