using System; using Pong.Scripts.Data; using Pong.Scripts.Objects; namespace Pong.Scripts.Managers; public partial class ScalingManager : Node { private HFlowContainer _score; private BasePaddle _paddle; private Ball _ball; private Enemy _enemy; private Area2D _leftWall; private Area2D _rightWall; private StaticBody2D _topWall; private StaticBody2D _bottomWall; private Vector2I _gameResolution; internal GameArea GameArea; public event Action NewPaddlePosition; public event Action NewEnemyPosition; public event Action NewBallPosition; public override void _EnterTree() { GetNodes(); GetTree().Root.SizeChanged += AdaptToGameResolution; AdaptToGameResolution(); } public override void _ExitTree() { GetTree().Root.SizeChanged -= AdaptToGameResolution; } /// /// a method that gets all the nodes that the scaling manager will manage the position and scale of. /// private void GetNodes() { _score = GetNode("../Score"); _paddle = GetNode("../Paddle"); _ball = GetNode("../Ball"); _enemy = GetNode("../Enemy"); _leftWall = GetNode("../Walls/Left"); _rightWall = GetNode("../Walls/Right"); _topWall = GetNode("../Walls/Top"); _bottomWall = GetNode("../Walls/Bottom"); _paddle.ScalingManager = this; _enemy.ScalingManager = this; NewPaddlePosition += _paddle.SetNewPosition; NewEnemyPosition += _enemy.SetNewPosition; } /// /// adapt to the current resolution of the game. /// private void AdaptToGameResolution() { _paddle.Running = false; _enemy.Running = false; var normalizedPaddlePosition = GameArea?.NormalizePosition(_paddle.Position) ?? new Vector2(0, 0.5f); var normalizedEnemyPosition = GameArea?.NormalizePosition(_enemy.Position) ?? new Vector2(1, 0.5f); var normalizedBallPosition = GameArea?.NormalizePosition(_ball.Position) ?? new Vector2(0, 0); _gameResolution = DisplayServer.WindowGetSize(); GameArea = new GameArea(_gameResolution); SetWallPosition(); SetScorePosition(); SetPaddlePosition(normalizedPaddlePosition); SetEnemyPosition(normalizedEnemyPosition); _paddle.Running = true; _enemy.GenerateCollisions(); _enemy.Running = true; _ball.FlickBall(); } /// /// set the position and scale of the walls according to the edge position. /// private void SetWallPosition() { var xSize = GameArea.X.ByWallSizeExtents; var ySize = GameArea.Y.ByWallSizeExtents; _leftWall.Position = new Vector2(-xSize, 0); _rightWall.Position = new Vector2(xSize, 0); _topWall.Position = new Vector2(0, -ySize); _bottomWall.Position = new Vector2(0, ySize); _leftWall.Scale = _leftWall.Scale with { Y = _gameResolution.Y }; _rightWall.Scale = _rightWall.Scale with { Y = _gameResolution.Y }; _topWall.Scale = _topWall.Scale with { X = _gameResolution.X - 60 }; _bottomWall.Scale = _bottomWall.Scale with { X = _gameResolution.X - 60 }; } /// /// set the position of the score ui. this has to be calculated with 0, 0 being the top left of the screen as /// the UIs point starts from there instead of the point being in the middle of the screen. /// private void SetScorePosition() { _score.Position = new Vector2(-GameArea.X.ByWallSize, -GameArea.Y.ByWallSize); _score.Size = new Vector2(_gameResolution.X - 60, _gameResolution.Y - 60); } /// /// set the paddle position to a normalized position that gets globalized. the paddle gets the new position with an event. /// private void SetPaddlePosition(Vector2 normalizedPosition) { var newPaddlePos = GameArea.GlobalizePosition(normalizedPosition with { X = 0 }) + new Vector2(48, 0); NewPaddlePosition?.Invoke(newPaddlePos); } private void SetEnemyPosition(Vector2 normalizedPosition) { var newEnemyPos = GameArea.GlobalizePosition(normalizedPosition with { X = 1 }) + new Vector2(-48, 0); NewEnemyPosition?.Invoke(newEnemyPos); } private void SetBallPosition(Vector2 normalizedPosition) { var newBallPos = GameArea.GlobalizePosition(normalizedPosition); NewBallPosition?.Invoke(newBallPos); } public static void SetNewPosition(ref Vector2 newPositionField) { } }