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

Movimento da bola

Vamos analisar neste primeiro momento como a bola do nosso jogo irá se movimentar. Na figura baixo podemos ver que para a bola se movimentar precisamos de um vetor que vai indicar qual direção a bola se moverá. Além disso, precisamos também definir uma velocidade de movimento para que a bola possa se deslocar naquela direção em uma fração de tempo. Sendo assim, a próxima posição da bola pode ser definida como a posição atual somada ao vetor direção, multiplicado pela velocidade, multiplicado pela diferença de tempo. Esta diferença de tempo no nosso caso é o gameTime.ElapsedGameTime do nosso jogo, ou seja, a diferença de tempo entre uma atualização e outra. Simples não?

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

Vamos começar a ver então como isso vai ficar em nosso jogo, abra o projeto que estamos desenvolvendo. E analise o que fizemos no método Update da classe Ball no tutorial passado.

Código:


public void Update(GameTime gameTime)
{
    Position += Direction * Velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;
}


Analisando o código acima, o que estamos fazendo aqui? estamos fazendo com que a nossa posição antiga seja incrementada em uma fração de tempo, em uma direção multiplicada por uma velocidade, para atingir a próxima posição da bola. Mas isso só vai acontecer se existir uma velocidade, e se o vetor direção não for nulo.

Vamos então definir inicialmente uma direção para nossa bola. Para isso modifique os valores iniciais do vetor direção no construtor da classe Ball. Veja no código abaixo como é para ficar seu construtor.

Código:

public Ball(Game game, Vector2 position)
{
    Texture = game.Content.Load<Texture2D>(@"Textures\ball");
    Position = position;
    Direction = new Vector2(1.0f, 1.0f);
    velocity = 150.0f;
}


Neste caso modificamos nossa direção para receber um Vector2(1.0f, 1.0f), então se você neste momento compilar e executar o código (F5) você verá a bola se movimentar para baixo e indo para direita, por que isto? porque nosso vetor direção esta apontando para aquele lado. Se você quiser pode ir alterando os valores do vetor entre (0, –1 ou 1) para você ir vendo o que acontece com a bola.

Porém note que a bola vai embora infinitamente e não colide com nosso campo. Isto acontece pois não criamos condição que impessam que a bola continue ou no caso que ela colida com o cenário e volte para o outro lado. Para isto iremos ter que digitar o seguinte código logo após a chamada do método Update do nosso objeto ball na classe Game1.

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çaõ em Y do vetor
    ball.Direction *= new Vector2(1.0f, -1.0f);
}
// 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);
}


Veja (figura abaixo e código axima), quando a posição y da bola é maior que 570 (linha inferior do campo) mudamos o vetor direção para -1, ou seja a seta do nosso vetor vai inverter o sentido em Y. O mesmo acontece para quando a posição y da bola é menor que 0. Se você executar o programa agora você verá a bola colidir com a parte inferior do campo porém ela ainda vai sumir a direita e não vai aparecer novamente, pois quando ela ultrapassa a direita ou a esquerda da tela algum jogador deve recebe pontos por ter marcado um “gol” e logo em seguida a bola deve volta ao centro do campo para recomeçar a partida. Mas como fazer isto?

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

Marcando a pontuação dos jogadores

Para somar a pontuação e até mesmo exibir na tela, precisamos definir uma variavel para armazenar os pontos dos jogadores, então logo abaixo de definir os objetos bat e ball na classe Game1, escreva o seguinte código.

Código:

// Pontuação dos jogadores
// indice 0 = jogador 1
// indice 1 = jogador 2
int[] score = new int[2];


Quando o jogo começar, precisamos dizer para nosso score que os jogadore tem 0 pontos. Então vamos iniciar nossas pontuações no método Initialize do nosso jogo.

Código:

protected override void Initialize()
{
    // Inicializando a pontuação dos jogadores
    score[0] = 0; // Jogador 1
    score[1] = 0; // Jogador 2
    base.Initialize();
}


Log em seguida, quando a bola passar os limites de tala a direita (0.0f) e a esquerda (800.0f), precisamos fazer a bola retornar a sua posição inicial e aumentar um ponto no score do outro jogador. Para isso digitemos o seguinte código logo após o código de fazer a bola colidir com o campo, que escrevemos agora de pouco.

Código:

// Verifica se alguem marcou ponto
// Se a bola passar pela direita da tela
if (ball.Position.X + ball.Texture.Width > 800.0f)
{
    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)
{
    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);
}


Agora se executar o jogo poderá ver a bola ultrapassar a posição do campo de um jogador, aumentar um ponto do jogador que marcou ponto, retornar a bola ao centro e mudar a direção x da bola fazendo que ao recomeçar a partida a bola comece para o outro lado. Agora com o movimento da bola funcionando precisamos somente exibir a pontuação na tela para informar quanto está a partida, para isso vamos definir uma definir uma font arial de tamanho 30 como o nome de gameFont.spritefont.

Clique com o botão direito do mouse em “TutorialPongContent -> Add -> New Folder” e coloque o nome da pasta como Fonts, após fazer isso clique com o botão direito na pasta Fonts que acabou de criar “Add -> New Item” e selecione SpriteFont colocando o de gameFont. Agora crie uma variável do tipo SpriteFont e carregue nossa font no método LoadContent() ainda na classe Game1. Então abaixo do local onde declaramos nosso score, vamos fazer a seguinte declaração.

Código:

// SpriteFont para escrever na tela
SpriteFont fontScore;


E no método LoadContent() após carregar o background do jogo digite o seguinte código para carregar a font.

Código:

// Carrega a font para escrita
fontScore = Content.Load(@"Fonts\score");


Legal galera, o ultimo passo deste tutorial passo é desenhar o score na tela, para fazermos isso vamos no método Draw() logo após desenhar a bola e vamos digitar o seguinte código.

Código:

// Desenhando o score do jogador 1 no centro do quadrado
Vector2 textSize = fontScore.MeasureString(score[0].ToString("000"));
spriteBatch.DrawString(fontScore,
    score[0].ToString("000"),
    new Vector2(300, 35) - textSize/2,
    Color.White);
// Desenhando o score do jogador 2 no centro do quadrado
textSize = fontScore.MeasureString(score[1].ToString("000"));
spriteBatch.DrawString(fontScore,
    score[1].ToString("000"),
    new Vector2(500, 35) - textSize / 2,
    Color.White);


O que estamos fazendo, estamos declarando um vetor com o nome de tamanho do texto (textSize), e estamos falando que ele recebe o tamanho em pixel da escrita do valor. Para que isso? Para desenhar nosso texto em um centro especifico, pois assim como ao desenhar imagens ele desenha de um ponto (x,y) para frente, ou seja quando nossa pontuação aumentar da casa unitária para casa decimal, ele vai ficar fora do centro do quadrado da nossa imagem. Sendo assim, pegamos o centro do local que queremos desenhar menos metade do tamanho desta escrita e começamos a desenhar a partir deste (x,y), mantendo sempre a escrita do score no cento do quadrado.

Resultado do tutorial

Por hoje é isso pessoal, se não nos esquecemos de nada, podemos rodar nossa aplicação e ver o resultado do nosso jogo, com a bola se movimentando e marcando pontos. Porém os jogadores ainda não conseguem rebater a bola.

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