Aproveite o mês das
carreiras na Alura

Até 44% OFF

Falta pouco!

00

DIAS

00

HORAS

00

MIN

00

SEG

Matemática para jogos - Como Utilizar Vetores

Ricardo Bugan Debs
Ricardo Bugan Debs

Compartilhe

Imagem de destaque #cover

No nosso jogo, desenvolvido na engine Unity, o Zumbi precisa perseguir a heroína, como fazer isso?

Como podemos observar na imagem abaixo, a heroína está na posição x = 100, y = 30 e o zumbi, na posição x = 200, y = 120.

Banner da Imersão de IA da Alura com Google Gemini. Participe de aulas gratuitas online com certificado. Domine as inovações mais recentes da IA.

Vamos escrever um código que faça com que o zumbi se desloque até a posição da heroína.

Uma boa prática na hora de resolver problemas é dividi-lo em partes simples e resolver cada uma antes de resolver o problema todo. Nesse caso, qual é a parte mais simples do problema?

Se precisamos sair da posição (200, 120) para a posição (100,30), precisamos alterar a posição do inimigo em dois eixos - horizontal e vertical. Vamos mover o inimigo apenas na horizontal, para depois mover ele no outro eixo.

Se eu estou na posição 200 e quero chegar na posição 100, qual a distância que eu preciso andar?

Na imagem temos d representando a distância que precisamos nos mover para chegar até a posição desejada. Fica fácil perceber que o zumbi precisa andar 100 unidades para chegar na posição da heroína.

Só que o computador não consegue "ver" a imagem e descobrir essa distância. Precisamos achar uma maneira dele calcular essa distância. Nesse caso, para chegarmos no número 100,precisamos subtrair a posição X do zumbi da posição X da heroína.

Depois, é só somar essa distância na posição atual do zumbi para ele se deslocar!


float distânciaX = zumbi.x - heroína.x;
zumbi.x += distânciaX ;

Abaixo, você confere como o código fica na Unity.


public class Zumbi : MonoBehaviour {
[SerializeField]
private Transform alvo;
private void Update()
{
float distanciaX = this.transform.position.x - this.alvo.position.x;
this.transform.position = new Vector3( this.transform.position.x + distanciaX , this.transform.position.y, this.transform.position.z);
}
}

O componente que guarda as informações de posição dos objetos é o Transform, por isso, declaramos uma variável "alvo" do tipo Transformque vai receber seu valor por meio do inspetor da Unity.

Apesar de estarmos trabalhando em um jogo 2D, a Unity ainda guarda as posições com 3 valores (X, Y e Z). Por isso, na hora de atribuirmos a nova posição ao zumbi, utilizamos um Vector3.


this.transform.position = new Vector3( this.transform.position.x + distanciaX, this.transform.position.y, this.transform.position.z);

O que acontece agora se testarmos nosso código?

 

Reparem que o zumbi foi para o lado errado, se afastando da heroína.

Acontece que o sentido do deslocamento importa e, quem define o sentido que estamos andando é o sinal de positivo(+) ou negativo(-).

Quando desenhamos o eixo horizontal, utilizamos uma seta (preta) para representá-lo. Ao mesmo tempo que usamos outra seta (laranja) para representar a distância que devemos andar.

A seta que representa o eixo X aponta na direção em que esse eixo cresce, ou seja se andarmos naquela direção vamos aumentar o valor da nossa posição em X. Nesse caso, estamos indo no sentido positivo (+) do eixo.

A seta que representa o caminho a percorrer aponta no sentido contrário do eixo, isso indica que queremos andar no sentido negativo (-) desse eixo. Como podemos mudar a conta que estamos fazendo para refletir isso?

A conta atual é:


float distânciaX = zumbi.x - heroína.x;

colocando os valores ficaria:


float distânciaX = 200 - 100;

O valor numérico dessa conta está correto, mas queremos o sinal contrário. Como a ordem dos valores de uma subtração importa, podemos inverter os valores da nossa conta para termos o resultado desejado.


float distânciaX = heroína.x - zumbi.x;
distancaX = 100 - 200;
distanciaX = -100;

Se voltarmos no nosso código, precisamos trocar somente a linha onde fazemos essa subtração.


private void Update()
{
**float distanciaX = this.alvo.position.x - this.transform.position.x;**
this.transform.position = new Vector3( this.transform.position.x + distanciaX , this.transform.position.y, this.transform.position.z);
}

Será que essa abordagem funciona também para o eixo vertical?

Vamos testar. No caso do eixo Y, a heroína está na posição 120 e o zumbi na posição 30.

Colocando esses valores na conta:


float distânciaY = heroína.y - zumbi.y;
float distânciaY = 30 - 120;
float distânciaY = - 90;

Chegamos ao número -90 e ele faz sentido, pois o zumbi tem que andar 90 unidades na direção oposta a direção de crescimento do próprio eixo Y.

Podemos então generalizar, ou seja, sempre que precisamos calcular o sentido e a distância entre dois pontos, precisamos subtrair a posição X e Y do nosso destino pelo X e Y da nossa origem.

Voltando ao nosso código da classe zumbi, adicionamos o cálculo da *distânciaY *para que o zumbi vá atrás da heroína.


private void Update()
{
float distanciaX = this.alvo.position.x - this.transform.position.x;
float distanciaY = this.alvo.position.y - this.transform.position.y;
this.transform.position = new Vector3( this.transform.position.x + distanciaX, this.transform.position.y + distanciaY, this.transform.position.z);
}

Será que agora chegamos no comportamento desejado?

Parece que não, agora o zumbi está se teleportando para a posição da heroína.

Resumindo: sempre que temos um comportamento de perseguição precisamos subtrair a posição do destino da posição da origem para achar a direção que temos que seguir e a distância que estamos do alvo.

Ao somar o resultado da subtração na posição do inimigo ele se moverá instantâneamente para o destino.

Como esse texto está ficando longo, resolver apenas esse problemas do perseguidor teleportar para a posição de destino em um outro post.Você conhece alguma outra situação onde podemos usar essa mesma lógica? Qual outro problema relacionado a jogos você gostaria de ver explicado aqui no blog? Deixa nos comentários!

Aproveita e olha lá no site da alura os cursos que temos sobre jogos, tenho certeza que você vai encontrar algo interessante para aprender.

Ricardo Bugan Debs
Ricardo Bugan Debs

Ricardo é designer de jogos, programador e instrutor. Trabalha desenvolvendo jogos desde 2012 e está sempre em busca de novas quests. Como instrutor, vê jogos como mundos interativos onde as pessoas entram para aprender.

Veja outros artigos sobre Programação