1
resposta

duvida com o js

Estou tentado fazer o exercício com o js dom, ao invés de utilizar o canvas, eu criei uma "div" para fazer referência ao jogo. Montei o código abaixo, porém não sei como implementar a colisão, o personagem está se movimentando e os carros também, (obs.: eu só preciso da colisão). Eu até tive uma ideia a qual coloquei como comentário na última linha, se alguém puder me ajudar a desvendar o "mistério da colisão", eu agradeço muito:

let gameWindow = document.querySelector(".gameWindow");

let jogador = document.createElement("div");
jogador.id = "jogador";
jogador.classList.add("jogador");
let playerPositionY = 460;
let playerPositionX = 385;
jogador.style.top = playerPositionY + "px";
jogador.style.left = playerPositionX + "px";
gameWindow.appendChild(jogador);
let velocity = 5;
let y = 0;

document.addEventListener("keydown", (event)=>{
    const keyName = event.key;
    switch(keyName){
        case "ArrowUp":
            y--;
            vertical();
            break;
        case "ArrowDown":
            y++;
            vertical();
            break;
    }
})

let arr = [];

let carro1PosicaoX = 700;
let carro1PosicaoY = 130;

let carro1 = document.createElement("div");
carro1.classList.add("carro1")
carro1.style.top = carro1PosicaoY + "px";
carro1.style.left = carro1PosicaoX + "px";
gameWindow.appendChild(carro1);

let carro2PosicaoX = 350;
let carro2PosicaoY = 270;

let carro2 = document.createElement("div");
carro2.classList.add("carro2")
carro2.style.top = carro2PosicaoY + "px";
carro2.style.left = carro2PosicaoX + "px";
gameWindow.appendChild(carro2);

// let carro3PosicaoX = 700;
let carro3PosicaoY = 400;
let carro3PosicaoX = 0;
let carro3 = document.createElement("div");
carro3.classList.add("carro3")
carro3.style.top = carro3PosicaoY + "px";
carro3.style.left = carro3PosicaoX + "px";
gameWindow.appendChild(carro3);

let dx1 = 1;
let dx2 = 1;
let dx3 = 1;
let velocityCarro1 = 4;
let velocityCarro2 = 4;
let velocityCarro3 = 4;

function moveCar1(){

    carro1PosicaoX+=(dx1*velocityCarro1);

    carro1.style.left = carro1PosicaoX + "px";

    if(carro1PosicaoX > 720){
        dx1 = -1;
    } else if (carro1PosicaoX <30){
        dx1 = 1;
    }
    anima = requestAnimationFrame(moveCar1);
}

window.requestAnimationFrame(moveCar1);

function moveCar2(){

    carro2PosicaoX+=(dx2*velocityCarro2);

    carro2.style.left = carro2PosicaoX + "px";

    if(carro2PosicaoX > 720){
        dx2 = -1;
    } else if (carro2PosicaoX <30){
        dx2 = 1;
    }
    anima = requestAnimationFrame(moveCar2);
}

window.requestAnimationFrame(moveCar2);

function moveCar3(){

    carro3PosicaoX+=(dx3*velocityCarro3);

    carro3.style.left = carro3PosicaoX + "px";

    if(carro3PosicaoX > 600){
        dx3 = -1;
    } else if (carro3PosicaoX < 30){
        dx3 = 1;
    }
    anima = requestAnimationFrame(moveCar3);
}

window.requestAnimationFrame(moveCar3);

function vertical(){
    movePlayerY = velocity * y + playerPositionY;
    jogador.style.top = movePlayerY + "px";
    arr.push(movePlayerY)
    console.log(arr)
}

// O que eu tenho que fazer é criar um array que verifique se existe algum carro que esteja na posição x quando o personagem estiver na posição y, se as duas posições forem iguais (posiçãoCarroX == posiçãoJogadorY), então quer dizer que o carro conseguiu colidir com o jogador, para que possamos verificar se isso está ocorrendo devemos criar um array que sempre marca a posição do jogador e a posição dos carros, quando houver a coincidência, haverá a colisão, se não houver, o jogador ganha um ponto, se houver o jogador perde um ponto.

1 resposta

Boa tarde Tiago, tudo certo?

Vou escrever aqui uma pequena explicação e implementação de como podemos resolver o problema de colisões entre dois corpos retangulares e em duas dimensões. Caso queira ver outros casos, recomendo olhar a implementação da biblioteca collide2D do P5.js.

Inclusive, eu sugiro utilizar bibliotecas como o próprio P5.js para te auxiliar com algumas funções de distância e outros métodos auxiliares, mas vou tentar não utilizar muitos conceitos dessas bibliotecas aqui.

Vamos criar uma função que vai receber os seguintes parâmetros e dar os seguintes nomes daqui em diante:

Significado do parâmetroNome do parâmetro na função
Coordenada X do primeiro corpox1
Coordenada Y do primeiro corpoy1
Altura do primeiro corpoa1
Largura do primeiro corpol1
Coordenada X do segundo corpox2
Coordenada Y do segundo corpoy2
Altura do segundo corpoa2
Largura do segundo corpol2

Então não vai importar para essa função quais são esses corpos, apenas basta que eles tenham um par de coordenadas, sejam retangulares e tenham um comprimento e largura. Então como é a função em si que vai verificar se existe ou não uma colisão? Vamos lá:

Considerando que para os navegadores o eixo X cresce da esquerda para a direita, e que o eixo Y cresce de cima para baixo, podemos fazer os seguintes testes:

Diagrama mostrando o sistema de coordenadas começando na origem (0,0) e crescendo em X para a direita e em Y para baixo. Um retângulo verde dentro do sistema com coordenada no canto superior direito equivalente à (x1,y1) , altura a1 e largura l1. Um retângulo laranja dentro do sistema com coordenada no canto superior direito equivalente à (x2,y2) , altura a2 e largura l2

Teremos um caso de colisão quando um dos cantos de cada retângulo estiver dentro da área interna ao outro retângulo, sendo assim podemos verificar se as seguintes condições são verdadeiras:

CondiçãoSignificado
x1 + l1 >= x2A lateral direita do retângulo verde passou da lateral esquerda do retângulo laranja
x1 <= x2 + l2A lateral esquerda do retângulo verde passou da lateral direita do retângulo laranja
y1 + a1 >= y2A lateral do topo do retângulo verde passou da lateral inferior do retângulo laranja
y1 <= y2 + a2A lateral inferior do retângulo verde passou da lateral superior do retângulo laranja

Caso não tenha ficado claro instantaneamente, não se preocupe! Precisamos de um tempo para internalizar essas informações e entender essas relações. Eu sugiro fazer vários desenhos e realmente brincar com esses parâmetros para tentar internalizar melhor essas relações. Isso leva um certo tempo e é completamente normal. E também recomendo buscar por outras fontes, pois existem diversos outros tópicos e conteúdos sobre o assunto e ver essas perspectivas diferentes podem te ajudar no processo.

Então agora vamos implementar a função que vai fazer essa verificação:

function detectaColisao( x1, y1, l1, a1, x2, y2, l2, a2){
    if ( x1 + l1 >= x2 &&
            x1 <= x2 + l2 &&
            y1 + h1 >= y2 &&
            y1 <= y2 + h2) {
                return true;
            }
            else {
                return false;
            }
}

Sendo assim, agora basta você inserir a função no código e utilizar os parâmetros da forma como foram passados. As detecções de colisão são o tipo de problema que parecem triviais mas têm certos "truques" por trás, então qualquer dúvida é completamente normal e estarei feliz de tentar contribuir mais.

Espero ter ajudado e bons estudos!