14# 1942 Classic 1.
1942 byla jedna z klasických arkádových her, kdy máte na spodní straně obrazovky svoje letadlo a postupně na vás útočí vlny nepřátel. O podobnou hru se v těchto lekcích pokusíme.
Samozřejmě s ohledem na “Space theme”, který tu na webu mám vše posunu do vesmíru a bude to něco jako 1942/Space invaders. Na tuto hru již budeme používat o něco profesionálnější assety než na té předchozí a existuje pěkná knihovna assetů od Kenney.nl. Všechny Assety jsou zdarma a tak stahujte a jdeme na to.
Založíme si nový projekt. Můj si pojmenuju “1942 Classic”. Jméno je samozřejmě na vás. Rozbalte si balík Assets a celou složku si přetáhněte do Assets. Nebudeme potřebovat všechny, uvidíme jak velkou část použijeme. Případně pokud by nám to bylo málo můžeme ještě vzít balík rozšíření z Kenney.nl. Případně můžete vzít i tento balík, kdy všechny jsou udělané ve stejném stylu. Jaké Assety použijete bude pouze na vás. Pokud se vám nechce stahovat jednotlivé balíky a jste trochu LAZY, můžete si to vzít celé připravené jako unitypackage.
Po importování balíku upravíme ještě rozlišení hry. Pokusíme se přiblížit našemu vzoru a použijeme formát 9:16. To můžeme nastavit v záložce GAME, kde aktuálně máme 4:3, úplně dole klikneme na + a nastavíme rozlišení 9:16 -> Typ Aspect ration.
Nyní začneme přebírat věci co budeme chtít použít v naší hře. Vytvoříme si přímo v Assets složku Sprites (Pravé tlačítko -> Create -> Folder), do ni přetáhneme věci co budeme v naší hře potřebovat. Přejde do složky KenneySpace -> PNG. Zde máme několik verzí pro PlayerShip. Vybereme si, kterou chceme a přesuneme ji do Sprites.
Stejným způsobem si vezeme zatím jednu nepřátelskou loď. Můžeme si vzít jednu ze složky Enemies. Případně Sprites – Ships, nebo jednoho z mimozemšťanu přímo ve složce PNG. Je to jen na vás. Já si ke své červené lodi vzal modrého mimozemšťana. Poslední co nám chybí je nějaké pozadí pro hru. V balíku jsou zatím pouze jednobarevná pozadí, ale pokud chcete je čas si najít nějaký cool background pro vaši hru. Doporučuji větší rozlišení, aby jsme jím mohli posouvat na pozadí pro efekt pohybu. Opět si ho přidáme do Sprites.
Pozadí si z Sprites můžeme rovnou přetáhnout do scény, aby jsme ve hře hned něco měli. Jako druhá část přidáme si do hry Canvas, protože pomocí něj můžeme přidávat UI prvky a texty. Klikneme si pravým do Hierarchy a vybereme UI -> Canvas. U toho uděláme rovnou v Canvas několik nastavení v inspektoru. V části Canvas Scaler vybereme Scale with Screen Size a reference resolution nastavíme na 1080×1920.
V další části si připravíme hráče. Začneme tím, že si vytvoříme prázdný object, pojmenujeme ho Player a tomu v inspektoru přidáme component Sprite Renderer. S ohledem na to, že ve hře máme opravdu hodně Sprites, připojení toho správného by mohlo být trochu náročné. Proto si ukážeme nový způsob. V Assets si necháme otevřené naše připravené Sprites. Pak si klikneme na player v Hierarchii a nakonec si zamkneme inspektora, aby nám nezmizel a my jsme mohli přetáhnout Sprite do políčka Sprite Renderer -> Sprite.
Dalším kliknutím na zámek inspektora opět odemkneme, aby se měnil na to na co máme aktuálně kliknuto. Stejným způsobem jako jsme si přidali hráče, přidáme i jednoho nepřítele. Pokud nevidíte hráče nebo nepřítele ve hře klikněte pravým tlačítkem do Transform a vyberte “Reset”.
Pokud stále nevidíte Player ani Enemy pravděpodobně nemáte správně nastavený background, ten by měl být dál než Sprites hry, a tak si rozklikněte Background a měli by jste mít v Transform X0 Y0 Z5. Tím zajistíme, že pozadí bude skutečně vzadu.
Jako další krok, když již vidíme hráče a nepřítele, musíme nastavit jejich správnou velikost a začneme velikostí kamery. Opět máme Main Camera a její výchozí velikost je 5. Tohle bude již hodně na vás, ale mě připadá pro tuto hru správná velikost 7, kdy nejsou sprites obří ani miniaturní. Pokud chcete měnit velikosti jednotlivých elementů (Player/Enemy), rozklikněte si ho v Assets a upravte Pixels Per Unit a potvrďte Apply.
Náš další cíl, pohyb hráče.
Začneme tím, že přidáme hráči (Player) script Player a otevřeme si Visual Studio. Pohyb hráče bude něco co se bude dít stále a tak píšeme do Update(). Hráč toho bude dělat více a budeme sledovat, pohyb, střelbu kolize a další. Proto si uděláme vlastní metodu/funkci na pohyb.
První hru jsme ovládali pomocí kláves (GetKeyDown), Později jsme přešli na tlačítka na obrazovce a poslední hra má ovládání pomocí myši. Ale co jsme ještě nepoužili je GamePad. Ten ale samozřejmě každý nemá, a tak musíme udělat hybridní ovládání pomocí klávesnice nebo Gamepadu. Naštěstí toto není pro Unity něco překvapujícího a pro to má vše připravené. Když si otevřete v Unity záložku EDIT -> Project Settings. Najdete zde položku Input. Zde jsou výchozí nastavení ovládání unity. Zatím nás nebudou zajímat všechny, ale hlavně Horizontal. Vyskytuje se v seznamu 2x. Jen je hned na začátku, ten je pro ovládání klávesnicí (šipky + AD) a druhý je pro GamePad.
Když mluvíme o negative a positive button je tím myšlen pohyb po ose X. Zároveň veškerý Input, který zde vidíme spadá pod Axes, což jsou již všechna klíčová slova, který potřebujeme. Pro pohyb, si vytvoříme proměnou, která bude rozdílem k aktuální poloze a proměnná vznikne na základě toho co získáme z Axes -> Horizontal.
Můžete udělat první test a zde narazíme na drobné rozdíly. Pokud máte počítač za 100.000 kde máte 2080 Ti v SLI, pravděpodobně po kliknutí na A nebo D vám loď prostě zmizí. Pokud máte 15 let starý školní počítač může to být celkem normální pohyb. A to proto, že pohyb hráče je vázaný na FPS (Počet snímků za sekundu). S podobným nastavením byl vydán Fallout 76 a tak když se vám povedlo zrušit nastavení maximální snímků mohli jste se pohybovat výrazně rychleji než ostatní hráč. My sice nejsme Bethesda Softworks, ale stejnou chybu neuděláme. Funkce Time.deltaTime nám totiž řekne jak dlouho nám trvalo vytvoření (render) předchozího snímku, pomocí této hodnoty dokážeme stabilizovat rychlost pohybu pro všechny rychlosti počítačů.
Input.GetAxis vrací hodnoty od -1 po 1, pokud tyto hodnoty vynásobíme tím, jak dlouho nám trvalo vytvoření předchozího snímku, získáme tím pomalou loď, ale stejně pomalou na všech počítačích. Protože pokud máme 100 FPS, jeden snímek renderujeme Loď se pohne o 0.01s. 1*0.01 = 0.01 jednotky za jeden snímek. Za 1s se pohne 100×0.01 = 1 jednotku. Když náš počítač je super pomalý a udělá jen 2FPS. Jeden snímek se bude renderovat 0.5s Loď se pohne o 1*0.5 = 0.5 jednotky za snímek a za 1s se pohne o 0.5 * 2 = 1 jednotku. Doufám, že to dává smysl.
O naši šourající loď by ale nikdo neměl zájem, musíme tedy přidat proměnnou. Na začátek jedno serializované pole pro rychlé testování, typ float aby jsme mohli psát i desetinní čísla. Jméno může být třeba moveSpeed a předvyplníme se hodnotu 10f. Také můžeme odstranit knihovny co nepoužíváme (System, System.Collections a System.Collection.Generic), stačí nám knihovny Unity.
Proměnnou použijeme moveX.
Později si můžeme hrát s rychlostí lodi přímo v Unity. Co ale ještě musíme udělat je přidat pohyb nahoru a dolů (Vertical). Základ již máme napsaný jen uděláme pár CTRL + C a +V, přepíšeme pár slov a máme hotovo.
Loď nám již může volně létat, možná až příliš volně. Uletět mimo obrazovku by jsme hráči dovolit neměli a tak přidáme hranice. V minulém projektu jsme použili Mathf.Clamp, to pužijeme i zde, ale přimícháme do toho kameru. Existuje na to funkce ViewPortToWorldPoint. Kdy hodnoty rohů kamery jsou 0-1 po ose X i Y. Takže levý spodní roh bude 0,0. pravý spodní roh bude 1,0, levý hodní bude 0,1 a pravý horní bude 1,1. Ty se pak přepočítávají na polohu objektů, například střed je 0.5X a 0.5Y. Pomocí funkce ViewPortToWorldPoint můžeme hodnotu přepočítat na units. V mém případě 4x 7y. Jednotky pak můžeme používat ve funkcích. Výhodou použití ViewPortTOWorldPoint je to, že i pokud změníme velikost kamery, nebo její poměr stran, vše bude stále fungovat.
Na začátku, získáme polohu hranic kamery, a pak z nich vytvoříme hranice pro loď. Hranice bude vytvářet pouze jednou při zapnutí a tak si vytvoříme funkci SetUpWalls, kterou budeme volat ze Start().
Budeme ještě k tomu potřebovat 4 proměnné xMax, xMin, yMax a yMin. Ty vytvoříme na začátku a budeme do nich ukládat hranice pro pohyb.
Pro přípravu zdí budeme potřebovat připojit hlavní kameru, z které budeme získávat informace o poloze rohů obrazovky v jednotkách.
Když máme připravenou kameru, můžeme začít psát funkci s ViewportToWorldPoint, začneme pro xMin. Vezmeme kameru a z ní ViewportToWorldPont.
Zatím nám Visual Studio bude hlásit chybu, ale pokud na ni najedete myší, dozvíte se, že potřebujeme Vector3. Zatím jsme používali Vector2, například pro posunutí míčku od pálky. Vector3 nám přidává ještě osu Z, tu ale ve 2D hře nevyužijeme a tak vždy zůstane nula. Co se tyče zbytku čísel, již jsem vám je prozradil. Víme jaké hodnoty mají všechny rohy a tak můžeme začít levým spodním rohem pro xMin.
Stejně vytvoříme hodnoty pro xMax, yMin a yMax.
Nyní přišel čas na Mathf.Clamp. Již máme uložené maximální a minimální hodnoty pro X a Y, stačí je jen použít v MovePlayer. Tam již máme vytvořené proměnné, newXPosition a newYPosition. Do tech uložíme Mathf.Clamp, kdy první hodnota je číslo které chceme omezit (původní proměnná), druhá hodnota je minimum (odkážeme na příslušný X/YMin) a třetí hodnota je maximum (odkážeme na příslušný X/YMax).
Nyní máme hotový pohyb hráče. Ještě nás čeká:
- Střelba hráče
- Pohyb nepřátel
- Životy hráče / Životy nepřátel
- Vlny nepřátel
- Skóre
- Střelba nepřátel
- Menu, Efekty a další ladění
V další lekci se dostane ke střelbě.
0 Comments