[Tens de ter uma conta e sessão iniciada para poderes visualizar esta imagem]

Nesse penúltimo tutorial da série “Desenvolvendo um Pong em XNA 4.0” vamos ver como fazer a colisão da bola com as raquetes (bastões) dos jogadores e também colocar os efeitos sonoros e música de fundo para deixar nosso jogo semi-pronto. Para fazermos a colisão da bola com as raquetes precisamos saber onde estão e qual a área que esses objetos ocupam na tela, para sabermos se algum objeto sobrepôs ou encostou-se a outro. Vamos começar então definindo as áreas de nossos objetos para usarmos nas colisões.

Área da Bola

Para definirmos a área da bola, vamos usar a classe Rectangle do próprio XNA, esta função já foi vista no tutorial de colisão por retângulos. Então na classe Ball vamos criar um novo método que retorna um Rectangle que será usado para checar a intersecção com o Rectangle dos bastões. Veja como fica este método.

Código:


/// <summary>
/// Área de colisão retangular da sprite
/// </summary>
/// <returns>Retorna um retângulo de colisão</returns>
public Rectangle getBounding()
{
    return new Rectangle((int)Position.X,  // X
        (int)Position.Y,                    // Y
        (int)Texture.Width,                // Largura
        (int)Texture.Height);              // Altura
}


Área dos Bastões

O método que devolve o Rectangle do bastão é identico ao método da bola, então segue o código abaixo para a classe Bat.

Código:

/// <summary>
/// Área de colisão retangular da sprite
/// </summary>
/// <returns>Retorna um retângulo de colisão</returns>
public Rectangle getBounding()
{
    return new Rectangle((int)Position.X,  // X
        (int)Position.Y,                    // Y
        (int)Texture.Width,                // Largura
        (int)Texture.Height);              // Altura
}


Rebatendo a bola

Agora que temos a área da bola e dos bastões chamando a função GetBounding() de cada objeto, podemos verificar se elas em algum momento se intersectam e mudar então a direção X da bola. Então no método Update(GameTime gameTime) da classe Game1 após o teste de colisão da bola com a parede, coloque o seguinte código.

Código:

// Checa a colisão da bola com as raquetes dos jogadores
// Jogador 1 (Raquete da esquerda)
if (ball.GetBounding().Intersects(bat1.GetBounding()))
{
    // Inverte a direção X da bola
    ball.Direction *= new Vector2(-1.0f, 1.0f);
}
// Jogador 2 (Raquete da direita)
if (ball.GetBounding().Intersects(bat2.GetBounding()))
{
    // Inverte a direção X da bola
    ball.Direction *= new Vector2(-1.0f, 1.0f);
}


Percebeu o que fizemos? Estamos verificando se houve colisão entre a área da bola com a área do bastão 1 e depois com o bastão 2, caso aconteça alguma colisão então mudamos a direção da bola (multiplicando por -1 a direção em X). Se você testar seu programa agora poderá jogar evitando os pontos do outro jogador, porém existe diversos bugs neste modo ainda, mas não vamos corrigir neste momento (isso será feito no próximo tutorial). Agora vamos colocar alguns sons em nosso jogo para deixa-lo mais divertido.

Colocando os efeitos sonoros e música de fundo

Nesta parte, vamos direto ao assunto, carregando e tocando os sons que devem ser baixados clicando aqui..

Para iniciar, vamos organizar nossos efeitos sonoros criando uma pasta chamada Audios dentro do Content do nosso projeto e adicione todos os audios que vocês fez download. Em seguida, defina algumas variáveis para carregarmos os sons.

Código:

// Efeito sonoro da colisão da bola com o bastão
SoundEffect soundToc1 = null;
// Efeito sonoro da colisão da bola com o campo
SoundEffect soundToc2 = null;
// Efeito sonoro para quando marca ponto
SoundEffect soundPoint = null;
// Música de fundo do jogo
Song music = null;


Após declarar as variáveis, vamos carregar os áudios e já começar a tocar a música de fundo do jogo. você se lembra onde deve colocar os códigos de carregamento das informações? Isso, coloque no método LoadContent().

Código:

// Carrega o efeito sonoro da colisão da bola com o campo
soundToc1 = Content.Load<SoundEffect>(@"Audios\toc_1");
// Carrega o efeito sonoro da colisão da bola com os bastões
soundToc2 = Content.Load<SoundEffect>(@"Audios\toc_2");
// Carrega ó efeito sonoro para quando marcar pontos
soundPoint = Content.Load<SoundEffect>(@"Audios\point");
// Carrega a música de fundo do jogo
music = Content.Load<Song>(@"Audios\music");
// Toca a música de fundo
MediaPlayer.Play(music);
// Coloca a música de fundo em loop infinito
MediaPlayer.IsRepeating = true;


Em seguida, só nos resta tocar os sons das rebatidas nos momentos das colisões do jogo. Então no método Update() faça as atualizações necessárias conforme o código abaixo.

Código:

// Checa colisões da bola com as paredes do campo
// Verifica se a bola colidiu em baixo
if (ball.Position.Y + ball.Texture.Height > 570.0f)
{
    // Inverte a direção em Y do vetor
    ball.Direction *= new Vector2(1.0f, -1.0f);
    // Toca o efeito sonoro de colisão com o campo
    soundToc1.Play();
}
// Verifica se a bola colidiu em baixo
if (ball.Position.Y < 70.0f)
{
    // Inverte a direção em Y do vetor
    ball.Direction *= new Vector2(1.0f, -1.0f);
    // Toca o efeito sonoro de colisão com o campo
    soundToc1.Play();
}
// Atualiza a posiação da bola
ball.Update(gameTime);
// Verifica se alguem marcou ponto
// Se a bola passar pela direita da tela
if (ball.Position.X + ball.Texture.Width > 800.0f)
{
    // Toca o efeito sonoro para marcar pontos
    soundPoint.Play();
    score[0] += 1; // aumenta um ponto ao score do jogador 1
    // Coloca a bola no centro do campo novamente
    ball.Position = new Vector2(386.0f, 310.0f);
    // Muda a direção de disparo da bola em X
    ball.Direction *= new Vector2(-1.0f, 1.0f);
}
// Se a bola passar pela esquerda da tela
else if (ball.Position.X < 0.0f)
{
    // Toca o efeito sonoro para marcar pontos
    soundPoint.Play();
    score[1] += 1; // aumenta um ponto ao score do jogador 2
    // Coloca a bola no centro do campo novamente
    ball.Position = new Vector2(386.0f, 310.0f);
    // Muda a direção de disparo da bola
    ball.Direction *= new Vector2(-1.0f, 1.0f);
}
 
// Checa a colisão da bola com as raquetes dos jogadores
// Jogador 1 (Raquete da esquerda)
if (ball.GetBounding().Intersects(bat1.GetBounding()))
{
    // Inverte a direção X da bola
    ball.Direction *= new Vector2(-1.0f, 1.0f);
    // Toca o efeito sonoro de colisão com a bola
    soundToc2.Play();
}
// Jogador 2 (Raquete da direita)
if (ball.GetBounding().Intersects(bat2.GetBounding()))
{
    // Inverte a direção X da bola
    ball.Direction *= new Vector2(-1.0f, 1.0f);
    // Toca o efeito sonoro de colisão com a bola
    soundToc2.Play();
}


Resultado do tutorial

Caso não tenhamos esquecido de nada, podemos rodar nossa aplicação e ver o resultado da nossa janela com a imagem de fundo, as raquetes se movendo e rebatendo a bola que também bate na parede e emite alguns sons, além da gargalhada ao marcar ponto e uma música de fundo, caso não tenha erros.

[Tens de ter uma conta e sessão iniciada para poderes visualizar esta imagem]