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

Porque quando eu clico várias vezes o botão os círculos começam a se mover mais rápido?

Acredito eu que deva ser algo relacionado ao setInterval, mas o que exatamente?

<canvas width="500" height="500"></canvas>
<br>
<button>Mover aleatoriamente!</button>
<script>

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

    pincel.fillStyle = '#85FDAB';
    pincel.fillRect(0, 0, 500, 500);

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

    function limpaTela() {
        pincel.fillStyle = '#85FDAB';
        pincel.fillRect(0, 0, 500, 500);
    }

    function andarParaDireita(circulo) {
        limpaTela();
        desenharCirculo(x[circulo], y[circulo], cor[circulo], raio);
        x[circulo]++;
        for(var i = 0; i < qtdCirculos; i++) {
            desenharCirculo(x[i], y[i], cor[i], raio);
        }
        if(x[circulo]==500-raio) {
            cor[circulo] = corAleatoria();
            direcoes[circulo] = 'esquerda';
        }
    }

    function andarParaEsquerda(circulo) {
        limpaTela();
        desenharCirculo(x[circulo], y[circulo], cor[circulo], raio);
        x[circulo]--;
        for(var i = 0; i < qtdCirculos; i++) {
            desenharCirculo(x[i], y[i], cor[i], raio);
        }
        if(x[circulo]==raio) {
            cor[circulo] = corAleatoria();
            direcoes[circulo] = 'direita';
        }

    }

    function moverCirculo() {
        for(var i = 0; i < qtdCirculos; i++) {
            if(direcoes[i] == 'direita') {
                andarParaDireita(i);
            } 
            if(direcoes[i] == 'esquerda') {
                andarParaEsquerda(i);
            }
        }
    }

    function preencherCoresAleatorias() {
        var cores = [];
        for(var i=0; i < qtdCirculos; i++) {
            cores.push(corAleatoria());
        }
        return cores;
    }

    function corAleatoria() {
        return cores[Math.round(Math.random()*5)];
    }

    function preencherXInicial() {
        var x = [];
            for(var k = 30, i = 0; i < qtdCirculos; i++, k = k + 20) {
                x.push(k);
            }
        return x;
    }

    function preencherYInicial() {
        var x = [];
            for(var k = 30, i = 0; i < qtdCirculos; i++, k = k + 50) {
                x.push(k);
            }
        return x;
    }

    function preencherDirecoesIniciais() {
        var direcoes= [];
        for(var i = 0; i < qtdCirculos; i++) {
            direcoes[i] = direcaoAleatoria();
        }
        return direcoes;
    }

    function direcaoAleatoria() {
        return direcaoPermitida[Math.round(Math.random())];
    }
    var direcaoPermitida = ['direita', 'esquerda'];
    var qtdCirculos = 10;
    var cores = ['blue', 'red', 'purple', 'green', 'yellow', 'orange'];
    var x = preencherXInicial();
    var y = preencherYInicial();
    var cor = preencherCoresAleatorias();
    raio = 20;
    var direcoes = preencherDirecoesIniciais();

    var button = document.querySelector('button');

    var atualizacaoFrame = setInterval(moverCirculo, 5);

    button.onclick = function() {
        direcoes = preencherDirecoesIniciais();
        var atualizacaoFrame = setInterval(moverCirculo, 5);
    }
</script>
2 respostas

Olá Danilo. O problema estava ocorrendo porque a função 'moverCirculo()' estava sendo chamada repetidamente com um intervalo de 5 milissegundos ('setInterval(moverCirculo, 5)') a cada vez que o botão era clicado. Além disso, havia um escopo local redundante para a variável 'atualizacaoFrame' dentro da função do botão. Isso criava uma nova variável local em vez de atualizar a variável global corretamente.

A solução foi remover o 'setInterval' inicial da declaração da variável 'atualizacaoFrame' e apenas chamar a função 'moverCirculo()' dentro do loop principal. Além disso, corrigi o escopo da variável 'atualizacaoFrame' dentro da função do botão, removendo a palavra-chave var.

Outra modificação que fiz foi ajustar a função 'corAleatoria()' para que ela retorne cores aleatórias com base no comprimento do array de cores disponíveis, em vez de usar um número fixo.

Essas correções garantem que a função 'moverCirculo()' seja chamada apenas uma vez por frame, evitando a aceleração indesejada dos círculos quando o botão é clicado várias vezes.

<canvas id="tela" width="500" height="500"></canvas>
<br>
<button>Mover aleatoriamente!</button>

<script>
    var tela = document.querySelector('#tela');
    var pincel = tela.getContext('2d');

    pincel.fillStyle = '#85FDAB';
    pincel.fillRect(0, 0, 500, 500);

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

    function limpaTela() {
        pincel.fillStyle = '#85FDAB';
        pincel.fillRect(0, 0, 500, 500);
    }

    function moverCirculo(circulo) {
        if (direcoes[circulo] === 'direita') {
            andarParaDireita(circulo);
        } else if (direcoes[circulo] === 'esquerda') {
            andarParaEsquerda(circulo);
        }
    }

    function andarParaDireita(circulo) {
        limpaTela();
        x[circulo]++;
        desenharCirculo(x[circulo], y[circulo], cor[circulo], raio);

        for (var i = 0; i < qtdCirculos; i++) {
            if (i !== circulo) {
                desenharCirculo(x[i], y[i], cor[i], raio);
            }
        }

        if (x[circulo] === 500 - raio) {
            cor[circulo] = corAleatoria();
            direcoes[circulo] = 'esquerda';
        }
    }

    function andarParaEsquerda(circulo) {
        limpaTela();
        x[circulo]--;
        desenharCirculo(x[circulo], y[circulo], cor[circulo], raio);

        for (var i = 0; i < qtdCirculos; i++) {
            if (i !== circulo) {
                desenharCirculo(x[i], y[i], cor[i], raio);
            }
        }

        if (x[circulo] === raio) {
            cor[circulo] = corAleatoria();
            direcoes[circulo] = 'direita';
        }
    }

    function preencherCoresAleatorias() {
        var cores = [];
        for (var i = 0; i < qtdCirculos; i++) {
            cores.push(corAleatoria());
        }
        return cores;
    }

    function corAleatoria() {
        return cores[Math.floor(Math.random() * cores.length)];
    }

    function preencherXInicial() {
        var x = [];
        for (var k = 30, i = 0; i < qtdCirculos; i++, k = k + 20) {
            x.push(k);
        }
        return x;
    }

    function preencherYInicial() {
        var y = [];
        for (var k = 30, i = 0; i < qtdCirculos; i++, k = k + 50) {
            y.push(k);
        }
        return y;
    }

    function preencherDirecoesIniciais() {
        var direcoes = [];
        for (var i = 0

tenta agora para ver se dá certo :)

solução!

Depois que corrigi agora ficou joia, obrigado!