using System;
using UnityEngine;
namespace Controllers
{
///
/// The controller for the basketball-game logic.
///
public class GameController : MonoBehaviour
{
private State state = State.JumpBall; // A basketball game always starts with a jump ball.
public Player player;
public Player enemy;
///
/// The single ball for the game.
///
[SerializeField] public 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
{
///
/// Whether this player is the AI-enemy.
///
internal bool isEnemy;
///
/// A back-reference to the containing GameController.
///
internal GameController controller;
private State dribble => isEnemy ? State.EnemyDribble : State.PlayerDribble;
private State shoot => isEnemy ? State.EnemyShoot : State.PlayerShoot;
public bool HasBall => controller.state == dribble;
///
/// When dribbling, move the ball with the player.
///
/// The position of the hand dribbling the ball.
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.
}
///
/// Grab the ball if possible given the current game state.
///
/// The position of the hand to attempt grabbing from.
/// Whether or not the ball was able to be picked up.
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;
}
///
/// Shoot the ball if possible.
///
///
/// Whether or not the ball was shot
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;
}
}
}