BF Summer sales
Pouze tento týden sleva až 80 % na HTML & CSS a JavaScript
80 % bodů zdarma na online výuku díky naší Letní akci!

Lekce 8 - Další částicové efekty ve SpriteKit

V minulé lekci, Dokončení kolizí ve SpriteKit, jsme zprovoznili kolize při střílení.

Hra již obstojně funguje, ale stále je to takové suché, nemyslíte? Skvělá příležitost přidat si částicové efekty exploze a laseru.

Efekt exploze

Začneme efektem exploze.

Vytvoření efektu

Vytvoříme tedy nový soubor pojmenovaný Explosion.sks a jako šablonu vybereme opět oheň.

Nejdůležitější je zde nastavení pro Emitter, kde zvolíme Birthrate 900 a Maximum 300. Tím zajistíme, že se velmi rychle zobrazí 300 částic a další již nebudou vytvořeny. Designer v Xcode přehrává preview pořád dokola, při použití ale uvidíme pouze jeden výbuch.

Dále jsem nastavil Lifetime na 0.4, aby částice rychle zmizely. Position Range 10 pro X a Y. Nastavení Angle na 0° a Range na 360° zajistí rovnoměrnou explozi do všech směrů. Speed jsem nastavil na 200 a Range na 50. Acceleration na 0 pro X a Y.

Potom jsem ještě upravil Color Ramp pro úpravu barvy. Kliknutím na slider přidáte druhý kontrolní bod a klikem na něj můžete upravit barvu. Zvolil jsem světle oranžovou a kontrolní bod posunul, viz obrázek níže:

Myslím, že výsledek nevypadá vůbec špatně :-) :

Exploze ve SpriteKit hře pro iOS ve Swift

Ve skutečné hře by to samozřejmě chtělo více variant exploze. Takže byste mohli první výsledek rozkopírovat a mírně upravit parametry, aby nepřátelé nebouchali tak repetitivně.

Spuštění efektu

Upravíme metodu missileHit(), kde nejdříve nastavíme name obou objektů na nil a vytvoříme explozi. Tu nastavíme na bod kontaktu:

missile.name = nil
enemy.name = nil
if let explosion = SKEmitterNode(fileNamed: "Explosion") {
    explosion.position = point
    explosion.zPosition = 5
    addChild(explosion)
}
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Jména nastavujeme na nil jako pojistku, aby náhodou nedošlo k rozpoznání druhého kontaktu mezi objekty, se kterými ještě pracujeme.

Pro odebrání nepřítele můžeme ještě vytvořit krátkou SKAction s animací, aby okamžitě nezmizel:

let fadeOut = SKAction.fadeIn(withDuration: 0.2)
let sequence = SKAction.sequence([fadeOut, SKAction.removeFromParent()])
enemy.run(sequence)

Samozřejmě nezapomeňte odstranit původní volání enemy.removeFromParent().

Možná si všimnete drobné chybky a sice, že můžeme zneškodnit nepřítele, který má již připravenou laserovou střelu. Pak to vypadá, že se objevila z prázdna. To vyřešíme později.

Efekt zásahu laserem

Zásah raketou máme, teď je čas na zásah hráče. Na závěr lekce tedy připravíme další částicový efekt a vyřešíme kolizi laseru a hráče. Později hráči přidáme životy, teď bude zatím nesmrtelný.

Vytvoření efektu

Laser by měl spíše způsobit menší kouř než plnohodnotnou explozi. Přidáme si tedy nový soubor s částicemi a jako šablonu vybereme Smoke. Birthrate jsem nastavil na 900 a Maximum na 10. Dále Lifetime Start na 0.5 a Range na 0.1. Position Range 5 pro X a 10 pro Y. Dále Angle Start na 90° a Range 180°, takže dojde k pokrytí směru, odkud bude hráč zasažen laserem. Speed Start nastavíme na 40 a Range na 0. A konečně Alpha Start 0.2 a Range 0.1.

A výsledek:

Efekt laseru ve SpriteKit

Jako vždy můžete experimentovat a vytvořit si vlastní efekt nebo klidně několik a střídat je náhodně.

Opět platí, že opakování je vidět pouze v náhledu.

Přidání efektu

Přidání efektu po zasažení hráče je skoro stejné jako u raket a nepřátel. Připravíme si metodu pro reakci na zasažení hráče:

func laserHitPlayer(_ laser: SKNode, at point: CGPoint) {
}

Pro objekt hráče máme referenci přímo v GameScene, takže parametr není potřeba. Teď stačí v didBegin() detekovat kolizi laseru a hráče:

if nodeA.name == "laser" || nodeB.name == "laser" {
    if nodeA.name == "player" {
        laserHitPlayer(nodeB, at: contact.contactPoint)
    } else {
        laserHitPlayer(nodeA, at: contact.contactPoint)
    }
}

Na konec předchozí podmínky pro rakety jsem přidal return, aby zbytečně metoda nezkoušela vyhodnotit druhou podmínku, když jsme kolizi již zpracovali.

A nakonec zbývá doplnit metodu laserHitPlayer(). Nejdříve vymažeme jméno a přidáme efekt kouře:

laser.name = nil
if let laserHit = SKEmitterNode(fileNamed: "LaserHit") {
    laserHit.position = point
    laserHit.zPosition = 5
    addChild(laserHit)
}

Efekt pohlcení střely lodí

Bylo by hezké nějak zapracovat s objektem laserové střely. Můžeme zkusit vytvořit efekt, že je celá střela vlivem nárazu "pohlcena" lodí hráče. To zní docela komplexně. Pomocí SKAction můžeme změnit škálu (rozměr) buď celkově nebo na ose X či Y. Když změníme škálu Y na 0, můžeme tím dosáhnout efektu, kdy bude animací laserová střela zmenšena, jako by reagovala na zásah. Jenže bude zmenšena do svého středu. Můžeme si ale pomoci druhou SKAction, která zmenšující se střelu posune po ose Y a tím navodí dojem, že se zmenšuje přesně v bodě, kde trefila loď hráče :-)

Protože je na střele již jedna aktivní SKAction pro její pohyb, tak nejdříve odstraníme všechny akce a potom pomocí guard přetypujeme objekt na SKSpriteNode. Budeme totiž potřebovat získat výšku:

laser.removeAllActions()
guard let laser = laser as? SKSpriteNode else { return }

Nyní již stačí "jen" poskládat SKAction do sekvence:

let shrink = SKAction.scaleY(to: 0, duration: 0.2)
let move = SKAction.moveBy(x: 0, y: -laser.size.height / 2, duration: 0.2)
let fadeOut = SKAction.fadeOut(withDuration: 0.1)
let group = SKAction.group([shrink, move])
let sequence = SKAction.sequence([group, fadeOut, SKAction.removeFromParent()])

laser.run(sequence)

Můžeme zakomentovat nastavení timeru playerFireTimer a podívat se, jak zásah laserem bude vypadat:

Animace zásahu laserem v iOS hře ve SpriteKit ve Swift

Aktuálně hra vypadá takto:

Vesmírná střílečka ve SpriteKit ve Swift

V příští lekci, Přidání parallax efektu a životů hráče ve SpriteKit, už budeme dolaďovat drobnosti. Přidáme hráči životy a ukážeme si paralax efekt.


 

Stáhnout

Staženo 3x (962.35 kB)
Aplikace je včetně zdrojových kódů v jazyce Swift

 

Předchozí článek
Dokončení kolizí ve SpriteKit
Všechny články v sekci
SpriteKit - Tvorba iOS her ve Swift
Článek pro vás napsal Filip Němeček
Avatar
Jak se ti líbí článek?
1 hlasů
Autor se věnuje vývoji iOS aplikací (občas macOS) či těch webových ve frameworku Django. Twitter: @nemecek_f | GitHub nemecek-filip - mrkněte na veřejné projekty
Aktivity (5)

 

 

Komentáře

Avatar
Radek
Člen
Avatar
Radek:3. ledna 15:44

K nakousnutému tématu, že by bylo možno použít více animací exploze: zkusil jsem to, tímto způsobem:

let explosionAnimation: [String] = (1...4).map({ "Explosion\($0)"})

if let explosion = SKEmitterNode(fileNamed: explosionAnimation.randomElement()!) {
...

Furt mi to zobrazovalo jen tu první nebo žádnou, až jsem přišel na to, že nakopírované a upravené .sks animace v Xcode se nepropsaly správně do pbxproj souboru. Je proto lepší si ty .sks soubory nakopírovat na úrovni filesystému a pak přidat v Xcode, než je přímo kopírovat v Xcode přes option + drag&drop.

 
Odpovědět
3. ledna 15:44
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 1 zpráv z 1.