Pular para o conteúdo principal

JOGO MINI TENNIS - Tutorial Java Game Programming - PARTE 06

Parte 06:

Jogo Mini Tennis

Detecção de colisão

Neste tutorial aprenderemos como detectar quando um sprite colide com outro. No nosso jogo vamos fazer a bola quicar na raquete. Também faremos o jogo terminar se a bola chegar à borda inferior da tela, mostrando uma janela pop-up com a clássica mensagem "Game Over".

Fim de jogo

Abaixo podemos ver nosso jogo de classe, que é exatamente o mesmo que o anterior, com a única diferença que este tem um método gameOver();

O método gameOver() lança um popup usando JOptionPane.showMessageDialog com a mensagem "Game Over" e um botão "Aceitar". Após o popup, System.exit(ABORT) faz com que o programa termine. O método gameOver() é público, pois será chamado do sprite "Ball" quando detectar que chegou à borda inferior da tela.

Colisão de Sprite

Para detectar a colisão entre a bola e a raquete usaremos retângulos. No caso da bola vamos usar um quadrado ao redor da bola como você pode ver na figura 2.


A classe java.awt.Rectangle tem um método intersect (Retângulo r) que retorna verdadeiro quando dois retângulos ocupam o mesmo espaço, como no caso da figura 3 ou 4. Este método não é exatamente, porque como você pode ver na figura 4, a bola não toca na raquete, mas pelo nosso exemplo ela é mais do que suficiente.

Abaixo podemos ver a classe Racquet, com a única diferença que adicionamos um método getBounds(), que retorna um tipo de objeto retângulo, indicando a posição da raquete. Este método será usado pelo sprite "Ball", para saber a posição da raquete e desta forma para detectar a colisão.


Outra pequena mudança é a inclusão de constantes:



Como dissemos antes, o valor da posição "y", foi fixado para 330. Este valor é usado tanto no método de pintura quanto no getBounds. Quando criamos uma constante, o bom é que se queremos mudar o valor, só temos que mudá-lo em um só lugar. Dessa forma, evitamos o possível erro de mudá-lo em um lugar e não alterá-lo em outro.

A maneira de definir uma constante é declarar uma propriedade "final estática" e escrevê-la em maiústia. O compilador nos permite usar minúsculas, mas o standar diz que usamos maiústos para as constantes.

Por último, a aula de Bola:

Da mesma forma, incluímos o método getBounds() e a constante DIÂMETRO para a classe "Raquete".

Mais interessante é a inclusão do novo método chamado collision() que retorna verdadeiro, se o retângulo ocupado pela raquete "game.racquet.getBounds()" se cruza com o retângulo ocupado pela bola "getBounds()".


Se a colisão ocorrer, mudaremos a direção e a posição da bola. Se a colisão ocorrer na lateral (figura 1), a bola pode estar vários pixels abaixo do lado superior da raquete. No loop do jogo seguinte, mesmo que a bola se movesse para cima (figura 2), ela ainda poderia estar em colisão com a raquete.



Para evitar isso, colocaremos a bola em cima da raquete (figura 3) usando:
y = game.racquet.getTopY() - DIAMETER;

O método "Raquete" getTopY() nos dá a posição no eixo "y" da parte superior da raquete, e se descontarmos o DIÂMETRO, obtemos a posição exata onde colocar a bola para que ela fique em cima da bola.

Por fim, é o método move() da classe "Bola" que usa os novos métodos collision() e gameOver() da classe "Game". O salto quando chega à borda inferior é substituído por uma chamada para game.gameOver().

if (y + ya > game.getHeight() - DIAMETER)
			game.gameOver();

E incluindo um novo método condicional usando o método de colisão() temos a bola para saltar para cima se colidir com a raquete:

		if (collision())
			ya = -1;



Comentários