227 lines
7.0 KiB
C#
227 lines
7.0 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Mirror;
|
|
using TMPro;
|
|
using UnityEngine.SceneManagement;
|
|
public class NetGameManager : NetworkBehaviour
|
|
{
|
|
public const int WAITING_TIME = 120;
|
|
public static NetGameManager instance;
|
|
public TMP_Text statusText;
|
|
public TMP_Text scoreText_me;
|
|
public TMP_Text scoreText_enemy;
|
|
public GameOverScreen gameOverScreen;
|
|
public bool gameStarted = false;
|
|
float waitingTimer = WAITING_TIME;
|
|
public PlayerType winner = PlayerType.Client;
|
|
public bool gameOver = false;
|
|
|
|
[Header("MP")]
|
|
public GameObject fruitPrefab;
|
|
public List<GameObject> spawnedFruits = new List<GameObject>();
|
|
public int maxFruits = 10;
|
|
public float fruitSpawnInterval = 5f;
|
|
|
|
void Awake()
|
|
{
|
|
instance = this;
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
Application.targetFrameRate = 60;
|
|
}
|
|
|
|
public void UpdateScore(bool isLocalPlayer, int score){
|
|
if(isLocalPlayer){
|
|
scoreText_me.text = score.ToString();
|
|
}else{
|
|
scoreText_enemy.text = score.ToString();
|
|
}
|
|
}
|
|
public bool playerSpawned = false;
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
if(!isServer) return;
|
|
|
|
SnakeController[] players = FindObjectsOfType<SnakeController>();
|
|
|
|
if(!gameStarted){
|
|
if(players.Length >1){
|
|
gameStarted = true;
|
|
RpcSetGameStarted(true);
|
|
StartCoroutine(StartGame());
|
|
}else{
|
|
if(players.Length == 1){
|
|
if(waitingTimer >0){
|
|
waitingTimer -= Time.deltaTime;
|
|
SetStatusText("Waiting for another player...\nRemaining time: " + waitingTimer.ToString("F0") + " seconds");
|
|
}else{
|
|
SetStatusText("Opponent abandoned the game");
|
|
GameOver(players[0].playerType);
|
|
}
|
|
}
|
|
}
|
|
}else{
|
|
if(players.Length == 1){
|
|
if(playerSpawned){
|
|
SetStatusText("Opponent left the game");
|
|
GameOver(players[0].playerType);
|
|
}else{
|
|
gameStarted = false;
|
|
SetStatusText("Waiting for another player...");
|
|
}
|
|
}
|
|
|
|
ManageAndPopulateFruits();
|
|
}
|
|
}
|
|
|
|
|
|
[ClientRpc]
|
|
void RpcSetGameStarted(bool started){
|
|
gameStarted = started;
|
|
}
|
|
|
|
void ManageAndPopulateFruits(){
|
|
if(spawnedFruits.Count < maxFruits){
|
|
SpawnFruit();
|
|
}
|
|
}
|
|
|
|
void SpawnFruit(){
|
|
GameObject fruit = Instantiate(fruitPrefab, GetRandomPoint(), Quaternion.identity);
|
|
NetworkServer.Spawn(fruit);
|
|
spawnedFruits.Add(fruit);
|
|
}
|
|
public void DestroyFruit(Vector2 position){
|
|
int index = -1;
|
|
for(int i=0; i < spawnedFruits.Count; i++){
|
|
if(spawnedFruits[i].transform.position == (Vector3)position){
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
if(index != -1){
|
|
NetworkServer.Destroy(spawnedFruits[index]);
|
|
spawnedFruits.RemoveAt(index);
|
|
}
|
|
}
|
|
|
|
Vector2 GetRandomPoint(){
|
|
SnakeController p = FindObjectOfType<SnakeController>();
|
|
|
|
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);
|
|
}
|
|
|
|
public IEnumerator StartGame(){
|
|
int counter = 10;
|
|
SnakeController[] players = FindObjectsOfType<SnakeController>();
|
|
|
|
while(counter > 0){
|
|
players = FindObjectsOfType<SnakeController>();
|
|
if(players.Length <= 1){
|
|
yield break;
|
|
}
|
|
SetStatusText("Game starts in " + counter);
|
|
yield return new WaitForSeconds(1f);
|
|
counter--;
|
|
}
|
|
SetStatusText("Game Started");
|
|
foreach (SnakeController player in players)
|
|
{
|
|
player.StartGame();
|
|
}
|
|
playerSpawned = true;
|
|
yield return new WaitForSeconds(1f);
|
|
SetStatusText("");
|
|
}
|
|
|
|
void SetStatusText(string text){
|
|
if(!isServer){return;}
|
|
statusText.text = text;
|
|
RpcSetStatusText(text);
|
|
}
|
|
[ClientRpc]
|
|
void RpcSetStatusText(string text){
|
|
statusText.text = text;
|
|
}
|
|
public void GameOver(SnakeController player){
|
|
winner = player.playerType;
|
|
GameOver(winner);
|
|
}
|
|
|
|
public void GameOver(PlayerType winner){
|
|
if(gameOver){return;}
|
|
|
|
SetStatusText($"Player {(winner == PlayerType.Master ? "1" : "2")} wins!");
|
|
Debug.Log("Game Over " + winner);
|
|
|
|
gameOver = true;
|
|
string winnerKey = winner == PlayerType.Master ? "master" : "client";
|
|
StartCoroutine(CoroutineGameOver(winnerKey));
|
|
RpcGameOver(winnerKey);
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcGameOver(string winnerKey){
|
|
bool won = (winnerKey == "master" && GameData.isMaster) || (winnerKey == "client" && !GameData.isMaster);
|
|
gameOverScreen.Show(won);
|
|
|
|
Debug.Log("Game Over " + winnerKey);
|
|
}
|
|
|
|
|
|
IEnumerator CoroutineGameOver(string winnerKey){
|
|
string winnerPubkey = winnerKey == "master" ? GameData.betData.owner : GameData.betData.joiner;
|
|
string winnerId = winnerKey == "master" ? GameData.betData.owner_id : GameData.betData.joiner_id;
|
|
int masterScore=0, clientScore =0;
|
|
|
|
Dictionary<string, string> data = new Dictionary<string, string>(){
|
|
{"gameAddress", GameData.address},
|
|
{"winnerPublicKey", winnerPubkey},
|
|
{"winnerUsername", winnerId},
|
|
{"wager", (GameData.betData.wager * 1e8).ToString()},
|
|
{"game_id", GameData.betData.id.ToString()},
|
|
{"loserUsername", winnerKey == "master" ? GameData.betData.joiner_id : GameData.betData.owner_id},
|
|
{"masterScore", masterScore.ToString()},
|
|
{"clientScore", clientScore.ToString()},
|
|
{"masterId", GameData.betData.owner_id},
|
|
{"clientId", GameData.betData.joiner_id}
|
|
};
|
|
|
|
string queryString = "?";
|
|
foreach(KeyValuePair<string, string> entry in data) {
|
|
queryString += entry.Key + "=" + WWW.EscapeURL(entry.Value) + "&";
|
|
}
|
|
queryString = queryString.TrimEnd('&');
|
|
|
|
string validator_url = GameData.isDev ? Constants.VALIDATOR_URL_DEV : Constants.VALIDATOR_URL_PROD;
|
|
string url = validator_url + "finalize" + queryString;
|
|
Debug.Log("Finalizing game on " + url);
|
|
WWW www = new WWW(url);
|
|
yield return www;
|
|
|
|
if(www.error == null){
|
|
RpcProcessed();
|
|
}
|
|
|
|
Debug.Log("Processed game, quitting in 10 seconds...");
|
|
yield return new WaitForSeconds(10f);
|
|
Application.Quit();
|
|
}
|
|
|
|
[ClientRpc]
|
|
void RpcProcessed(){
|
|
gameOverScreen.Processed();
|
|
}
|
|
|
|
|
|
}
|