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

Jogo com colisão

Estou acompanhando a vídeo aula de Lógica de Programação II, a parte do jogo. Tentei avançar um pouco mais e fazer um joguinho de colisão: assim que a bolinha tocar o quadrado, aparecerá o alerta de game over. Minha dúvida é: como faço essa parte de colisão?

<canvas width="600" height="400"></canvas>

<script>

    var tela = document.querySelector('canvas');
    var pincel = tela.getContext('2d');

    pincel.fillStyle = 'lightblue';
    pincel.fillRect(0, 0, 600, 400);

    var x = 30;
    var y = 20;

    //Códigos do teclado:
    var esquerda = 37;
    var cima = 38;
    var direita = 39;
    var baixo = 40;

    //Taxa de incremento:
    var taxa = 5;
    var colisao = desenhaQuadrado;

    function desenhaQuadrado() {

        pincel.fillStyle = 'blue';
        pincel.beginPath();
        pincel.fillRect(50, 50, 50, 50);
        pincel.fillStroke = 'black';
        pincel.strokeRect(50, 50, 50, 50);

    }


    function desenhaBolinha(x, y, raio) {

        pincel.fillStyle = 'black';
        pincel.beginPath();
        pincel.arc(x, y, raio, 0, 2 * Math.PI);
        pincel.fill();

    }


    function limpaTela() {

        pincel.clearRect(0, 0, 600, 400);

    }


    function atualizaTela() {

        limpaTela();
        desenhaBolinha(x, y, 10);
        desenhaQuadrado();
    }

    setInterval(atualizaTela, 20);

    function setasDoTeclado(evento) {

        if(evento.keyCode == cima) {

            y = y - taxa;

        } else if (evento.keyCode == baixo) {

            y = y + taxa;

        } else if (evento.keyCode == esquerda) {

            x = x - taxa;

        } else if (evento.keyCode == direita) {

            x = x + taxa;

        }
    }

    if(desenhaBolinha == colisao) {

        alert('Você perdeu');

    }

    document.onkeydown = setasDoTeclado;

</script>
2 respostas
solução!

Oi André, tudo bom?

Existem muitas maneiras de se fazer colisão entre dois objetos em um jogo, No seu caso você está querendo verificar a colisão entre uma bola e um quadrado, antes de chegar lá vamos pensar em um caso mais simples.

Se eu pego a posição do mouse dentro da tela e quero saber se o mouse está colidindo com um quadrado, como eu faço isso?

Bom, para o mouse estar colidindo com o quadrado, a posição do mouse deve estar dentro da posição do quadrado.

Como um quadrado representa uma região da tela podemos verificar se a posição X do mouse está dentro do intervalo X que o quadrado ocupa. É importante no nosso código manter cada função com uma única responsabilidade. Ou seja, precisamos de uma função que apenas calcule a colisão entre um ponto e um quadrado.

function pontoEstaColidindoComQuadrado(pontoX, pontoY, quadradoX, quadradoY, quadradoAltura, quadradoLargura ){

    if(pontoX>quadradoX && pontoX< QuadradoX+QuadradoLargura ){
        //O ponto está dentro do intervalo X do quadrato
        return true;
    }
    return false;
}

Para conseguirmos reutilizar essa função em vários pontos do nosso código vamos passa por parâmetro todas as informações necessárias para a colisão. Com essas informação conseguimos verificar se o pontoX está dentro do intervalo do quadrado.

Até esse pontos, estamos verificando apenas o eixo X e isso significa que podemos retornar verdadeiro mesmo se o mouse estiver para baixo ou para cima do quadrado. Precisamos então verificar as informações para o eixo Y. A colisão só acontece quando o mouseX e o mouseY estiverem dentro do quadrado, vamos fazer o segundo if dentro do primeiro.

function pontoEstaColidindoComQuadrado(pontoX, pontoY, quadradoX, quadradoY, quadradoAltura, quadradoLargura ){

    if(pontoX>quadradoX && pontoX< quadradoX+quadradoLargura ){
        //O ponto está dentro do intervalo X do quadrato
        if(pontoY>quadradoY && pontoY< quadradoY+quadradoAltura){
            //o ponto também está dentro do intervalo Y do quadrado
            return true;        
        }
    }
    return false;
}

Agora sim, só vamos retornar verdadeiro quando o ponto que passamos por parâmetro para essa função estiver dentro do quadrado e nesse caso eles estão colidindo.

Como você tem um circulo e quer verificar a colisão dele com um quadrado podemos usar o ponto em que esse circulo está sendo desenhado, mas nesse caso o seu aviso só vai aparecer quando o centro do circulo encostar no quadrado.

Acontece que nós sabemos o raio desse circulo então podemos pegar alguns pontos do perímetro do circulo e verificar eles. Para pegar esses pontos só precisamos pegar o centro do circulo e somar/subtrair o raio no X e no Y e fazer a verificação desses pontos.

function atualizaTela() {
        limpaTela();
        desenhaBolinha(x, y, 10);
        desenhaQuadrado();

    if(pontoEstaColidindoComQuadrado(x+10, y, quadradoX, quadradoY, quadradoAltura, quadradoLargura )){
        //game over
    }
    if(pontoEstaColidindoComQuadrado(x-10, y, quadradoX, quadradoY, quadradoAltura, quadradoLargura )){
        //game over
    }
    if(pontoEstaColidindoComQuadrado(x, y + 10, quadradoX, quadradoY, quadradoAltura, quadradoLargura )){
        //game over
    }
    if(pontoEstaColidindoComQuadrado(x, y-10, quadradoX, quadradoY, quadradoAltura, quadradoLargura )){
        //game over
    }

}

Espero ter ajudado, qualquer duvida manda aqui :)

Obrigado, me ajudou baste.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software