Olá, pessoal. Neste tutorial darei continuidade a parte 1 da nossa série Simon Says em Unity3D que, inclusive, você pode conferir aqui.
Agora irei mostrar como utilizar a classe que criamos anteriormente em um controlador para executar a sequência do nosso jogo.
Preparação
Primeiro vamos colocar as lâmpadas no cenário, serão cinco.
Para isso, basta criarmos cinco GameObjects com os componentes SpriteRenderer: o nosso LampadaBehaviourScript e um BoxCollider2D.
No campo sprite do SpriteRenderer colocaremos o sprite do octógono mais escuro. Já para o campo Sprite Aceso do LampadaBehaviourScript, usaremos o octógono mais claro. Agora, para colorir as lâmpadas, basta alterar a propriedade color do SpriteRenderer de cada uma delas.
Por último, vamos colocar Text para exibirmos mensagens e um Button para iniciar o Game. No meu caso fiz algo como o seguinte:
Iniciando nosso Script
Agora sim vamos escrever a nossa classe do game. Então criaremos um novo script chamado GameBehaviourScript.
Vamos criar as seguintes propriedades para aparecer no inspector:
- um Array com as lâmpadas para o game;
- a quantidade que acenderão logo no início do jogo;
- o botão para iniciar e as mensagens de prompt; e
- informação do level.
[Header("Lâmpadas do game")] public LampadaBehaviourScript[] lampadas; [Header(“Quantidade de lâmpadas que iram acender inicialmente”)] public int qtdInicial = 1; [Header("Prompt para mensagens")] public Text mensagem; [Header("Botão para iniciar")] public Button buttonStart; [Header("Texto do Level")] public Text textLevel;
As seguintes serão variáveis privadas:
- uma List de LampadaBehaviourScript que vai ser incrementada a cada rodada com uma nova lâmpada;
- uma bool para controlar a vez do jogador; e
- um contador para sabermos o nível da partida.
// sequencia de execução das lampadas private List<LampadaBehaviourScript> sequencia = new List<LampadaBehaviourScript>(); //controles private bool _vezDojogador = false; // controla quando é a vez do jogador private int indexDaVez = 0; // controla o index que o jogador está tentando acertar private int level = 1; // nível da partida
As Funções
Vamos precisar escrever algumas funções também. Isso parece meio óbvio, não é?
Irei detalhando conforme apresento cada função.
No método Start configuramos o Handler do evento de toque e o conteúdo inicial para o Text do level.
// Use this for initialization void Start () { // evento de quando a lampada foi tocada LampadaBehaviourScript.QuandoTocada += ToqueHandler; // mostra o nível atual textLevel.text = "Lv. " + level; }
Agora temos o Setup que será chamado pelo botão de iniciar. Nele primeiramente vamos desativar o GameObject do botão. Em seguida, configuramos a mensagem inicial e então adicionamos uma lâmpada. Isso será de acordo com o que foi definido na variável no inspector. Finalmente iniciaremos uma Coroutine que será responsável por executar a sequência.
/// <summary> /// Configurações iniciais /// </summary> public void Setup(){ // faz o botão sumir buttonStart.gameObject.SetActive (false); // configuração inicial this.ExibirMensagem("Repita a sequência"); for (int i = 0; i < qtdInicial; i++) { AdicionarLampada(); } // exibe a sequência StartCoroutine (ExibirSequencia()); } /// <summary> /// Adiciona uma lampada a sequencia /// </summary> private void AdicionarLampada(){ LampadaBehaviourScript lampada = PegarLampada (); sequencia.Add (lampada); } /// <summary> /// Recupera uma lampada aleatoria do array de lampadas /// </summary> /// <returns>The lambada.</returns> private LampadaBehaviourScript PegarLampada(){ return lampadas [Random.Range (0, lampadas.Length)]; } /// <summary> /// Exibe a mensagem /// </summary> /// <param name="mensagem">Mensagem.</param> void ExibirMensagem(string mensagem){ this.mensagem.text = mensagem; }
Nossa Coroutine chamará o método acender em um loop de cada lâmpada, mas com uma pequena pausa entre cada uma delas. Finalizando a execução, setamos a vez do jogador.
/// <summary> /// Exibe a seguencia de cores /// </summary> /// <returns>The sequencia.</returns> private IEnumerator ExibirSequencia(){ yield return new WaitForSeconds (2); this.ExibirMensagem("Repita a sequência"); int quantidade = sequencia.Count; for (int i = 0; i < quantidade; i++) { yield return sequencia [i].Acender (); yield return new WaitForSeconds (1); } // libera para o jogador jogar _vezDojogador = true; }
Para controlar o toque, usaremos o ToqueHandler que primeiramente só pode ser executado se for a vez do jogador. Assim sendo, deveremos verifica se a lâmpada tocada é a mesma da vez da lista. Para isso, usarei a variável indexDaVez e, em caso positivo, devemos “Acender” esta e incrementar o indexDaVez. Depois, verificar se foi atingida a quantidade total de elementos da lista. Se esta condição também for atingida, devemos zerar o indexDaVez, incrementar o level, adicionar uma nova lâmpada e reexecutar a sequência. Se a lâmpada selecionada não for igual à lâmpada da sequência, a partida termina.
/// <summary> /// Trata a lampada tocada /// </summary> /// <param name="lampada">Lampada.</param> private void ToqueHandler(LampadaBehaviourScript lampada){ if ( !_vezDojogador) // permite jogar se apenas for a vez do jogador return; if (lampada == sequencia [indexDaVez]) { StartCoroutine (sequencia [indexDaVez].Acender ()); indexDaVez++; if (indexDaVez == sequencia.Count) { level++; textLevel.text = "Lv. " + level; indexDaVez = 0; AdicionarLampada (); this.ExibirMensagem ("Muito bom! Você subiu de nível."); StartCoroutine (ExibirSequencia()); } } else { this.ExibirMensagem("Ops! Você errou."); _vezDojogador = false; // para a vez do jogador GameOver (); // se errou então gameover para ele } } /// <summary> /// Game over. /// </summary> private void GameOver(){ this.ExibirMensagem (":( Você perdeu. Tente novamente."); level = 1; sequencia.Clear(); buttonStart.gameObject.SetActive(true); }
O script final ficaria algo como:
using UnityEngine; using UnityEngine.UI; using System.Collections; using System.Collections.Generic; public class GameBehaviourScript : MonoBehaviour { [Header("Lampadas do game")] public LampadaBehaviourScript[] lampadas; [Header("Quantida de lampadas que iram acender inicialmente")] public int qtdInicial = 1; [Header("Prompt para mensagens")] public Text mensagem; [Header("Botão para iniciar")] public Button buttonStart; [Header("Texto do Level")] public Text textLevel; // sequencia de execução das lampadas private List<LampadaBehaviourScript> sequencia = new List<LampadaBehaviourScript>(); //controles private bool _vezDojogador = false; private int indexDaVez = 0; // controla o index que o jogador está tentando acertar private int level = 1; // Use this for initialization void Start () { // evento de quando a lampada foi tocada LampadaBehaviourScript.QuandoTocada += ToqueHandler; // mostra o nível atual textLevel.text = "Lv. " + level; } /// <summary> /// Configurações iniciais /// </summary> public void Setup(){ // faz o botão sumir buttonStart.gameObject.SetActive (false); // configuração inicial this.ExibirMensagem("Repita a sequência"); for (int i = 0; i < qtdInicial; i++) { AdicionarLampada(); } // exibe a sequencia StartCoroutine (ExibirSequencia()); } /// <summary> /// Exibe a seguencia de cores /// </summary> /// <returns>The sequencia.</returns> private IEnumerator ExibirSequencia(){ yield return new WaitForSeconds (2); this.ExibirMensagem("Repita a sequência"); int quantidade = sequencia.Count; for (int i = 0; i < quantidade; i++) { // verifica se está funcionando yield return sequencia [i].Acender (); yield return new WaitForSeconds (1); } // libera para o jogador jogar _vezDojogador = true; } /// <summary> /// Trata a lampada tocada /// </summary> /// <param name="lampada">Lampada.</param> private void ToqueHandler(LampadaBehaviourScript lampada){ if ( !_vezDojogador) // permite jogar se apenas for a vez do jogador return; if (lampada == sequencia [indexDaVez]) { StartCoroutine (sequencia [indexDaVez].Acender ()); indexDaVez++; if (indexDaVez == sequencia.Count) { level++; textLevel.text = "Lv. " + level; indexDaVez = 0; AdicionarLampada (); this.ExibirMensagem ("Muito bom! Você subiu de nível."); StartCoroutine (ExibirSequencia()); } } else { this.ExibirMensagem("Ops! Você errou."); _vezDojogador = false; // para a vez do jogador GameOver (); // se errou então gameover para ele } } /// <summary> /// Adiciona uma lampada a sequencia /// </summary> private void AdicionarLampada(){ LampadaBehaviourScript lampada = PegarLampada (); sequencia.Add (lampada); } /// <summary> /// Game over. /// </summary> private void GameOver(){ this.ExibirMensagem (":( Você perdeu. Tente novamente."); level = 1; sequencia.Clear(); buttonStart.gameObject.SetActive(true); } /// <summary> /// Recupera uma lampada aleatoria do array de lampadas /// </summary> /// <returns>The lambada.</returns> private LampadaBehaviourScript PegarLampada(){ return lampadas [Random.Range (0, lampadas.Length)]; } /// <summary> /// Exibe a mensagem /// </summary> /// <param name="mensagem">Mensagem.</param> void ExibirMensagem(string mensagem){ this.mensagem.text = mensagem; } }
Para finalizar nosso Simon Says em Unity3D
Devemos voltar ao editor do Unity e criarmos um novo GameObject. Assim, adicionar nosso novo script e preencher nossas variáveis no inspector. Algo como:
Bom, agora é só executar e brincar com o seu Simon Says em Unity3D.
Qualquer dúvida e/ou sugestão, fiquem à vontade nos comentários. Fico por aqui e até a próxima.