Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

[Dúvida] Não entendi a logica na movimentação da raquete do oponente.

até então o curso tem sido bem didático, mas quando veio a criação do código para a movimentação da Raquete Do Oponente, em especifico:

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

simplesmente não entendi nada da logica dessa função, pareceu muito complexa e o professor só pincelou por cima e próxima, e na descrição da aula não se aprofundou em nada, alguém disserte um pouco mais sobre?

4 respostas

Oi Cleber? Tudo bem por aí?

Agradeço pelo seu feedback e peço desculpas por essa experiência, não é o que queremos levar para nossos alunos e alunas.

Quando temos excesso de informações, a compreensão lógica torna-se mais desafiadora. Irei te explicar 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 está na tela

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 +=  velocidadeYOponente ;

}

Resultado:

gif do jogo Pong. A bolinha está se movimentando, e a raquete do jogador está parada. A bolinha colide algumas vezes com a raquete do oponente que está se movendo, e bate na parte superior da raquete

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 +=  velocidadeYOponente;

}

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

solução!

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. 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.

Abraço!

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

Olá, fiquei com uma dúvida na sua explicação. No vídeo mostra a seguinte solução:

Insira aqui a descrição dessa imagem para ajudar na acessibilidade )

Sua solução foi parecida, porém você utilizou uma variável diferente para receber a soma do yRaqueteOponente.

Insira aqui a descrição dessa imagem para ajudar na acessibilidade )

Esse foi o seu exemplo, fiquei mais na dúvida ainda, pois em que momento eu uso essa variável deslocamentoYRaqueteOponente?

Minha raquete do oponente não esta funcionando... :/

Preciso de ajuda.

//ball variables
let xBall = 100;
let yBall = 200;
let diameter = 15;
let rays = diameter / 2;

//ball speed
let xVelocity = 5;
let yVelocity = 5;

//racket variables
let xRacket = 5;
let yRacket = 150;
let racketLength = 10;
let racketHeight = 90;

//oponents variables
let xRacketOponent = 585;
let yRacketOponent = 150;
let speedYoponent;

let collided = false;

    function setup() {
        createCanvas(600, 400);
    }
    function draw() {
        background(0);
        showBall();
        ballMovement();
        ballCheck();    
        showRacket(xRacket, yRacket);
        moveMyRacket();
        collisionMyRacketBibliotec();
        showRacket(xRacketOponent, yRacketOponent);
    }
    function showBall() {
        circle(xBall, yBall, diameter);
    }
    function ballMovement() {
        xBall += xVelocity;
        yBall += yVelocity;
    }
    function ballCheck() {
        if(xBall + rays > width || xBall - rays < 0) {
            xVelocity *= -1;
        }
        if(yBall + rays > height || yBall - rays < 0) {
            yVelocity *= -1;
        }
    }
    function showRacket(x, y) {
        rect(x, y, racketLength, racketHeight);
    }
    function moveMyRacket() {
        if(keyIsDown(UP_ARROW)) {
            yRacket -= 10;
        }
        if(keyIsDown(DOWN_ARROW)) {
            yRacket += 10;
        }
    }
    function collisionMyRacketBibliotec() {
        collideRectCircle(xRacket, yRacket, racketLength, racketHeight, xBall, yBall, rays);
        if(collided == true) {
            xVelocity *= -1;
        }
    }
    function moveRacketOponent() {
        speedYoponent = yBall - yRacketOponent - racketLength / 2 - 30;
        yRacketOponent += speedYoponent;
    }

Esse é meu código.

Oi Gabriel, tudo bem?

De fato, a variável deslocamentoYRaqueteOponente foi o nome que usei em meu código, mas falhei em explicar isso exatamente. Ela tem exatamente a mesma função que a variável velocidadeYOponente. Alterei minha resposta para evitar mais confusão e agradeço muito por ter me avisado. Espero que tenha ficado mais claro.

No seu código, a movimentação não está funcionando pois faltou chamar a função moveRacketOponent dentro da função draw. Percebi que a colisão também não funciona, para isso, atribua collideRectCircle à variável collided, assim:

    function collisionMyRacketBibliotec() {
       collided = collideRectCircle(xRacket, yRacket, racketLength, racketHeight, xBall, yBall, rays);
        if(collided == true) {
            xVelocity *= -1;
        }
    }

Gabriel, caso tenha mais alguma dúvida, peço que abra um novo tópico no fórum.

Espero ter ajudado, fico a disposição.

Abraço!