Hlavní obsah
Interaktivní scény
V tomto bodě už umíš vytvářet pěkné animované scény. Pojďme se tedy podívat na další druh nestatické scény: scénu, která reaguje na interakci uživatele. Mohli bychom například chtít nakreslit scénu, ve které má Winston děti (po jeho hvězdném období, samozřejmě) -- a chceme uživateli umožnit kliknutí na tlačítko, které Winstonovi přidá VÍCE dětí. Protože pár dalších malých Winstonů se ve světě nikdy neztratí, že ano?
Zde je ukázka, jak by tato scéna vypadala jako samostatný program. Program vykresluje statickou část scény a poté v
mouseClicked
nakreslí obrázek Winstonova dítěte na místě kliknutí myši, přidávajíc tak dítě navrch čehokoli, co již bylo vykresleno.Jak bychom mohli scénu začlenit do našeho programu s více scénami? Začneme tím, že vložíme kód kreslení do funkce pro nakreslení scény
drawScene5()
a přidáme do mouseClicked
logiku pro přepnutí scény:var drawScene5 = function() {
currentScene = 5;
background(173, 239, 255);
fill(7, 14, 145);
textSize(39);
text("Winston má děti!", 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();
}
};
Takhle to vypadá:
Jak však integrujeme funkcionalitu
mouseClicked
? V našem kódu jsme již funkci mouseClicked
definovali a nemůžeme ji proto definovat dvakrát. V JavaScriptu poslední definice funkce "vyhrává", přepíše všechny předchozí definice. To znamená, že musíme najít vhodné místo, abychom kód pro nakreslení dítěte mohli umístit do již existující mouseClicked
. Pojďme se podívat na několik možností:1. Mohli bychom kód vložit na začátek funkce:
mouseClicked = function() {
image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
...
};
Pak se ale funkce zavolá POKAŽDÉ, když uživatel klikne myší, i když to nebude scéna pro nakreslení dítěte (bylo by divné, kdyby se u malého Winstona objevilo miminko). To nechceme.
2. Mohli bychom kód vložit do kódu pro
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();
}
};
Koneckonců, odtamtud voláme
drawScene5()
a děti by měly být přidávány právě do scény 5. Ale zamysli se: to by znamenalo, že bychom vždycky nakreslili další dítě, pokaždé při vykreslení této scény. To by také znamenalo, že bychom nikdy nenakreslili více dětí, protože currentScene
by se nastavila na 5, a kód v ní by již nebyl spuštěn znovu.3. Mohli bychom kód vložit do kódu pro
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();
}
};
To by znamenalo, že bychom nenakreslili dítě, dokud neklikneme po prvotním vykreslení scény. Ale jak vidíte z dalšího řádku kódu, dítě by bylo okamžitě nahrazeno scénou 1.
Zde si uvědomíme zásadní chybu celé této myšlenky o integraci klikatelné scény pro kreslení dítěte v našich scénách: používáme pořád tu stejnou interakci - kliknutí myší kdekoli na obrazovce - pro změnu scén a také k interakci uvnitř scény. Nyní máme před sebou hádanku a musíme zvážit radikálnější možnosti integrace scény.
4. Mohli bychom přestat kreslit scénu 1 na konci kódu a říct uživateli, aby program sám restartoval. Jistě, to by fungovalo, ale jenom za předpokladu, že bude naše klikatelná scéna jako poslední. Co kdybychom chtěli udělat klikatelnou scénu dříve? V tom případě by toto řešení selhalo.
5. Můžeme použít jiný druh interakce - například
mouseDragged.
Tento způsob bude fungovat, protože přetažení myši nespustí akci kliknutí. Pořád ale musíme zkontrolovat currentScene === 5
, abychom se ujistili, že přetahování nenakreslí děti v žádné jiné scéně:mouseDragged = function() {
if (currentScene === 5) {
image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
}
};
Vyzkoušej si to níže a ujisti se, že v poslední scéně vyzkoušíš přetažení:
Nějakým způsobem nám to funguje, i když jsme trochu znepokojeni množstvím dětí, které bude Winston nakonec mít. Jako obecně přijatelné řešení to není, protože to znamená, že se musíme omezit na navrhování scén bez reakce na kliknutí myší. Toto omezení mít nechceme, musí existovat nějaký lepší způsob.
Co kdybychom místo toho rozlišovali kliknutí myší dle jejich umístění, takže kliknutí v jednom místě by znamenalo změnu scény, a kliknutí jinde lze použít pro interakci se scénou? Víte co mám na mysli, tlačítko! Popravdě se jedná o způsob, jak k tomuto problému přistupuje většina programů s více scénami a to také probereme příště.
Chceš se zapojit do diskuze?
Zatím žádné příspěvky.