Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Colisao com a Raquete e explicação de Lógica.

Olá pessoal, dei uma lida nos tópicos e parece que não sou o único com dúvidas na colisão da bolinha com a raquete. Infelizmente nenhuma das soluções mostradas sanou a minha dúvida, então segue meu emaranhado.

(De antemão peço desculpas pela alteração de algumas palavras para declarar as variáveis, mas a lógica é a mesma.)

O código inteiro é o seguinte:

let xBolinha = 300
let yBolinha = 200
let velocidadeX = 2
let velocidadeY = 2
let diametro = 15
let raio = diametro / 2

// R = raquete

let xR = 5
let yR = 150
let larguraR = 5
let alturaR = 90

function draw() {
  background(0);
  desenhaBolinha();
  velocidadeBolinha();
  colisaoBorda();
  desenhaRaquete();
  movimentaR();
  verificaColisaoR();
}

function setup() {
  createCanvas(600, 400);
}

function desenhaBolinha(){
  circle(xBolinha, yBolinha, diametro);
}

function velocidadeBolinha(){
  xBolinha += velocidadeX
  yBolinha += velocidadeY
}

function colisaoBorda(){
  if (xBolinha + raio > width || xBolinha - raio < 0){
    velocidadeX *= -1
  }

  if (yBolinha + raio > height || yBolinha - raio < 0){
    velocidadeY *= -1
  }
}

function desenhaRaquete(){
  rect(xR, yR, larguraR, alturaR);
}

function movimentaR() {
  if(keyIsDown(UP_ARROW)){
    yR += -10;
  }
  if(keyIsDown(DOWN_ARROW)){
    yR += 10;
  }
}

function verificaColisaoR(){
  if(xBolinha - raio < xR ){
    velocidadeX *= -1
  }
}

Minha dúvida está no porque colocar a altura da raquete no If da colisão? Se eu coloco no meu código a bolinha retorna muito antes de sequer tocar na raquete e se eu retiro o código funciona.

O código correto do professor fica:

function verificaColisaoRaquete() {
    if (xBolinha - raio < xRaquete + raqueteComprimento
        && yBolinha - raio < yRaquete + raqueteAltura
        && yBolinha + raio > yRaquete) {
        velocidadeXBolinha *= -1;
    }
}

Dúvida seguinte que é a de porque mexermos no eixo Y da bolinha e o Raio? Não consegui entender a lógica de como funciona pra caso a bolinha não toque a raquete.

1 resposta
solução!

Olá Yago, tudo bem?

Então, vamos por partes. Comece comentando a linha que movimenta a bolinha no eixo Y e altere a velocidadeX para -1, assim a bolinha estará se movendo na horizontal e indo direto pra direção da raquete, agilizando as visualizações:

let velocidadeX = -1
function velocidadeBolinha(){
  xBolinha += velocidadeX
  // yBolinha += velocidadeY
}

Agora, faça três testes. O primeiro é deixar a bolinha colidir com a raquete, o que deve ocorrer sem problemas. Agora, movimenta a raquete para cima e depois para baixo, deixando ela fora do caminho da bolinha. Percebeu que o movimento continua sendo alterado mesmo sem se chocar com a raquete?

O que está acontecendo é que, no seu código, a colisão na verdade está sendo feita apenas com o eixo X da bolinha em relação ao X da raquete. Experimente alterar o xR para um número maior, e nota que agora a bolinha, chocando com a raquete ou não, vai inverter seu movimento bem mais distante da borda:

let xR = 50

É aí que entram as comparações entre os eixos Y da bolinha e da raquete. Comparando ambos eixos ao mesmo tempo, fazemos nossa colisão ser de fato entre a raquete e a bolinha, e não apenas parecer que é o caso. Vou separar em etapas cada pensamento por trás da colisão, vê se isso te ajuda a entender a lógica (lembre de voltar o seu xR pro valor anterior):

  • Primeiro verificamos se o eixo Y da bolinha é menor que o eixo Y da raquete. Lembre-se que lá no canto superior-esquerdo da tela temos o ponto (X: 0, Y: 0). Então, quanto maior o valor pro eixo Y de algum elemento, mais distante ele está do topo da tela:
yBolinha - raio < yR + alturaR 

Assim:

function verificaColisaoR(){
  if(xBolinha - raio < xR + larguraR && yBolinha - raio < yR + alturaR ){
    velocidadeX *= -1
  }
}
  • Faça os testes lá do começo novamente. Você vai perceber que agora a bolinha toca na borda da tela caso a raquete esteja acima da bolinha, mas isso ainda não acontece pra caso ela esteja abaixo. Nós somamos alturaR pelo mesmo motivo de subtrairmos o raio: queremos pegar a borda da raquete;

  • Agora, precisamos verificar se a raquete está abaixo da bolinha. Dessa vez iremos somar o raio no eixo Y da bolinha para pegarmos a parte de baixo da bolinha:

function verificaColisaoR(){
  if(xBolinha - raio < xR + larguraR && yBolinha - raio < yR + alturaR && yBolinha + raio > yR){
    velocidadeX *= -1
  }
}

Assim, se as três condições forem satisfeitas, o if será verdadeiro, e assim a bolinha muda de direção.

Você comentou que com o código do instrutor sua bolinha era rebatida antes da colisão. Isso provavelmente aconteceu por algum valor ou sinal trocado na sua condição da função! Qualquer coisa posta aqui sua função do jeitinho que estava dando problemas e damos uma olhada juntos.

Espero ter ajudado, um abraço e ótimos estudos!