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