|
|
- namespace Oculus.Platform.Samples.VrBoardGame
- {
- using UnityEngine;
- using UnityEngine.UI;
-
- // This is the primary class that implements the game logic.
- public class GameController : MonoBehaviour
- {
- // instance of the object interfacing with the matchmaking service
- [SerializeField] private MatchmakingManager m_matchmaking = null;
-
- [SerializeField] private GameBoard m_board = null;
- [SerializeField] private GamePiece m_pieceA = null;
- [SerializeField] private GamePiece m_pieceB = null;
- [SerializeField] private GamePiece m_powerPiece = null;
-
- // colors for the various states of the selectable games pieces
- [SerializeField] private Color m_unusableColor = Color.white;
- [SerializeField] private Color m_unselectedColor = Color.white;
- [SerializeField] private Color m_selectedColor = Color.white;
- [SerializeField] private Color m_highlightedColor = Color.white;
-
- [SerializeField] private Text m_ballCountText = null;
- [SerializeField] private Text m_player0Text = null;
- [SerializeField] private Text m_player1Text = null;
-
- private enum GameState {
- None,
- PracticingMyTurn, PracticingAiTurn,
- OnlineMatchMyTurn, OnlineMatchRemoteTurn
- }
-
- private GameState m_state;
-
- // the game piece the player is currently looking at
- private GamePiece m_interestedPiece;
-
- // the piece the player selected with the Fire button
- private GamePiece m_selectedPiece;
-
- // the piece that would be placed if the player pressed the Fire button
- private GamePiece m_proposedPiece;
-
- // how many IAP power-balls the user has
- private uint m_powerBallcount;
-
- // the name of the current opponent
- private string m_opponentName;
-
- void Start()
- {
- TransitionToState(GameState.None);
- UpdateScores();
- }
-
- void Update()
- {
- PerFrameStateUpdate();
- }
-
- #region Game State
-
- private void TransitionToState(GameState state)
- {
- m_state = state;
-
- UpdateGamePieceColors();
- }
-
- private void TransitionToNextState()
- {
- if (!m_board.IsFull())
- {
- switch (m_state)
- {
- case GameState.PracticingAiTurn:
- TransitionToState(GameState.PracticingMyTurn);
- break;
- case GameState.PracticingMyTurn:
- TransitionToState(GameState.PracticingAiTurn);
- break;
- case GameState.OnlineMatchRemoteTurn:
- TransitionToState(GameState.OnlineMatchMyTurn);
- break;
- case GameState.OnlineMatchMyTurn:
- TransitionToState(GameState.OnlineMatchRemoteTurn);
- break;
- }
- }
- else
- {
- switch (m_state)
- {
- case GameState.OnlineMatchRemoteTurn:
- case GameState.OnlineMatchMyTurn:
- m_matchmaking.EndMatch(m_board.GetPlayerScore(0), m_board.GetPlayerScore(1));
- break;
- }
- TransitionToState(GameState.None);
- }
- }
-
- private void PerFrameStateUpdate()
- {
- switch (m_state)
- {
- case GameState.PracticingAiTurn:
- // don't move immediately to give the AI time to 'think'
- if (Random.Range(1, 100) < 3)
- {
- MakeAIMove(1);
- }
- break;
-
- case GameState.PracticingMyTurn:
- case GameState.OnlineMatchMyTurn:
- if (Input.GetButton("Fire1"))
- {
- TrySelectPiece();
- TryPlacePiece();
- }
- break;
- }
- }
-
- #endregion
-
- #region Practicing with an AI Player
-
- public void PracticeButtonPressed()
- {
- m_opponentName = "* AI *";
-
- switch (m_state)
- {
- case GameState.OnlineMatchMyTurn:
- case GameState.OnlineMatchRemoteTurn:
- m_matchmaking.EndMatch(m_board.GetPlayerScore(0), m_board.GetPlayerScore(1));
- break;
- }
- m_board.Reset();
-
- // randomly decised whether the player or AI goes first
- if (Random.Range(0, 2) == 1)
- {
- TransitionToState(GameState.PracticingMyTurn);
- }
- else
- {
- TransitionToState(GameState.PracticingAiTurn);
- }
-
- UpdateScores();
- }
-
- private void MakeAIMove(int player)
- {
- bool moved = false;
-
- // pick a random search start position
- int rx = Random.Range(0, GameBoard.LENGTH_X - 1);
- int ry = Random.Range(0, GameBoard.LENGTH_Y - 1);
-
- // from (rx,ry) search of an available move
- for (int i = 0; i < GameBoard.LENGTH_X && !moved; i++)
- {
- for (int j = 0; j < GameBoard.LENGTH_Y && !moved; j++)
- {
- int x = (rx + i) % GameBoard.LENGTH_X;
- int y = (ry + j) % GameBoard.LENGTH_Y;
-
- // first try to place a piece on the current position
- if (m_board.CanPlayerMoveToPostion(x, y))
- {
- GamePiece p = Random.Range(0, 2) == 0 ? m_pieceA : m_pieceB;
- m_board.AddPiece(player, p.Prefab, x, y);
- moved = true;
- }
- // a random percentage of the time, try to powerup this position
- else if (m_board.CanPlayerPowerUpPosition(x, y) && Random.Range(0, 8) < 2)
- {
- m_board.AddPowerPiece(player, m_powerPiece.Prefab, x, y);
- moved = true;
- }
- }
- }
-
- if (moved)
- {
- UpdateScores();
- TransitionToNextState();
- }
- }
-
- #endregion
-
- #region Playing Online Match
-
- // called from the MatchmakingManager was a successly online match is made
- public void StartOnlineMatch (string opponentName, bool localUserGoesFirst)
- {
- m_board.Reset();
- m_opponentName = opponentName;
-
- if (localUserGoesFirst)
- {
- TransitionToState(GameState.OnlineMatchMyTurn);
- }
- else
- {
- TransitionToState(GameState.OnlineMatchRemoteTurn);
- }
-
- UpdateScores();
- }
-
- // called from the Matchmaking Manager when the remote users their next move
- public void MakeRemoteMove(GamePiece.Piece piece, int x, int y)
- {
- GameObject prefab = m_pieceA.PrefabFor(piece);
-
- if (piece == GamePiece.Piece.PowerBall)
- {
- m_board.AddPowerPiece(1, prefab, x, y);
- }
- else
- {
- m_board.AddPiece(1, prefab, x, y);
- }
-
- UpdateScores();
- }
-
- // called from the MatchmakingManager when the local user becomes the room
- // owner and thus it's safe for the local user to make their move
- public void MarkRemoteTurnComplete()
- {
- if (m_state == GameState.OnlineMatchRemoteTurn)
- {
- TransitionToNextState();
- }
- }
-
- // the match ended from a player leaving before the board was complete
- public void RemoteMatchEnded()
- {
- m_matchmaking.EndMatch(m_board.GetPlayerScore(0), m_board.GetPlayerScore(1));
- }
-
- #endregion
-
- #region Selecting and Placing a Game Place
-
- public void StartedLookingAtPiece(GamePiece piece)
- {
- m_interestedPiece = piece;
- UpdateGamePieceColors();
- }
-
- public void StoppedLookingAtPiece()
- {
- m_interestedPiece = null;
- UpdateGamePieceColors();
- }
-
- // This method is used to display an example piece where the player is looking
- // so they know what to expect when they press the Fire button.
- public void StartedLookingAtPosition(BoardPosition position)
- {
- if (m_state != GameState.OnlineMatchMyTurn && m_state != GameState.PracticingMyTurn)
- return;
-
- GamePiece newPiece = null;
-
- if ((m_selectedPiece == m_pieceA || m_selectedPiece == m_pieceB) &&
- m_board.CanPlayerMoveToPostion(position.x, position.y))
- {
- newPiece = m_board.AddProposedPiece(m_selectedPiece.Prefab, position);
- }
- else if (m_selectedPiece == m_powerPiece &&
- m_board.CanPlayerPowerUpPosition(position.x, position.y))
- {
- newPiece = m_board.AddProposedPowerPiece(m_selectedPiece.Prefab, position);
- }
-
- if (newPiece != null)
- {
- if (m_proposedPiece != null)
- {
- Destroy(m_proposedPiece.gameObject);
- }
- m_proposedPiece = newPiece;
- }
- }
-
- public void ClearProposedMove()
- {
- if (m_proposedPiece != null)
- {
- Destroy(m_proposedPiece.gameObject);
- }
- }
-
- public void TrySelectPiece()
- {
- if (m_interestedPiece == m_pieceA || m_interestedPiece == m_pieceB)
- {
- m_selectedPiece = m_interestedPiece;
- }
- else if (m_interestedPiece == m_powerPiece &&
- (m_powerBallcount > 0 || m_state == GameState.PracticingMyTurn))
- {
- m_selectedPiece = m_interestedPiece;
- }
- UpdateGamePieceColors();
- }
-
- public void TryPlacePiece()
- {
- if (m_proposedPiece == null)
- return;
-
- var position = m_proposedPiece.Position;
- switch(m_proposedPiece.Type)
- {
- case GamePiece.Piece.A:
- case GamePiece.Piece.B:
- m_board.AddPiece(0, m_proposedPiece.Prefab, position.x, position.y);
- break;
- case GamePiece.Piece.PowerBall:
- m_board.AddPowerPiece(0, m_proposedPiece.Prefab, position.x, position.y);
- break;
- }
- Destroy(m_proposedPiece.gameObject);
-
- if (m_state == GameState.OnlineMatchMyTurn)
- {
- m_matchmaking.SendLocalMove(m_proposedPiece.Type, position.x, position.y);
- }
-
- UpdateScores();
- TransitionToNextState();
- }
-
- #endregion
-
- #region UI
-
- public void QuitButtonPressed()
- {
- UnityEngine.Application.Quit();
- }
-
- public void AddPowerballs(uint count)
- {
- m_powerBallcount += count;
- m_ballCountText.text = "x" + m_powerBallcount.ToString();
- }
-
- private void UpdateScores()
- {
- m_player0Text.text = string.Format("{0}\n\n{1}",
- PlatformManager.MyOculusID, m_board.GetPlayerScore(0));
-
- m_player1Text.text = string.Format("{0}\n\n{1}",
- m_opponentName, m_board.GetPlayerScore(1));
- }
-
- private void UpdateGamePieceColors()
- {
- switch (m_state)
- {
- case GameState.None:
- case GameState.PracticingAiTurn:
- case GameState.OnlineMatchRemoteTurn:
- m_pieceA.GetComponent<Renderer>().material.color = m_unusableColor;
- m_pieceB.GetComponent<Renderer>().material.color = m_unusableColor;
- m_powerPiece.GetComponent<Renderer>().material.color = m_unusableColor;
- if (m_proposedPiece != null)
- {
- Destroy(m_proposedPiece.gameObject);
- }
- break;
-
- case GameState.PracticingMyTurn:
- case GameState.OnlineMatchMyTurn:
- m_pieceA.GetComponent<Renderer>().material.color = m_unselectedColor;
- m_pieceB.GetComponent<Renderer>().material.color = m_unselectedColor;
- m_powerPiece.GetComponent<Renderer>().material.color = m_unselectedColor;
- if (m_interestedPiece == m_pieceA || m_interestedPiece == m_pieceB ||
- m_interestedPiece == m_powerPiece)
- {
- m_interestedPiece.GetComponent<Renderer>().material.color = m_highlightedColor;
- }
- if (m_selectedPiece != null)
- {
- m_selectedPiece.GetComponent<Renderer>().material.color = m_selectedColor;
- }
- break;
- }
- }
-
- #endregion
- }
- }
|