RELATÓRIO MINI PROJECTO A CAVERNA por: Hugo Manuel Marques Ferreira [email protected] Luís Miguel Borges Guilherme [email protected] Classe Nave Nesta classe é criada a nave, o seu rasto e são construídos todos os métodos de colisão dos diferentes objectos, com a nave. No construtor é definido o rasto, e este é colocado num array, array esse que vai sendo alterado consoante o posicionamento que a nave tomar. É também carregada a imagem para a nave. Nos métodos desenha desta classe são desenhados a nave, consoante as coordenadas que são passadas pelo método, e o rasto desta, que é constantemente actualizado, movendo os valores já contidos no array, para a direita, e colocando neste as novas posições, o que nos permite ver as posições anteriores ocupadas pela nave. São definidos métodos que nos permitem conhecer as coordenadas da nave em todos os instantes, de modo a serem usados noutras classes e nesta igualmente. No que diz respeito a métodos que detectam as colisões com objectos, estes estão declarados de forma a que, consoante as posições dos objectos e da nave, as colisões possam ser detectadas (ao mínimo pormenor), devolvendo os métodos: true; e apagando os objectos, no caso de ter havido colisão. No que diz respeito à colisão com as paredes, o tipo de retorno é semelhante, mas a detecção de colisão é feita da seguinte forma: são obtidas as coordenadas da parede que vão desde a posição posX da nave até à sua posição final getPosXFinal(). Deste modo a posY da nave não pode ser superior (no caso de bater em baixo) e inferior (no caso de bater em cima) ao maior ponto da parede naquele intervalo. Classe Paredes Esta classe vai criar e desenhar as paredes do jogo. No construtor da classe é construída a parede em cima e em baixo. Esta parede é construída colocando em cada posição do array (que tem a dimensão do ecrã do jogo) um valor aleatório dentro de um certo limite. O método desenha desta classe, de modo a dar a sensação de movimento ao jogo, faz deslocar o array 10 posições para a esquerda e actualiza a parede com mais posições aleatórias. A medida que o jogo avança, as paredes vão aumentando de espessura (este aumento é dado pelo parâmetro increParede). Este aumento de espessura é dado pelo aumento do intervalo da instrução Math.random(). Depois de fazer a actualização desenha o conteúdo dos arrays. Nesta classe são declarados dois métodos que devolvem o valor máximo do array na parede de cima e na de baixontre o intervalo X da nave, ou seja, entre a posição inicial e final da nave em X. O método getEsparede() devolve a espessura da parede máxima da parede Classe Obstaculos Esta classe permite criar, desenhar, apagar e obter certas coordenadas úteis para a gestão dos objectos desta classe. O construtor desta classe predefine a posX inicial de cada obstáculo(o tamanho do ecrã de jogo em x). O método criaObstaculos(...) determina as características necessárias (através da atribuição de valores a variáveis) para que o objecto possa ser utilizado correctamente. No método desenha desta classe são desenhados os objectos mediante certas condições. No caso do objecto ter sido apagado (por tiro ou colisão com a nave), este deixa de ser desenhado e passa apenas a ser decrementado a partir a da parte de trás da nave (sem colidir com esta). De modo a manter o fluxo do jogo, quando um objecto é apagado por um tiro, existirá uma posição para a qual o método retornara true, de modo a que seja criado um novo obstáculo. No entanto, caso o obstáculo não tenha sido apagado(por um tiro), este método retornara, também, true de modo a manter o fluxo do jogo. Existe, de modo a que um obstáculo seja apagado caso tenha colidido com a nave ou com um tiro, um método que apaga esse mesmo obstáculo. À semelhança de outras classes, existem métodos que nos permite obter as posições de cada obstáculo, sempre que esta sejam necessárias. Classe ObsMoveis Nesta classe existem métodos que nos permitem criar, desenhar, apagar e detectar colisões, referentes aos obstáculos móveis. Com o construtor da classe predefinimos o valor da posição de X de cada objecto(o tamanho do ecrã de jogo em x). No método criaObsMoveis(...) são determinadas as características necessárias à criação de cada objecto desta classe, dando valores as variáveis de cada instância. São construídos dois métodos (veColisaoPrdCima(...) e veColisaoPrdCima(...)) que nos permite determinar quando o objecto bate na parede, para nesse caso o objecto passar a andar num sentido contrário (em y) ao anterior, ou seja, antes de ter batido na parede. Estes métodos têm uma construção semelhante ao método que determinava a colisão da nave com as paredes. No método desenha acontece o seguinte: no caso de o objecto ainda não estar totalmente dentro do rectângulo de jogo é lhe decrementada apenas a sua posição em X . Esta situação deve-se ao facto de não ser possível detectar uma possível colisão (devido ao tipo de detecção usado) com a parede antes de o objecto estar totalmente dentro da área de jogo. Depois do objecto estar dentro da área de jogo, passa a movimentar-se quer em X, quer em Y. Ainda neste método desenha e à semelhança da classe descrita anteriormente, de modo a manter o fluxo do jogo , quando um obstáculo móvel é apagado por um tiro, existirá uma posição para a qual o método retornara true, de modo a que seja criado um novo obstáculo móvel. No entanto, caso o obstáculo móvel não tenha sido apagado por um tiro, este método retornara, também, true de modo a manter o fluxo do jogo. Nesta classe são, também, declarados métodos para aceder às posições de cada instância, quando isso é necessário. Classe Bonus Esta classe permite criar, desenhar e obter certas coordenadas, que são precisas para o controle de cada instância da classe. O construtor desta classe atribui a posição de x de um objecto um determinado valor (o tamanho do ecrã de jogo em x). O método cria desta classe, difere dos outros obstáculos apenas num aspecto: no facto de criar um número aleatório que vai determinar que tipo de bónus vai ser aquele objecto. O método desenha desta classe, consoante o parâmetro que recebe, decide qual das “strings” deve desenhar, ou seja, se deve desenhar um bónus que permite aumentar os pontos ou um bónus que da mais gasolina. Se este objecto tiver sido apagado (por tiro ou colisão com a nave), passa para a parte de trás da nave apenas a ser decrementado e não desenhado. Este método desenha devolve true quando a posX de uma instancia desta classe passar por uma determinada posição(Isto acontece, à semelhança de outras classes, para que o fluxo dos objectos possa ser efectuado com regularidade). Também nesta classe existe um método que permite apagar o bónus quando se der uma colisão com a nave ou com os tiros, e métodos que devolvem as posições das instancias. Classe Armadilhas Esta classe permite criar, desenhar e obter certas coordenadas, que são precisas para o controle de cada instância da classe. O construtor desta classe atribui a posição de x de um objecto um determinado valor (o tamanho do ecrã de jogo em x). O método cria desta classe, difere dos outros obstáculos apenas num aspecto: no facto de criar um número aleatório que vai determinar que tipo de armadilha vai ser aquele objecto. O método desenha apenas uma desenha uma string “?”. A consequência (perca ou ganho de vidas, e perca de gasolina) da armadilha é determinada na classe Caverna. Se este objecto tiver sido apagado (por tiro ou colisão com a nave), passa para a parte de trás da nave apenas a ser decrementado, sem ser desenhado. Este método desenha devolve true quando a posX de uma instancia desta classe passar por uma determinada posição(de modo a manter o fluxo dos objectos no ecrã de jogo). Também nesta classe existe um método que permite apagar a armadilha quando se der uma colisão com a nave ou com os tiros, e métodos que devolvem as posições das instancias. Classe TirosLaser Nesta classe são criados os tiros, são detectadas as colisões dos tiros com os diferentes obstáculos que existem, são desenhados os tiros e são recolhidas posições de X e de Y dos tiros. No construtor, o atributo desenha dos tiros é colocado a true. No método desenha, são incrementadas as posições de X dos tiros criados, de modo a dar a sensação de disparo. O atributo desenha é colocado a false quando existe uma colisão com um obstáculo(móvel, fixo, armadilha ou bónus) ou quando o tiro saiu do ecrã de jogo. O método usado para apagar, apenas atribui coordenadas a um determinado tiro, não tendo essa posição interferência com mais nenhum elemento do jogo. Os métodos que detectam colisões são semelhantes aos usados na classe nave. Apenas a reacção a essas colisões é que são diferentes. Quando se dá uma colisão é apagado o objecto com o qual o tiro colidiu e o tiro. Notas: → Para os objectos das classes anteriores (Obstaculos, ObsMoveis, Bonus, Armadilhas), existe uma instrução, no método cria de cada classe, que determina que posição de y o objecto deve tomar quando este é criado. Para esta instrução é considerado um intervalo de espessura máxima da parede, em baixo e em cima. Os objectos quando são criados têm em atenção esse respectivo intervalo, de modo a que um objecto nunca se sobreponha às paredes. → Para que as instruções de todas as classes que falamos anteriormente foi necessário o import da package: java.awt.* Classe Janela Na classe janela é definido o ambiente do jogo. É defino o tamanha da janela do jogo, são criados os botões e as labels que vão interagir com o jogo. No inicio do jogo vão estar activos quatro botões que nos permitem: começar o jogo; ver os resultados do ficheiro de pontos (para isso foi criado nesta classe um objecto da classe Ficheiro); fazer o reset ao ficheiro dos pontos e sair do jogo. Ao carregar no botão para começar o jogo, são desactivados três botões dos anteriores, ficando apenas o botão sair, e são activados as lables que permitem ao jogador ver os seus pontos, vidas, gasolina, tiros que a nave ainda dispõem e o nível em que se encontra. A labels anteriores são constantemente actualizadas pela classe Caverna, através do método setLabels(...). Quando o jogador perde uma vida, muda de nível ou faz pause no jogo, são activados um conjunto de botões que permitem ao jogador interagir com o jogo (setBotaoPerde() setBotaoSegue() setBotoes()). O construtor desta classe recebe um objecto Caverna por forma a que quando se carrega no botão “Novo Jogo” , este inicie. No método actionPerformed(ActionEvent e) estão declaradas todas acções que devem ser tomadas quando se carrega num determinado botão. De modo a que todo este conjunto de instruções fosse possível foi necessária fazer a extensão desta classe à classe JFrame e implementar o ActionListener. Classe JanelaNome Esta janela serve para um jogador introduzir o seu nome caso tenha batido um record. Para este efeito foram criadas labels que vão receber o nome do jogador, e um botão para fechar a janela. O método getJanelaNome() vai buscar o nome escrito na label, de modo a que este possa ser inserido no ficheiro de pontos. O tamanho desta janela e as suas propriedades são também aqui definidas. Para que as janelas seguintes a esta não ficassem activas enquanto esta não fosse fechada, fez-se a extensão desta janela à classe JDialog, e no construtor desta classe (a classe JanelaNome) foi passado com parâmetro um objecto JFrame, e dentro do construtor foi chamado o construtor da classe JDialog (super(owner, true)). Por causa do botão foi feita a implementação do evento ActionListener. Classe JanelaPontos Nesta janela é mostrado o conteúdo actualizado do ficheiro de pontos. Para esse efeito foram criadas várias labels que recebem o nome dos jogadores e a sua pontuação. Foi criado um botão para sair desta janela. Mais uma vez, para a construção desta janela foi necessário fazer a extensão à classe JFrame implementando o ActionListener para o botão. Nota: Em todas estas classes foi necessário o código que tem o seguinte comentário: //Evita modificações no aspecto gráfico. Esse código foi usado de modo a que pudéssemos alinhar as labels e os botões ao nosso critério. Para a construção destas classes foi necessário fazer o import das seguintes packages: java.awt.* e javax.swing.* e java.awt.event.* Classe Vista É o rectângulo definido por esta classe que vai ser o ecrã do jogo, ou seja, a zona onde os objectos vão ser desenhados. Esta classe descende da classe Canvas. Para esta classe foi necessário fazer o import da seguinte package: java.awt.* Classe Ficheiro Esta classe permite que as sua instâncias manipulem o ficheiro que vai conter os records do jogo. Esta classe contém métodos que permitem: fazer o reset do ficheiro; escrever dados no ficheiro; visualizar o conteúdo do ficheiro; ler o conteúdo do ficheiro e verificar a se a pontuação de um determinado jogador bateu algum record. A construção desta classe permitiu que o acesso ao ficheiro pudesse ser feito de várias partes de todo o programa, tal como a partir da classe Janela e outras, por forma a melhorar a dinâmica do jogo. Para podermos usar algumas das instruções para esta classe necessitamos de fazer o importa das seguintes packages: java.util.* e java.io.* ObsMoveis Estrutura do Programa Obstaculos javax.swing.JFrame Ficheiro Janela Nave JanelaPontos Caverna JanelaNome Paredes Vista Armadilhas java.swing.JDialog java.awt.Canvas Bonus TirosLaser