using Assets.StreetLight.Poco; using Assets.StreetLight.Scripts; using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Specialized; using System.IO; using System.Linq; using System.Threading.Tasks; using TMPro; using Unity.VisualScripting; using UnityEngine; using UnityEngine.UI; namespace Assets.Pong { public class PongBehavior : MonoBehaviour { Person playerLeft; Person playerRight; State state = State.WaitingForPlayers; Ball ball; BlockingCollection taskQueue; string logFileName; enum State { WaitingForPlayers, ReadyForKickoff, Running } PersonManager PersonManager => personManagerLazy.Value; public int ScoreLeft { get; set; } public int ScoreRight { get; set; } Lazy personManagerLazy; private void Awake() { personManagerLazy = new Lazy(FindObjectOfType); } private void Start() { PersonManager.PersonAppeared += PersonManager_PersonAppeared; PersonManager.PersonDisappeared += PersonManager_PersonDisappeared; var sphere = GameObject.Find("Sphere"); ball = sphere.GetComponent(); taskQueue = new BlockingCollection(); logFileName = Path.Combine(@".\Logs", $"Log{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.txt"); InitializeLogFile(); } private void InitializeLogFile() { var directoryPath = Path.GetDirectoryName(logFileName); if (!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); } if (!File.Exists(logFileName)) { File.WriteAllText(logFileName, string.Empty); } } private void AppendNewLogEntry(string message) { taskQueue.Add(() => File.AppendAllLines(logFileName, new string[] { $"{DateTime.Now}: {message}" })); Task.Run(() => taskQueue.Take().Invoke()); } private void PersonManager_PersonDisappeared(object sender, Person e) { if (playerLeft.Id == e.Id) { playerLeft = null; if (state == State.Running) { EndGame(); } } else if (playerRight.Id == e.Id) { playerRight = null; if (state == State.Running) { EndGame(); } } } private void EndGame() { AppendNewLogEntry($"Game ended with score {ScoreLeft}:{ScoreRight}."); ScoreLeft = 0; ScoreRight = 0; ball.GoalScored -= Ball_GoalScored; ball.Recenter(); state = State.WaitingForPlayers; } private void PersonManager_PersonAppeared(object sender, Person e) { if (playerLeft == null && playerRight == null) { if (e.GetUnityPosition().x > 0) { playerRight = e; AppendNewLogEntry("Right player joined. Waiting for left player..."); } else { playerLeft = e; AppendNewLogEntry("Left player joined. Waiting for right player..."); } } else if (playerLeft == null) { playerLeft = e; AppendNewLogEntry("All players joined. Let's go!"); StartGame(); } else if (playerRight == null) { playerRight = e; AppendNewLogEntry("All players joined. Let's go!"); StartGame(); } } private void StartGame() { state = State.Running; AppendNewLogEntry($"New game started."); ball.GoalScored += Ball_GoalScored; ball.Kickoff(); } private void Ball_GoalScored(object sender, Side e) { var ball = (Ball)sender; if (e == Side.Left) { ScoreRight++; AppendNewLogEntry($"Right player scored a goal. Current score: {ScoreLeft}:{ScoreRight}"); } else { ScoreLeft++; AppendNewLogEntry($"Left player scored a goal. Current score: {ScoreLeft}:{ScoreRight}"); } ball.Recenter(); ball.Kickoff(); } void Update() { if (playerLeft != null) { var bumper = GameObject.Find("Bump1"); bumper.transform.position = new Vector3(bumper.transform.position.x, bumper.transform.position.y, playerLeft.GetUnityPosition().z); } else { var bumper = GameObject.Find("Bump1"); bumper.transform.position = new Vector3(bumper.transform.position.x, bumper.transform.position.y, 0); } if (playerRight != null) { var bumper = GameObject.Find("Bump2"); bumper.transform.position = new Vector3(bumper.transform.position.x, bumper.transform.position.y, playerRight.GetUnityPosition().z); } else { var bumper = GameObject.Find("Bump2"); bumper.transform.position = new Vector3(bumper.transform.position.x, bumper.transform.position.y, 0); } } } }