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

como manter a velocidade de execução constante

eu estou tentando fazer um jogo de asteroides bem simples, mas eu queria que a velocidade dos asteroides fosse constante, só que em algumas execuções a velocidade sobe algumas vezes em relação à velocidade que eu queria

aqui está o código:

<canvas id = 'tela' width = 1528 height = 706></canvas>
<script>
    var pincel = document.getElementById('tela').getContext('2d');
    function desenhaFoguete(cor, tamanho) {
        //esses dois comandos giram as coordenadas do canvas inteiro ao redor do foguete
        pincel.translate(xFoguete, yFoguete);
        pincel.rotate(angulo * Math.PI / 180);
        //desenhando foguete
        pincel.fillStyle = cor;
        pincel.beginPath();
        pincel.moveTo(-5 * tamanho, -5 * tamanho);
        pincel.lineTo(5 * tamanho, 15 * tamanho);
        pincel.lineTo(15 * tamanho, 5 * tamanho);
        pincel.lineTo(-5 * tamanho, -5 * tamanho);
        pincel.fill();
        //fazendo as coordenadas do cavas voltarem ao normal
        pincel.rotate(-angulo * Math.PI / 180);
        pincel.translate(-xFoguete, -yFoguete);
    }
    function desenhaAsteroide(x, y) {
        pincel.fillStyle = 'brown';
        pincel.beginPath();
        pincel.arc(x, y, 20, 0, Math.PI * 2);
        pincel.fill();
    }
    function criaAsteroide() {
        //decide um lugar da borda da tela pro asteroide aparecer
        var decideParede = Math.random() * 4;
        var x;
        var y;
        var Vx;
        var Vy;
        if(decideParede < 1) {
            x = -764;
            y = Math.random() * 706 - 353;
        } else if(decideParede < 2) {
            x = Math.random() * 1528 - 764;
            y = -353;
        } else if(decideParede < 3) {
            x = 764;
            y = Math.random() * 706 - 353;
        } else {
            x = Math.random() * 1528 - 764;
            y = 353;
        }
        //cria um direção aleatória para o asteroide se mover
        Vx = - x / 150 + Math.random();
        Vy = - y / 150 + Math.random();
        setInterval(function() {
            //apaga o "rastro" do asteroide
            pincel.fillStyle = 'white';
            pincel.beginPath();
            pincel.arc(x + 764, y + 353, 21, 0, Math.PI * 2);
            pincel.fill();
            //muda os valores de x e y
            x += Vx;
            y += Vy;
            //testa se o asteroide passou da borda e teletransporta pra outra
            if(Math.abs(x) > 784) {
                x *= -1;
            }
            if(Math.abs(y) > 373) {
                y *= -1;
            }
            //testa colisão e imprime mensagem de derrota
            if(Math.hypot(x - xFoguete + 764, y - yFoguete + 353) <= 25) {
                //atualiza o recorde
                if(segundos > localStorage.getItem('recorde'))
                    localStorage.setItem('recorde', segundos);
                if(!perdeu) {
                    //escreve mensagem de derrota
                    document.write('<h1>VOCÊ PERDEU!</h1>');
                    document.write('<h3>você sobreviveu por ' + segundos + ' segundos</h3>');
                    document.write('o seu recorde é ' + localStorage.getItem('recorde') + ' segundos');
                    perdeu = true;
                }
            }
            //desenha asteroide e foguete
            desenhaAsteroide(x + 764, y + 353);
            desenhaFoguete('yellow', 1);
        }, 10);
    }
    function moveFoguete() {
        //para apagar o "rastro" do foguete
        desenhaFoguete('white', 1.4);
        if(event.keyCode == 38) { // se pressionar seta para baixo ou para cima move o foguete
            //essas contas complicadas é para ir na direção certa
            xFoguete -= (Math.cos(angulo * Math.PI / 180) - Math.sin(angulo * Math.PI / 180)) * 5;
            yFoguete -= (Math.sin(angulo * Math.PI / 180) + Math.cos(angulo * Math.PI / 180)) * 5;
        }
        if(event.keyCode == 40) {
            xFoguete += (Math.cos(angulo * Math.PI / 180) - Math.sin(angulo * Math.PI / 180)) * 5;
            yFoguete += (Math.sin(angulo * Math.PI / 180) + Math.cos(angulo * Math.PI / 180)) * 5;
        }
        if(event.keyCode == 39) // se pressionar seta para esquerda ou para direita gira o foguete
            angulo += 6;
        if(event.keyCode == 37)
            angulo -= 6;
        if(xFoguete > 1528 || xFoguete < 0) // se passar da borda da tela aparece na outra borda
            xFoguete = Math.abs(xFoguete - 1528);
        if(yFoguete > 706 || yFoguete < 0)
            yFoguete = Math.abs(yFoguete - 706);
    }
    //verifica se o localstorage recorde existe, e se não existir cria um
    if(typeof localStorage.getItem('recorde') == 'object')
        localStorage.setItem('recorde', 0);
    var xFoguete = 764;
    var yFoguete = 353;
    var angulo = 45;
    var segundos = 0;
    var perdeu = false;
    //cria os asteroides
    for(var i = 1;i <= 5;i++) {
        criaAsteroide();
    }
    setInterval(criaAsteroide, 5000)
    //conta quantos segundos se passaram até o jogador perder
    setInterval(function() {segundos += 0.1;segundos = Math.round(segundos * 10) / 10}, 100)
    document.onkeydown = moveFoguete;
</script>

eu pesquisei um pouco e um site (https://stackoverrun.com/es/q/208974) diz que o setinterval e settimeout de uma pag afeta o das outras e que é para dar nomes bem aleatórios para as funções e variáveis, tipo ௹૱৲৳֏¢¥£, mas isso pioraria muito o entendimento do código e seria extremamente dificil resolver bugs ou fazer atualizações no sistema

esse código tem algumas funcionalidades não vistas ao longo do curso, então podem perguntar o que cada coisa faz

3 respostas

Olá Gabriel, tudo bem com você??

Eu achei muito interessante a sua proposta!

Entendo a questão de legibilidade e preocupação com isso que você colocou referente as variáveis. Uma opção para manter isso e ainda assumir nomes não tão interessantes, seria comentar no código ao lado, justificando as opções escolhidas e facilitando o entendimento do mesmo.

Eu não possuo conhecimento suficiente para te direcionar com relação a funções de JS e essas variações em navegadores, mas irei acompanhar a discussão aberta aqui e espero que a minha sugestão seja interessante diante desse problema mencionado.

Obrigado por compartilhar conosco seu projeto e sinta-se sempre à vontade para retornar aqui no fórum e tirar suas dúvidas. Vou comentar sobre o seu post com uma galera fera em JS e ver o que eles trazem de conteúdo para te auxiliar!

Bons estudos!

Obrigado Victor, vou tentar fazer o sugerido por você

solução!

bem, eu consegui resolver de um jeito mais simples, parece que eu estava fazendo UM MONTE de setInterval ao mesmo tempo, e isso deixava a execução instável eu resolvi esse problema dos setIntervals reescrevendo o programa do 0 com oo, que suporta polimorfismo, coisa mais difícil de fazer com os métodos que eu estava usando e como as coisas ficaram mais simples eu pude adicionar umas coisas, como colisões matematicamente rigorosas, tiros que destroem os asteroides e colisões entre os asteroides para eles não ficarem um em cima do outro