If you're seeing this message, it means we're having trouble loading external resources on our website.

Se você está atrás de um filtro da Web, certifique-se que os domínios *.kastatic.org e *.kasandbox.org estão desbloqueados.

Conteúdo principal

Cenas interativas

Agora que sabemos como fazer ótimas cenas animadas, vamos nos certificar que podemos lidar com o outro tipo de cena não-estática: cenas que respondem à interação do usuário. Por exemplo, queremos desenhar uma cena onde Winston tem bebês (após a sua fase de estrela do rock, claro) -- mas queremos também permitir que o usuário clique para dar a Winston MAIS bebês. Porque podemos sempre ter mais pequenos Winstons no mundo, certo?
Aqui está como se pareceria a cena como um programa autônomo. O programa desenha a parte estática da cena, e depois em mouseClicked, ele desenha imagens de Winstons bebês no local do mouse clicado, colocando-os em cima de tudo o que já foi desenhado.
Como integraríamos isto em nosso programa multi-cenas? Bem, começaríamos apenas envolvendo todo o código de desenho estático em uma função de desenho de cena drawScene5() e adicionando lógica de troca de cenas para mouseClicked:
var drawScene5 = function() {
    currentScene = 5;
    background(173, 239, 255);
    fill(7, 14, 145);
    textSize(39);
    text("Winston has babies!", 10, 47);
    ...
};

mouseClicked = function() {
    if (currentScene === 1) {
        drawScene2();
    } else if (currentScene === 2) {
        drawScene3();
    } else if (currentScene === 3) {
        drawScene4();
    }  else if (currentScene === 4) {
        drawScene5();
    } else if (currentScene === 5) {
        drawScene1();
    }
};
Isso vai ficar assim:
Mas como podemos integrar a funcionalidade de mouseClicked? Já definimos um mouseClicked em nosso código, e nós não podemos defini-lo duas vezes. Em JavaScript, a última definição de função "vence", ela substitui quaisquer definições anteriores. Isso significa que precisamos encontrar um bom lugar para colocar essa linha do desenho de bebê dentro do nosso mouseClicked existente. Vamos falar sobre algumas opções:
1. Poderíamos colocar a linha no início da função:
mouseClicked = function() {
    image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
    ...
};
Então, ela será chamada TODA vez que o usuário clicar o mouse, mesmo se não for a cena de criação de bebês (e seria estranho se o bebê Winston tivesse um bebê). Não é bom.
2. Nós poderíamos colocar a linha dentro do bloco "if" currentScene === 4:
mouseClicked = function() {
    if (currentScene === 1) {
        drawScene2();
    } else if (currentScene === 2) {
        drawScene3();
    } else if (currentScene === 3) {
        drawScene4();
    }  else if (currentScene === 4) {
        drawScene5();
        image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
    } else if (currentScene === 5) {
        drawScene1();
    }
};
Afinal, é onde nós chamamos a drawScene5(), e os bebês devem ser acrescentados à cena 5. Mas pense bem: isso significaria que seria sempre desenhado um bebê extra, toda vez que criássemos a cena. Isso também significaria que nós nunca iríamos desenhar mais nenhum bebê, porque currentScene seria 5 e o código desse bloco não seria mais executado.
3. Nós poderíamos colocar a linha dentro do bloco "if" currentScene === 5:
mouseClicked = function() {
    if (currentScene === 1) {
        drawScene2();
    } else if (currentScene === 2) {
        drawScene3();
    } else if (currentScene === 3) {
        drawScene4();
    }  else if (currentScene === 4) {
        drawScene5();
    } else if (currentScene === 5) {
        image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
        drawScene1();
    }
};
Isso significa que não desenharíamos bebês até o primeiro clique depois do desenho inicial da cena. Mas, como você pode ver a partir da linha seguinte, o bebê seria instantaneamente substituído pela cena 1.
Aí é onde percebemos uma falha fatal na nossa ideia de integrar esta cena clicks / bebês em nossas cenas: estamos usando exatamente a mesma interação--um clique do mouse em qualquer lugar na tela--tanto para mudar de cenas quanto para fazer interação dentro de cena. Agora realmente temos um enigma em nossas mãos, e precisamos considerar opções mais radicais para integrar a cena.
4. Poderíamos parar de redesenhar a cena 1 no final e informar ao usuário para reiniciar neste caso. Com certeza, isto iria funcionar, mas isto se baseia no fato de que nossa tela controlada por cliques aconteceu de ser a última. E se quiséssemos uma cena anterior controlada por cliques? Essa solução iria falhar.
5. Poderíamos usar um tipo diferente de interação - como mouseDragged. Vai funcionar, porque arrastando não causamos também um evento clique. Ainda precisamos verificar se currentScene === 5, para nos certificarmos de que ao arrastar não estamos desenhando os bebês em qualquer outra cena:
mouseDragged = function() {
    if (currentScene === 5) {
        image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
    }
};
Faça um teste, e lembre-se de arrastar na cena final:
Então, isto até que funciona, embora eu fique um pouco preocupado com quantos bebês Winston pode acabar tendo. Geralmente, isto não é uma solução ideal, pois isso significa que temos de nos limitar a projetar cenas que não respondem a cliques de mouse. Não queremos ter que ter essa restrição, deve haver uma maneira melhor.
E se nós diferenciarmos os cliques de mouse por localização, de modo que um clique em um único local significasse alterar cenas e cliques em outros lugares pudessem ser usados para interação na cena? Você sabe, como um botão! Na verdade, é como a maioria dos programas de multicenas abordam este problema, e nós falaremos sobre isso a seguir.

Quer participar da conversa?

Você entende inglês? Clique aqui para ver mais debates na versão em inglês do site da Khan Academy.