123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- 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
- }
- }
|