Solucionado (ver solução)
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.