Buscar

Pilhas em Jogos Digitais

Prévia do material em texto

03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=uczP… 1/54
PROGRAMAÇÃO E INTEGRAÇÃO DEPROGRAMAÇÃO E INTEGRAÇÃO DE
JOGOSJOGOS
PILHAS E FILASPILHAS E FILAS
Autor: Me. Victor de Assis Rodrigues
Revisor : Emerson dos Santos Paduan
IN IC IAR
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=uczP… 2/54
introdução
Introdução
Nesta unidade, discorreremos sobre as características de dois tipos abstratos
de dados muito conhecidos e importantes: pilha e �la. Cada um possui
características singulares relacionadas à implementação e também contextos
de utilização.
Exploraremos contextos de utilização dessas estruturas em jogos digitais. E o
objetivo aqui é separar a lógica de implementação de mecanismos da lógica
de design de jogos, pois cada uma possui formas de implementação e
objetivos diferentes.
Por �m, exploraremos também os mecanismos clássicos de iteração, para
que você possa ter mais conhecimento e habilidade na implementação de
seus jogos digitais.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=uczP… 3/54
Imagine que você está numa livraria em busca de um livro muito interessante
para sua coleção. Enquanto analisa a vitrine e as estantes, repara que, bem
perto de onde você está, existe uma pilha de livros em promoção; a pilha está
bem alta e possui diversos livros, e você passa o olho nas lombadas
veri�cando se existe algum de seu interesse. Eis que, naquele momento, você
encontra o livro que procurava. Entretanto, surge um problema: o livro é um
dos últimos da pilha, ou seja, se pegá-lo, provavelmente derrubará todos os
que estão acima.
O que podemos perceber é que existe uma forma lógica para resgatar o livro
que queremos: retirar os itens que estão acima até termos acesso ao
exemplar. Outro ponto a ser observado é que o livro apenas se encontrava
naquela posição porque foi inserido na pilha antes dos outros, ou seja, o livro
no topo da pilha foi o último a ser colocado nela.
Em várias outras situações de nosso cotidiano esse mecanismo acontece: se
montamos um ventilador de teto, por exemplo, muito provavelmente a
ordem de encaixe das peças será: suporte de rotação; hélices; cúpula; e
PilhasPilhas
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=uczP… 4/54
lâmpada. E, para desmontar, será justamente o inverso: lâmpada; cúpula;
hélices; e suporte.
Outro exemplo é a Máquina PEZⓒ , uma fornecedora de doces (GOODRICH;
TAMASSIA, 2013). Nesse equipamento, os doces são armazenados dentro de
um compartimento que possui na base uma mola. Toda vez que a tampa do
compartimento é aberta, o doce mais ao topo é liberado, como ilustra a
Figura 2.2.
Figura 2.1 – Ventilador de teto
Fonte: Aopsan / Freepik.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=uczP… 5/54
Começaremos a explorar melhor a estrutura e também as formas de
implementá-las em nossos jogos, a seguir.
Estrutura de Dados em Pilha
Uma pilha é “uma coleção de objetos que são inseridos e retirados de acordo
com o princípio que o último elemento que entra é o primeiro que sai”
(GOODRICH; TAMASSIA, 2013). Esse princípio também é chamado de LIFO (
Last In, First Out ) ou, ainda, FILO ( First In, Last Out ) (TENENBAUM; LANGSAM;
AUGENSTEIN, 1995). Apesar de ser considerada a estrutura de dados mais
simples de todas, pode ser aplicada em diversos contextos.
Imagine que você programa um sistema que sorteia números para que
organizadores de determinado evento possam dar brindes aos participantes.
Suponha que serão sorteados 5 brindes e os números irão de 1 a 100.
Quando um número for sorteado, pode ocorrer de o participante não estar
mais no evento; nesse caso, precisamos descartar o número e sortear outro.
Essa é uma situação em que poderia ser implementada uma pilha, de forma
semelhante ao ilustrado na Figura 2.3.
Figura 2.2 – Funcionamento do dispensador da Máquina PEZⓒ (marca
registrada da PEZ Candy Inc.)
Fonte: Goodrich e Tamassia (2013, p. 178).
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=uczP… 6/54
Na Figura 2.3, podemos observar algumas situações:
Em (a), nenhum número foi sorteado; logo, a pilha está vazia.
Em (b), temos o primeiro número sorteado; logo, esse número está
no topo da pilha, e agora a pilha possui um elemento.
Em (c) e (d), temos a inclusão de novos números, e,
consequentemente, o topo da pilha também se altera.
Em (e), temos a inclusão de um número de participante que não está
mais no evento. Nesse caso, ele foi adicionado à pilha, mas deve ser
descartado.
Em (f), o número foi retirado da pilha, e, consequentemente, a
referência do topo também é alterada.
Em (g), um novo número é sorteado e inserido normalmente, no
lugar do número anterior.
Em (h), temos a inserção do quinto número, o qual resulta na
condição de término do sorteio.
Como pode ser identi�cado no exemplo anterior, uma pilha possui 2 métodos
fundamentais: empilhar ( push ) e desempilhar ( pop ). Os dois estão
relacionados, consecutivamente, a inserir e remover um elemento da pilha.
Figura 2.3 – Funcionamento de uma pilha
Fonte: Elaborada pelo autor.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=uczP… 7/54
Por sua vez, existem outros métodos adicionais que podemos criar para
facilitar o gerenciamento da pilha: retornar a quantidade de elementos ( size );
checar se a pilha está vazia ( is empty ); veri�car o valor do elemento no topo (
top ); veri�car se a pilha está cheia, caso haja limite máximo ( is full ); e até
criar nova pilha ( create ) (FERRARI et al., 2014; GOODRICH; TAMASSIA, 2013;
TENENBAUM; LANGSAM; AUGENSTEIN, 1995). O Quadro 2.1 apresenta
descrição resumida de algumas dessas operações.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=uczP… 8/54
Quadro 2.1 – Métodos básicos de pilhas e alguns adicionais
Fonte: Elaborado pelo autor.
Métodos Descrição
Empilhar(P, item,
sucesso)
O método Empilhar() é responsável por inserir
o elemento no topo da lista. O parâmetro P é a
pilha que será utilizada; item é o elemento a
ser inserido; e a variável sucesso terá a
informação sobre o processo ter dado certo
ou não, sendo esse último um parâmetro
opcional.
Desempilhar(P,
sucesso)
Esse método retira o elemento da pilha. O
elemento a ser retirado sempre será aquele
localizado no topo. O parâmetro P é a pilha
que será utilizada; e a variável sucesso terá a
informação sobre o processo ter dado certo
ou não, sendo esse último um parâmetro
opcional.
ContarElementos(P) Esse método adicional conta a quantidade de
elementos inseridos na pilha. É necessário
informar a pilha que será utilizada no
parâmetro P.
EstaVazia(P) Método adicional que veri�ca se existe algum
elemento na pilha. O parâmetro P é a pilha a
ser utilizada.
Veri�caTopo(P) Método adicional que retorna qual elemento
está no topo. Caso a pilha esteja vazia, um
erro será lançado.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=uczP… 9/54
Nas próximas seções, exploraremos detalhes dessas operações e
descobriremos como aplicá-las numa linguagem de programação. Vamos
conferir!
Operações em Pilhas
Existem algumas formas que podemos escolher para implementar a estrutura
de dados em pilha: utilizar vetores, ponteiros ou com recursos de uma
linguagem deprogramação orientada a objetos; utilizar classes e interfaces.
Como nosso objetivo é aplicar a estrutura de dados em jogos em linguagem
orientada a objetos, explicaremos sua implementação utilizando uma
modelagem de classes.
Quando escolhemos a “orientação a objetos”, temos duas opções: podemos
implementar os elementos de forma encadeada; ou utilizar recursos da
própria linguagem. Como algumas estruturas de dados são utilizadas numa
in�nidade de situações, muitas linguagens já fornecem recursos aos
programadores.
Sendo o nosso principal objetivo aprender o funcionamento da estrutura,
implementaremos por meio de elementos encadeados. Entretanto, no
momento de aplicarmos em jogos, utilizaremos alguns recursos da própria
linguagem, que nos ajudam a alcançar o resultado que queremos.
Tipo Abstrato de Dados em Pilha
O primeiro assunto que precisamos compreender é que a pilha é um
conjunto de itens, e cada item é dividido, de forma teórica, em duas partes:
valor e referência para o próximo elemento. As duas partes estão ilustradas
na Figura 2.4.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 10/54
Antes de criarmos uma estrutura de dados em pilha, devemos de�nir a
estrutura item , que é um tipo de dados compostos. Segue um exemplo de
dois atributos: valor e próximo. Além disso, declaramos um construtor para a
classe, para o qual deve ser informado um valor – sem esse, o Item não
deveria existir.
class Item {
valor = 0;
proximo = null;
constructor(valor) {
this.valor = valor;
}
Com a criação do Item , podemos implementar a estrutura de dados em
pilha. Segue a de�nição principal (no decorrer das próximas seções,
exploraremos os métodos especí�cos desse tipo de dados):
class Pilha {
Figura 2.4 – Representação do item
Fonte: Elaborada pelo autor.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 11/54
topo = null;
totalElementos = 0;
// Métodos e funções
}
A classe Pilha possui dois atributos: topo e totalElementos . O atributo topo
armazenará a referência do último elemento inserido na pilha, que, por sua
vez, deve ser o primeiro a ser retirado quando houver necessidade. O atributo
totalElementos representa a quantidade de elementos armazenados na
pilha.
Após de�nir os atributos da classe Pilha , podemos iniciar a implementação
de métodos responsáveis por gerenciar elementos da coleção.
Primeiramente, analisaremos o método empilhar, responsável por inserir um
novo elemento em nossa estrutura de dados.
Empilhar elemento
saiba mais
Saiba mais
O site VisuAlgo permite a visualização de
diversas estruturas de dados e operadores
de manipulação de forma grá�ca, o que
facilita o entendimento do tema aqui
abordado. É possível interagir com as
estruturas em pilha, �la, lista, árvores e
diversas outras, além da implementação de
algoritmos conhecidos.
Fonte: Visualgo ([S.d.]).
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 12/54
O método empilhar receberá como parâmetro um elemento, que sempre
entrará no topo da pilha. Na Figura 2.5, é possível perceber as ligações que
deverão ser atualizadas nessa operação.
A partir de agora, exploraremos o código em Javascript.
No método, recebemos como parâmetro o elemento que será empilhado.
Primeiro, atualizaremos a referência do item , onde o atributo proximo
receberá o item que está no topo. Se a pilha estiver vazia, essa propriedade
receberá o valor nulo, que é condizente para a situação, uma vez que não
existe um próximo elemento.
Agora que criamos a ligação do item com a pilha, podemos atualizar a
referência do atributo topo , cujo valor será o do próprio item. Assim, temos
as ligações necessárias estabelecidas de forma completa.
Ao �nal, apenas adicionamos mais 1 (um) no atributo totalElementos .
Desempilhar Elemento
O método desempilhar é mais simples, uma vez que apenas atualizaremos a
referência do atributo topo , como ilustrado na Figura 2.6.
Figura 2.5 – Empilhar elemento
Fonte: Elaborada pelo autor.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 13/54
No código anterior, não precisamos passar nenhum parâmetro para o
desempilhar, uma vez que o elemento já está na lista. Precisamos
primeiramente veri�car se a pilha está vazia, isto é, se o total de elementos
for igual a 0. Caso esteja, retornaremos um erro.
Se a pilha não estiver vazia, armazenaremos o elemento numa variável
temporária, chamada elemento. Depois, atualizaremos a referência da
variável topo , para pegar o próximo elemento da pilha, e descontaremos
numa unidade o valor do atributo correspondente ao total de elementos. No
�nal, retornaremos o elemento que acabamos de retirar da lista.
Contar Elementos e Pilha Vazia
Como já temos um atributo destinado na classe Pilha, que controla a
quantidade de elementos, basta criarmos uma função que retorne esse
número, como segue:
function contarElementos () {
return this.totalElementos;
Figura 2.6 – Empilhar elemento
Fonte: Elaborada pelo autor.
A partir de agora, exploraremos o código em Javascript.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 14/54
}
Da mesma forma, para saber se a pilha está vazia, basta consultarmos esse
atributo. Se o atributo totalElementos for igual a 0, a pilha estará vazia:
function pilhaVazia () {
return (this.totalElementos == 0);
}
É importante lembrar que existem outras formas de veri�car se uma
estrutura está vazia, além da quantidade de elementos. Outra forma seria
veri�car a referência armazenada pelo atributo topo : caso o valor seja nulo, a
pilha está vazia.
Concluímos o estudo da estrutura de dados em pilha e suas funcionalidades
básicas. Iremos, na próxima seção, explorar a sua utilização no contexto de
jogos digitais.
reflita
Re�ita
Você já parou para pensar que a funcionalidade ‘desfazer’ (o
famoso “Ctrl + Z”) é implementada por meio de pilhas? Para
cada ação que você realiza num documento, ocorre um
registro inserido nesse tipo de estrutura. Caso queira voltar a
um estado de edição anterior, basta retirar a última ação
realizada, que está localizada no topo.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 15/54
praticar
Vamos Praticar
Leia o trecho a seguir.
“Uma pilha é um conjunto ordenado de itens, no qual novos itens podem ser
inseridos e a partir do qual podem ser eliminados itens de uma extremidade,
chamada topo da pilha.”
Fonte: LAUREANO, Marcos. Estrutura de dados com algoritmos e C. São Paulo:
Brasport, 2008.
Sobre os operadores e características da pilha, assinale a alternativa correta.
a) Uma pilha é considerada um contêiner de elementos que respeita o
princípio FIFO – First In, First Out.
b) Na estrutura de dados em pilha, as operações podem ser realizadas em
qualquer extremidade do conjunto.
c) Quando implementamos o método empilhar, precisamos informar qual
índice queremos inserir no elemento.
d) Entre os métodos possíveis de implementação de uma pilha, existem dois
fundamentais: empilhar e desempilhar.
e) Entre os métodos possíveis na implementação de uma pilha, existem dois
fundamentais: empilhar e contar elementos.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 16/54
Veremos alguns aspectos de implementação da estrutura de dados em pilha
em jogos digitais. Para tanto, serão apresentados contextos de aplicação e
trechos de códigos em Javascript. Esse conhecimentopoderá ser usado
depois como apoio para confecção de novos jogos digitais e também como
apoio para atividades do curso.
Criando um Menu
O objetivo desta seção é criar um menu para nosso jogo utilizando a estrutura
de dados em pilha. O menu que criaremos terá três níveis de profundidade,
porém, você pode customizá-lo e criar quantos níveis quiser aproveitando a
mesma estrutura.
Antes de explorarmos a parte de implementação, procuraremos entender de
forma teórica esse mecanismo. Ao entrar no jogo, o usuário verá as opções
ilustradas na Figura 2.7.
Pilha – Aplicação noPilha – Aplicação no
Desenvolvimento deDesenvolvimento de
JogosJogos
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 17/54
Repare que existe, na frente da descrição de cada item, uma sugestão de
comando para que o usuário possa interagir com o teclado. Se o usuário
apertar a tecla 2 do teclado, deverá acessar o menu Con�gurações, que
carregará no lugar do primeiro, conforme ilustrado na Figura 2.8.
Figura 2.8 – Menu Con�gurações
Fonte: Elaborada pelo autor.
Nesse menu de con�gurações, temos a opção de acessar outros menus, os
quais comumente chamamos de submenus . Se quisermos acessar o menu
Controles, basta apertar a tecla 6 do teclado e, da mesma forma que o menu
Figura 2.7 – Menu principal
Fonte: Elaborada pelo autor.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 18/54
anterior, acessaremos as con�gurações relacionadas, conforme ilustrado na
Figura 2.9.
Por �m, se precisarmos voltar ao menu anterior, pressionaremos a tecla 0.
Por que isso é uma pilha?
A forma de acesso aos menus e, principalmente, a volta a menus anteriores
tornam esse mecanismo passível de ser implementado com uma pilha. À
medida que o usuário acessa um submenu, esse pode ser empilhado na
estrutura. Assim o menu atual, ou seja, aquele que o usuário está
visualizando, sempre estará no topo da pilha. E, quando o usuário utiliza o
comando voltar, basta desempilhar o menu na estrutura, e, automaticamente,
o menu que deverá ser apresentado é aquele que está agora no topo da
pilha. Na Figura 2.10, podemos ver um exemplo desse mecanismo, utilizando
o contexto do menu.
Figura 2.9 – Menu Con�gurações de Controles
Fonte: Elaborada pelo autor.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 19/54
Outro ponto importante no contexto especí�co desse problema é que a pilha
nunca estará vazia, já que o usuário sempre estará visualizando um dos
menus. Implementaremos essa regra na programação.
Modelagem do TAD da Pilha
Implementaremos a pilha da mesma forma que vimos na seção 2.1, com
todas as características e considerações. Entretanto, teremos duas alterações
que serão tratadas a seguir.
No método empilhar, precisamos implementar a regra de ter sempre um
elemento na pilha, isso devido ao contexto do nosso problema. Para resolver
isso, basta veri�carmos se o atributo totalElementos (responsável por contar
os elementos da pilha) é maior ou igual a 1. Em caso positivo, podemos
realizar as operações necessárias, para retirar o elemento da pilha. Caso
contrário, nenhum processo será executado.
Outra modi�cação na estrutura é a criação do método veri�carTopo . Em
alguns momentos, precisaremos veri�car qual elemento está no topo sem
retirá-lo da pilha – e podemos realizar isso criando um método que retorna o
valor contido no elemento.
Figura 2.10 – Menu Con�gurações de Controles
Fonte: Elaborada pelo autor.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 20/54
verificarTopo = function() {
return this.topo.texto;
}
Com isso, concluímos a implementação do TAD da pilha, e o código completo
deve �car semelhante a:
Modelagem da classe Menu
Segue o código da classe Menu :
Na classe Menu , tivemos uma única alteração, em comparação ao código
anterior. Teremos um atributo chamado texto , cujo objetivo é armazenar o
texto das opções mostradas ao usuário. E os demais aspectos foram
mantidos.
Textos dos Menus
Os menus foram criados com a descrição informada no Quadro 2.2:
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 21/54
Quadro 2.2 – Descrição dos menus
Fonte: Elaborado pelo autor.
Operação Descrição do menu
0
Menu:
[1]  Iniciar Jogo
[2]  Con�gurações
[3]  Créditos
1
Menu Iniciar Jogo
[4]  Jogar
[0]  Voltar
2
Menu Con�gurações
[5]  Som
[6]  Controles
[0]  Voltar
3
Menu Créditos
Desenvolvido pelo Programador
[0]  Voltar
4
Iniciando jogo
[0]  Voltar
5
Menu Som
Con�gurações de Som
[0]  Voltar
6
Menu Controle
Con�gurações de Controle
[0]  Voltar
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 22/54
Podemos utilizar o construtor da classe Menu para inserir os textos de cada
menu do sistema. Assim, criaremos um método chamado RetornarMenu ,
que retornará a instância da classe Menu com a descrição do menu. Nesse
método, passaremos um parâmetro chamado indice , que nada mais é que o
código da operação informada na primeira coluna do Quadro 2.2.
Você poderá reparar que nas descrições dos menus foi utilizada a sequência
\n para indicar quebra de linha. Veri�caremos como imprimir o menu no
“canvas”.
Mecanismos dos Menus
Como já explicamos o essencial do mecanismo da estrutura de dados,
focaremos nos aspectos relacionados ao game engine. Em primeiro lugar,
criaremos uma variável que representará nossa pilha de menus.
var pilha = null;
Criaremos um evento chamado IniciarJogo , que será executado no início do
programa. Nesse método, vamos “setar” nossa variável pilha com uma
instância da classe Pilha . Em seguida, precisamos empilhar nosso primeiro
menu, ou seja, o menu principal. Para isso, chamaremos o método
RetornarMenu , passando o índice correspondente por parâmetro. E, por
�m, chamaremos o método ImprimirMenu , que será explicado
posteriormente.
Para imprimir o menu, criamos um método chamado ImprimirMenu .
Sabemos que o menu que deve ser impresso ao usuário sempre estará no
topo da pilha. Assim, não precisamos passar a informação como parâmetro
de entrada do método.
Já dentro do método, na primeira e segunda linhas, recuperaremos o objeto
“canvas” e o contexto (2D ou 3D). Em seguida, limparemos o “canvas”,
apagando todos os desenhos realizados anteriormente, com o método
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 23/54
clearRect . Esse passo é importante, uma vez que esse método ocorrerá
diversas vezes durante a execução.
Depois, devemos resolver um problema ocasionado por limitação do “canvas”:
o objeto “canvas” não reproduz as quebras de linhas de um texto. Para
solucionarmos essa necessidade, dividiremos a string utilizando o método
split , que aceita como parâmetro um comparador de separação. Esse
método devolverá um vetor, e cada posição será uma linha do menu.
Com esses valores, executaremos um laço de repetição, que repetirá igual
quantidade de itens no vetor. Para imprimir o texto, utilizamos o método
�llText , informando o texto do menu e as coordenadas X e Y. A variável Y é
calculada de acordo com esta fórmula:
Onde y é a coordenada correspondente, e i é o índice da linha do menu.
Eventos do Teclado
Os menus serão empilhados de acordo com os eventos inseridos pelo jogador
via teclado. Como vimos, o comando pertence ao intervalo 0 a 6 – onde 0 é o
comando para desempilhar o menu atual, e os comandos de 1 a 7 servem
para empilhar o menu correspondente.Analisaremos o código:
Dentro do método, podemos recuperar a informação da tecla pressionada
com a propriedade event.key . A diferença entre essa propriedade e a
event.keyCode é a primeira retornar o nome da tecla pressionada, já a
segunda retorna o código ASCII. Depois disso, basta veri�carmos se devemos
empilhar ou desempilhar o código, dependendo da tecla pressionada. Ao
�nal, imprimimos novamente o menu.
Código Completo
y = 50 ∗ (i + 1)
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 24/54
A seguir, temos o código completo da implementação. Para rodar, basta
copiar o código e colar, salvando o arquivo com a extensão .html . Em
seguida, deve-se abrir o arquivo em navegador com suporte à linguagem
HTML5.
Uma pilha pode ser utilizada em jogos digitais em outros contextos. Um
exemplo são jogos de cartas, onde temos pilhas de cartas que, como o
próprio nome sugere, podem ser implementadas com a estrutura de dados
em pilha.
Outro exemplo são os jogos de tiros em que o jogador possui um armamento
básico e, à medida que avança, pode receber armas temporárias,
empilhando-as na pilha de armas. Essas armas possuem uma limitação de
tempo ou quantidade de munição e, quando expiram, podem ser
desempilhadas da pilha de armas do jogador.
praticar
Vamos Praticar
Leia o trecho a seguir.
STL é uma biblioteca da linguagem C que fornece ao programador recursos de pilha.
Um stack de STL fornece as operações push (empilhar), pop (desempilhar), empty
(vazia) e size (quantidade de elementos). Apesar de representar uma estrutura de
dados em pilha, ela é implementada internamente utilizando-se uma estrutura
linear.
Fonte: RICARTE, I. L. M. Estrutura de dados. Campinas: Unicamp, 2008. Disponível
em: http://calhau.dca.fee.unicamp.br/wiki/images/0/01/EstruturasDados.pdf .
Acesso em: 13 dez. 2019.
http://calhau.dca.fee.unicamp.br/wiki/images/0/01/EstruturasDados.pdf
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 25/54
Assinale a alternativa correta.
a) Quando inserimos um elemento na pilha, é necessário veri�car a
quantidade de elementos.
b) Quando retiramos um elemento da pilha, precisamos veri�car a
quantidade de elementos.
c) Quando veri�camos o elemento topo da pilha , é ideal veri�car a
quantidade de elementos.
d) Quando veri�camos se a pilha está vazia, podemos veri�car a quantidade
de elementos já inseridos.
e) Quando veri�camos o elemento topo da pilha , uma boa prática é retirar
o elemento da pilha e inseri-lo novamente.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 26/54
Quantas vezes você chegou num banco ou outro estabelecimento e
encontrou pessoas para serem atendidas? Muito provavelmente, se a boa
educação for mantida, as pessoas que serão atendidas primeiro chegaram
antes ao local do que as outras. A esse mecanismo damos o nome de �la
(FERRARI et al. , 2014).
Uma �la é uma coleção de itens ordenados, onde a ordem de inserção de
elementos determina as posições dos mesmos no grupo (FERRARI et al .,
2014).
Imagine que temos quatro elementos na �la: PessoaA , PessoaB , PessoaC e
PessoaD , como ilustra o Quadro 2.3; o início da �la é representado por
PessoaA , e o �nal da �la é representado por PessoaD . Se quisermos retirar
um elemento da �la, sabemos que a única pessoa que poderá ser retirada
será a PessoaA , uma vez que só é possível retirar o elemento que estiver no
início.
Por sua vez, se quisermos adicionar um elemento à �la, esse elemento deverá
ir ao �nal da �la, após a PessoaD .
FilasFilas
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 27/54
Começaremos a explorar melhor essa estrutura e também as formas de
implementá-la em nossos jogos, adiante.
Estrutura de Dados em Pilha
Uma �la é “um conjunto ordenado de itens a partir do qual podem-se eliminar
itens em uma extremidade, chamada de início da �la, e no qual podem-se
inserir itens na outra extremidade, chamada �nal da �la”. Esse princípio
também é chamado de FIFO – First In, First Out (TENENBAUM; LANGSAM;
AUGENSTEIN, 1995, p. 207).
Como pode ser identi�cado no exemplo anterior, uma �la possui 2 métodos
fundamentais: inserir ( enqueue ) e retirar ( dequeue ); e outros dois métodos
relacionados (está vazia, isEmpty ; e contar elementos, size ) (FERRARI et al .,
2014; GOODRICH; TAMASSIA, 2013; TENENBAUM; LANGSAM; AUGENSTEIN,
1995).
Perceba que os métodos da �la são bem parecidos com o da pilha, porém o
mecanismo é diferente, pois se deve seguir a regra estabelecida pelo FIFO. O
Quadro 2.4 apresenta descrição resumida de algumas dessas operações:
Quadro 2.3 – Ilustração de uma �la e suas operações
Fonte: Adaptado de Freepik.com.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 28/54
Métodos Descrição
Inserir(P, item,
sucesso)
O método Empilhar() é responsável por inserir
o elemento no topo da lista. O parâmetro P é
a pilha que será utilizada; item é o elemento a
ser inserido; e a variável sucesso terá a
informação sobre o processo ter dado certo
ou não.
Retirar(P, sucesso) Esse método retira o elemento da pilha. O
elemento a ser retirado sempre será aquele
localizado no topo. O parâmetro P é a pilha
que será utilizada; e a variável sucesso terá a
informação sobre o processo ter dado certo
ou não.
ContarElementos(P) Esse método adicional conta a quantidade de
elementos inseridos na pilha. É necessário
informar a pilha que será utilizada no
parâmetro P.
EstaVazia(P) Método adicional que veri�ca se existe algum
elemento na pilha. O parâmetro P é a pilha a
ser utilizada.
Quadro 2.4 – Métodos básicos de pilhas e alguns adicionais
Fonte: Elaborado pelo autor.
Nas próximas seções, exploraremos detalhes dessas operações e
descobriremos como aplicá-las numa linguagem de programação. Vamos
conferir!
Operações em �ilas
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 29/54
Da mesma forma que as pilhas, a implementação das �las é escolhida, muitas
vezes, em conjunto com as características e recursos que a linguagem de
programação utilizada oferece. Lembra-se que, de acordo com a linguagem,
podemos utilizar vetores, ponteiros ou classes e interfaces (programação
orientada a objetos).
Nas próximas seções, continuaremos a explorar a implementação de lista
encadeada baseada em modelagem de classes, uma vez que a linguagem
escolhida é o Javascript.
Tipo Abstrato de Dados em Fila
Para os itens, utilizaremos a mesma implementação vista na seção 1.2.1:
class Item {
valor = 0;
proximo = null;
constructor(valor) {
this.valor = valor;
}
}
Entretanto, a modelagem da estrutura de dados mudará, por trabalharmos
com �la. Teremos dois atributos que representação, respectivamente, o início
e o �nal da �la:
class Fila {
inicio = null;
fim = null
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 30/54
totalElementos = 0;
// Métodos e funções
}
Além dos atributos inicio e �m , representamos o totalElementos , que
indicará a quantidade de elementos armazenados na �la.
Inserir Elemento
O método inserir receberá como parâmetro um elemento, que sempre
entrará no �nal da �la. Na Figura 2.11, é possível perceber as ligações que
deverão ser atualizadas nessa operação.
Entretanto, temos também outra situação: quando a �la está vazia. Como
podemos observar na Figura 2.12, nessa situação, quando inserimos um novo
elemento, precisamos atualizar tanto a referênciado atributo inicio como a
referência do atributo �m.
Figura 2.11 – Inserir elemento na �la
Fonte: Elaborada pelo autor.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 31/54
A partir de agora, exploraremos o código em Javascript.
Nesse método, recebemos como parâmetro o elemento que será inserido. E
precisamos primeiramente veri�car a situação da nossa �la: se está vazia ou
se já possui elementos. Para isso, veri�camos se a quantidade de elementos é
igual a 0 (zero). Quando a �la está vazia, precisamos atualizar os atributos
inicio e �m , para receber a referência do nosso novo elemento.
Caso a �la já possua itens, conforme explicamos anteriormente, precisamos
atualizar o atributo proximo do último elemento da �la, para receber nosso
novo elemento. E, depois, atualizaremos a referência do atributo �m, também
para o nosso novo elemento. Ao �nal, basta adicionar mais 1 (um) no atributo
totalElementos .
Retirar Elemento
O método retirar elemento possui uma lógica bem semelhante à da inserção.
Se a �la tiver elementos, é mais simples, basta alterar a referência do inicio
para o 2º elemento da �la, como ilustrado na Quadro 2.5.
Figura 2.12 – Inserir elemento em �la vazia
Fonte: Elaborada pelo autor.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 32/54
Além disso, outra situação é termos apenas um elemento na �la. Quando
retiramos o único elemento, precisamos limpar os valores contidos nos
atributos inicio e �m , uma vez que a �la se tornará vazia. Na Figura 2.13 é
possível observar essa situação.
Figura 2.13 – Retirar elemento único da �la
Fonte: Elaborada pelo autor.
A seguir, exploraremos o código em Javascript.
No código anterior, não precisamos passar nenhum parâmetro para remover
Quadro 2.5 – Retirar elemento da �la
Fonte: Elaborado pelo autor.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 33/54
o elemento, uma vez que o elemento já está na �la. O método começa com
comparações para veri�car se a �la está vazia; se estiver, não é possível retirar
nenhum elemento, então, um erro será lançado.
Na segunda comparação, temos apenas um elemento na �la. Para solucionar
essa questão, como explicado anteriormente, precisamos “setar” os atributos
inicio e �m para nulo, ou seja, limpar a referência anterior.
Na última situação, temos uma �la com 2 (dois) ou mais elementos. Nesse
caso, é mais simples: basta atualizar a referência do atributo inicio para o
segundo item da �la. E, para isso, podemos atribuir à variável inicio o valor do
atributo proximo do elemento inicial. Por �m, decrementaremos o valor do
atributo totalElementos , que serve como contador de itens para a �la.
Contar Elementos e Fila Vazia
Os algoritmos para contar elementos e �la vazia são muito semelhantes aos
da estrutura de dados em pilha, uma vez que usamos atributo próprio para
controlar os elementos. Segue o código:
function contarElementos () {
return this.totalElementos;
}
Da mesma forma, para saber se a �la está vazia, basta consultarmos esse
atributo. Se o atributo totalElementos for igual a 0, a �la estará vazia:
function filaVazia () {
return (this.totalElementos == 0);
}
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 34/54
Concluímos o estudo da estrutura de dados em �la e suas funcionalidades
básicas. Na próxima seção, exploraremos sua utilização no contexto de jogos
digitais.
praticar
Vamos Praticar
Leia o trecho a seguir.
“Uma lista ligada é uma estrutura que corresponde a uma sequência lógica de
entradas ou nós. Tipicamente, em uma lista ligada há um ou dois pontos conhecidos
de acesso – normalmente o topo da lista (seu primeiro elemento) e eventualmente o
�m da lista (seu último elemento). Cada nó armazena também a localização do
próximo elemento na sequência, ou seja, de seu nó sucessor.”
Fonte: RICARTE, Ivan Luiz Marques. Estrutura de dados . Campinas: Unicamp, 2008.
Disponível em:
http://calhau.dca.fee.unicamp.br/wiki/images/0/01/EstruturasDados.pdf . Acesso
em: 13 dez. 2019.
Sobre tipo abstrato de dados em �la, assinale a alternativa correta.
a) O mecanismo de funcionamento da �la é semelhante aos da pilha e da
lista. A única diferença, porém, é a implementação, que utiliza dois ponteiros.
b) A melhor forma de implementar uma �la é a utilização de uma lista
encadeada em conjunto de estrutura linear de alocação estática (vetores).
c) Uma �la é uma coleção de itens ordenados, onde a ordem de inserção dos
elementos determina a posição dos mesmos no grupo.
http://calhau.dca.fee.unicamp.br/wiki/images/0/01/EstruturasDados.pdf
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 35/54
d) Para inserir um elemento na �la, basta atualizar a referência do início da
estrutura para o novo elemento.
e) Para remover um elemento na �la, basta atualizar a referência do �m da
estrutura para o novo elemento.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 36/54
Veremos, nesta seção, alguns aspectos de implementação da estrutura de
dados em �la em jogos digitais. Serão apresentados contextos de aplicação e
trechos de códigos em Javascript.
Lançamento de Mísseis
O objetivo dessa seção é explicar as características de implementação de um
lançador de mísseis de um avião. Teremos três tipos de mísseis: nas cores
verde, vermelha e preta, conforme ilustrado na Figura 2.14.
TópicoTópico
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 37/54
Consideraremos que o lançamento dos mísseis deve respeitar uma ordem:
primeiro, serão lançados 2 mísseis verdes; em seguida, 5 mísseis vermelhos;
e, por último, 4 mísseis pretos. Podemos representar os mísseis numa
estrutura de dados em �la, como segue:
Veremos que, para um míssil alcançar o objetivo, dado por uma coordenada
no plano 2D do “canvas”, ele será retirado da �la. E as coordenadas de destino
de cada míssil serão dadas pelo usuário, utilizando-se um clique no mouse .
Figura 2.14 – Lançador de mísseis. Em (a), míssil verde; em (b), míssil
vermelho; e, em (c), míssil preto
Fonte: Elaborada pelo autor.
Figura 2.15 – Fila de mísseis de um avião
Fonte: Elaborada pelo autor.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 38/54
Modelagem do TAD da Fila
Implementaremos a �la da mesma forma que vimos na seção 3.2, com todas
as características e considerações. Entretanto, teremos a criação de uma nova
função chamada pegarInicio , que será destinada a obter o item do início da
�la sem precisarmos retirá-lo da estrutura.
pegarInicio = function() {
return this.inicio;
}
Como podemos notar, o método pegarInicio é bastante simples: ele apenas
retornará o elemento que está no topo da �la; basta retornar a referência do
atributo inicio. É importante lembrar que o contexto do problema permite
que esse atributo esteja vazio ou nulo, caso o jogador tenha disparado todos
os mísseis.
O restante do código �cará igual, dessa forma. Havendo qualquer dúvida com
relação a ele, por favor, veri�que a seção relacionada.
A seguir, analisaremos a classe Missil , que será utilizada para representar os
itens da nossa �la. Por ser um elemento mais complexo, será importante
analisar os atributos e métodos implementados.
Modelagem da Classe Míssil
A classe Missil é um pouco mais complexa: possui singularidadesrelacionadas ao contexto do problema.
Atributos x e y : um míssil é disparado de uma posição inicial; e
precisaremos representar as coordenadas dessa posição. A posição é
conhecida a priori, no início do programa.
Atributos destino_x e destino_y : um míssil terá um alvo, que
também será representado pelas coordenadas correspondentes.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 39/54
Essa coordenada apenas será conhecida quando o usuário efetuar
um comando com o mouse .
Atributo cor: armazenará a cor do míssil, sendo: green (verde), red
(vermelho) ou black (preto).
Atributo possuiAlvo : variável que indica se o míssil já possui ou não
um alvo/objetivo. Enquanto ele não possuir um alvo, o míssil não foi
lançado, ou seja, não será desenhado para o jogador;
Atributo acertouAlvo : variável que indica se o míssil acertou o
alvo/objetivo. Enquanto o míssil não tiver acertado, ele deve ser
desenhado no meio da trajetória. Quando tiver acertado, podemos
retirá-lo da �la.
Método Construtor: receberá apenas a cor do míssil, uma vez que
todos os mísseis saem do mesmo lugar, sendo o compartimento do
avião.
Método setarObjetivo : receberá as coordenadas informadas pelo
usuário, quando o mesmo clicar na área do “canvas”.
Método atualizarPosicao : método responsável por atualizar a
posição do míssil durante a trajetória, sendo o caminho entre a
coordenada inicial até o destino. Receberá o contexto do “canvas”,
para que seja possível desenhar o míssil na tela.
Como o objetivo é explicar a implementação de um mecanismo do jogo, não
buscaremos a implementação massiva de todos os elementos. Todos os
atributos serão inicializados com valores padrão ( default ), com exceção dos
atributos de coordenadas de origem x e y , que será sempre o mesmo para
todos os mísseis.
No método “setar” objetivo, receberemos as coordenadas do destino, geradas
pela ação do mouse; depois, estabeleceremos esses valores aos atributos
destino_x e destino_y . Em seguida, atualizaremos a coordenada possuiAlvo
para true , indicando que temos um objetivo/alvo.
Já o método atualizarPosicao tem o objetivo de atualizar a posição do míssil
para seguir uma rota. A implementação escolhida foi a mais simples
encontrada, e é possível encontrá-la mediante simples pesquisa sobre outros
tipos de implementações, desde trajetórias parabólicas até em linha reta.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 40/54
O método atualizarPosicao parece complexo, mas, na verdade, sua lógica é
simples (apenas um pouco grande). Atualizaremos as coordenadas do míssil a
cada 1 pixel ; e essa quantidade pode ser alterada para tornar a velocidade de
disparo mais rápida, porém, nosso objetivo não é entrar nessas
singularidades. A questão é o míssil precisar ir na direção do objetivo e, para
isso, nós aumentamos ou diminuímos a coordenada do mesmo de acordo
com a coordenada de nosso objetivo.
Por isso, realizamos a comparação: se a coordenada X do objetivo for maior
que a coordenada atual do míssil, precisamos aumentar o valor da
coordenada do míssil. Caso contrário, precisamos diminuir. A mesma regra
será aplicada para a coordenada Y. E o resultado disso é uma pequena
animação, na qual o míssil se deslocará até o objetivo.
No �nal, veri�camos se o míssil chegou ao objetivo, ou seja, se as
coordenadas do míssil e do objetivo possuem os mesmos valores. Se essa
condição for satisfeita, podemos “setar” o valor do atributo acertouAlvo para
true . Segue o código completo da classe:
Como já de�nimos a estrutura de dados em �la e também a classe Missil,
abordaremos os aspectos do game.
Aspectos do Game
Antes de explicarmos os aspectos próprios do jogo, declararemos as variáveis
que serão utilizadas dentro dos métodos:
Variável canvas : referência do objeto html canvas.
Variável ctx : referência do objeto de contexto, por sua vez, atributo
do objeto canvas .
Variável �la : representa a instância da nossa estrutura de dados em
�la.
Variável imgAviao : representa a imagem do avião. Serve apenas
para apresentação ao usuário.
Variável lastUpdate : variável que armazena data e horário da última
vez em que o “canvas” foi atualizado. A sua utilização ainda será
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 41/54
melhor explorada, no decorrer desta seção.
A declaração das variáveis �cará assim:
Com a declaração das variáveis, podemos explicar o método iniciarJogo , que
será executado apenas no início do jogo. Nesse método, instanciaremos a
variável �la e também a inicializaremos com os itens, que serão 2 mísseis
verdes, 5 mísseis vermelhos e 4 mísseis pretos.
Exploraremos o método inserirMisseisAviao mais detalhadamente, porém,
saiba, neste momento, que ele é responsável por inserir os mísseis em nossa
�la. Em seguida, teremos a inicialização do “canvas” e do contexto.
Repare que estamos chamando o método addEventListener pertencente ao
“canvas”, o qual é responsável por executar uma ação toda vez que um
determinado evento acontecer – nesse caso, o evento mousedown , que
consegue registrar quando um botão do mouse é pressionado e recuperar as
coordenadas.
Também no evento, recuperaremos a referência do contexto 2D do “canvas”,
o que é necessário para desenharmos �guras e imagens na tela, para o
usuário. Nesse momento, criaremos no código a referência da imagem do
avião ( vide a Figura 2.16).
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 42/54
Por �m, temos a inicialização do atributo lastUpdate , que receberá a data e
hora atual do sistema pelo método getTime . E, a seguir, exploraremos o
método inserirMisseisAviao , responsável por adicionar os mísseis à �la.
function inserirMisseisAviao(cor, quantidade) {
for (var i = 1; i <= quantidade; i++)
fila.inserir(new Missil(cor));
}
Esse método merece atenção. Na primeira linha, limparemos toda a área de
desenho do “canvas” com o método clearRect .
Figura 2.16 – Imagem de avião utilizada na implementação
Fonte: Adaptado de Gagu / Freepik.com.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 43/54
saiba mais
Saiba mais
O método clearRect fornece uma forma de
limpar a área do “canvas”, onde são passados
os parâmetros da área do “canvas” que se
deseja aplicar, sendo: as posições x e y de um
retângulo, largura e altura. Caso tenha
dúvidas sobre o método, acesse o link a
seguir.
Fonte: Adaptado de Mozilla ([S.d.]).
ACESSAR
Em seguida, desenharemos a imagem do avião, que sempre estará na mesma
coordenada. Para isso, chamamos o método drawImage , informando a
imagem a ser desenhada, as coordenadas e as respectivas dimensões.
A partir de agora analisaremos a lógica principal do método, responsável por
imprimir o míssil durante a coordenada. Devemos lembrar que apenas os
mísseis que possuem um objetivo/alvo serão desenhados: caso o míssil não
tenha um alvo, não devemos fazer nada; e saímos desse método executando
o comando return .
Se o míssil possui um alvo, o atributo possuiAlvo do objeto será true . Dessa
forma, poderemos atualizar a coordenada do míssil. Devemos lembrar que
esse método apenas atualiza 1 pixel por vez, até o míssil chegar ao seu
destino. Isso quer dizer que o método desenhar será executado em todo o
tempo da execução do programa, mesmo que não exista qualquer interação
do usuário.
No momento em que o alvo chegar ao seu destino, o valor do atributo
acertouAlvo será atualizado para true . Quando isso ocorrer, o míssil será
removido da �la.
https://developer.mozilla.org/pt-BR/docs/Web/API/CanvasRenderingContext2D/clearRect
03/04/2023,21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 44/54
Game Loop
Jogos de computadores tradicionalmente são programados como um simples
loop , ou laço in�nito, até o momento em que o jogador queira �nalizar sua
execução. Dentro do loop realizamos várias operações: lemos as interações
do usuário, atualizamos a tela, calculamos coordenadas de objetos e outras
operações (VALENTE; CONCI; FEIJÓ, 2005).
A arquitetura de um game loop pode ser representada tal como a Figura 2.17.
Dividimos a execução em três etapas: a inicialização , responsável por
carregar recursos e inserir informações básicas necessárias à execução do
programa; o game loop propriamente dito, que executará as rotinas
computacionais e respostas de eventos do usuário; e a �nalização do
programa, responsável por executar ações para desalocar a memória
utilizada, fechar possíveis conexões e outras rotinas de encerramento.
No HTML 5, podemos criar um game loop com um método da própria
tecnologia chamado requestAnimationFrame e, junto com ele, utilizar
recursividade.
Figura 2.17 – Game loop
Fonte: Elaborada pelo autor.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 45/54
Criaremos um código que utiliza o recurso requestAnimationFrame do
Javascript, indicando ao navegador que precisamos redesenhar os elementos
da página após a execução. Segue o código:
No código, criamos um método que chamaremos de loop . O Javascript
permite criar uma variável que armazena a referência de um método e
trabalha da mesma forma que uma variável comum ou ponteiro. Na última
linha, quando passamos essa variável como parâmetro para o método
requestAnimationFrame , estamos dizendo que queremos executar o
método loop no modo animação, que é um recurso especial do HTML5 que
não bloqueia comandos do usuário e outros processos do navegador.
Repare que na última linha dentro da função loop , antes do encerramento
das chaves, chamamos novamente a função. Assim, criamos um vínculo
recursivo, sendo essa uma das formas de criar um loop in�nito na
programação de computadores.
Dentro da função, a primeira coisa que faremos é calcular o tempo de
atualização. Para isso, obteremos data e hora atuais, por meio do método
Date.getTime , e subtrairemos o valor da última atualização. Se essa
saiba mais
Saiba mais
O método requestAnimationFrame permite
chamar um mecanismo do navegador
apropriado para a execução de animações. A
rotina prepara uma atualização nos quadros
de animação antes do próximo repaint
(método do navegador para desenhar os
componentes grá�cos). Acesso em: 24 jan.
2020.
ACESSAR
https://developer.mozilla.org/pt-BR/docs/Web/API/Window/requestAnimationFrame
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 46/54
diferença for maior que uma constante, no caso, 5 milissegundos,
atualizaremos o “canvas” executando o método desenhar . Caso contrário, o
“canvas” não será atualizado. Isso permite assegurar que a animação da
trajetória do míssil seja realizada no tempo que queremos. Por �m, basta
atualizar a variável lastUpdate , que armazenará a data da última atualização
do “canvas” (nesse caso, a hora atual).
Eventos do Mouse
O evento de leitura do mouse é muito semelhante aos do teclado e de outros
eventos do HTML 5 e Javascript. Devemos lembrar que já criamos o vínculo do
evento do mouse dentro do método iniciarJogo ; agora, basta criar o evento
chamado de clickMouse (bem sugestivo, não?).
No método, recebemos um parâmetro chamado event , que contém as
informações do clique do mouse . Com os atributos pageX e pageY
recuperamos, respectivamente, as coordenadas X e Y do clique.
Após, podemos atualizar, no item do início da �la, a coordenada do alvo. Para
isso, recuperaremos o elemento inicial e executaremos o método
setarObjetivo , por meio do qual as informações das coordenadas serão
passadas por parâmetro.
Código Completo
Por �m, segue o código completo da solução – tanto as partes HTML como o
código em Javascript estão descritos:
Para você visualizar o resultado do código descrito, copie-o e cole-o num
arquivo de extensão .HTML; em seguida, abra-o em navegador com suporte à
linguagem HTML 5. Lembre-se de ser necessária uma imagem de avião para
que o código seja executado perfeitamente.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 47/54
praticar
Vamos Praticar
Leia o trecho a seguir.
“O conceito de �la existe no mundo real, vide exemplos como �las de banco,
pedágios, restaurantes.” Apesar de muitas vezes serem representadas com o vetor,
a �la é uma estrutura dinâmica e pode crescer inde�nidamente.
Fonte: LAUREANO, Marcos. Estrutura de dados com algoritmos e C. São Paulo:
Brasport, 2008, p. 51.
Assinale a alternativa cujo mecanismo não pode ser representado por uma �la.
a) Passar produtos no caixa do supermercado.
b) Canais de um aparelho de TV.
c) Andar de bicicleta.
d) Lista de itens para comprar no mercado.
e) Passo a passo de uma receita culinária.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 48/54
indicações
Material
Complementar
LIVRO
Orientação a objetos: aprenda seus
conceitos e suas aplicabilidades de forma
efetiva.
Thiago Leite e Carvalho.
Editora: Casa do Código (edição de 2016).
ASIN: B01LXHG8HX
Comentário: Esse livro aborda conceitos de orientação
a objetos e explora formas e�cientes de sua utilização,
tornando o processo de desenvolvimento mais
produtivo e de manutenção mais fácil.
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 49/54
FILME
Video Games: the Movie.
Ano: 2014.
Comentário: Documentário que explora a evolução de
diversas plataformas de jogos digitais e fornece
informações interessantes sobre a criação dessa
indústria, novos equipamentos e visão de mercado.
Para conhecer mais sobre o �lme, acesse o link a
seguir.
TRA ILER
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 50/54
conclusão
Conclusão
Nesta unidade, tivemos a oportunidade de conhecer conceitos sobre os tipos
abstratos de dados em pilha e em �la. Nesse contexto, aprendemos um
pouco mais sobre abstração e formas de implementá-la em linguagem de
programação.
Vimos também a aplicação em alguns mecanismos de jogos. No caso do uso
de pilhas, podemos representar menus de jogos, jogos de cartas e até mesmo
a evolução de peças e armamentos, entre diversos outros. No caso de �las,
podemos representar jogos como Snake , trajetos de personagens e um
menu de fases, entre diversos outros mecanismos.
Por �m, você pôde compreender uma forma de aplicar os conceitos vistos na
unidade de forma prática, com a criação de um menu “customizado” e o
mecanismo de lançamento de projéteis de um avião.
referências
Referências
Bibliográ�cas
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 51/54
FERRARI, R. et al . Estrutura de dados com jogos. Rio de Janeiro: Elsevier,
2014.
GOODRICH, M. T.; TAMASSIA, R. Estruturas de dados e algoritmos em Java .
5. ed. Porto Alegre: Bookman, 2013.
LAUREANO, M. Estrutura de dados com algoritmos e C. São Paulo: Brasport,
2008.
MOZILLA. CanvasRenderingContext2D.clearRect(). [ S.d .]. Disponível em:
https://developer.mozilla.org/pt-
BR/docs/Web/API/CanvasRenderingContext2D/clearRect . Acesso em: 24 jan.
2020.
TENENBAUM, A. M.; LANGSAM, Y.; AUGENSTEIN,M. J. Estruturas de dados
usando C. São Paulo: Pearson Universidades, 1995.
VALENTE, L.; CONCI, A.; FEIJÓ, B. Real time game loop models for single-player
computer games. In: SBGAMES / WJOGOS 2005, 2005, São Paulo, Anais... São
Paulo: USP, 2005. p. 89‐99. (IV Workshop Brasileiro de Jogos e Entretenimento
Digital).
VIDEO Games: the Movie ( Trailer ). Produção de Jeremy Snead. New York:
Variance Films, 2014. 1min42s, color. Disponível em:
https://www.youtube.com/watch?v=CFtXlfpkr_Y . Acesso em: 24 jan. 2020.
VISUALGO. Linked List. [ S.d. ]. Disponível em: https://visualgo.net/pt/list .
Acesso em: 24 jan. 2020.
https://developer.mozilla.org/pt-BR/docs/Web/API/CanvasRenderingContext2D/clearRect
https://www.youtube.com/watch?v=CFtXlfpkr_Y
https://visualgo.net/pt/list
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 52/54
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 53/54
03/04/2023, 21:06 Ead.br
https://student.ulife.com.br/ContentPlayer/Index?lc=S7S6ENZny18%2blDVzjSI6gg%3d%3d&l=VPic%2fFbeAnDPgloJidbuAg%3d%3d&cd=ucz… 54/54

Mais conteúdos dessa disciplina