Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Problemas para jogar um dado obtido por "input" dentro do "setInterval"

Colegas, boa tarde!

Tentando dar uma incrementada no jogo de tiro ao alvo proposto no curso, tentei incluir uma variável de interação com o usuário que determinaria a "dificuldade" do jogo. Tentei jogar essa variável dentro da função setInterval para determinar a velocidade de repetição, entretanto o dado parece ser ignorado e a repetição ocorre de forma frenética, não importando o número que estou inserindo no HTML. Talvez o setInterval não suporte esse tipo de entrada, mas aguardo o retorno de vocês para confirmar.

Abraços e bom domingo a todos!

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

<br>
Escolha o nível de dificuldade: 1000 = molezinha
                                700 = Faroeste
                                500 = Ninja do tiro
                                300 = Super Saiyajin
                                <input type= "number" class="dificuldade">

<script>

    var tela = document.querySelector('canvas');
    var pincel = tela.getContext('2d');
    var xAleatorio;
    var yAleatorio;
    var input = document.querySelector(".dificuldade");

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

    var raio = 10;

    function desenhaCirculo(x, y, raio, cor) {

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

    function limpaTela() {

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

    function desenhaAlvo(x, y){

        desenhaCirculo(x, y, raio + 20, 'red'); // maior círculo
        desenhaCirculo(x, y, raio + 10, 'white');
        desenhaCirculo(x, y, raio, 'red'); // menor circulo
        }

    function sorteiaPosicao(maximo) {
            return Math.floor(Math.random() * maximo);

    }

    function atualizaTela(){
        xAleatorio = sorteiaPosicao(600);
        yAleatorio = sorteiaPosicao(400);

        limpaTela();

        desenhaAlvo(xAleatorio, yAleatorio);
    }

    setInterval(atualizaTela, input.value);


    function dispara(evento) {

        var x = evento.pageX - tela.offsetLeft;
        var y = evento.pageY - tela.offsetTop;

        if (x > xAleatorio - raio 
            && x < xAleatorio + raio 
                && y > yAleatorio - raio 
                    && y < yAleatorio + raio) {

            alert("Pow! Você acertou!");

        }
        }


    tela.onclick = dispara;

</script>
1 resposta
solução!

Oi Vinícius,

O problema é que quando o seu script é executado, o input ainda não foi preenchido. A primeira coisa a se fazer é dar um valor padrão para o input, digamos 1000.

<input type= "number" class="dificuldade" value="1000">

Isso faz com que ele comece com uma velocidade melhor, mas ainda não conseguimos escolher nada. Dessa forma, quando a linha

setInterval(atualizaTela, input.value);

for executada, nós temos um valor razoável.

Queremos poder mudar o valor da frequência de atualização da tela. Mas quando? Ora, quando mudarmos o valor do input. Portanto podemos adicionar, além do setInterval, o seguinte código

input.onchange = function () {
    setInterval(atualizaTela, input.value);
}

Semelhante ao tela.onclick, nós queremos chamar a função setInterval sempre que o valor do input for modificado.

Perceba que uma vez que setInterval foi chamada, nós vamos ficar chamando a função atualizaTela a cada input.value milisegundos. Se nós chamarmos setInterval com outro valor, nós não vamos parar de atualizar com a frequência anterior e teremos a tela sendo atualizada com duas frequências diferentes. Portanto a primeira coisa a se fazer é ignorar o último setInterval para fazer um novo. Para isso, temos a função clearInterval, que precisa receber um parâmetro: o id do intervalo que queremos limpar. Esse valor é retornado pela própria função setInterval. Ficamos com o código dessa forma

var intervalo = setInterval(atualizaTela, input.value);
input.onchange = function () {
    clearInterval(intervalo);
    intervalo = setInterval(atualizaTela, input.value);
}

Agora, sempre que o valor do input mudar, mudaremos a frequência de atualização da tela. Não se esqueça de apertar Enter depois que mudar o valor!