IV. díl Codemas
Máme za sebou generování mapy, dnes se vrhneme na generování hlavní postavy. Spoustu věcí už jsme si řekli v předchozích dílech, a tak to dnes nebude tak dlouhé. 😊
Vytvoření herního objektu
Hráče si v JavaScriptu vydefinujeme jako herní objekt. Ten vypadá následovně:
let player = { x: 8, y: 1 }
Herní objekt je datová struktura, ve které budeme uchovávat údaje o našem hráči. Nám stačí uchovávat dvě informace, a to pozici x a y na naší herní ploše. Jinak lze uchovávat libovolný počet informací - ty musejí být vždy oddělené čárkou.
Jelikož budeme postavu vykreslovat jako obrázek, musíme si založit proměnnou, do které obrázek uložíme.
let hero = new Image() hero.src = "images/pernicek_dolu.png"
Připadá ti ten kód povědomý? Včera jsme takto zakládali proměnnou pro zeď. Máme herní objekt a obrázek a jak už jsem zmiňoval pár řádků nahoru, budeme muset postavu vykreslit.
Vykreslení hráče
Vytvoříme si novou funkci s názvem draw.
function draw() { }
Tato funkce nám bude sloužit nejen k vykreslení hráče, ale bude jakousi hlavní metodou naší hry. Přidáme si do funkce příkaz nutný k vykreslení postavy:
ctx.drawImage(hero,player.x * blockSize, player.y * blockSize, blockSize, blockSize)
Samotnou funkci jsme ještě nezavolali, proto se nám po spuštění žádný hráč nezobrazí. Včera jsme si na konci dne přidali do kódu poslouchač události, který čekal na načtení stránky. Jakmile se načte stránka, zavolá se funkce generateBoard. Pojďme toto trošku upravit, funkci generateBoard zavoláme ve funkci draw a funkce draw se nám zavolá při načtení stránky. Upravený kód vypadá následovně:
function draw() { generateBoard() ctx.drawImage(hero,player.x * blockSize, player.y * blockSize, blockSize, blockSize) } window.addEventListener("load", draw)
Pokud nyní hru zapneme, vykreslí se nám do ní i hlavní postava.
Pohyb hlavní postavy
Dnes ještě uděláme jednu důležitou věc, a to pohyb postavy. 😊 Naše hra bude reagovat na stisk klávesy, přičemž konkrétněbudeme využívat šipky. Přidejme si tedy na konec skriptu následující kód:
document.body.addEventListener("keydown", function(e) { keys[e.keyCode] = true draw() }) document.body.addEventListener("keyup", function(e) { keys[e.keyCode] = false draw() })
Na tělo celého dokumentu umístíme dva poslouchače události keydown a keyup. Keydown se zaktivuje ve chvíli, kdy stiskneme nebo budeme držet libovolnou klávesu, keyup pak zareaguje při uvolnění klávesy. Jedna bez druhého v našem případě nemůže fungovat. Každá klávesa má svůj kód, takže pokud budeš nějakou klávesu držet nebo ji stiskneš, tak se v poli keys označí jako true. Pokud ji pustíš, označí se jako false. Aby nám vše fungovalo tak, jak má, musíme vytvořit novou proměnnoukeys, do které uložíme prázdné pole. Na začátek celého našeho skriptu vlož mezi proměnné tento řádek kódu:
let keys = []
Samotné poslouchače v sobě volají funkci draw a to z jednoduchého důvodu - při každém stisku chceme aktualizovat pozici i stav hry.
Nyní si vytvoříme funkci, která se bude čistě starat o pohyb hlavní postavy a nazveme si ji movement.
function movement() { if (keys[39]) { // šipka doprava hero.src = "images/right.png" player.x++ } if (keys[37]) { // šipka doleva hero.src = "images/left.png" player.x-- } if (keys[38]) { // šipka nahoru hero.src = "images/up.png" player.y-- } if (keys[40]) { // šipka dolů hero.src = "images/down.png" player.y++ } }
V této funkci jsou 4 podmínky. Každá podmínka se kouká do pole keys a zjišťuje, jestli se stiskla šipka doprava, doleva, nahoru nebo dolů. V každé podmínce se i překreslí obrázek hlavní postavy podle směru, kterým jdeme. V každé podmínce potom měníme i pozici na ose x nebo y. Funkci zavoláme ve funkci draw.
function draw() { generateBoard() movement() ctx.drawImage(hero,player.x * blockSize, player.y * blockSize, blockSize, blockSize) }
Když si zkusíme nyní hru spustit a pohnout se libovolným směrem, funguje to! Jsou zde jen 2 drobnosti, na kterých musíme zapracovat. Zaprvé, zatím jsme nikde nedefinovali „náraz do zdi“, takže se hlavní postava může pohybovat libovolně po bludišti (dokonce i za něj). Může se ti tak stát, že postava při stisku klávesy zmizí a při dalším se zase objeví - je to způsobené canvasem jako takovým a bohužel s tím nic neuděláme.
A druhá věc, kterou dnes vyřešíme, je to, že naše postava zůstává vykreslená i na polích, kde se nenacházíme, což určitě není dobře.
Toto vyřešíme funkcí clearRect, kterou přidáme na začátek naší funkce draw před generateBoard.
function draw() { ctx.clearRect(player.x * blockSize, player.y * blockSize, blockSize, blockSize) generateBoard() movement() ctx.drawImage(hero,player.x * blockSize, player.y * blockSize, blockSize, blockSize) }
Tato funkce nám zajistí, že se hlavní postava na začátku funkce smaže ze své konkrétní pozice a vykreslí se na nové pozici díky naší funkci drawImage na konci.
Na závěr
Hurááá, hýbeme se! :D A naše hra pomalu získává finální podobu. Dobrá práce! Celý kód z dnešní hodiny najdeš zde.
Pokud s něčím bojuješ, neboj se nám napsat pod příspěvek na naší facebookové události, rádi ti pomůžeme. K dotazu ideálně pošli i URL adresu s odkazem na tvůj projekt. :)
Začala sis pohrávat s myšlenkou, že bys chtěla prozkoumat IT trochu víc? Podívej se na nabídku kurzů od Czechitas, kteří se zaměřují na vzdělávání převážně žen a dětí v IT. Jak si vybrat vhodný kurz zjistíš zde.
Michal z Czechitas