Buscar

2 PROGRAMAÇÃO PARA JOGOS 2D

Prévia do material em texto

Programação para jogos 2D
Unidade 2 - Projeto de jogo: Breakout
Autor: Vanessa Pereira do Nascimento
Revisor técnico: Renato Medeiros
Iniciar
Introdução
A programação de jogos 2D de maneira orientada a objetos foi introduzida na unidade anterior. Até este
momento você entrou em contato com os seguintes principais conceitos de Orientação a Objetos: classes,
objetos, atributos, métodos, construtores, hierarquia, encapsulamento e polimor�smo. Vimos também os
principais elementos da interface da game engine Unity , além da programação de um de seus scripts na IDE
(Ambiente de desenvolvimento integrado) Visual Studio . A pequena inserção de código que �zemos, os
conceitos que foram abordados e a apresentação da engine servirão de base para o conteúdo desta e das
próximas unidades.
Nesta segunda unidade, conforme adiantado pelo seu título, você irá programar seu primeiro jogo 2D na Unity .
Tendo como ponto de partida um jogo clássico, o Breakout (1976) da empresa Atari, iniciaremos um exercício de
abstração e aplicaremos os conceitos estudados até aqui no desenvolvimento desse projeto.
Na primeira parte desta unidade, você poderá aplicar os conceitos de OO enquanto cria as relações necessárias
para o desenvolvimento de uma versão do game Breakout . Serão abordadas as diversas maneiras de se
construir uma classe, incluindo termos como agregação, composição, classes estáticas e abstratas, dentre
outros. Durante a segunda parte, já trabalhando na Unity , criaremos a interface grá�ca do jogo, ou seja, todos
os elementos visuais necessários para seu funcionamento. Essa etapa abordará estes elementos básicos da
engine : GameObjects , Componentes, Tipos primitivos, Sprites , Câmera, Luzes, Skybox e Prefabs .
Na terceira parte desta unidade, iniciaremos a programação de scripts em C#, utilizando simultaneamente a
Unity e o Visual Studio . Serão desenvolvidos os códigos para a movimentação dos objetos e sua interação. Na
quarta e última parte você aprenderá a centralizar o controle do game.
Prepare-se para pôr em prática todos os conceitos de programação de jogos 2D aprendidos até aqui. Bons
estudos!
1. Construção das classes
As classes representam um dos conceitos base da POO, já que é a partir da de�nição de uma classe que torna-
se possível a criação de objetos, também chamada de instanciação. Uma instância é uma das cópias de uma
classe, é o objeto que apresenta os atributos e métodos de�nidos pela sua classe. Na Orientação a Objetos
precisamos, portanto, de�nir as classes que criarão os objetos para interagirem entre si.
Conforme foi abordado na unidade anterior, é através do exercício de abstração que é possível classi�car
objetos em conjuntos, de�nindo suas características e comportamentos. A abstração nos permite separar um
elemento de sua realidade, tornando possível transpor objetos do mundo físico para o universo computacional.
Ao projetar um jogo, ainda que este apresente um universo fantástico, representamos ali elementos
conhecidos do mundo físico, com características e comportamentos que podem ser agrupadas em diferentes
conjuntos. Sendo cada um desses conjuntos uma classe, é importante conhecermos as possibilidades de
construção de classes em OO.
1.1 Relacionamento entre classes
Em programação é muito comum a utilização de diagramas, permitindo a representação grá�ca dos sistemas.
Através de um diagrama, por exemplo, é possível visualizar as conexões entre comandos de uma Programação
Estruturada. Em POO, um diagrama permite visualizarmos a comunicação entre os objetos.
Devido a OO não ser focada nas ações de um sistema, sua visualização deve ser feita de maneira que possibilite
a representação de seus conceitos, do seu foco na relação entre seus objetos. Para essa tarefa é utilizada a UML
( Uni�ed Modeling Language) , isto é, a Linguagem de Modelagem Uni�cada. A ULM não se trata de um diagrama,
pois é uma linguagem que possui códigos próprios para construir e documentar um sistema. Como é possível
utilizar diferentes tipos de diagramas de ULM na representação de um sistema, durante esta disciplina será
utilizado apenas um dos tipos mais utilizados: o diagrama de classes.
Em um diagrama de classes são descritos os tipos de objetos e suas relações. Em seu desenho são inseridas
caixas (retângulos) para representar as classes e linhas e/ou setas que indicam suas relações. Cada caixa indica
o nome da classe, junto a seus atributos e métodos. Por enquanto, utilizaremos essa representação sem todos
os detalhes, pois a notação especí�ca do diagrama de classes representa cada tipo de atributos e métodos de
uma determinada maneira. Veja um modelo de representação de classes:
Figura 1: Diagrama de classes simpli�cado. Fonte: Proprio autor, 2020
Dentre os principais tipos de relacionamento entre classes estão: generalização, realização, dependência,
associação, agregação e composição. O que foi representado na imagem acima é a relação do tipo associação.
Seguem as de�nições dos tipos de relacionamento de classes e como são representadas no diagrama:
● Generalização
Uma classe que abrange características mais gerais, sendo possível especi�car tais características em
subclasses. Na generalização vemos aplicado o conceito de herança e a possibilidade de aplicar o
polimor�smo. Esse tipo é representado por uma seta que parte do topo da classe �lha e aponta para a
base da classe mãe;
● Realização
Esse tipo descreve a relação entre uma interface, espécie de contrato implementado em uma classe, e
essa classe, já que esta última não herda mas sim implementa a anterior. Essa relação é representada por
uma seta tracejada que parte do topo da classe e aponta para a base da interface implementada;
● Dependência
Relação criada quando uma classe utiliza em seus métodos outra classe, consequentemente, ao modi�car
o método na segunda, a primeira também é modi�cada. É representada por uma seta tracejada que parte
lateralmente da primeira classe, a classe dependente, e aponta para a segunda.
● Associação
Quando os objetos de classes diferentes podem se comunicar. É representada por uma linha que liga as
classes lateralmente;
● Agregação
Um tipo especí�co do relacionamento de associação. Na agregação, duas classes existem de maneira
independente à outra. Objetos podem ser criados em uma classe tendo como base a outra, contendo
assim a outra classe dentro dela. É representada por uma espécie de seta, que conecta as classes
lateralmente, e apresenta um losango vazado em sua ponta. Ela parte da classe que é contida e aponta
para a classe que a contém.
● Composição
Outro tipo de relacionamento por associação. Na composição, uma classe é composta por outra, isto é, a
existência de uma classe só é possível devido a existência da outra. Caso uma classe que compõem outra
seja removida, essa também será. Sua representação no diagrama é semelhante a do tipo agregação, mas
o losango é preenchido, apontando para a classe que é composta por aquela que estiver ligada a ela.
Além de de�nir o tipo de relacionamento entre uma classe, temos que de�nir se essa será concreta, abstrata ou
estática. Pode haver ainda a necessidade de se criar uma interface. Durante  a construção de classes, portanto,
é importante ainda o conhecimento das seguintes variações:
A partir do próximo tópico você começará a pôr esses conceitos em prática. Até o �nal desta disciplina, você
será capaz de construir classes para a programação de seus jogos, de�nindo seu tipo e suas relações.
1.2 O game Breakout
Durante a primeira unidade desta disciplina, você exercitou a construção de classes ao propor uma versão do
game Pong (1972). Agora que você tem mais informações sobre esse processo, vamos fazer um exercício de
abstração para organizar os elementos do jogo Breakout (1976), um dos games derivados do Pong .
● Classe concreta
Permite a criação de instâncias e todos os seus métodos podem ser implementados. Utilizada para a
criação de objetos;
● Classe estática
Não pode serinstanciada nem herdada, pois somente possui atributos e métodos auxiliares estáticos, isto
é, que se referem a classe como um todo e não a objetos. Utilizada para não permitir sua instanciação;
● Classe abstrata
Uma classe base que não pode ser instanciada, pois contém ao menos um método abstrato, isto é, um
método que não pode ser implementado, apenas uma de�nição genérica de algo que será especi�cado
em cada uma de suas classes derivadas. Utilizada para centralizar atributos e métodos que serão
herdadas por outras classes, suas �lhas, que serão classes concretas;
● Interface
Não é uma classe, mas sim uma espécie de contrato que as classes com que se relaciona devem assinar.
Em uma interface todos os seus métodos são abstratos e as classes que a implementam são obrigadas a
implementá-los. Utilizada para aplicar o conceito de herança múltipla, no qual uma mesma classe
implementa duas ou mais interfaces.
Assim com o Pong , o Breakout foi lançado em arcade, mais conhecido no Brasil como �iperama. Essa máquina
integra o sistema do jogo com todo o hardware necessário para jogá-lo. Por ter sido criado nos anos iniciais do
desenvolvimento de jogos eletrônicos, a estrutura do Breakout não é muito complexa, mas já apresenta novos
elementos em relação ao Pong .
Os elementos adicionais no Breakout são alguns blocos localizados no topo da tela. Ao serem atingidos pela
bola, tais blocos desaparecem e o jogador acumula pontos. O jogador controla uma espécie de raquete que �ca
na base da tela e apenas se movimenta para os lados. Com a tarefa de não deixar a bola cair, o jogador deve
destruir a maior quantidade possível de blocos no menor número de tentativas.
Figura 2: Uma das versões do game Breakout. Fonte: wikimedia, 2020
Contendo essas poucas regras, o jogo permite que sejam criadas diversas variações, que podem ser facilmente
encontradas na internet em uma simples pesquisa. Durante esta unidade, criaremos uma versão de Breakout
próxima àquela lançada em 1976, mas dentro do que já foi aprendido nesta disciplina.
Partindo do que foi abordado nesta aula, vamos de�nir como esse jogo pode ser representado em classes. Por
ter sua mecânica muito simpli�cada em relação a jogos atuais, o Breakout não necessita de um exercício muito
complexo de abstração. Além disso, programaremos uma versão do jogo já existente, eliminando assim a etapa
de abstrair características e comportamentos do nosso mundo físico.
Seguindo a �gura 2, que apresenta um exemplo de versão do jogo, podemos identi�car 5 elementos diferentes:
o jogador, a bola, os blocos, a pontuação ( score ) e as vidas ( lives ). Para esse primeiro exercício, podemos
considerar cada um desses elementos como diferentes classes. Observe que a partir da classe blocos serão
criadas diversas instâncias, cada uma contendo, ao menos o atributo cor, com alguma variedade. Durante o
desenvolvimento do game continuaremos a criar relações entre os conceitos estudados e sua aplicação prática.
Você quer ler
O livro A condição eletrolúdica: Cultura visual nos jogos eletrônicos, do autor Guilherme Xavier, traz um
histórico da origem dos games, incluindo a era dos arcades . 
2. Elementos de construção do jogo
Para iniciar o desenvolvimento de uma versão do game Breakout , abra o Unity Hub e crie um novo projeto a
partir de um template 2D. Lembre-se de nomear o arquivo e indicar um diretório do computador para encontrá-
lo facilmente. A primeira vez que a Unity abrir o projeto levará mais tempo para carregar seus elementos, o que
não acontecerá nas próximas vezes
Primeiramente, vamos inserir os sprites que serão necessários. Para esse projeto apenas utilizaremos os tipos
primitivos do software , isto é, as formas disponíveis em seu menu de opções, sem incluirmos as possibilidades
de importação de grá�cos.
Utilizando o menu Assets > Create > Sprites , adicione dois quadrados ( square ) e um círculo ( circle ). Renomeie
respectivamente para Jogador, Blocos e Bola. Arraste os três objetos para a cena, a Scene . Foram criados um
GameObject para cada uma de suas inserções, já que esse elemento na Unity corresponde a um objeto. Observe
que a câmera também é um objeto dentro da engine , e precisa existir para conseguirmos fechar o jogo e para
visualizá-lo no painel Game . Salve seu projeto em File > Save .
Antes de adicionar diversos blocos na cena vamos transformar esse GameObject em um Prefab , isto é, um
modelo que servirá de base para diversas cópias. Como uma espécie de template de um GameObject , um Prefab
permite a criação de instâncias na cena. Dessa maneira, assim que as propriedades de um forem modi�cadas é
possível aplicar a todos. O Prefab é indicado para a criação dos blocos pois permite essa alteração em massa, já
que um asset não tem componentes, somente quando é inserido como objeto na cena.
Para transformar nosso GameObject Blocos em um Prefab é necessário arrastá-lo para uma pasta do painel
Project . Clique no menu Assets > Create > Folder e renomeei a pasta criada, por exemplo, chame-a de Prefabs .
Arraste o GameObject Blocos, que está localizado na janela Hierarchy , para dentro da pasta Prefabs criada no
painel Project . Automaticamente a Unity exibe o ícone do GameObject Blocos em azul, indicando se tratar de um
Prefab .
Você pode até mesmo deletar o GameObject da janela hierarquia que ele continuará existindo na pasta Prefabs ,
pronto para ser adicionado novamente. Posicione alguns blocos na cena arrastando-os da pasta Prefabs , ao
invés do asset Blocos que você criou através da adição do sprite .
Figura 3: Elementos do projeto Breakout. Fonte: Proprio autor, 2020
Ao clicar em um dos objetos da cena, você poderá ver seus componentes de�nidos por padrão na janela
Inspector. É possível modi�car seu posicionamento alterando os eixos x e y na opção Position , assim como suas
dimensões na opção Scale . Aproveite para melhorar a aparência dos objetos da cena, já que por padrão a bola
�ca muito grande e o jogador quadrado di�culta a jogabilidade. Clique no jogador e utilize as opções de escala (
Scale ) no painel Inspector para modi�car seu formato. No exemplo da �gura 3 suas dimensões são 1.5 em x e
0.3 em y. A bola foi con�gurada com 0.3 em ambos os eixos.
Como nossos blocos agora são Prefabs , faremos essa adição em apenas um deles e aplicaremos em todos os
demais automaticamente. Selecione um dos blocos na cena e modi�que suas dimensões. O exemplo da �gura 3
apresenta as seguintes medidas: 1 em x e 0.4 em y. Ainda no painel Inspector clique em Overrides > Apply All ,
para aplicar a modi�cação em todos os blocos. Não esqueça de salvar seu projeto.
Para mais customização, selecione a câmera na janela Scene e no painel Inspector você poderá alterar a cor de
fundo na opção Background , o plano de fundo. Clique na cor azul padrão e selecione uma cor na roda de cores.
Lembre-se de manter um contraste entre �gura e fundo que seja agradável para jogar, por esse motivo, dê
preferência a cores mais contrastantes. Se preferir, você poderá também modi�car a cor dos outros elementos,
clicando no objeto correspondente e na opção Color do painel Inspector .
Nesse mesmo painel poderemos adicionar os novos componentes que serão necessários. Para que os scripts de
controle do jogo consigam identi�car quando os objetos se colidirem com a bola, teremos que adicionar um
componente do tipo Collider .
Clique no jogador, no painel Inspector clique na opção Add Component . Pesquise nesta caixa de busca pela
palavra collider . Escolha a seguinte opção: Box Collider 2D . Para a bola selecione o collider correspondente a seu
formato: o Circle Collider 2D . Para adicionar simulação de física na bola, como a possibilidade dela rebater e ser
lançada automaticamente, adicione mais um componente: o RigidBody 2D. Clique em um dos blocos e adicione
também o componente Box Collider 2D. Lembre-se de aplicar a mudança a todos os blocos utilizando a opção
Overrides > Apply All .
Nesse momento, todos os elementosvisuais do jogo foram inseridos, com exceção do placar de pontuação e a
contagem de tentativas. Para que os scripts , que serão programados na próxima aula, consigam calcular essas
informações, precisamos adicionar elementos que identi�quem quando o jogador deixar a bola cair. Para que a
bola não saia da tela e seja rebatida também pelas paredes do jogo, precisamos adicionar um elementos que
impeça essa saída.
Vamos adicionar um GameObject vazio, isto é, sem nenhum asset associado. Clique no menu GameObject >
Create Empty . Ele será adicionado na janela de hierarquia e pode ser renomeado, basta clicar com o botão
direito do mouse sobre seu nome e escolher a opção Renomear. Dê o nome de Topo. Adicione mais três
GameObjects vazios renomeando para: Base, Direita e Esquerda. Esses elementos servirão para limitar o espaço
da bola na tela, rebatendo ela de volta, ou, no caso da Base, indicando que o jogador perdeu uma tentativa.
Para isso adicione o componente Box Collider 2D em cada um desses GameObjects vazios.
Para que esses elementos cumpram seu papel de limitar a bola, devemos redimensioná-los a �m de cobrir todo
o perímetro da tela. Arraste cada um deles para sua respectiva posição, fora dos limites da tela, e clique na
opção Edit Collider , dentro do painel Inspector para redimensioná-los. Observe o exemplo na �gura a seguir:
Figura 4: Posicionamento do GameObject Base. Fonte: proprio autor, 2020
Após posicionar e redimensionar corretamente cada um dos elementos, clique novamente no menu
GameObject , mas dessa vez escolha a opção UI > Text . Repita esse processo mais uma vez, criando assim dois
textos. Mais adiante, durante os estudos desta disciplina, abordaremos os conceitos relacionados a UI, a
interface do usuário, do inglês: User Interface . Por enquanto, adicionaremos apenas dois GameObjects do tipo
texto para exibirmos o placar e a contagem de tentativas do jogador. Renomeie um dos objetos de texto para
Placar e o outro para Tentativas. Você deve ter percebido que eles pertencem a outro GameObject , o Canvas,
que será responsável por posicionar esses elementos sobre nosso jogo.
Clique em cada um dos textos e altere suas propriedades no painel Inspector. Você também poderá posicioná-
los no melhor lugar da tela para visualização durante a partida. Nesse momento considere como tela do jogo a
área maior delimitada pelo Canvas. É possível visualizar a tela do jogo com os elementos de UI na janela Game .
Conforme exempli�cado na �gura a seguir, foram alterados além do posicionamento: o texto, a cor e o estilo
das letras.
Figura 5: Interface do game Breakout. Fonte: elaborado pela autora. 2020
Agora que todos os elementos necessários para a programação do jogo foram inseridos, iniciaremos a
programação dos scripts na próxima aula. Não esqueça de salvar o seu projeto.
Você quer ver
O site itch.io é uma plataforma para a comercialização de jogos de desenvolvedores independentes. Nesse
site é possível encontrar diversas versões do game Breakout para jogar gratuitamente, além de milhares de
outros jogos. Para acessar as versões disponíveis de Breakout clique no link: https://itch.io/search?
q=breakout 
3. Programação das interações
Antes de iniciarmos a criação dos scripts é necessário pensar em quais interações deverão ser programadas.
Para esse primeiro projeto, não se preocupe ainda em representar as classes de acordo com um diagrama de
ULM. Essa etapa será abordada na próxima unidade, quando criaremos um jogo de maior complexidade.
Em nossa versão de Breakout teremos as seguintes interações de quem irá jogar: movimentar o jogador e
reiniciar a partida. Podemos destacar as seguintes interações entre objetos:
Barreiras - Topo, Esquerda e Direita: limitam os movimentos da Bola;
Barreira - Base: soma às Tentativas cada vez que for atingida pela Bola;
Blocos : somam pontos no Placar ao serem atingidos pela Bola;
Observe que todas essas interações partem de comportamentos do objeto Bola. Ainda que seja possível
programar todo o código em praticamente um script , apenas se referindo aos outros objetos quando
necessário, em OO devemos sempre optar por separar as ações de nossos objetos, facilitando a manutenção
do código. Dessa maneira, a colisão da Bola com a Base será programada em um script dedicado somente a
essa tarefa, e será associado à Base. Caso seja necessário corrigir erros ou modi�car alguma parte do código,
saberemos exatamente onde encontrá-lo. Faremos então estes cinco scripts :
Script Bola : controla sua movimentação;
Script Jogador : controla sua movimentação dentro dos limites da tela;
Script Blocos : destrói sua cópia que foi atingida pela Bola e aciona o comando que soma pontos ao Placar;
Script Base: identi�ca a colisão com a Bola e então aciona o comando que soma mais um às Tentativas,
enviando a Bola novamente para o centro da tela;
Script GameManager: controla os comandos de UI e de gerenciamento de cena, além de calcular a soma
do Placar e das Tentativas.
Veremos mais sobre o objeto e o script GameManager na próxima aula, quando serão programados os controles
gerais do jogo. Por enquanto, faremos a programação dos scripts que controlarão as movimentações dos
nossos objetos. Note que não precisamos de um script para limitar os movimentos da Bola, pois isso já está
https://itch.io/
https://itch.io/search?q=breakout
sendo feito com a interação entre dois componentes da Unity : o Circle Collider 2D e o RigidBody 2D . Esse último,
por ser um componente de simulação física, identi�ca que colidiu e responde automaticamente a essa colisão,
rebatendo a bola nesse caso.
3.1 Movimentação do jogador
Para iniciar a programação do objeto Jogador crie um novo script com esse nome. Você também pode organizar
todos os scripts em uma pasta dentro da janela Project . Observe a �gura a seguir contendo todo o código
necessário para esse script :
Figura 6: Script Jogador. Fonte: Próprio autor, 2020
Conforme foi projetado o script Jogador apenas cumpre uma ação: permite a movimentação do objeto Jogador,
limitando seus movimentos para que ele permaneça visível na tela. Além da estrutura apresentada na unidade
anterior temos novos elementos nesse script . Um novo método chamado MovimentaJogador (entre as linhas
23 e 37) foi criado para realizar a ação do objeto. Ele apresenta a mesma estrutura dos métodos Start e Update ,
mas para ser executado precisa ser chamado em algum momento dentro de um deles. Na linha 20 podemos
ver a notação para invocá-lo dentro do método Update , ou seja, a cada frame .
Dentro do método MovimentaJogador, temos decisões sendo feitas baseadas em condições. O objeto deverá se
movimentar para a direita e para a esquerda de acordo com a seta do teclado que for pressionada. Na linha 28
temos a expressão If, que é uma forma de veri�carmos se uma condição é atendida. Nesse caso, ela veri�ca se
a tecla pressionada (no código o trecho: Input.GetKey ) é a seta para a direita (no código o trecho:
KeyCode.RightArrow ). Caso essa condição seja atendida, o programa executará o que foi determinado entre as
chaves que vem a seguir.
Na linha 30, temos a expressão responsável pela movimentação do Jogador. A partir do componente transform,
embutido no GameObject , modi�camos seu posicionamento utilizando seu método Translate . Esse método
movimenta o objeto pelos eixos x e y da tela, indicados pela expressão Vector2 . A palavra right (direita) indica a
direção que o objeto deverá seguir. Para que ele se movimente em uma velocidade acima de 1, devemos
multiplicá-lo pelo valor desejado. Para que o Jogador se movimente com a mesma velocidade em todas as
execuções do jogo, devemos multiplicar ainda pela expressão Time.deltaTime , que converte a movimentação do
Jogador para pontos por segundo, ao invés de pontos por frame . Isso deve ser feito, pois, ao rodar o jogo, o
computador não mantém o mesmo intervalo entre a execução de cada frame , o que resulta em diferentes
velocidades durante a partida.
Observeque a expressão Vector2.right não está multiplicando seu valor padrão (1) por um outro número, mas
sim pela palavra velocidade. Essa palavra se refere a variável declarada na linha 7 do script . Cada variável é uma
espécie de caixa, onde é possível guardar uma informação. Seu valor é atribuído de acordo com o seu tipo, e
pode ser modi�cado.
A palavra public , no início da linha 7, indica o tipo de encapsulamento desse atributo, ou seja, seu modi�cador
de acesso é do tipo público. Isso possibilita que o valor de velocidade pode ser atribuído também na interface da
Unity . A expressão indica ainda o tipo �oat , que se refere a um tipo de variável que aceita guardar números
com casas decimais. Esse tipo é utilizado para o atributo velocidade para assim, permitir mais variações de
valores, não somente números inteiros. A movimentação do Jogador será, portanto, o resultado da expressão
da linha 30, e esse cálculo será feito de acordo com o valor que for atribuído à variável velocidade.
Entre as linhas 33 e 36 do script está a segunda condição, aquela que caso seja atendida, decide a
movimentação do Jogador para a esquerda. Somente com as expressões que foram explicadas até aqui já é
possível movimentar o Jogador. Para isso, é preciso associar o script Jogador ao GameObject de mesmo nome,
arrastando o primeiro a partir do painel Project para o segundo no painel Hierarchy .
No painel Game , ao dar play no jogo você já poderá movimentar seu jogador. Nesse momento ele ainda poderá
sair da tela ao atingir suas extremidades, por esse motivo que a linha 26 do código foi adicionada. Novamente
vamos modi�car o componente transform a partir do script . A expressão transform.position modi�ca o
posicionamento do objeto. O símbolo = indica que o que vem depois é o que está sendo atribuído ao que veio
antes. Nessa linha, a posição do objeto será igual ao posicionamento de seus eixos x e y, que estão sendo
movimentados pelas linhas 30 e 35. Para inserir algum limite na movimentação do Jogador, devem ser de�nidos
os pontos mínimo e máximo de sua movimentação na tela.
Observe que dentro dos parentes de Vector2 , na linha 26, temos a expressão transform.position .y, indicando
que seu posicionamento vertical será aquele mesmo do objeto. Onde �caria a expressão transform.position .x,
para o posicionamento horizontal, temos a seguinte expressão:
Mathf.Clamp(transform.position.x, xMin, xMax)
Esse método permite que o posicionamento do objeto no eixo indicado, nesse caso o x, se modi�que de acordo
com os valores mínimo e máximo indicados. Para modi�carmos esses valores com maior facilidade, sem ter
que procurar por essa linha no código, criamos uma variável para cada valor: a xMin e a xMax. Veja que o nome
das variáveis são inventados, bem como os nomes dos métodos que criamos. Apenas certi�que-se de nomeá-
los de maneira que sua escrita e leitura sejam facilitados.
As variáveis utilizadas pelo método Clamp foram declaradas nas linhas 8 e 9 do código. Elas também são do tipo
�oat , já que esse cálculo precisa ser feito com números decimais. Observe que elas não possuem a indicação
public , o que as torna privadas por padrão. Como seus valores já são atribuídos dentro do código (-8 e 8), não
há necessidade de �carem acessíveis na interface da Unity .
A linha 26, portanto, garante que o posicionamento do objeto Jogador no eixo x não ultrapasse os limites
indicados, ou seja, ele somente poderá se movimentar entre o ponto -8 e o ponto 8 do eixo x. Esse números
indicam exatamente os limites da tela do jogo, e podem ser veri�cados no painel Inspector, ao posicionar seu
objeto nesses limites. Agora que seu jogador se movimenta e não sai da tela, vamos para o próximo script .
Lembre-se de salvar seu projeto a cada modi�cação signi�cativa.
3.2 Movimentação da bola
Ao clicar em play na janela Game , você verá que já é possível movimentar o Jogador. A Bola também se
movimenta, caindo de sua posição inicial e parando ao atingir o jogador. Isso se dá porque o componente
RigidBody2D foi adicionado, ainda que não haja nenhum script associado, ela já é afetada pela gravidade.
Para que a Bola seja rebatida é necessário indicar ao componente RigidBody 2D qual seu tipo de material. Clique
no menu Assets > Create > Physics Material 2D para adicionar o tipo de material correspondente à simulação
física 2D. Renomeie o material criado para Bola. Agora selecione o GameObject Bola na janela de hierarquia e
arraste o material Bola, que acabou de ser criado,   para o campo Material do componente RigidBody 2D, no
painel Inspector. Esse processo deve ser feito para associar o asset material Bola com o objeto Bola inserido na
cena.
Selecione o asset material Bola, no painel Project , e modi�que suas propriedades no painel Inspector. O campo
Friction permite con�gurar um valor para o atrito do material, e o Bounciness sua elasticidade. Insira 0 e 1 para
cada campo respectivamente, fazendo com que a bola não sofra nenhum atrito ao colidir, mas continue sendo
rebatida. Crie um novo script para controlar a Bola e renomeie-o também como Bola, assim �ca mais fácil
identi�car a relação entre os objetos e seus componentes.
Figura 7: Script Bola. Fonte: proprio autor, 2020
Na �gura 7, temos o script Bola já com o código necessário para seu funcionamento. Logo após a de�nição da
classe, feita na linha 5, temos a declaração da variável corpoBola (linha 7). Seu encapsulamento é do tipo
público e esse atributo pertence à classe RigidBody2D . Lembre-se que um componente com esse mesmo nome
foi adicionado ao GameObject Bola, associando assim ambas as classes.
Dentro do método Start foi inserida o código para a movimentação da Bola. Dessa maneira, essa ação será
iniciada assim que o objeto Bola for criado no jogo. Na linha 12, portanto, temos o comando de movimentação
da Bola. Novamente vemos a criação de um objeto Vector2 , mas dessa vez com seus valores padrão: um ponto
por vez. Nesse caso, sua direção inicial será para cima e para direita, sendo Vector2 (x,y). Aqui também temos a
multiplicação pelo Time.deltaTime , a �m de padronizar a execução do jogo. Essa movimentação é atribuída ao
atributo velocity , do objeto corpoBola.
Nossa variável corpoBola, portanto, é um atributo da classe Bola, mas ela também é um objeto da classe
RigidBody2D . Essa última classe tem como um de seus atributos a velocity (velocidade). Como as classes Bola e
RigidBody2D estão associadas, podemos criar um novo objeto do tipo RigidBody2D (chamado corpoBola) dentro
do método Start da classe Bola. Isso deve ser feito para que possamos utilizar as opções de simulação física, da
classe RigidBody2D , em nosso objeto Bola.
Associe o script Bola com o GameObject Bola. No painel Inspector, arraste o componente RigidBody2D para o
atributo Corpo Bola dentro do componente Script . Ao �nal dessa etapa, o painel de seu objeto Bola deverá
estar conforme a �gura a seguir:
Figura 8: Material Bola aplicado ao componente RigidBody2D e este último aplicado ao atributo Corpo Bola. Fonte: proprio autor, 2020.
3.3 Comportamento dos blocos
Para que os Blocos identi�quem a colisão com a Bola e possam desaparecer, podemos identi�car a Bola com
uma etiqueta, uma tag . Dessa maneira, utilizaremos um método no script dos Blocos que veri�cará se eles
foram atingidos pela Bola, executando assim a ação de auto destruição.
Clique no GameObject Bola e na janela Inspector clique em Tag > Untagged > Add Tag > + . Para nomear essa
nova tag escreva Bola e clique em Save . Clique no objeto Bola novamente e agora na janela Inspector clique em:
Tag > Bola. Você acaba de associar uma tag para facilitar a identi�cação de seu objeto pelos demais objetos da
cena. Crie um novo script chamado Blocos. Lembre-se de associá-lo a pelo menos um dos blocos e, como são
Prefabs , no painel Inspector clique em Overrides > Apply All .
Figura 9: Script Blocos. Fonte: proprio autor, 2020
Na �gura 8, você pode observar o código necessário para os Blocos desapareceremao colidirem com a Bola.
Entre as linhas 19 e 25, vemos o método OnCollisionEnter2D sendo utilizado. Ele é um método da classe Collider ,
a classe base de todas as classes de colliders . Lembre-se que ela está associada a nossa classe Blocos, pois
adicionamos como um componente através do painel Inspector.
Esse método veri�ca a colisão entre colliders e objetos do tipo RigidBody2D . A variável collision dentro dos
parênteses, indica ser do tipo Collision2D . Essa variável é utilizada na linha 21, referindo-se a seguinte condição:
collision.gameObject.CompareTag (“Bola”). Essa expressão indica que o objeto da classe Blocos colidiu com um
GameObject com a tag Bola. Caso essa condição seja atendida o método executará ação da linha 23, ou seja,
destruirá este ( this ) GameObject . Salve seu projeto para continuarmos a programação de scripts . Na próxima
aula serão programados os códigos para o controle geral do jogo.
4. Game manager
Para controlar os elementos de interface do usuário do jogo e o gerenciamento da cena, podemos trabalhar
com um Game Manager . Esse é o nome padrão do gerenciador do jogo dentro da Unity , permitindo que o script
que controla o game seja identi�cado facilmente pelo desenvolvedor.
Crie um novo script chamado GameManager . Observe que quando esse nome é dado a seu script ele apresenta
um ícone diferente dos demais, uma engrenagem. Para que o código inserido nele seja rodado junto com o jogo
você deverá associá-lo a um objeto. Crie um novo GameObject vazio e adicione a ele esse novo script .
Figura 10: Script GameManager.Fonte: proprio autor, 2020
Para que possamos controlar os elementos da interface do usuário, utilizando os métodos já existentes na Unity
é necessário adicionar a linha 4, indicada na �gura anterior, em seu código. A linha 5 deve ser adicionada para
que possamos controlar as cenas do projeto.
Nas linhas 9 e 10 foram criadas duas variáveis do tipo int , que indicam somente aceitar números inteiros. A
primeira servirá para guardar os pontos do jogador e a segunda, para guardar as vidas já utilizadas. Nas linhas
11 e 12 foram criadas variáveis da classe Text , que serão utilizadas para exibir os valores das variáveis pontos e
vidas em nossos objetos de texto da cena.
Entre as linhas 23 e 26 temos uma condicional. Caso a tecla espaço seja apertada a cena será carregada
novamente. Para isso foi utilizado o método LoadScene da classe SceneManager . O LoadScene carrega a cena
que for indicada entre aspas dentro de seus parênteses. Veri�que o nome de sua cena no painel Project , caso
não a tenha modi�cado em nenhum momento está com seu nome padrão: SampleScene . Esse trecho de código
então deverá ser: SceneManager.LoadScene("SampleScene ");
Entre as linhas 28 e 32 foi criado o método VezesCaiu, ele soma um à variável vidas e modi�ca o texto da
variável Tentativas para: Tentativas + o valor da variável vidas. O mesmo acontece com o método Pontua, mas
ele soma um à variável pontos e modi�ca o texto da variável Placar.
Observe que esses métodos não estão sendo chamados dentro de seu próprio script . A ação de somar pontos,
somar tentativas e modi�car o texto da UI será acionada pelo objeto Base. Para que o GameManager consiga
acessar os objetos Placar e Tentativas arrastes esses GameObjects para os campos correspondentes no painel
Inspector com o GameObject GameManager selecionado.
4.1 Programação da base
Crie um novo script com o nome Base. Ele servirá para invocar o método VezesCaiu cada vez que a Bola atingir o
objeto Base. Veja o código completo na �gura a seguir:
Figura 11: Script Base. Fonte: proprio autor, 2020
O método OnTriggerEnter2D é utilizado para identi�car a colisão do objeto da classe RigidBody2D , sem interferir
em suas propriedades físicas. Dessa maneira, a Base servirá apenas para identi�car a colisão da Bola, não mais
para rebatê-la. Para que esse método possa ser utilizado clique no objeto Base e acione a opção Is Trigger , no
painel Inspector .
Assim como o método que adicionamos na Bola, esse também executa uma ação com base na comparação de
qual tag colidiu com seu objeto. A linha 21 veri�ca se o objeto other é a Bola. Na linha 23 o script procura o
objeto GameManager e invoca seu método VezesCaiu. A linha 25 retorna o objeto Bola (identi�cado como other )
para a posição central da tela, o Vector2 .zero. Não esqueça de associar o script Base com seu respectivo
GameObject .
Antes de salvar seu projeto adicione mais uma linha no script dos Blocos. Nesse último passo nós invocaremos
o método Pontua, que criamos no GameManager , dentro do método OnCollisionEnter2D dos Blocos. Adicione
uma linha abaixo da linha 23 desse script , insira a seguinte expressão: FindObjectOfType<gamemanager>
().Pontua()</gamemanager> ;
Agora o método criado dentro do script dos Blocos deverá ter �cado com o seguinte código:
Muito bem! Você acaba de concluir uma programação de uma versão de Breakout . Caso você tenha testado seu
jogo verá que todos os controles funcionam, porém, a bolinha apresenta um comportamento errático. Não se
preocupe, na próxima unidade iniciaremos o processo de testes de jogabilidade e correção de bugs, uma etapa
essencial para a programação de jogos.
Você sabia
A habilidade de programar jogos é muito útil no mercado de trabalho. Há muito anos a indústria de games
é a maior indústria de entretenimento do mundo, com rendimentos superiores aos das indústrias
cinematográ�ca e fonográ�ca. Informações detalhadas sobre quais foram os jogos e categorias mais
rentáveis em 2019 podem ser acessadas em: www.superdataresearch.com/reports/2019-year-in-review 
Síntese
Programar um jogo com OO facilita o entendimento do porquê desse paradigma de programação ser tão
utilizado em game engines . Nossa programação de Breakout focou nos objetos utilizados no jogo e nas suas
interações. Assim, durante o desenvolvimento de um jogo da era dos arcades foi possível aplicar os conceitos
da Programação Orientada a Objetos. O projeto de uma versão do Breakout também nos ajudou a conhecer
melhor o funcionamento da game engine Unity e a programar utilizando a linguagem C#.
Vimos que em programação há diversas maneiras de se realizar uma tarefa, o que fazemos é utilizar as boas
práticas para escrever um código de acordo com as indicações do paradigma de OO, a organização de dois
projetos podem ser diferentes, desde que sigam as orientações para melhor escrita e leitura do código, bem
como aproveitar as facilidades oferecidas pela Unity , como os Prefabs e os componentes de simulação física.
Durante esta unidade você entrou em contato com:
● Criação de um projeto de jogo simpli�cado;
● Construção de classes e diagrama de ULM;
● Elementos básicos na Unity;
http://www.superdataresearch.com/reports/2019-year-in-review
● Programação de movimentos e de interação entre objetos;
● Controle geral do jogo.
Download do PDF da unidade
Bibliografia
FOWLER, Martin. UML Distilled : A Brief Guide to the Standard Object Modeling Language. Addison-Wesley
Professional, 2003. 
XAVIER, Gley Fabiano Cardoso. Lógica de Programação . São Paulo: Editora Senac São Paulo, 2011. 
XAVIER, Guilherme. A condição eletrolúdica : Cultura visual nos jogos eletrônicos. Teresópolis, RJ: Novas Ideias,
2010. 
(Documentação da Unity). Disponível em: https://docs.unity3d.com . Acesso em 28/03/2020. 
Referências Imagéticas: 
Figura 1 e 3 a 11: Cópias de tela produzidas pela própria redatora. 
Figura 2: Uma das versões do game Breakout. Disponível em: <
https://commons.wikimedia.org/wiki/File:Yakanoid2.png > Acesso em 03/2020. 
https://docs.unity3d.com/
https://commons.wikimedia.org/wiki/File:Yakanoid2.png

Continue navegando