==== 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 ===