namespace Pong.Scripts.Objects; public partial class Ball : CharacterBody2D { [Export] private double _ballSpeed; [Export] private double _maxRandomAngle; /// /// this property multiples the ballSpeed by the Meter constant. /// private double BallSpeed => _ballSpeed * Constants.Meter; public override void _Ready() { FlickBall(); } /// /// flick the ball in a direction. /// internal void FlickBall() { // this should dispose when this method goes out of scope (this means after the velocity variable is assigned) using var rng = new RandomNumberGenerator(); rng.Randomize(); // set the velocity currently to the left of the screen with a random y angle. var randomAngle = new Vector2 { Y = rng.RandfRange(-_maxRandomAngle, _maxRandomAngle) * BallSpeed }; Velocity = GetRandomStartingDirection() * BallSpeed + randomAngle; } public override void _PhysicsProcess(double delta) { CollisionCheck(delta); } /// /// this method moves the ball and bounces if it collides with something. /// /// delta time from the _PhysicsProcess method. private void CollisionCheck(double delta) { var collision = MoveAndCollide(Velocity * delta); if (collision == null) return; Velocity = Velocity.Bounce(collision.GetNormal()); } /// /// this method generates a random number between 0 and 1 and /// either returns Vector2.Left or Vector2.Right /// based on that number. /// private static Vector2 GetRandomStartingDirection() { using var rng = new RandomNumberGenerator(); rng.Randomize(); var range = rng.RandiRange(0, 1); if (range == 0) { return Vector2.Left; } return Vector2.Right; } }