2
respostas

O alvo deveria ser um CÍRCULO e não um QUADRADO

Semelhantemente ao que comentei na atividade "Acertando o alvo", novamente a proposta do instrutor foi um teste IF que testa se a posição do mouse no momento do clique estava ou não dentro de uma área retangular.

Insisto que, uma vez que podemos ser mais exatos, utilizando apenas operações matemáticas de que já conhecemos, devemos fazê-lo.

Ora, diante de um cenário no qual você possui as corrdenadas de um ponto central tido por alvo, mas que admite acerto em qualquer dos pontos em uma área circunferencial com raio predefinido, e as coordenadas do clique efetuado pelo usuário, para testar se este acertou ou não, basta verificar se a distância entre o ponto central e a posição do clieque é igual ou inferior ao raio da área do alvo.

Segue todo o código, com a mudança proposta:

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

<script>

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

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

    var raio = 10;
    var xAleatorio;
    var yAleatorio;

    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');
        desenhaCirculo(x, y, raio+10, 'white');
        desenhaCirculo(x, y, raio, 'red');

    }

    function sorteiaPosicao(maximo) {

        return Math.floor(Math.random() * maximo);

    }

function atualizaTela() {
    limpaTela();
    xAleatorio = sorteiaPosicao(600);
    yAleatorio = sorteiaPosicao(400);
    desenhaAlvo(xAleatorio, yAleatorio);
}

setInterval(atualizaTela, 1000);

function dispara(evento) {

    var x = evento.pageX - tela.offsetLeft;
    var y = evento.pageY - tela.offsetTop;
    // Declarei a distanciaCliqueCentroAlvo (teorema de Pitágoras)
    var distanciaCliqueCentroAlvo = Math.pow(Math.pow(xAleatorio-x,2)+Math.pow(yAleatorio-y,2),0.5);
    // Teste se a distância é menor ou igual que o raio do alvo 
    if (distanciaCliqueCentroAlvo<=raio) {
        alert("Você acertou!!");
    }

}




tela.onclick = dispara;

</script>
2 respostas

Olá, Renato! Tudo certo?

Agradeço a paciência em aguardar uma resposta.

Parabéns por ter trazido mais da Matemática para o desenvolvimento do programa! Existem diferentes maneiras de elaborar uma situação-problema, e explorar novas alternativas pode auxiliar no nosso aprendizado.

Obrigada por ter compartilhado com a gente sua sugestão, acredito que ela será importante para outros estudantes da plataforma.


Achei muito interessante que você utilizou o Math.pow para construir o Teorema de Pitágoras em Javascript.

Quando estamos lidando com um código, é muito importante que ele faça sentido no momento atual, no futuro e também que outras pessoas de fora o compreendam. Nesse sentido, trago uma dica de como você pode aplicar isso em seu programa:

Alguns dos motivos pelos quais criamos funções são: generalização de código e centralização de tarefas. Por esse motivo, criei a função calculaDistanciaCentroAlvo:

// função que calcula a distância entre os pontos!
function calculaDistanciaCentroAlvo(x1, x2, y1, y2) {
    return Math.sqrt(Math.pow(x1 - x2 , 2) + Math.pow(y1 - y2, 2))
}

Observe que ela possui 4 parâmetros (x1, x2, y1 e y2), eles serão colocados dentro dos métodos Math.pow. Isso é fundamental para que possamos trazer a generalização da atividade executada pela função!

Além disso, cabe ressaltar que substitui o Math.pow mais externo por Math.sqrt, que realiza diretamente a raiz quadrada do valor passado.

Agora, atribuímos a variável distancia o valor retornado pela função calculaDistanciaCentroAlvo, passando como parâmetros xAleatorio, x, yAleatorio e y . Isso acontecerá dentro da função dispara. A variável distancia fará parte da verificação da estrutura condicional:

function dispara(evento) {

    var x = evento.pageX - tela.offsetLeft;
    var y = evento.pageY - tela.offsetTop;
    // Declarei a distanciaCliqueCentroAlvo (teorema de Pitágoras)

    distancia = calculaDistanciaCentroAlvo(xAleatorio, x, yAleatorio, y)
    // Teste se a distância é menor ou igual que o raio do alvo 
    if (distancia <= raio) {
        alert("Você acertou!!");
    }

}

Dessa maneira, chegamos ao mesmo resultado que você compartilhou! No entanto, criamos uma função que generaliza e centraliza o processo de calcular a distância entre o Centro e o Alvo!

O resultado final do programa será este:

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

<script>

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

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

    var raio = 10;
    var xAleatorio;
    var yAleatorio;

    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');
        desenhaCirculo(x, y, raio+10, 'white');
        desenhaCirculo(x, y, raio, 'red');
    }

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

function atualizaTela() {
    limpaTela();
    xAleatorio = sorteiaPosicao(600);
    yAleatorio = sorteiaPosicao(400);
    desenhaAlvo(xAleatorio, yAleatorio);
}

setInterval(atualizaTela, 1000);

// função que calcula a distância entre os pontos!
function calculaDistanciaCentroAlvo(x1, x2, y1, y2) {
    return Math.sqrt(Math.pow(x1 - x2 , 2) + Math.pow(y1 - y2, 2))
}

function dispara(evento) {

    var x = evento.pageX - tela.offsetLeft;
    var y = evento.pageY - tela.offsetTop;
    // Declarei a distanciaCliqueCentroAlvo (teorema de Pitágoras)

    distancia = calculaDistanciaCentroAlvo(xAleatorio, x, yAleatorio, y)
    // Teste se a distância é menor ou igual que o raio do alvo 
    if (distancia <= raio) {
        alert("Você acertou!!");
    }

}

tela.onclick = dispara;

</script>

Caso surjam dúvidas ao longo dos seus estudos, sinta-se confortável para enviá-las ao fórum. Fico à disposição para te auxiliar no que for preciso!

Abraços, Renato!

Obrigado pelas dicas!

Vão de encontro aos princípios que estou estudando em "Código Limpo" de Robert C. Martin, entre os quais, de que as funções, bem, como os laços, devem ser pequenas, podendo, provavelmente, chamar outra função, o que, além de tornar cada uma menor, contribuirá com mais informação para outros desenvolvedores, a partir do próprio nome descritivo das funções.