2
respostas

Dúvidas sobre a lógica da movimentação inimiga

Esse curso não está sendo tão didático quanto outros que já vi na Alura... Ainda tenho dúvidas relacionadas a lógica abaixo.

function movimentaRaqueteOponente() {
    velocidadeYOponente = yBolinha - yRaqueteOponente - raqueteComprimento / 2 - 30;
    yRaqueteOponente += velocidadeYOponente;
}

É a primeira vez que experimento o javascript e a forma como funciona o plano cartesiano tem me confundido muito... Provavelmente essas subtrações são para centralizar as coordenadas com o centro da raquete (foi o que eu entendi com os outros posts do fórum), mas ainda não está 100% esclarecido.

2 respostas

Oi Diego! Tudo certo por aí?

Peço desculpas pela demora em te responder!

Agradeço pelo seu feedback e peço desculpas por essa experiência, não é o que queremos levar para nossos alunos e alunas. Realmente quando se tem excesso de informações a compreensão lógica torna-se desafiadora, mas, irei te explicar passo a passo como a função movimentaRaqueteOponente está funcionando. O objetivo da função movimentaRaqueteOponente() é criar uma movimentação para a raquete do oponente que tenha como principal característica acompanhar o movimento da bolinha, ou seja, se a bolinha faz uma movimentação com direção para cima, a raquete se moverá para cima, se a bolinha faz uma movimentação com direção para baixo, a raquete se movimenta para baixo.

Vamos entender o papel das variáveis que utilizamos dentro da função:

  • yBolinha = 200: posição inicial em que a bolinha estará, no eixo vertical. Quando o play for clicado, o yBolinha se modificará de acordo com a posição da bolinha na tela.
  • yRaqueteOponente = 150: posição inicial da raquete do oponente, no eixo vertical. Essa variável terá seu valor alterado a partir da função movimentaRaqueteOponente(), considerando o valor de yBolinha.
  • velocidadeYOponente : velocidade, nesse caso, diz respeito ao deslocamento da raquete do oponente, no eixo vertical. Ela receberá um valor dinâmico: essa variável é responsável por armazenar a posição Y da raquete do oponente em relação ao movimento da bolinha. Ou seja, se yBolinha em um dado momento é 5, será feito um cálculo para saber se a raquete do oponente tem que se movimentar para cima ou para baixo para acompanhar a posição 5 da bolinha. raqueteComprimento: guarda o tamanho da raquete.

Considerando que o objetivo da função movimentaRaqueteOponente é fazer com que a raquete siga a bolinha, uma lógica simples que pode vir a mente seria apenas igualar o valor yRaqueteOponente com yBolinha, pois assim, a raquete se moveria exatamente da mesma forma que a bolinha, com a mesma coordenada, da forma mostrada abaixo:

function movimentaRaqueteOponente(){
  velocidadeYOponente = yBolinha 
  yRaqueteOponente += velocidadeYOponente; 
}

Resultado:

gif do jogo pong. A bolinha está se movimentando. A raquete do jogador está parada, e a raquete do oponente não aparece. O placar marca 1 para os dois lados. Após alguns movimentos, marca 2 para os dois lados.

Porém, quando implementamos isso, o y da raquete passa a ser tão alto, que por consequência do incremento a raquete nem aparece na tela. Por isso é importante que façamos a subtração de yRaqueteOponente. Assim o valor ficará dinâmico como desejamos: se a posição da bolinha é 205 e a posição da raquete é 150, teremos como resultado um y = 56, que está dentro das dimensões da tela e será próximo da posição da bolinha. Se a bolinha sobe, a raquete sobe, se a bolinha desce, a raquete desce. Exemplo:

function movimentaRaqueteOponente(){

velocidadeYOponente = yBolinha - yRaqueteOponente;

yRaqueteOponente += deslocamentoYRaqueteOponente ;

}

Resultado:

gif do jogo pong. A bolinha está se movimentando. A raquete do jogador está parada, e a raquete está seguindo o movimento da bolinha. A bolinha colide com a raquete do oponente, batendo na parte superior. O placar começa zerado e marca pontos para o oponente conforme a bolinha toca na parede do lado do jogador.

Dessa forma, a colisão já acontece, e a raquete não ultrapassa as dimensões da tela, mas a bolinha bate na extremidade superior da raquete. Para que o jogo tenha uma melhor experiência, as próximas operações são feitas, e a colisão da bolinha vai acontecer na extremidade central da raquete. Assim temos nosso código final:


function movimentaRaqueteOponente(){

velocidadeYOponente = yBolinha - yRaqueteOponente - raqueteComprimento / 2 - 30;

yRaqueteOponente += deslocamentoYRaqueteOponente;

}

Resultado:

gif do jogo pong. A bolinha está se movimentando. A raquete do jogador está parada, e a raquete está seguindo o movimento da bolinha. A bolinha colide com a raquete do oponente, batendo na parte central. O placar começa zerado e marca pontos para o oponente conforme a bolinha toca na parede do lado do jogador

O trecho raqueteComprimento/2 -30 diz respeito a bolinha colidir com a parte central da raquete. Porquê 30? O valor 30 é arbitrário, é um valor escolhido com base em testes, por exemplo, testo 10, não ficou como eu queria, então, testo 15, testo 20 e assim por diante. A subtração desse valor é porque queremos que o valor da variável velocidadeYOponente seja ainda menor para que a bolinha possa tocar ao centro.

Quando trabalhamos com criação de jogos, em muitos casos não conseguiremos fugir desse cenário de tentativas e erros, óbvio que existem técnicas matemáticas capazes de fazer com que esses testes fiquem mais rápidos e assertivos, mas não cabe ao momento.

Em resumo, toda essa operação feita na função movimentaRaqueteOponente() é para que a raquete do oponente tenha seu movimento com base no movimento da bolinha e além disso, para que quando a bolinha tocar na raquete do oponente toque na extremidade central.

Caso queira se aprofundar mais em relação ao plano cartesiano do P5.js, deixo como recomendação a leitura de um artigo aqui da Alura que explica em detalhes o funcionamento das coordenadas:

Espero ter ajudado. Fico à disposição em casos de dúvidas.

Caso este post tenha lhe ajudado, por favor, marcar como solucionado! ✓.