Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
13
respostas

Bug no jogo: bolinha entrando dentro da raquete

O jogo está funcionando bem até o momento. O problema é que quando acontece a colisão entre a bolinha e a raquete pela parte "de cima" ou "de baixo" dela, a bolinha "agarra" no interior da raquete.

Eu já imagino até onde está o problema (na função verificaColisaoRaquete). O xBolinha-raio se torna menor que o xRaquete + raqueteComp, mas como a colisão se deu por cima, ele acaba ficando confinado dentro da raquete até sair do outro lado. É um pequeno bug, mas estou tentando pensar em uma forma de corrigir. Alguém poderia propor uma ideia e explicar o código da correção para mim?

Segue o código abaixo:

//Variáveis da Bolinha
let xBolinha = 300;
let yBolinha = 200;
let diametro = 26;
let raio = diametro/2;
let velocidadeXBolinha = 2;
let velocidadeYBolinha = 2;

//variáveis da raquete
let xRaquete = 5;
let yRaquete = 150;
let raqueteComp = 20;
let raqueteAlt = 90;
let colidiu = false;

//variáveis do oponente
let xRaqueteOponente = 575;
let yRaqueteOponente = 150;
let velocidadeYOponente;

//Aqui eu defino o que é a Bolinha:
function mostraBolinha (){
  circle (xBolinha, yBolinha, diametro);
}

//Aqui eu defino o movimento da Bolinha:
function movimentaBolinha (){
  xBolinha += velocidadeXBolinha;
  yBolinha += velocidadeYBolinha;
}

//Aqui defino o que são as raquetes:
 function mostraRaquete (x, y){ 
  rect (x, y, raqueteComp, raqueteAlt);
 }

//Aqui defino o movimento da Raquete:
function movimentaMinhaRaquete (){
  if (keyIsDown(UP_ARROW)){
    yRaquete -=10;
  }
  if (keyIsDown(DOWN_ARROW)){
    yRaquete +=10;
  }
}

//Aqui defino o movimento do Oponente. 
function movimentaOponente (){
  velocidadeYOponente = yBolinha -yRaqueteOponente -raqueteComp /2 - 30;
  yRaqueteOponente += velocidadeYOponente;
}

//Aqui é verificada a colisão da raquete: 
function verificaColisaoRaquete(){
  if (xBolinha - raio < xRaquete + raqueteComp && yBolinha - raio < yRaquete + raqueteAlt && yBolinha + raio > yRaquete){
    velocidadeXBolinha *= -1;
  }
}

//Aqui eu defino a colisão das bordas da tela:
function colisaoBorda () {

    //Aqui é criado a colisão na horizontal, eixo X, com as paredes. 
  if (xBolinha > width-raio ||
     xBolinha < raio){
    velocidadeXBolinha *= -1;
  }

  //Aqui é criado a colisão vertical, eixo Y, com o teto e o chão. 
  if (yBolinha > height-raio ||
     yBolinha < raio){
    velocidadeYBolinha *= -1;
  }
}

//Aqui é criada as dimensões da "tela" que será trabalhada. 
function setup() {
  createCanvas(600, 400);
}

//Aqui se cria todas as funções. 

function draw() {
  background(0);
  mostraBolinha();
  movimentaBolinha();
  mostraRaquete(xRaquete, yRaquete);
  movimentaMinhaRaquete();
  colisaoBorda ();
  verificaColisaoRaquete ();
  colisaoRaqueteBiblioteca(xRaquete, yRaquete);
  mostraRaquete(xRaqueteOponente,yRaqueteOponente);
  movimentaOponente ();
  colisaoRaqueteBiblioteca(xRaqueteOponente, yRaqueteOponente);
}

//Aqui crio a colisão baixada da biblioteca
function colisaoRaqueteBiblioteca (x, y){
  colidiu = 
  collideRectCircle(x,y,raqueteComp,raqueteAlt,xBolinha,yBolinha,raio);
  if (colidiu){
  velocidadeXBolinha *= -1;
  }
}
13 respostas

Acho que consegui consertar esse bug acrescentando a seguinte linha:

  if (yBolinha - raio < yRaquete + raqueteAlt && yBolinha + raio > yRaquete && xBolinha - raio < xRaquete + raqueteComp){
    velocidadeYBolinha *= -1;
  }

Esse problema foi resolvido, mas surgiu outro: agora, toda vez que encosta na minha raquete, a bolinha volta para o mesmo sentido de onde veio. Como consertar?

Fala ai Roberto, tudo bem? Tentei simular o problema com seu primeiro código, mas, ele deu erro por conta da biblioteca para verificar colisão.

Sendo assim, posso pedir um favor? Compartilhe o link do seu projeto, assim eu consigo abrir ele por aqui, simular o problema e analisá-lo com mais calma.

Fico no aguardo.

Ei Matheus,

É esse aqui: https://editor.p5js.org/robertogouvea/sketches/TcQPvL9Q5

Oi Roberto, então... tem um outro rapaz que desenvolveu uma solução bem criativa mas 100% não vi nenhum rsrsrs.

Na função setup ele adicionou: inicio() e criou a função inicio colocando a bolinha no meio do campo de novo. Vou deixar o link pras duas versões.

Minha versão: https://editor.p5js.org/Laino/full/Dan4Jf0u9 Código: https://cursos.alura.com.br/forum/topico-minha-versao-do-jogo-100627

Código do outro rapaz: https://cursos.alura.com.br/forum/topico-outra-ideia-para-deixar-o-jogo-mais-interessante-96880

Fala ai Roberto, tudo bem? Dei uma olhada no projeto, o problema é porque você tinha bastante funções que verifica colisão e elas estavam sendo chamados no seu draw.

O ideal é existe apenas uma função e ela seja chamada uma vez (para suas raquetes e uma para a do oponente).

Fiz algumas alterações no código:

//Variáveis da Bolinha
let xBolinha = 300;
let yBolinha = 200;
let diametro = 26;
let raio = diametro/2;
let velocidadeXBolinha = 6;
let velocidadeYBolinha = 6;

//variáveis da raquete
let xRaquete = 5;
let yRaquete = 150;
let raqueteComp = 20;
let raqueteAlt = 90;
let colidiu = false;

//variáveis do oponente
let xRaqueteOponente = 575;
let yRaqueteOponente = 150;
let velocidadeYOponente;

//placar do jogo
let meusPontos = 0;
let pontosDoOponente = 0;

//Aqui eu defino o que é a Bolinha:
function mostraBolinha (){
  circle (xBolinha, yBolinha, diametro);
}

//Aqui eu defino o movimento da Bolinha:
function movimentaBolinha (){
  xBolinha += velocidadeXBolinha;
  yBolinha += velocidadeYBolinha;
}

//Aqui defino o que são as raquetes:
 function mostraRaquete (x, y){ 
  rect (x, y, raqueteComp, raqueteAlt);
 }

//Aqui defino o movimento da Raquete:
function movimentaMinhaRaquete (){
  if (keyIsDown(UP_ARROW)){
    yRaquete -=10;
  }
  if (keyIsDown(DOWN_ARROW)){
    yRaquete +=10;
  }
}

//Aqui defino o movimento do Oponente. 
function movimentaOponente (){
  velocidadeYOponente = yBolinha -yRaqueteOponente -raqueteComp /2 - 30;
  yRaqueteOponente += velocidadeYOponente;
}

//Aqui defino a colisão da raquete com a bolinha

function verificaColisaoRaquete(x, y) {
    colidiu = collideRectCircle(x, y, raqueteComp, raqueteAlt, xBolinha, yBolinha, raio);
    if (colidiu){
        velocidadeXBolinha *= -1;
    }
}

//Aqui eu defino a colisão das bordas da tela:
function colisaoBorda () {

    //Aqui é criado a colisão na horizontal, eixo X, com as paredes. 
  if (xBolinha > width-raio ||
     xBolinha < raio){
    velocidadeXBolinha *= -1;
  }


  //Aqui é criado a colisão vertical, eixo Y, com o teto e o chão. 
  if (yBolinha > height-raio ||
     yBolinha < raio){
    velocidadeYBolinha *= -1;
  }
}


function incluiPlacar (){
  fill (255);
  text(meusPontos, 278, 26);
  text(pontosDoOponente, 321, 26);
}

function marcaPonto (){
  if (xBolinha > 587) {
  meusPontos += 1;
  }
  if (xBolinha < 13) {
  pontosDoOponente += 1;
  }
}
//Aqui é criada as dimensões da "tela" que será trabalhada. 


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

//Aqui se cria todas as funções. 

function draw() {
  background(0);
  mostraBolinha();
  movimentaBolinha();
  mostraRaquete(xRaquete, yRaquete);
  movimentaMinhaRaquete();
  colisaoBorda ();
  verificaColisaoRaquete(xRaqueteOponente, yRaqueteOponente);
  verificaColisaoRaquete(xRaquete, yRaquete);
  mostraRaquete(xRaqueteOponente,yRaqueteOponente);
  movimentaOponente ();
  incluiPlacar();
  marcaPonto();
}

Provavelmente o problema deva ser resolvido.

Espero ter ajudado.

Fala ai Roberto, tudo bem? Dei uma olhada no projeto, o problema é porque você tinha bastante funções que verifica colisão e elas estavam sendo chamados no seu draw.

O ideal é existe apenas uma função e ela seja chamada uma vez (para suas raquetes e uma para a do oponente).

Fiz algumas alterações no código:

//Variáveis da Bolinha
let xBolinha = 300;
let yBolinha = 200;
let diametro = 26;
let raio = diametro/2;
let velocidadeXBolinha = 6;
let velocidadeYBolinha = 6;

//variáveis da raquete
let xRaquete = 5;
let yRaquete = 150;
let raqueteComp = 20;
let raqueteAlt = 90;
let colidiu = false;

//variáveis do oponente
let xRaqueteOponente = 575;
let yRaqueteOponente = 150;
let velocidadeYOponente;

//placar do jogo
let meusPontos = 0;
let pontosDoOponente = 0;

//Aqui eu defino o que é a Bolinha:
function mostraBolinha (){
  circle (xBolinha, yBolinha, diametro);
}

//Aqui eu defino o movimento da Bolinha:
function movimentaBolinha (){
  xBolinha += velocidadeXBolinha;
  yBolinha += velocidadeYBolinha;
}

//Aqui defino o que são as raquetes:
 function mostraRaquete (x, y){ 
  rect (x, y, raqueteComp, raqueteAlt);
 }

//Aqui defino o movimento da Raquete:
function movimentaMinhaRaquete (){
  if (keyIsDown(UP_ARROW)){
    yRaquete -=10;
  }
  if (keyIsDown(DOWN_ARROW)){
    yRaquete +=10;
  }
}

//Aqui defino o movimento do Oponente. 
function movimentaOponente (){
  velocidadeYOponente = yBolinha -yRaqueteOponente -raqueteComp /2 - 30;
  yRaqueteOponente += velocidadeYOponente;
}

//Aqui defino a colisão da raquete com a bolinha

function verificaColisaoRaquete(x, y) {
    colidiu = collideRectCircle(x, y, raqueteComp, raqueteAlt, xBolinha, yBolinha, raio);
    if (colidiu){
        velocidadeXBolinha *= -1;
    }
}

//Aqui eu defino a colisão das bordas da tela:
function colisaoBorda () {

    //Aqui é criado a colisão na horizontal, eixo X, com as paredes. 
  if (xBolinha > width-raio ||
     xBolinha < raio){
    velocidadeXBolinha *= -1;
  }


  //Aqui é criado a colisão vertical, eixo Y, com o teto e o chão. 
  if (yBolinha > height-raio ||
     yBolinha < raio){
    velocidadeYBolinha *= -1;
  }
}


function incluiPlacar (){
  fill (255);
  text(meusPontos, 278, 26);
  text(pontosDoOponente, 321, 26);
}

function marcaPonto (){
  if (xBolinha > 587) {
  meusPontos += 1;
  }
  if (xBolinha < 13) {
  pontosDoOponente += 1;
  }
}
//Aqui é criada as dimensões da "tela" que será trabalhada. 


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

//Aqui se cria todas as funções. 

function draw() {
  background(0);
  mostraBolinha();
  movimentaBolinha();
  mostraRaquete(xRaquete, yRaquete);
  movimentaMinhaRaquete();
  colisaoBorda ();
  verificaColisaoRaquete(xRaqueteOponente, yRaqueteOponente);
  verificaColisaoRaquete(xRaquete, yRaquete);
  mostraRaquete(xRaqueteOponente,yRaqueteOponente);
  movimentaOponente ();
  incluiPlacar();
  marcaPonto();
}

Provavelmente o problema deva ser resolvido.

Espero ter ajudado.

Ei Matheus, obrigado por me ajudar!

Mas fui testar seu código e ainda está com o tal "bug". Quando a bolinha se choca com a parte superior da raquete, ela "entra" dentro da raquete (ou melhor dizendo, ela fica presa entre a raquete e a parede).

Para exemplificar melhor, até tirei um print da tela, olha só: https://imgur.com/U5mpa9x

Por isso até criei aquele código doido que a bolinha volta pelo eixo Y também. Mas queria isso apenas na parte superior, não na lateral da raquete.

Estranho Roberto, testei os códigos novamente e aqui está funcionando certinho:

https://editor.p5js.org/mahenrique94/sketches/4HFzMqulb

Dá uma olhada.

Então Matheus, peguei esse seu link que você mandou e fui testar. Olha só:

https://imgur.com/a/JkpHYi5

Agora eu entendi o problema Roberto, não tinha pegado a ideia do mesmo.

Como não manjo muito sobre desenvolvimento de games, vou pedir para o Guilherme (instrutor do curso) dar um help.

Abraços e bons estudos.

solução!

Fala Roberto, como vai?

Antes de tudo, Parabéns pelo seu projeto e por compartilhar o seu código. Em relação a este comportamento, sugiro uma solução simples mas que funciona:

  • Quando houver colisão com alguma raquete, invertemos a direção com velocidadeXBolinha *= -1;. Porém, para a bolinha não ficar pressa na raquete, podemos alterar o xBolinha para o lado oposto que esta se movendo. Por isso a verificação if (xBolinha > 500). Segue o código:
function colisaoRaqueteBiblioteca(x, y){
  colidiu = collideRectCircle(x,y,raqueteComp,raqueteAlt,xBolinha,yBolinha,raio);
  if (colidiu){
    velocidadeXBolinha *= -1;
    if (xBolinha > 500){
          xBolinha -= 10
    } else {
          xBolinha += 10
    }
  }
}

Além disso, tenha certeza qual verificação está executando draw:

function draw() {
  background(0);
  mostraBolinha();
  movimentaBolinha();
  mostraRaquete(xRaquete, yRaquete);
  movimentaMinhaRaquete();
  colisaoBorda();
  //verificaColisaoRaquete();
  colisaoRaqueteBiblioteca(xRaquete, yRaquete);
  mostraRaquete(xRaqueteOponente,yRaqueteOponente);
  movimentaOponente();
  colisaoRaqueteBiblioteca(xRaqueteOponente, yRaqueteOponente);
  incluiPlacar();
  marcaPonto();
}

Segue o link do projeto

Peço por gentileza que realize essas alteração e faça um novo teste, nos dizendo se deu certo. Vale dar uma olhada nos projetos que o Lucas compartilhou também.

Abraço e bons estudos!

: )

Ei Guilherme, boa noite!

Agora resolveu o problema do bug! Muito obrigado!

E obrigado você também, Matheus!

Magina Roberto, sempre que precisar não deixe de criar suas duvidas.

Abraços e bons estudos.