Tutorial: Mecânica do Simon Says em Unity3D – Parte 2

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:

simon_image_01

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:

simon_image_02

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.

Allan Douglas

Allan Douglas (Redator) – Formado em Análise e Desenvolvimento de Sistemas (Estácio de Sá). Atualmente trabalha como Analista Líder na Teccenter no Recife – PE. Também desenvolve soluções WEB, Mobile e Games. É fanboy da SEGA e adora jogos de estratégia digitais ou analógicos.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *