==== Autíčko ====
=== Ovládání z klávesnice ===
{{ :krouzek:klavesnice.jpg?300|}}
Došli jsme k poznání, že kód pro zachytávání stisků kláves:
document.addEventListener('keypress', function(event){
if(event.key=== 'w' || event.key=== 'W'){
zrychli();
}
//dalsi klavesy
});
není dokonalý - událost //keypress// je totiž ta chvíle, kdy je písmenko po zmáčknutí napsáno (např. do dokumentu). Proto se při držení klávesy vykoná jedna akce (například pohyb vlevo), chvíli se počká a pak se bude vykonávat opakovaně.
Proto by se v takto naprogramované hře dalo snadno podvádět - lze totiž počáteční prodlevu i kadenci opakování nastavit v Ovládacích panelech/klávesnice (mimochodem, dialog nastavení klávesnice - viz obrázek - se v aktuální verzi Windows 10 neliší od prastarých WindowsXP).
== Dolů a nahoru ==
Budeme tedy sledovat jiné události - //keydown// a //keyup// - okamžik, kdy jde klávesa dolů (=je zamáčknuta) a kdy se vrací nahoru.
Tyto události ovšem i pro dlouhé držení (např. chci dlouho zrychlovat autíčko) vykonají pouze jednou. Proto není žádoucí, aby volaly přímo akci //pridej()//. Místo toho si zkusíme představit, že máme tabulku, ve které je informace, zda je momentálně klávesa držena, či ne. Po zamáčknutí //w// by tabulka vypadala takto:
^ Klávesa ^ Proměnná ^ Zmáčknuta? ^
| w | ''zmacknutoZrychli'' | ''true'' |
| s | ''zmacknutoZpomal'' | ''false'' |
| a | ''zmacknutoDoleva'' | ''false'' |
| d | ''zmacknutoDoprava'' | ''false'' |
V kódu to bude (zde pouze pro klávesu w, zbytek doplňte sami :)) takto:
//deklarace globalni promenne
zmacknutoZrychli = false;
document.addEventListener('keydown', function(event){
//klavesa byla zmacknuta
if(event.key=== 'w' || event.key=== 'W'){
zmacknutoZrychli=true;
}
//todo:dalsi klavesy
});
document.addEventListener('keyup', function(event){
//klavesa byla odmacknuta
if(event.key=== 'w' || event.key=== 'W'){
zmacknutoZrychli=false;
}
//todo:dalsi klavesy
});
Po této úpravě samozřejmě nebude funkce //zrychli()// volána přímo zmáčknutím klávesy. Proto je potřeba tuto funkci volat v hlavním opakovaném cyklu (funkce //render// naplánovaná pomocí //setInterval//, resp. //requestAnimationFrame//)
//Funkce ktera bude volana znovu a znovu = herní loop
function render(){
//Ovlivneni na zaklade stavu klaves
if(zmacknutoZrychli){
zrychli();
}
//todo: další akce
//todo přepočítání x,y na základě rychlosti - viz další část textu
//nastav aktualni stav do prvku
document.getElementById('monster').style.top=y+"px";
document.getElementById('monster').style.left=x+"px";
}
//Naplánování herního loopu každých 33ms
setInterval(render,33);
Poznámka: aby byla hra skutečně stejně hratelná pro všechny, je třeba pamatovat, že 33ms není úplně spolehlivých - mezi jednotlivými snímky může uplynout i víc času. Jako námět pro rozšíření bychom tedy mohli měřit dobu skutečně uplynulou od minulého snímku a přenásobovat tím přírustky k pozici (= jak daleko se auto pohne)
=== Rychlost ===
{{ :krouzek:rychlost_draha.png?400|}}
Dosud jsme autíčko pohybovali pouze ve chvíli zmáčknutí klávesy, a to jeho maximální rychlostí. Jak to ovšem funguje s reálnými pohybujícími se předměty? Rychlost se nezvyšuje skokově. Dokud držíme nohu na plynu, rychlost roste. Když nohu z plynu sundáme (nebo začneme brzdit), rychlost se začne snižovat (až klesne k nule).
Z programátorského hlediska budeme potřebovat v naší hře zavést novou proměnnou (případně dvě, pro každou ze souřadnic x,y) - rychlost. Měl by platit vzoreček:
polohaX_nova=polohaX_stara + rychlostX * uplynulyCas
zjednodušeně (spoléháme se na správnost časování intervalem):
polohaX=polohaX + rychlostX
což se dá napsat i způsobem:
polohaX+=rychlostX
Toto se odehraje v každém výpočtu snímku (funkce //render//). Rychlost není v km/h či m/s jak jsme zvyklí z reálného života - v našem kontextu má zřejmě jednotku "uražené pixely za dobu mezi dvěma snímky"
== Setrvačnost ==
Pro ještě lepší dojem z autíčka zkuste rychlost ovlivňovat i přirozeným zpomalováním (aerodynamickým odporem, třením pneumatik). Pozor, nestačí prostě nějakou hodnotu od rychlosti odečítat - rychlost může být i záporná = v opačném směru! Musíte udělat podmínku, která rychlost snižuje, pokud je rychlost větší než 0 a zvyšuje, pokud je menší než 0.
=== Otáčení a rychlost jako vektor ===