Advertisement
  1. Game Development
  2. Unity

Criando um Arkanoid com Unity: mecânica de blocos, Prefabs e Design

Scroll to top
Read Time: 10 min
This post is part of a series called Build Arkanoid With Unity.
Build Arkanoid With Unity: Player and Ball Mechanics
Build Arkanoid With Unity: Audio, New Levels, and Deployment

() translation by (you can also view the original English article)

Final product imageFinal product imageFinal product image
What You'll Be Creating

Nesta série de tutoriais, mostraremos como recriar o clássico jogo Arkanoid (ou Breakout) com Unity, usando ferramentas nativas 2D do Unity. Em cada postagem, vamos nos concentrar em uma parte específica do jogo. Nesta, nós vamos lidar com a mecânica de blocos e a criação de Prefabs.

Onde paramos

Nos tutoriais anteriores, você configurou o projeto e programou os comportamentos do bastão e da bola. Se você não tiver concluído os tutoriais anteriores, é altamente recomendável que você faça isso antes de continuar.

Produto final

Dê uma olhada nesta demo para ver o que queremos alcançar em toda a série:

E aqui está o que nós vamos fazer até o final deste post:

Criando o bloco de script

Neste momento, quase toda a mecânica base está pronta. A parte que falta está relacionada aos blocos. Como os blocos são uma parte importante do jogo, precisamos criar um script personalizado para ele.

O bloco de script deve conter informações sobre:

  • Total de acertos que ele pode ter.
  • Pontos a receber por quebrar.

(Observe que o número de acertos e de pontos podem mudar de acordo com a cor do bloco). Com base nisso, vamos dar ao bloco três variáveis:

  • Uma variável para armazenar o número de pancadas que o bloco pode levar.
  • Uma variável para armazenar o valor de pontos do bloco.
  • Uma variável para armazenar o número de vezes que o bloco foi atingido.

Os dois primeiros serão public, desde que você queira modificar seus valores no editor. O terceiro será private, já que é somente para uso interno.

Então, crie um novo script chamado BlockScript. Definia as variáveis e inicialize o número de acertos com 0:

1
public class BlockScript : MonoBehaviour {
2
3
    public int hitsToKill:
4
  public int points;
5
	private int numberOfHits;
6
7
	// Use this for initialization

8
	void Start () {
9
		numberOfHits = 0;
10
	}
11
	
12
	// Update is called once per frame

13
	void Update () {
14
	
15
	}
16
}

O próximo passo é detectar quando as bolas acertam um bloco. Quando ocorre esta colisão, verificamos se o bloco foi atingido o suficiente para ser destruído, ou se ainda ficará intacto. Por isso, podemos usar um método específico, chamado OnCollisionEnter2D, que é chamado sempre que uma colisão ocorre com o seu objeto.

Para verificar se esta colisão é entre a bola e o bloco, você deve marcar o objeto bola. No editor, selecione a bola na guia Hierarchy e, em seguida, o Inspector. No topo do Inpector, sob o nome de objeto, há um campo chamado Tag que atualmente está definido como Untagged. Clique no botão, e um menu drop-down vai abrir com as possibilidades de marcação (tag):

Nós queremos uma tag específica para a bola, clique então em Add Tag para criar uma nova marcação. Uma vez que você pressionar a opção uma nova interface vai aparecer:

Para este tutorial, enfatizaremos apenas a propriedade Element 0. Isso define o nome da marcação, então, digite o nome Ball para ela.

Agora que você tem a tag Ball, mude a marca do objeto bola para Ball.


Abra o arquivo BlockScript para nós programarmos o método OnCollisionEnter2D. Para identificar o objeto do jogo, verifique se a marcação do objeto bola é Ball; se assim for, então, a colisão será entre o bloco e a bola. Adicione o seguinte código no seu script.

1
    void OnCollisionEnter2D(Collision2D collision){
2
3
		if (collision.gameObject.tag == "Ball"){
4
5
        }
6
	}

Agora você pode detectar colisões com a bola. Após cada colisão, queremos aumentar o número de vezes que o bloco foi atingido e, se o número de vezes for o mesmo que o número máximo de pancadas que o bloco pode tomar, destruiremos o bloco. Por último, podemos usar o método Destroy.

A modificação no trecho OnCollisionEnter2D para fazer isso será mais ou menos assim:

1
    void OnCollisionEnter2D(Collision2D collision){
2
3
		if (collision.gameObject.tag == "Ball"){
4
			numberOfHits++;
5
6
			if (numberOfHits == hitsToKill){
7
				// destroy the object

8
				Destroy(this.gameObject);
9
			}
10
		}
11
	}

Agora, adicione o BlockScript ao objeto Ball (Hierarchy > Inspector > Add Component):

Agora é hora de verificar se está tudo bem. Altere o valor de Hits To Kill no editor para 1 e jogue o jogo. Quando a bola atingir o bloco, o bloco deve desaparecer.

Criando um Prefab

Agora que a mecânica do bloco está pronta, vamos preencher a fase. Como você usará vários blocos para isto, este é um bom momento para introduzir Prefabs do Unity.

Um Prefab é um objeto reutilizável que pode ser inserido diversas vezes na mesma cena. Basicamente, isto significa que se você quiser, por exemplo, alterar o valor de pontos dos blocos azuis, você não precisa fazê-lo para cada bloco azul na cena: se você tem um Prefab de um bloco azul, é só ajustar o valor no Prefab e todos os blocos azuis serão atualizados na cena.

Para criar um Prefab para os blocos azuis, comece renomeando o objeto Block para Blue Block. Em seguida, crie uma nova pasta na pasta Assets chamada Prefabs. Agora, arraste o objeto Blue Blocks para dentro da nova pasta.

Como você deve ter notado, o ícone de cubo no topo do Inspector agora está azul. Além disso, o nome do objeto na cena Hierarchy também está azul. Isto significa que o bloco é agora um Prefab. Bastante simples, não é? De agora em diante, selecionando o Prefab e alterarando seus valores, as alterações serão aplicadas a todos os parâmetros de todos os nossos blocos azuis.

Para testar o Prefab, arraste-o da pasta para a guia Hierarchy. Como você pode ver, agora temos dois blocos azuis, mas eles compartilham a mesma posição, que ficou definida pelo Prefab.

Para ter dois blocos em posições diferentes, basta selecionar um na guia Hierarchy e movê-lo na cena. Desta forma, você altera os valores dessa cópia específica do bloco e não de todos os blocos.

Você pode jogar e testar os Prefabs.

Recriando Prefabs

Agora você criará os Prefabs restantes para os outros blocos (verde, amarelo e vermelho). As principais etapas para cada um são:

  1. Criar um novo Sprite.
  2. Adicionar a imagem correspondente.
  3. Adicionar um Box Collider 2D.
  4. Adicionar o BlockScript.
  5. Nomeá-lo de acordo.
  6. Criar um Prefab.

No final você deve ter quatro Prefabs diferentes (uma para cada tipo de bloco):

A fim de tornar o jogo mais interessante, mude a variável Hits To Kill para cada tipo de bloco da seguinte forma:

  • Azul: 1 acerto.
  • Verde: 2 acertos.
  • Amarelo: 3 acertos.
  • Vermelho: 4 acertos.

Adicione alguns blocos e jogue o jogo; verifique se tudo está funcionando como esperado.

Design de fases

Agora é hora de criar sua primeira fase. Usando os Prefabs, preencha a área de jogo com vários blocos. Se você colocou vários blocos como nós fizemos, sua guia Hierarchy provavelmente estará lotada objetos! A fim de manter seu projeto bem organizado, vamos criar objetos vazios para os quatro tipos de blocos e em seguida agrupá-los por cor:

Neste ponto, seu jogo está quase pronto, sua mecânica básica está implementada, e ela deve ser semelhante à seguinte figura:

Sistema de vidas e pontuação

A pontuação e sistema de vidas é uma maneira de testar os jogadores e introduzir novas dinâmicas aos jogos. Neste ponto, o nosso jogo não tem forma alguma para o jogador avançar ou perder. Vamos mudar isso agora.

Abra o PlayerScript e adicione duas variáveis: uma para a pontuação e outra para o número de vidas que o jogador tem. Deixaremos que o jogador comece o jogo com três vidas e sem pontos:

1
private int playerLives;
2
    private int playerPoints;
3
4
	// Use this for initialization

5
	void Start () {
6
		// get the initial position of the game object

7
		playerPosition = gameObject.transform.position;
8
9
		playerLives = 3;
10
		playerPoints = 0;
11
12
	}

Precisamos de um método que aumenta o número de pontos que o jogador tem sempre que destrói um bloco. Crie um novo método chamado addPoints para fazer isso:

1
void addPoints(int points){
2
    playerPoints += points;
3
}

Agora temos o novo método que está esperando um valor — mas como ele irá recebê-lo? Existem muitos blocos para fazer referências ao bastão do jogador em cada um...

A melhor maneira de resolver isto é enviar uma mensagem do objeto bloco para o objeto bastão. Como fazemos isso? Bem, primeiro você precisa marcar o bastão (Hierarchy > Inspector > Tag) com a tag Player.


Com o bastão marcado, é hora de passar para o script do bloco, onde vamos mudar o método OnCollisionEnter2D para enviar os pontos para o objeto do jogador: antes que o bloco seja destruído, ele vai procurar um objeto com a marcação Player usando o método de FindGameObjectsWithTag; Isso retornará uma matriz de objetos correspondente, uma vez que existe apenas um objeto com essa marca, sabemos que o objeto na posição 0 da matriz é o objeto bastão do jogador.

Agora que você tem a referência do jogador, você pode enviar uma mensagem usando o método SendMessage. Com isso, você pode chamar um método específico do objeto — neste caso, o método addPoints.

O seguinte trecho mostra-lhe como isto funciona:

1
void OnCollisionEnter2D(Collision2D collision){
2
3
    if (collision.gameObject.tag == "Ball"){
4
		numberOfHits++;
5
6
		if (numberOfHits == hitsToKill){
7
			// get reference of player object

8
			GameObject player = GameObject.FindGameObjectsWithTag("Player")[0];
9
10
			// send message

11
			player.SendMessage("addPoints", points);
12
13
			// destroy the object

14
			Destroy(this.gameObject);
15
		}
16
	}
17
}

A próxima coisa que precisamos fazer é editar os Prefabs e dar valores específicos de pontos para cada tipo de bloco. Você pode usar os seguintes valores:

  • Azul: 10 pontos;
  • Verde: 20 pontos;
  • Amarelo: 35 pontos;
  • Vermelho: 50 pontos;

Agora, vamos mostrar estes pontos e vidas na interface do jogo. No script do jogador, crie um método chamado OnGUI. Este método irá representar o GUI de seu jogo; é um dos métodos básicos para apresentar informações na área de jogos. (Note que as maiúsculas e minúsculas são diferentes).

Para apresentar os pontos e as vidas, precisamos criar um Label (rótulo) com o texto desejado. No PlayerScript, adicione o método OnGUI e crie este rótulo nele:

1
void OnGUI(){
2
    GUI.Label (new Rect(5.0f,3.0f,200.0f,200.0f),"Live's: " + playerLives + "  Score: " + playerPoints);
3
}

Agora você pode jogar o jogo e o rótulo será apresentado na parte superior esquerda da tela. No entanto, você não programou ainda a exibição de vidas e pontos para atualizar de acordo!

Usando o mesmo PlayerScript, adicione o seguinte método TakeLife. O método vai subtrair uma vida do jogador cada vez que ele é chamado:

1
void TakeLife(){
2
    playerLives--;
3
}

Finalmente, vamos para o BallScript e, na seção onde você verifica se a bola caiu fora da tela, envie uma mensagem para o objeto do jogador com o métod TakeLife. O trecho completo é apresentado abaixo:

1
// Check if ball falls

2
    if (ballIsActive && transform.position.y < -6) {
3
		ballIsActive = !ballIsActive;
4
		ballPosition.x = playerObject.transform.position.x;
5
		ballPosition.y = -4.2f;
6
		transform.position = ballPosition;
7
				
8
		rigidbody2D.isKinematic = true;
9
10
		// New code - Send Message

11
		playerObject.SendMessage("TakeLife");
12
	}

Jogue o seu jogo e verifique se a pontuação e o sistema de vidas funciona conforme o esperado.

Para a próxima

Isto conclui a terceira postagem da série. A mecânica básica do jogo está toda implementada, então da próxima vez vamos adicionar o áudio e novos níveis e exportar o jogo terminado.

Se você tiver quaisquer perguntas ou comentários sobre o que cobrimos até agora, sinta-se livre para deixar um comentário abaixo.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Game Development tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.