[Guia do Iniciante Dia #6] Aprodundando no posicionamento de imagens 2D (Vector2)
Olá. Faz um tempo que não trago novidades, mas hoje começo a dar continuação ao Guia do Iniciante.
O tema de hoje é sobre Vector2. Uma das estruturas que você mais irá usar quando criar algo baseado em dois eixos (X e Y = 2D = 2 Dimensões).
No ultimo capitulo do Guia do Iniciante, nós usamos apenas Vector2.Zero. Irei realizar uma explicação melhor e iremos deixar o ultimo exemplo bem mais avançado.
Vamos começar!
- “O que é um Vector2?”
Resposta: Vector2 nada mais é do que uma estrutura/classe que armazena duas coordenadas : X e Y
- “Mas se só serve para armazenar X e Y, por que não uso a classe Point?”
Resposta: As facilidades que Vector2 nos fornece são muitas. Temos funções como: Vector2.Lerp, Vector2.Subtract, Vector2.Mutiply que realizam calculos digamos que muito extensos e repetitivos.
Veja, por exemplo, como somar dois Points em um novo Point.
Point ponto1 = new Point(200, 200);
Point ponto2 = new Point(100, 100);
Point pontoResultante = new Point();pontoResultante.X = ponto1.X + ponto2.X;
pontoResultante.Y = ponto1.Y + ponto2.Y;
O resultado é X = 300; Y = 300. Agora veja o mesmo exemplo com Vector2:
Vector2 vetor1 = new Vector2(200, 200);
Vector2 vetor2 = new Vector2(100, 100);
Vector2 resultado = new Vector2();resultado = Vector2.Add(vetor1, vetor2);
Isto produz exatamente o mesmo resultado, obiviamente a diferença não foi grande, mas ao realizarmos, por exemplo, uma interpolação linear, a classe estatica Vector2 é de grande utilidade.
Agora vamos ver o problema de hoje.
O Problema
Precisamos mover a imagem de um lado para o outro na tela em um loop interminável.
Vamos analisar algumas palavras-chaves:
-Mover: Isso significa que precisaremos posiciona-la, ou seja, usaremos Vector2.
-De um lado para o Outro: Podemos usar velocidade para isso.
-Loop Interminavel: Isto rima com o método Update() =D
Vamos agora resolver o problema.
A Resolução
Antes de tudo, vamos resumir os passos. Lembre-se de criar um novo projeto.
-> NÃO EXIGE CÓDIGO
1. Salve a imagem abaixo:
2. Adicione a imagem ao projeto.
-> CÓDIGO NO TOPO DA CLASSE
3. Crie uma variavel Texture2D para armazenar a imagem
4. Crie uma variavel Vector2 para o posicionamento.
5. Crie uma variavel int para armazenar a velocidade.
-> CÓDIGO NO LOADCONTENT()
6. Carregue a imagem
7. Inicialize a posição
8. Defina a velocidade inicial
-> CÓDIGO NO UPDATE()
9. Defina o Loop principal
-> CÓDIGO NO DRAW()
10. Desenhe a imagem
Agora vamos ao Trabalho.
1. Você já salvou a imagem, certo?
2. Você já sabe adicionar imagem correto? Se não souber, Clique Aqui.
3. Crie a váriavel Texture2D no topo da classe (antes do Construtor)
Texture2D t_Kakashi;
4. Agora criaremos a váriavel para posiciona-lo, adicione o seguinte logo abaixo de “Texture2D t_Kakashi;”
Vector2 p_Kakashi;
5. Adicione logo abaixo, a variavel que armazenará a velocidade.
int v_Kakashi;
6. Já no método LoadContent() carregue a imagem do Kakashi-san. Lembre-se que você pode colocar uma de sua preferencia, só basta carregar e substituir “Kakashi” por “NOME_DA_IMAGEM”.
t_Kakashi = Content.Load<Texture2D>(“Kakashi”);
7. Inicialize p_Kakashi, para fazer isso adicione logo abaixo:
p_Kakashi = new Vector2( 0 , 150);
8. Agora dê um valor para a velocidade da imagem
v_Kakashi = 2;
Isso significa que a velocidade dele será 2 pixels por atualização da tela.
9. No método Update() adicione a lógica. Veja como o mesmo irá ficar:
protected override void Update(GameTime gameTime)
{
if (v_Kakashi > 0) // Se a velocidade for maior que 0, ou seja positiva, significa que está indo para a direita
{
if (p_Kakashi.X < (Window.ClientBounds.Width – t_Kakashi.Width) – v_Kakashi)
{
p_Kakashi.X += v_Kakashi;
}
else
{
v_Kakashi *= -1;
}
}
else if (v_Kakashi < 0) // Se a velocidade for menor que 0, ou seja negativa, significa que está indo para a esquerda
{
if (p_Kakashi.X > 0)
{
p_Kakashi.X += v_Kakashi;
}
else
{
v_Kakashi *= -1;
}
}base.Update(gameTime);
}
Vou explicar a lógica envolvida neste loop que faz a mágica para nós. Siga o raciocinio:
Se estiver indo para a direita, ou seja, a velocidade é positiva…
if (p_Kakashi.X < (Window.ClientBounds.Width – t_Kakashi.Width) – v_Kakashi)
{
p_Kakashi.X += v_Kakashi;
}
Se a posição X do Kakashi for menor que a largura da tela – a largura da imagem do Kakashi – a velocidade, ele avança 2 pixels no caso.
Nota: Lembre-se que no 2D começa-se a contar do canto esquerdo-superior, se você esqueçer de considerar a largura da imagem, a imagem vai sair da tela até o canto superior-esquerdo atingir o ponto desejado.
Então lembre-se que o espaço ocupado por uma imagem é igual à:
EspaçoTotal.X = Posicao.x + Imagem.Largura
EspaçoTotal.Y = Posicao.y + Imagem.Altura
Voltando…
else
{
v_Kakashi *= -1;
}
Agora se já estiver no limite da tela, a velocidade é invertida. Lembre-se que o sinal pode ser invertido multiplicando-se um valor por –1.
Agora a velocidade é –2, ou seja, é menor que 0, portanto está indo para a direita:
if (p_Kakashi.X > 0)
{
p_Kakashi.X += v_Kakashi;
}
Se sua posição X for maior que 0 ele irá “adicionar” a velocidade, mas no caso, a velocidade é –2, então na verdade irá subtrair 2 pixels da posição.
Agora se a posição é 0, então novamente se inverte a velocidade.
Terminada a lógica envolvida.
10. No método Draw() simplemente desenhe a imagem em sua respectiva posição. Por questões de estética, mude a cor de fundo para White (Branco). Veja como ficou seu método Draw:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.White);spriteBatch.Begin();
spriteBatch.Draw(t_Kakashi, p_Kakashi, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
Pressione F5 para realizar o Debug e veja o programa em ação!
Obrigado! E até a próxima!