IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

2. diel - Pozadia, ovládanie hráča a časticové efekty vo SpriteKit

V predchádzajúcej lekcii, Úvod do tvorby iOS hier s frameworkom SpriteKit , sme si predstavili SpriteKit vrátane štruktúry projektu a nachystali textúry pre vesmírnu strieľačku. Teraz sa pustíme do budovania našej hry.

Nakopírovaniu textúr

Ako prvý krok je potrebné nakopírovať naše obrázky do Assets.xcassets v projekte a ideálne zvoliť nejaké výstižné a jednoduché názvy. My si zvolíme background pre pozadie a player pre loď hráča.

Pozíciovanie vo SpriteKit

Začneme s vytvorením pozadia. Než si pozadie pridáme do našej scény, potrebujeme si vysvetliť, ako funguje systém súradníc SpriteKit. V predvolenom stave totiž nezačína v ľavom hornom rohu ako UIKit.

Keď si otvoríte GameScene.sks, tak napravo v Attributes inšpektorovi môžete vidieť informácie o našej scéne. Nás zaujíma položka "Anchor". Je to vlastne taká virtuálna kotva v scéne, podľa ktorej sa budú umiestňovať ďalšie prvky.

V predvolenom stave je nastavená na X: 0.5 a Y: 0.5. To znamená stred scény. V praxi sa používa buď toto nastavenie alebo X: 0.0 a Y: 0.0, čo znamená ľavý dolný roh.

Rozhodnutie aký Anchor zvoliť je dosť podstatné a nejde urobiť jednoznačné odporúčania. Záleží totiž na tom, ako je vaša hra koncipovaná. Ak by sme tvorili hru, v ktorej bude obrazovka celá herná aréna a hráč sa nebude pohybovať mimo, tak je najlogickejšie ponechať práve 0.5 ; 0.5 a všetko nastavovať vzhľadom ku stredu. Naša hra bude mať v spodnej časti loď hráča, ilúziu letu vesmírom a nepriateľov v hornej časti obrazovky. Z pohľadu tejto hry dáva zmysel použiť Anchor 0.0 ; 0,0.

Budem teda používať toto pozicovanie. Ak sa vám lepšie uvažuje a pracuje s iným, tak ho samozrejme používajte. Len budete musieť pri každom pozicovanie prísť na súradnice pre váš Anchor, aby bol výsledok rovnaký.

Pretože je pozíciovanie dôležité, pripravil som ešte ilustračný obrázok rôzneho nastavenia Anchor:

Anchors vo SpriteKit - Tvorba iOS hier vo Swift

Pozadia

Presunieme sa do GameScene.swift. Ako už vieme z prvej lekcie, máme tu k dispozícii metódu didMove(), ktorá je zavolaná vždy na začiatku a môžeme v nej nastaviť všetko v scéne.

Podobne ako s viewDidLoad() odporúčam vytvárať pre nastavenie jednotlivých vecí v scéne oddelené metódy a tie potom volať v didMove(), aby sa jej telo čítalo ako zoznam príkazov. Vďaka tomu oveľa ľahšie zistíte, čo má vlastne metóda na starosť. Vytvoríme si teda novú metódu createBackground(), v ktorej pozadí vytvoríme. Vlastne skoro akýkoľvek objekt vo SpriteKit má za potomka triedu SKNode, ktorá slúži ako taký základný stavebný blok. My budeme často používať SKSpriteNode, ktorý je špecializovaná na zobrazovanie 2D objektov.

Začneme teda jej vytvorením a použijeme náš obrázok ako textúru:

let background = SKSpriteNode(imageNamed: "background")

Teraz nastavíme vlastnosť zPosition, čo je klasická z súradnice určujúce, v akom poradí sú na sebe objekty "naskladané". Pozadie bude logicky najnižšie, takže mu dáme napr. -5.

background.zPosition = -5

Zostáva nastaviť pozíciu a pridať objekt do scény. Pozíciu musíme nastaviť z dôvodu, že sme zmenili predvolený Anchor zo stredovej (0.5 ; 0.5) na ľavý dolný roh, ale pozícia akýchkoľvek ďalších SKNode je stále predvolený, teda (0.5 ; 0.5). Pozíciu teda posunieme o polovicu šírky a o polovicu výšky scény a pomocou addChild() pridáme pozadí ako objekt scény:

background.position = CGPoint(x: size.width / 2, y: size.height / 2)
addChild(background)

Teraz stačí createBackground() zavolať v didMove() a hru už môžete zapnúť. Uvidíte pozadie.

Tvorba iOS hier vo Swift

Hráč

Máme pozadia a podobným štýlom pridáme do hry vesmírnu loď hráča. Opäť si teda vytvoríme metódu setupPlayer(), avšak samotný objekt inicializujeme na úrovni triedy, aby sme k nemu mohli pristupovať:

let player = SKSpriteNode(imageNamed: "player")

A teraz už v tele metódy zatiaľ pridáme tieto riadky, ktoré hráča pridajú nadol doprostred:

player.position = CGPoint(x: size.width / 2, y: 120)
addChild(player)

Ovládanie

S loďou hráčov budeme horizontálne hýbať pomocou ťahanie prsta. To je intuitívne a na implementáciu jednoduchá metóda. Začneme v metóde touchesMoved(), ktorú sme síce pri našom čistení zmazali, ale nie je problém ju pomocou pomocníka dostať späť:

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
}

Metóda je zavolaná vždy, keď hráč pohne prstom po displeji a dostaneme sadu dotykov. Tu je najjednoduchšie vziať ten prvý a zistiť jeho umiestnenie v scéne:

guard let first = touches.first else { return }
let touchPosition = first.location(in: self)

Potom už stačí len upraviť pozíciu hráča takto:

player.position.x = touchPosition.x

Pretože nesiahame na súradnicu y, tak sa bude hráč pohybovať len horizontálne. Môžete hru zapnúť a vyskúšať.

Tvorba iOS hier vo Swift

Vyjdenie z obrazovky a teleport

Sú tu dva menšie problémy. Hráč môže loď dostať zhruba z polovice mimo obrazovku, čo nie je práve pekné. Okrem toho môže využiť teleportu, keď sa prstom nedotkne priamo lodi.

Vyjdenie z obrazovky

Prvý problém vyrieši guard pred nastavením nové pozície hráča, jednoducho sa spýtame, či je nová súradnice x väčší ako šírka lode a zároveň menšie ako šířka scény - šířka lodi:

guard touchPosition.x > player.size.width && touchPosition.x < size.width - player.size.width else { return }

Opäť môžete vyskúšať :-)

Teleport

A teraz zamedzenie teleportu. Najjednoduchšie bude vytvorenie bool premenné, ktoré nám povie, či sa hráč dotkol lodi. Inak mu pohyb nedovolíme. Vytvoríme teda premennú:

var shouldMovePlayer = false

A presunieme sa do metódy touchesBegan(). Tu sa opäť opýtame na prvý dotyk a pomocou dostupných metód zistíme, či sa hráč dotkol lodi. Celé to bude vyzerať takto:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let first = touches.first else { return }
        let tapped = nodes(at: first.location(in: self))
        shouldMovePlayer = tapped.contains(player)
}

Metóda nodes(at: ) je veľmi užitočná. Zo zadanej pozície v scéne nám vráti všetky objekty (teda SKNode), ktoré sa na danom mieste nachádzajú.

Potom už stačí upraviť touchesMoved() a pridať na začiatok ďalšej guard, kde overíme pridanou bool premennú:

guard shouldMovePlayer else { return }

A samozrejme nesmieme zabudnúť na situáciu, kedy hráč prestane jazdiť prstom po displeji. V metóde touchesEnded() nastavíme premennú opäť na false:

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        shouldMovePlayer = false
}

Môžete vyskúšať. Teraz už ide posúvať loď len pri priamom dotyku.

Časticové efekty

Na záver tejto lekcie si ukážeme, ako hru oživiť časticami. Tie nám neskôr poslúži k vytvoreniu explózií. Zatiaľ je využijeme na simulovanie "prachu" vo vesmíre, aby sme získali dojem, že sa hráč skutočne pohybuje.

Časticové efekty môžu znieť ako obtiažna časť vývoja hier, ale SpriteKit nám prácu s nimi podstatne uľahčuje. Primárne vďaka vizuálnemu editore a pripraveným šablónam.

Hviezdny prach

Pridajte si teda do projektu nový súbor a ako typ vyberte "SpriteKit Particle File" a ako šablónu "Snow". Ako názov som zvolil Space Dust.

Na začiatok vyzerá východzí sneh celkom dobre. Padá smerom, ktorý chceme, takže nás čakajú skôr menšie úpravy.

Najskôr upravíme hodnotu "Position range" na 750 pre x (čo je šírka scény) a 0 pre y. To znamená, že sa častice budú objavovať sa súradnicou x niekde v rozmedzí 0750.

Ďalej som nastavil "Speed" na hodnoty 20 pre "Štart" a 0 pre "Range". Teda konštantnú rýchlosť. Častice som tiež zmenšil nastavením "Scale" na 0.05 a "Range" na rovnakú hodnotu.

Počet sa ovláda pomocou nastavenia "Emitter" úplne hore, kde som pre "Birthrate" nastavil 20. Ako posledný som nastavil "Lifetime" na 20, aby častice nezmizli, kým sú vidieť na obrazovke.

Tu samozrejme zas platí, že hodnoty vyššie sú skôr odporúčané. Skúste si s nastavením pohrať a vytvoriť si častice vlastný :-)

Pridanie častíc do scény

Teraz už stačí pridať častice do scény. Opäť začneme s metódou createParticles(). Pre častice máme špeciálnu SKEmitterNode, ktorú vytvoríme a odovzdáme ju náš súbor:

func createParticles() {
        if let spaceDust = SKEmitterNode(fileNamed: "SpaceDust") {
            spaceDust.zPosition = -1
            spaceDust.position = CGPoint(x: size.width / 2, y: size.height)
            addChild(spaceDust)
        }
}

Je to podobné, ako u pozadie a hráča. Vytvoríme objekt, nastavíme zPosition a position tak, aby častice začínali uprostred hornej hrany. Potom už len stačí pridať do scény.

Teraz môžete hru vyskúšať, bude o poznanie živšie.

AdvanceSimula­tionTime ()

Máme tu ale problém, pretože po spustení efekt nevyzerá dobre, pretože časticiam zaberie, než zaplní celú obrazovku.

Našťastie má SKEmitterNode skvelú metódu, ktorá toto rieši. Volá sa advanceSimulationTime() a dovolí nám vlastne "pretočiť" čas simulácie. Nastavil som hodnotu na 15, tesne pred addChild(spaceDust) a po spustení výsledok vyzerá oveľa lepšie.

Výsledok je veľmi pôsobivý:

Časticový efekt v SpriteKit pre iOS - Tvorba iOS hier vo Swift

Pokračovať budeme nabudúce, v lekcii Nepriatelia a ich pohyb vo SpriteKit .


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 26x (119.84 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Swift

 

Predchádzajúci článok
Úvod do tvorby iOS hier s frameworkom SpriteKit
Všetky články v sekcii
Tvorba iOS hier vo Swift
Preskočiť článok
(neodporúčame)
Nepriatelia a ich pohyb vo SpriteKit
Článok pre vás napísal Filip Němeček
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje vývoji iOS aplikací (občas macOS)
Aktivity