using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Unity.Netcode; using Unity.VisualScripting; using UnityEngine; using UnityEngine.Assertions; using Object = UnityEngine.Object; using Random = UnityEngine.Random; namespace Game { public class GameManager : NetworkBehaviour { public static GameManager Singleton { get; private set; } private void OnEnable() { Singleton = this; } public Object ballPrefab; public Object playerPrefab; public Object modificationPrefab; public ModificationProperties[] modifications; public List Balls { get; } = new(); private static void Tests() { var v1 = new Vector2(1, 3); var v2 = new Vector2(3, 2); var v3 = new Vector2(4, 4); var v4 = new Vector2(1, 1); var v5 = new Vector2(4, 1); var v6 = new Vector2(2, 5); var v7 = new Vector2(2, 3); var v8 = new Vector2(-1, 4); var v9 = new Vector2(-2, 1); var v10 = new Vector2(3, -1); Vector2 p, rs; Assert.IsTrue(AIPlayer.Intersect(v8, v4, v1, v9, out p, out rs)); Assert.IsTrue(AIPlayer.Intersect(v1, v2, v4, v7, out p, out rs)); Assert.IsTrue(AIPlayer.Intersect(v10, v6, v9, v2, out p, out rs)); Assert.IsTrue(AIPlayer.Intersect(v9, v5, v8, v10, out p, out rs)); Assert.IsFalse(AIPlayer.Intersect(v8, v4, v6, v5, out p, out rs)); Assert.IsFalse(AIPlayer.Intersect(v3, v5, v6, v8, out p, out rs)); Assert.IsFalse(AIPlayer.Intersect(v10, v4, v8, v9, out p, out rs)); Assert.IsFalse(AIPlayer.Intersect(v1, v7, v3, v2, out p, out rs)); var v11 = new Vector2(0, 0); var v12 = new Vector2(0, 5); var v13 = new Vector2(-2, 2); var v14 = new Vector2(2, 2); Assert.IsTrue(AIPlayer.Intersect(v11, v12, v13, v14, out p, out rs)); Assert.AreApproximatelyEqual(rs.x, 0.4f); Assert.AreApproximatelyEqual(rs.y, 0.5f); } private void Awake() { Settings.Type = Type.Hybrid; Settings.AIDifficulty = Difficulty.VeryHard; var ball = Instantiate(ballPrefab).GetComponent(); Balls.Add(ball); ball.Radius = 0.5f; var p1Obj = Instantiate(playerPrefab); var p2Obj = Instantiate(playerPrefab); Player p1, p2; switch (Settings.Type) { case Type.AI: p1 = p1Obj.AddComponent(); p2 = p2Obj.AddComponent(); ((AIPlayer) p1).Difficulty = Settings.AIDifficulty; ((AIPlayer) p2).Difficulty = Settings.AIDifficulty; break; case Type.Real: p1 = p1Obj.AddComponent(); p2 = p2Obj.AddComponent(); ((RealPlayer) p1).isThisClient = true; break; case Type.Hybrid: p1 = p1Obj.AddComponent(); p2 = p2Obj.AddComponent(); ((RealPlayer) p1).isThisClient = true; ((AIPlayer) p2).Difficulty = Settings.AIDifficulty; break; default: throw new ArgumentOutOfRangeException(); } p1.Side = Side.Bottom; p2.Side = Side.Top; Tests(); } private IEnumerator Start() { while (Application.isPlaying) { yield return new WaitForSeconds(5); SpawnModification(); } } private void SpawnModification() { Vector2 pos = new Vector2(Random.Range(Dimensions.Singleton.left, Dimensions.Singleton.right), Random.Range(-2, 2)); ModificationProperties properties = modifications[Random.Range(0, modifications.Length)]; var mod = Instantiate(modificationPrefab, pos, Quaternion.identity).GetComponent(); mod.Properties = properties; } private void FixedUpdate() { foreach (var ball in Balls.Where(b => !b.IsAlive)) Destroy(ball.gameObject); int count = Balls.RemoveAll(b => !b.IsAlive); for (int _ = 0; _ < count; _++) { Balls.Add(Instantiate(ballPrefab).GetComponent()); } } } }