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

[Bug] Uma opção para evitar bolinha presa na raquete

Ao longo do curso também me deparei com esse "bug" da bolinha presa atrás da raquete ou dentro dela, e apesar das soluções muito boas apresentadas por outros alunos, decidi buscar uma minha. E acredito que encontrei.

Primeiro, no meu entendimento percebi que esse problema ocorria principalmente quando a bolinha batia na "quina" da raquete, pois ali a bolinha colidia com o Y da raquete, e ao mudar de direção podia esbarrar no X da raquete, resultando naquele efeito de deslizar por dentro dela. Coisa semelhante ocorria ao marcar ponto, pois a bolinha ao mudar de direção poderia bater atrás da raquete e pontuar sem parar, pois o X da bolinha ficava preso entre o X da borda e o X da raquete, gerando aquele efeito de zigue-zague.

Para tentar resolver isso, aprimorei a função que o professor utilizou com a biblioteca do p5.collide2D, feita para verificar a colisão da bolinha com a raquete.

Quando a bolinha colidir com a raquete, alterei o X da bolinha para ela apareça um pouco a frente da raquete e assim não volte a colidir logo em seguida.

function verificaColisaoRaqueteOponenteBiblioteca(){
  colidiu = collideRectCircle(xRaqueteOponente, yRaqueteOponente, comprimentoRaquete, alturaRaquete, xBola, yBola, raio);
  if (colidiu){
    velocidadeXBola *= -1
    xBola = 580 // altera o X da bolinha para evitar ficar presa na Raquete Oponente
    raquetada.play();
  }
}

function verificaColisaoMinhaRaqueteBiblioteca(){
  colidiu = collideRectCircle(xRaquete, yRaquete, comprimentoRaquete, alturaRaquete, xBola, yBola, raio);
  if (colidiu){
    velocidadeXBola *= -1
    xBola = 20 // altera o X da bolinha para evitar ficar presa na Minha Raquete
    raquetada.play();
  }
}

Da mesma forma, fiz um ajuste na função marcaPonto, ao pontuar também alterei o X da bolinha para evitar colidir com a raquete logo após o ponto. Além disso, deixei a mudança de direção do X da bolinha na marcaPonto, ao invés da verificaColisaoBorda

function marcaPonto(){
  if (xBola > 590){
    meusPontos += 1;
    velocidadeXBola *= -1;
    xBola = 580; // evita colidir com a raquete após ponto
    ponto.play();
  }
  if (xBola < 10){
    pontosDoOponente += 1;
    velocidadeXBola *= -1;
    xBola = 20; // evita colidir com a raquete após ponto  
    ponto.play();
  }
}

Os valores do xBola calculei de acordo com os valores que deixei nas minhas variáveis das raquetes e da bolinha.

// variáveis da bolinha
let xBola = 300;
let yBola = 200;
let diametro = 18;
let raio = diametro / 2;

// velocidade da bolinha
let velocidadeXBola = 7;
let velocidadeYBola = 7;

// variáveis da raquete
let xRaquete = 5;
let yRaquete = 150;
let comprimentoRaquete = 10;
let alturaRaquete = 80;


// variáveis do oponente
let xRaqueteOponente = 585;
let yRaqueteOponente  = 150;
let velocidadeYRaqueteOponente;
2 respostas

Código completo:


// variáveis da bolinha
let xBola = 300;
let yBola = 200;
let diametro = 18;
let raio = diametro / 2;

// velocidade da bolinha
let velocidadeXBola = 7;
let velocidadeYBola = 7;

// variáveis da raquete
let xRaquete = 5;
let yRaquete = 150;
let comprimentoRaquete = 10;
let alturaRaquete = 80;


// variáveis do oponente
let xRaqueteOponente = 585;
let yRaqueteOponente  = 150;
let velocidadeYRaqueteOponente;

let colidiu = false;

// variáveis do placar
let meusPontos = 0;
let pontosDoOponente = 0;
let bordaArredondada = 5;

//sons do jogo
let raquetada;
let ponto;
let trilha;

function preload(){
  raquetada = loadSound("raquetada.mp3");
  ponto = loadSound("ponto.mp3");
  trilha = loadSound("trilha.mp3");
}


function setup() {
  createCanvas(600, 400);
  trilha.loop();
}

function draw() {
  background(0);
  mostraBolinha();
  movimentaBolinha();
  verificaColisaoBorda();  
  mostraRaquete(xRaquete, yRaquete);
  movimentaMinhaRaquete();
  mostraRaquete(xRaqueteOponente, yRaqueteOponente);
  movimentaRaqueteOponente();
  //multiplayerRaqueteOponente();
  verificaColisaoRaqueteOponenteBiblioteca();
  verificaColisaoMinhaRaqueteBiblioteca();
  incluiPlacar();
  marcaPonto();
}

function mostraBolinha(){
  circle(xBola, yBola, diametro);
}

function movimentaBolinha(){
  xBola += velocidadeXBola;
  yBola += velocidadeYBola
}

function verificaColisaoBorda(){
  //if (xBola + raio > width || xBola - raio < 0){
  //  velocidadeXBola *= -1;
  //} comentado pois irá alterar direção ao marcar ponto
  if (yBola + raio > height || yBola - raio < 0){
    velocidadeYBola *= -1;
  }
}

function mostraRaquete(x, y){
  rect(x, y, comprimentoRaquete, alturaRaquete);
}

function movimentaMinhaRaquete(){
  if (keyIsDown(UP_ARROW)){
    yRaquete -= 6;
  }
  if (keyIsDown(DOWN_ARROW)){
    yRaquete += 6;
  }
}

function multiplayerRaqueteOponente(){
  if (keyIsDown(87)){
    yRaqueteOponente -= 6;
  }
  if (keyIsDown(83)){
    yRaqueteOponente += 6;
  }
}


function verificaColisaoRaqueteOponenteBiblioteca(){
  colidiu = collideRectCircle(xRaqueteOponente, yRaqueteOponente, comprimentoRaquete, alturaRaquete, xBola, yBola, raio);
  if (colidiu){
    velocidadeXBola *= -1
    xBola = 580 // altera o X da bolinha para evitar ficar presa na Raquete Oponente
    raquetada.play();
  }
}

function verificaColisaoMinhaRaqueteBiblioteca(){
  colidiu = collideRectCircle(xRaquete, yRaquete, comprimentoRaquete, alturaRaquete, xBola, yBola, raio);
  if (colidiu){
    velocidadeXBola *= -1
    xBola = 20 // altera o X da bolinha para evitar ficar presa na Minha Raquete
    raquetada.play();
  }
}

function movimentaRaqueteOponente(){
  velocidadeYRaqueteOponente = (yBola - yRaqueteOponente - comprimentoRaquete) / 2 - 35;
  yRaqueteOponente += velocidadeYRaqueteOponente
}

function incluiPlacar(){
  stroke(255);
  textAlign(CENTER);
  textSize(16);
  fill(color(255,140,0));
  rect(150, 10, 40, 20, bordaArredondada);
  fill(255);
  text(meusPontos, 170, 26);
  fill(color(255,140,0));
  rect(430, 10, 40, 20, bordaArredondada);
  fill(255);
  text(pontosDoOponente, 450, 26);
}

function marcaPonto(){
  if (xBola > 590){
    meusPontos += 1;
    velocidadeXBola *= -1;
    xBola = 580; // evita colidir com a raquete após ponto
    ponto.play();
  }
  if (xBola < 10){
    pontosDoOponente += 1;
    velocidadeXBola *= -1;
    xBola = 20; // evita colidir com a raquete após ponto  
    ponto.play();
  }
}
solução!

Opa Lucas, tudo ok por aí?

Sobre a sua solução ela é sim totalmente plausível e funciona sim.

A sua lógica de gerar fazer com que a bolinha vá para uma posição especifica quando começar aquele efeito loop de bater na “parede” e na “raquete” foi muito legal e interessante.

Parabéns por pensar em algo desse tipo e compartilhar com os outros estudantes aqui na plataforma.

Deixo como recomendação, dois vídeos de Alura + que explicam explicam sobre como obter máximo proveito do fórum da Alura:

Recomendo, caso se sinta confortável em compartilhar seu conhecimento, interagir com outros estudantes, trocar experiências e fazer networking, que participe do Discord oficial da Alura de alunas e alunos:

Em suma era isso, caso tenha dúvidas ou problemas relacionados ao curso recorra ao fórum!

E mais uma vez parabéns por sua atitude.

Um grande abraço e bons estudos.