diff options
Diffstat (limited to 'Assets/Scripts/Controllers/GameController.cs')
-rw-r--r-- | Assets/Scripts/Controllers/GameController.cs | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/Assets/Scripts/Controllers/GameController.cs b/Assets/Scripts/Controllers/GameController.cs new file mode 100644 index 0000000..2ae5f21 --- /dev/null +++ b/Assets/Scripts/Controllers/GameController.cs @@ -0,0 +1,113 @@ +using System; +using UnityEngine; + +namespace Controllers +{ + /// <summary> + /// The controller for the basketball-game logic. + /// </summary> + public class GameController : MonoBehaviour + { + private State state = State.JumpBall; // A basketball game always starts with a jump ball. + + public Player player; + public Player enemy; + + /// <summary> + /// The single ball for the game. + /// </summary> + [SerializeField] private Ball ball; + + private void Awake() + { + player = new Player { isEnemy = false, controller = this }; + enemy = new Player { isEnemy = true, controller = this }; + ball.controller = this; + } + + public struct Player + { + /// <summary> + /// Whether this player is the AI-enemy. + /// </summary> + internal bool isEnemy; + + /// <summary> + /// A back-reference to the containing GameController. + /// </summary> + internal GameController controller; + + private State dribble => isEnemy ? State.EnemyDribble : State.PlayerDribble; + private State shoot => isEnemy ? State.EnemyShoot : State.PlayerShoot; + + /// <summary> + /// When dribbling, move the ball with the player. + /// </summary> + /// <param name="handPosition">The position of the hand dribbling the ball.</param> + public void Move(Vector2 handPosition) + { + if (controller.state == (isEnemy ? State.EnemyDribble : State.PlayerDribble)) // Make sure they're dribbling. + controller.ball.transform.position = handPosition; // TODO: Make this perform a dribbling motion, otherwise it looks like they're travelling. + } + + /// <summary> + /// Grab the ball if possible given the current game state. + /// </summary> + /// <param name="handPosition">The position of the hand to attempt grabbing from.</param> + /// <returns>Whether or not the ball was able to be picked up.</returns> + public bool GrabBall(Vector2 handPosition) + { + // Don't allow the ball to be picked up if someone shot it. Also don't try picking it up if we're already holding it. + if (controller.state.IsShot() || controller.state == dribble) return false; + + // Make sure its within their grab area. + if (Vector2.Distance(controller.ball.transform.position, handPosition) > 0.75f) return false; + + controller.state = dribble; + Move(handPosition); + return true; + } + + /// <summary> + /// Shoot the ball if possible. + /// </summary> + /// <param name="playerTransform"></param> + /// <returns>Whether or not the ball was shot</returns> + public bool Shoot(Transform playerTransform) + { + if (controller.state != dribble) return false; // We must be dribbling the ball to shoot it. + controller.state = shoot; + controller.ball.Shoot(playerTransform); + return true; + } + } + + internal void BallDropped() + { + state = State.Idle; + } + + internal enum State + { + Idle, + JumpBall, + PlayerDribble, + PlayerShoot, + EnemyDribble, + EnemyShoot, + } + } + + internal static class GameControllerStateExtensions + { + internal static bool IsShot(this GameController.State state) + { + return state == GameController.State.EnemyShoot || state == GameController.State.PlayerShoot; + } + + internal static bool IsDribble(this GameController.State state) + { + return state == GameController.State.EnemyDribble || state == GameController.State.PlayerDribble; + } + } +} |