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