Lekce 4 - Střílení raket a další částicové efekty ve SpriteKit
V předchozí lekci, Nepřátelé a jejich pohyb ve SpriteKit, jsme úspěšně rozpohybovali nepřátele.
Je na čase přidat do hry arzenál. Implementujeme střílení raket hráčem.
Střílíme rakety
Loď hráče a později také nepřátelé budou střílet rakety, abychom hru pořádně oživili. Začneme implementací raket hráče. V první řadě potřebujeme obrázek:
Modely
Protože se nám začíná GameScene dost plnit a vytvoření a
nastavení raket by mělo být záležitostí objektu hráče, vytvoříme si
novou třídu Player, která bude dědit od
SKSpriteNode. Rovnou jsem si vytvořil novou group v projektu
pojmenovanou Model. Později si totiž vytvoříme i vlastní
třídu pro nepřátele.
Jediný menší zádrhel je metoda init(), protože musíme
použít výchozí, aby byl kompilátor spokojený, a zároveň implementovat
další povinnou. Bude to vypadat takto:
import SpriteKit class Player: SKSpriteNode { init() { let texture = SKTexture(imageNamed: "player") super.init(texture: texture, color: .clear, size: texture.size()) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
Potom již stačí v GameScene.swift změnit, jak se hráč
vytváří:
let player = Player()
Tvorba raket
A nyní slibované rakety. Naší nové třídě Player
přidáme metodu createMissiles(), která bude vracet
SKNode.
Podobně jako u nepřátel, i pro dvojici raket využijeme "kotvu" pro snadnější pozicování a animování:
func createMissiles() -> SKNode { let missilesAnchor = SKNode() missilesAnchor.position = position missilesAnchor.zPosition = -1 // Sem budeme ještě psát další kód... return missilesAnchor }
Pozici nastavíme na aktuální pozici hráče a rovnou nastavíme nižší
zPosition, aby byly rakety pod hráčem. Nyní vytvoříme dva
objekty naší rakety, pro tvorbu druhého jsem opět zvolil kopírování:
let missile1 = SKSpriteNode(imageNamed: "playerMissile") let missile2 = missile1.copy() as! SKSpriteNode
Co se týče pozicování, tak zde záleží, jaký používáte model pro hráče. Pro ten můj bude každá z raket na jednom křídle:
missile1.position = CGPoint(x: 25, y: -5) missile2.position = CGPoint(x: -25, y: -5)
Zbývá rakety přidat pod missilesAnchor a tento objekt
vrátit:
missilesAnchor.addChild(missile1)
missilesAnchor.addChild(missile2)
return missilesAnchor
Pohyb raket
Rovnou můžeme ve třídě Player vytvořit
SKAction pro pohyb raket:
static var missileMovement: SKAction { let move = SKAction.moveBy(x: 0, y: 1500, duration: 3) let remove = SKAction.removeFromParent() return SKAction.sequence([move, remove]) }
Tímto zajistíme, že se raketa dostane daleko mimo obrazovku a až potom ji
odebereme. Rychlost 3 sekundy mi přijde optimální, ale můžete
si nastavit vlastní.
Odpálení raket
A konečně se dostáváme k odpálení raket! Vraťme se do
GameScene.swift a nejdříve si založíme proměnou pro
Timer, který se bude starat o střelbu hráče:
var playerFireTimer: Timer?
Potřebujeme metodu, kterou bude náš nový timer v pravidelných intervalech volat. V ní rovnou přidáme a spustíme rakety:
@objc func playerFireTimerTick() { let missiles = player.createMissiles() addChild(missiles) missiles.run(Player.missileMovement) }
A náš timer v didMove() nakonfigurujeme:
playerFireTimer = Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(playerFireTimerTick), userInfo: nil, repeats: true)
Parametr timeInterval je na vás, záleží, jak rychle chcete,
aby mohl hráč "kosit" nepřátele. Třeba ho později můžeme zapracovat do
obtížnosti?
Hru můžeme zapnout a podívat se na výsledek:
Částicové efekty
Rakety už létají, ale zatím celkem nudně. Proto je nyní oživíme částicovými efekty.
Vytvoření efektu ohně
Vytvořil jsem si rovnou novou group pojmenovanou Particles a
přesunul tam SpaceDust.sks. Rovnou vytvoříme nový soubor
pojmenovaný RocketFire.sks. Jako šablonu zvolíme "Fire".
Pokud se chcete zbavit varování o duplicitě obrázků pro částice,
stačí otevřít Assets.xcassets na úrovni projektu a smazat
položku "Particle Sprite Atlas".
Můj obrázek rakety je široký 12 bodů, takže to samé je třeba nastavit
částicím. Jako první nastavíme tedy "Position Range" a to 6
pro X (neboli polovinu šířky rakety) a 0 pro Y. Dále "Angle" na
270, abychom pohyb částic správně otočili.
Dále jsem nastavil "Birthrate" na 200, potom také "Speed" na
300 a "Range" u "Speed" na 50. No a potom už jen
"Alpha" na 1.
Opět připomínám, že se jedná o vaši hru a můžete si vyrobit takové efekty, které se líbí vám.
Efekt vypadá zhruba takto:
Použití efektu
Nyní již stačí nové částice použít. Máme připravenou třídu
Player a vytvoření částic provedeme v metodě
createMissiles() a to hned za nastavením pozic pro naše
rakety:
if let missile1Fire = SKEmitterNode(fileNamed: "RocketFire") { missile1Fire.zPosition = -2 missile1Fire.position.y = -(missile1.size.height / 2) missile1.addChild(missile1Fire) let missile2Fire = missile1Fire.copy() as! SKEmitterNode missile2.addChild(missile2Fire) }
Vytvoření SKEmitterNode již znáte. Dále nastavíme
zPosition pod naše rakety a pozici na "konec" naší rakety. Oheň
stačí přidat pomocí addChild() a využít copy()
pro vytvoření části pro druhou raketu.
Hru můžeme vyzkoušet, celé to vypadá o poznání lépe:
Zvukové efekty
Na závěr dnešní lekce si přidáme zvukový efekt a to pro vystřelení
raket. Největší problém bude zřejmě najít zvuk vypálené rakety. Vy
můžete použít cokoliv, pokud hru nebudete šířit. Já jsem chvíli na
internetu hledal "rocket launch free sound effect" a jeden takový našel.
Vytvořil jsem si novou složku v projektu pojmenovanou Sounds/ a
.wav soubor tam nakopíroval.
Přehrání zvuku
Přehrávání zvuku je ve SpriteKit hodně jednoduché. Bude nám stačit
jedna SKAction. Vytvoříme si konstantu pro přehrávání efektu
v naší GameScene:
let rocketLaunchSoundAction = SKAction.playSoundFileNamed("rocketLaunch", waitForCompletion: false)
Samozřejmě místo "rocketLaunch" zadejte název vašeho
zvukového souboru 
A potom stačí spustit přímo v herní scéně při vypálení rakety:
@objc func playerFireTimerTick() { let missiles = player.createMissiles() addChild(missiles) run(rocketLaunchSoundAction) missiles.run(Player.missileMovement) }
SKAction by šlo vytvořit přímo v tomto kroku, měl jsem ale
pocit, že to způsobuje drobné zaseknutí hry, tak jsem si ji připravil jako
konstantu.
V příští lekci, Nepřátelé střílí zpět a dokonce laserem ve SpriteKit, začnou nepřátelé střílet zpět.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 14x (651.32 kB)
Aplikace je včetně zdrojových kódů v jazyce Swift

