Vytvorte si svoju prvú hru pre iPhone od nuly, nevyžaduje sa žiadna skúsenosť s kódovaním.

úvod

Tento tutoriál bol napísaný pre verziu Swift 4.0 / XCode 9, všetky budúce verzie môžu mať problémy, až kým tento článok neaktualizujem.

Zaujíma vás teda stavba mobilných hier? Možno je to pôvab vzletu a nákupu nového automobilu, alebo je to jednoducho vášeň vytvorenia vlastnej hry. Nech už je váš motív akýkoľvek, tento tutoriál vás prevedie krokmi nastavenia počítača na zostavenie aplikácií a vytvorenie jednoduchej hry od začiatku! Celý herný kód je zahrnutý v návode; na dokončenie tohto projektu nie sú potrebné žiadne predchádzajúce znalosti programovania.

Po dokončení tohto tutoriálu budete môcť na svojom zariadení alebo na simulátore zariadení spustiť aplikáciu IOS vlastnej konštrukcie. Pochopíte základy navrhovania hry od nuly, ako ukladať údaje do zariadenia po ukončení aplikácie, ako vykresliť škvrny na obrazovke a začnete chápať, ako používať herný engine SpriteKit. Prevediem vás tiež tým, ako som navrhol hru Snake a ako môžete začať vytvárať hru podľa vlastného návrhu!

Tu je odkaz na stiahnutie na mierne upravenú verziu tejto hry, ktorá je k dispozícii v obchode App Store: https://itunes.apple.com/us/app/minimal-snake/id1355406338?mt=8 (úplne zadarmo bez reklám).

Poznámka: V celom článku, ktorý som používal termín kópia / vloženie, mi čitateľ poukázal na to, že je to zlý postup a úplne súhlasím. Ak však chcete kód rýchlo skopírovať a vytvoriť funkčný produkt, ktorý je v poriadku, pravdepodobne budete mať viac zo zapisovania každého riadku ručne!

Dokončený produkt

Tu je video, ktoré demonštruje, čo budete do konca tohto tutoriálu zostaviť a nainštalovať do svojho telefónu!

Začíname

Ak sa chcete riadiť týmto tutoriálom, musíte si vytvoriť účet vývojára spoločnosti Apple a prevziať Xcode (program používaný na vytváranie aplikácií pre IOS). Xcode je bohužiaľ k dispozícii iba pre počítače Mac; ak máte počítač so systémom Windows / Linux, je tu webová stránka, ktorá vám môže pomôcť nastaviť Xcode.

Tieto ďalšie kroky vás prevedú registráciou bezplatného účtu vývojára a inštaláciou Xcode. Ak už máte účet a Xcode, môžete prejsť na ďalšiu časť. Najprv navštívte webovú stránku developer.apple.com a kliknite na členské centrum, potom sa prihláste pomocou svojho Apple ID. Prejdite na stránku Apple Developer Agreement a akceptujte zmluvu; teraz máte bezplatný účet vývojára! Ak chcete nahrať svoje projekty do obchodu s aplikáciami, budete musieť zaplatiť ročný poplatok 100 $.

Teraz, keď máte účet vývojára, musíte nainštalovať Xcode. Xcode je dostupný cez Mac App Store. Po nainštalovaní Xcode spustite program a kliknite na Xcode -> Predvoľby -> Účty -> + a zvoľte Pridať Apple ID. Prihláste sa pomocou Apple ID, ktoré sa používa na registráciu účtu vývojára. Gratulujeme, teraz môžete vyskúšať svoje aplikácie v simulátore iPhone alebo ich spustiť na svojom osobnom zariadení!

Začiatok projektu

Teraz, keď ste sa zaregistrovali na účet vývojára a nainštalovali Xcode, môžete začať vyvíjať svoju prvú mobilnú hru!

Spustite Xcode a kliknite na „Vytvoriť nový projekt Xcode“.

Kliknite na šablónu „Hra“.

Zadajte názov svojej hry „Snake“ (alebo čokoľvek chcete) pre svoju hru. Vyberte názov organizácie, ak máte webovú stránku, ktorú môžete zadať dozadu (com.gavinshrader), alebo môžete jednoducho použiť svoje meno ako identifikátor. Skontrolujte, či je jazyk nastavený na „Swift“ a či herná technológia je „SpriteKit“. Zrušte začiarknutie políčok 3, ak sú začiarknuté.

Kliknite pravým tlačidlom myši na „Actions.sk“ a presuňte sa do koša. Prejdite na GameScene.sk a kliknite na text „Hello World“ a potom ho odstráňte. Prejdite na GameScene.swift a odstráňte všetok preddefinovaný kód tak, aby sa váš súbor zhodoval s obrázkom nižšie.

Vytvorte nový súbor Swift tak, že prejdete do ponuky Súbor -> Nový súbor a kliknete na súbor Swift alebo pravým tlačidlom myši kliknete na priečinok projektu („Snake“) a vyberiete nový súbor. Nájdite ikonu súboru Swift, ktorá je zvýraznená nižšie, ak sa na paneli s filtrami nenachádza, napíšte „Swift“. Zadajte názov „GameManager“ a uistite sa, že váš projekt („had“) je vybratý v rámci cieľov, kliknutím na „Vytvoriť“ vytvorte nový rýchly súbor.

Vytvorenie ponuky hry

Predtým, ako začneme s kódovaním, skontrolujte, či sa váš projekt skompiluje po vykonaní zmien v poslednej časti. Vyberte zariadenie zo zoznamu simulátorov, kliknite na tlačidlo, kde sa nachádza „iPhone 6“, pravdepodobne bude označené ako „Generické zariadenie pre iOS“. Ak chcete vyskúšať pripojenie zariadenia iPhone k fyzickému zariadeniu, dajte chvíľu Xcode a potom kliknite na svoje zariadenie. Po dokončení kliknite na tlačidlo trojuholníkového spustenia. Ak ste vybrali simulované zariadenie, táto obrazovka by sa mala zobraziť:

Ak sa na obrazovke zobrazuje „Ahoj svet“, uistite sa, že ste štítok odstránili tak, že prejdete na stránku GameScene.sk, kliknutím na štítok a výberom možnosti Odstrániť.

Sme konečne pripravení začať hru! Keď začnete hru, pomôže vám to vopred rozložiť obrazovky. V tejto hre začneme jednoduchou obrazovkou s ponukou, ktorá zobrazuje názov / logo hry. Tlačidlo prehrávania spustí obrazovku hry s oblasťou hry a dvoma štítkami pre vaše aktuálne skóre a najlepšie skóre. Keď zomriete, zobrazí sa obrazovka s možnosťou ukončenia hry.

Aby sme mohli hru spustiť, musíme si najprv postaviť menu, aby sme mohli hru začať. Začneme písaním kódu, ktorý inicializuje menu pridaním názvu hry, menovky „najlepšie skóre“ a tlačidla pre prehrávanie. Otvorte súbor GameScene.swift a skopírujte celý kód zdola, aby sa váš súbor zhodoval s obrázkom (obrázok A).

// 1
var gameLogo: SKLabelNode!
var bestScore: SKLabelNode!
var playButton: SKShapeNode!
// 2
initializeMenu ()
// 3
private func initializeMenu () {
    // Vytvorenie názvu hry
    gameLogo = SKLabelNode (fontNamed: "ArialRoundedMTBold")
    gameLogo.zPosition = 1
    gameLogo.position = CGPoint (x: 0, y: (frame.size.height / 2) - 200)
    gameLogo.fontSize = 60
    gameLogo.text = "SNAKE"
    gameLogo.fontColor = SKColor.red
    self.addChild (gameLogo)
    // Vytvorte štítok s najlepším skóre
    bestScore = SKLabelNode (fontNamed: "ArialRoundedMTBold")
    bestScore.zPosition = 1
    bestScore.position = CGPoint (x: 0, y: gameLogo.position.y - 50)
    bestScore.fontSize = 40
    bestScore.text = "Najlepšie skóre: 0"
    bestScore.fontColor = SKColor.white
    self.addChild (bestScore)
    // Tlačidlo Vytvoriť prehrávanie
    playButton = SKShapeNode ()
    playButton.name = "play_button"
    playButton.zPosition = 1
    playButton.position = CGPoint (x: 0, y: (frame.size.height / -2) + 200)
    playButton.fillColor = SKColor.cyan
    nechať topCorner = CGPoint (x: -50, y: 50)
    nechať bottomCorner = CGPoint (x: -50, y: -50)
    nech stred = CGPoint (x: 50, y: 0)
    nech cesta = CGMutablePath ()
    path.addLine (do: topCorner)
    path.addLines (medzi: [topCorner, bottomCorner, middle])
    playButton.path = cesta
    self.addChild (playButton)
}
Obrázok A

Zostavte svoj kód a skontrolujte, či vaše zariadenie zobrazuje obrázok zhora. Toto je vysvetlenie toho, čo sa tu deje, môže to vyzerať ako stena kódu, ale pri jeho poruche je ľahké porozumieť.

  • 1: Vytvárame premenné pre logá / tlačidlá. „!“ Za názvom premennej znamená, že musíme inicializovať premenné, nemôžu byť prázdne alebo „nulové“.
  • 2: Funkciu „initializeMenu ()“ nazývame po načítaní zobrazenia hry. didMove (do: view: SKView) je funkcia, ktorá sa nazýva, keď sa načíta náš GameScene.
  • 3: Toto je funkcia intializeMenu (), ktorú sme napísali na vytvorenie objektov ponuky.
  • 4/5/6: Vytvorte objekty a pridajte ich do GameScene volaním „self.addChild ()“.
  • 7: Rozhodol som sa pre tento projekt použiť SKShapeNodes pre svoju jednoduchosť, je to alternatíva k vytvoreniu vašej grafiky v editore obrázkov. Tento riadok kódu vytvára cestu v tvare trojuholníka. Vezmite prosím na vedomie, že ak plánujete zostavenie a publikovanie aplikácie, ktorú by ste mali použiť na načítanie obrázka, ktorý ste vytvorili, pomocou SKSpriteNodes, ShapeNodes môže spôsobiť problémy s výkonom, keď sa použije vo veľkom množstve, pretože sa dynamicky vykresľuje raz za snímku.
  • 8: Nastavte trojuholníkovú cestu, ktorú sme vytvorili, do sprintu playButton a pridajte ju do GameScene.

Hranie hry

Teraz, keď máme jednoduché nastavenie ponuky, spustíme tlačidlo prehrávania. Najprv prejdite do súboru GameManager.swift a nahraďte ho celým kódom tak, aby sa zhodoval s obrázkom nižšie (obrázok B).

import SpriteKit
trieda GameManager {
}
Obrázok B

Skopírujte nižšie uvedený kód do svojho súboru GameScene.swift tak, aby sa zhodoval s obrázkom nižšie (obrázok C).

// 1
hra var: GameManager!
// 2
game = GameManager ()
// 3
prepísať func touchesBegan (_ touches: Set , s udalosťou: UIEvent?) {
    pre dotyk v dotykoch {
        let location = touch.location (in: self)
        let touchedNode = self.nodes (at: location)
        pre uzol v dotychedNode {
            if node.name == "play_button" {
                začať hru()
            }
        }
    }
}
// 4
private func startGame () {
    print ("start game")
}
Obrázok C
  • 1: Inicializácia objektu GameManager. Viac o tom neskôr ... bude obsahovať údaje o skóre a riadiť pohyb hráča.
  • 2: Nastavte premennú hry na nový objekt GameManager ().
  • 3: Túto funkciu nazýva herný engine vždy, keď sa užívateľ dotkne obrazovky. Pripomeňme, že tlačidlo prehrávania, ktoré sme vytvorili skôr, má názov „play_button“. Pomocou mena môžeme skontrolovať, či sa používateľ dotkol SpriteNode s názvom „play_button“, hneď ako sa to stane, zavoláme funkciu startGame () z bodu 4.
  • 4: Táto funkcia spustí hru.

Spustením aplikácie a kliknutím na tlačidlo trojuholníkového prehrávania sa ubezpečte, že váš kód funguje správne. Ak sú vaše dotyky správne zmerané, konzola by mala zobraziť „začiatočnú hru“, ako je uvedené na obrázku nižšie (obrázok D).

Obrázok D

Ak sa vaša konzola nezobrazuje, prejdite na hornú lištu a kliknite na „Pomoc“, do vyhľadávacieho riadku napíšte „Konzola“ a potom kliknite na „Debug Area> Activate Console“. Teraz máme funkčný systém ponúk a tlačidlo prehrávania. Na tomto mieste sa môžeme naozaj pobaviť.

Načítanie zobrazenia hry

Takže teraz máme tlačidlo prehrávania, ktoré môže spustiť funkciu, čo by sme mali robiť? Aby sme mohli ukázať pohľad na hru, musíme najskôr skryť tlačidlá ponuky. Pridajte tento riadok kódu, aby ste skryli tlačidlá ponuky pomocou jednoduchej animácie. Váš kód by sa mal zhodovať s obrázkom nižšie (obrázok E).

// spustiť hru
private func startGame () {
    print ("start game")
    // 1
    gameLogo.run (SKAction.move (autor: CGVector (dx: -50, dy: 600), trvanie: 0,5)) {
    self.gameLogo.isHidden = true
    }
    // 2
    playButton.run (SKAction.scale (do: 0, trvanie: 0.3)) {
        self.playButton.isHidden = true
    }
    // 3
    nech bottomCorner = CGPoint (x: 0, y: (frame.size.height / -2) + 20)
    bestScore.run (SKAction.move (do: bottomCorner, trvanie: 0,4))
}
Obrázok EObrázok F
  • 1: Presuňte hru GameLogo z obrazovky a potom ju skryte pred zobrazením. Hranice po SKAction sa spustia po dokončení akcie. Napríklad, ak spustíme SKAction s trvaním 10, kód v zátvorke by bežal po 10 sekundách. Tu je príklad:
exampleNode.run (SKAction.move (podľa: CGVector (dx: 0, dy: 0), trvanie: 10) {
    print ("Som dosiahnutý po 10 sekundách")
}
  • 2: Zmeniť nastavenie tlačidla play na 0; táto akcia stlačí tlačidlo a potom ho skryje pred zobrazením.
  • 3: Presuňte štítok bestScore do spodnej časti obrazovky.

Vaše menu by sa teraz malo správať ako tento gif (obrázok F), keď kliknete na tlačidlo Prehrať!

Teraz začneme navrhovať skutočnú „hadovú“ časť tejto hry, začnite pridaním týchto riadkov kódu tak, aby sa váš kód zhodoval s obrázkom nižšie (obrázok G).

// 1
var currentScore: SKLabelNode!
var playerPositions: [(Int, Int)] = []
var gameBG: SKShapeNode!
var gameArray: [(uzol: SKShapeNode, x: Int, y: Int)] = []
// 2
initializeGameView ()
// 3
private func initializeGameView () {
    // 4
    currentScore = SKLabelNode (fontNamed: "ArialRoundedMTBold")
    currentScore.zPosition = 1
    currentScore.position = CGPoint (x: 0, y: (frame.size.height / -2) + 60)
    currentScore.fontSize = 40
    currentScore.isHidden = true
    currentScore.text = "Skóre: 0"
    currentScore.fontColor = SKColor.white
    self.addChild (currentScore)
    // 5
    šírka = frame.size.width - 200
    výška = frame.size.height - 300
    nechať rect = CGRect (x: - šírka / 2, y: - výška / 2, šírka: šírka, výška: výška)
    gameBG = SKShapeNode (rect: rect, cornerRadius: 0.02)
    gameBG.fillColor = SKColor.darkGray
    gameBG.zPosition = 2
    gameBG.isHidden = true
    self.addChild (gameBG)
    // 6
    createGameBoard (šírka: šírka, výška: výška)
}
Obrázok GObrázok G
  • 1: Nové premenné! Vytvárame štítok, ktorý zobrazuje aktuálne skóre, pole všetkých pozícií, ktoré má „had“ alebo hráč v súčasnosti, pozadie nášho pohľadu na hru a pole na sledovanie pozícií každej bunky v zobrazení hry.
  • 2: Zavolajte funkciu initializeGameView ().
  • 3: Inicializuje zobrazenie hry.
  • 4: Pridajte na obrazovku aktuálny štítok so skóre, toto je skryté, kým neopustíme našu ponuku.
  • 5: Vytvorte ShapeNode, ktorý bude reprezentovať hrateľnú oblasť našej hry. Tu sa bude hada pohybovať.
  • 6: Vytvorte hernú dosku. Táto funkcia inicializuje tonu štvorcových buniek a pridá ich do hracej plochy.

Ďalej chceme vytvoriť rad buniek, ktoré použijeme na vykreslenie hada a bodov na obrazovke. Vytvorte funkciu createGameBoard z nižšie uvedeného kódu tak, aby zodpovedala obrázku H.

// vytvorte hernú dosku, inicializujte rad buniek
private func createGameBoard (width: Int, height: Int) {
    nechať šírku bunky: CGFloat = 27,5
    nech numRows = 40
    nech numCols = 20
    var x = CGFloat (šírka / -2) + (šírka bunky / 2)
    var y = CGFloat (výška / 2) - (šírka bunky / 2)
    // prechádza cez riadky a stĺpce, vytvára bunky
    pre i za 0 ... numRows - 1 {
        pre j za 0 ... numCols - 1 {
            let cellNode = SKShapeNode (rectOf: CGSize (width: cellWidth, výška: cellWidth))
            cellNode.strokeColor = SKColor.black
            cellNode.zPosition = 2
            cellNode.position = CGPoint (x: x, y: y)
            // pridať do poľa buniek - potom pridať na hraciu dosku
            gameArray.append ((uzol: cellNode, x: i, y: j))
            gameBG.addChild (cellNode)
            // iterovať x
            x + = šírka bunky
        }
        // reset x, iterácia y
        x = CGFloat (šírka / -2) + (šírka bunky / 2)
        y - = šírka bunky
    }
}
Obrázok H

Váš kód by sa mal zhodovať s kódom zhora, pri spustení hry sa nič nezmení. Ak chcete vidieť hernú dosku ako na snímke zo simulátora vyššie, pridajte nasledujúci kód do začiatočnej hernej funkcie tak, aby zodpovedal obrázku I.

bestScore.run (SKAction.move (do: bottomCorner, duration: 0.4)) {
    self.gameBG.setScale (0)
self.currentScore.setScale (0)
self.gameBG.isHidden = false
self.currentScore.isHidden = false
self.gameBG.run (SKAction.scale (do: 1, trvanie: 0,4))
self.currentScore.run (SKAction.scale (do: 1, duration: 0.4))
}

Stručné vysvetlenie metódy createGameBoard predtým, ako pôjdeme ďalej. Táto metóda vedie cez 40 riadkov a 20 stĺpcov, pre každú pozíciu riadka / stĺpca vytvoríme nové štvorcové pole alebo „cellNode“ a pridáme ho na scénu. Tento cellNode tiež pridávame do poľa „gameArray“, aby sme mohli ľahko označiť riadok a stĺpec do príslušnej bunky.

Obrázok I - zobrazuje novú hernú dosku!

Vytvorenie inštancie hry

Teraz máme funkčné tlačidlo na hranie, krabicu plnú menších krabíc a niektoré štítky. Ako z toho môžeme urobiť hru, ktorá je skutočne zábavná? Najprv budeme potrebovať objekt na sledovanie polohy „hada“ na obrazovke, aby sme sa mohli pohybovať. Otvorte triedu GameManager.swift a vytvorte nasledujúce metódy. Túto zmenu (// 1) pridajte aj do funkcie didMove (na zobrazenie: SKView) v GameScene.swift, aby sa váš kód zhodoval s obrázkom J.

// 1 - GameScene.swift
game = GameManager (scéna: samostatne)
// 2 - GameManager.swift
trieda GameManager {
    
    Var scéna: GameScene!
    init (scéna: GameScene) {
        self.scene = scéna
    }
}
Obrázok J

Vykonaním týchto zmien hovoríme, že GameManager musí po inicializácii obsahovať odkaz na triedu GameScene. Teraz môže trieda GameManager komunikovať s GameScene volaním scene.method_name. Napríklad scene.startGame () spustí funkciu spustenia hry z dosahu triedy GameManager.

Teraz sme pripravení načítať prehrávač do GameView. Najprv pridajte nasledujúci útržok kódu do súboru GameScene.swift v metóde startGame () vo vnútri zátvoriek bestScore.run () {} Táto metóda zavolá funkciu initGame, keď štítok bestScore dokončí svoju SKAction.

// nový kód
self.game.initGame ()
Obrázok K

Teraz prejdite na stránku GameManager.swift a pridajte nasledujúce metódy pod metódu init (scene: GameScene), aby sa váš kód zhodoval s obrázkom L.

// 1
func initGame () {
    // počiatočná pozícia hráča
    scene.playerPositions.append ((10, 10))
    scene.playerPositions.append ((10, 11))
    scene.playerPositions.append ((10, 12))
    renderChange ()
}
// 2
func renderChange () {
    pre (uzol, x, y) v scene.gameArray {
        ak obsahuje (a: scene.playerPositions, v: (x, y)) {
            node.fillColor = SKColor.cyan
        } else {
            node.fillColor = SKColor.clear
        }
    }
}
// 3
func obsahuje (a: [(Int, Int)], v: (Int, Int)) -> Bool {
    let (cl, c2) = v
    pre (v1, v2) v {if v1 == c1 && v2 == c2 {return true}}
    návrat nepravdivý
}
Obrázok L
  • 1: funkcia initGame (). Tým sa do poľa prehrávača GameScene pre hráča pridajú 3 súradnice,
  • 2: funkcia renderChange (). Túto metódu nazývame zakaždým, keď presunieme hada alebo hráča. Takto budú všetky prázdne štvorce jasné a všetky štvorce, v ktorých sa hráč nachádza, sú azúrové.
  • 3: Jedná sa o jednoduchú funkciu, ktorá kontroluje, či v súbore n-tíc existuje skupina (rýchla dátová štruktúra, ktorá môže obsahovať kombináciu typov vo forme (Int, CGFloat, Int, String) ... atď.). Táto funkcia skontroluje, či pole playerPositions obsahuje zadané súradnice z poľa buniek GameScene. Toto nie je nevyhnutne najúčinnejší spôsob, ako robiť veci, pretože pri každej aktualizácii kontrolujeme každú jednu bunku. Ak chcete napadnúť sami seba, skúste aktualizovať kód tak, aby upravoval iba štvorce z poľa playerPositions!

Posúvanie prehrávača

Obrázok M

Teraz máme nášho hráča vykresleného na obrazovke a schopnosť vykresliť ľubovoľný počet pozícií. Ak do poľa PlayerPositions pridáte viac súradníc, viac políčok sa sfarbí azúrovo. Počas hry chceme neustále hýbať „hadom“ jedným smerom, kým hráč neprejde prstom po obrazovke, aby zmenil smer. Tu je mriežka ukazujúca súradnice nášho mriežkového systému, aby ste mohli ľahko pochopiť, ako súradnice fungujú za scénami (obrázok M).

Ako vidíte z príšerne malých štítkov, ľavý horný roh je 0,0 a dolný pravý roh je 39,19. To znamená, že ak chceme posunúť hráča v smere doľava, doprava, nahor a nadol, robíme tak pomocou nasledujúcej základnej algebry (obrázok N).

Obrázok č

Ako vidíte, smery vľavo / vpravo sa zhodujú so smermi typickej súradnicovej roviny; ľavica je negatívna a pravá je pozitívna. Avšak, aby sme sa posunuli hore na súradnicovej rovine, chceme znížiť y a posunúť nadol chceme zvýšiť y. Je to spôsobené skutočnosťou, že funkcia for for loop vo funkcii createGameBoard začala hore a pracovala nadol.

Teraz, keď pochopíte smer dosky, môžete implementovať metódu, ktorá pohybuje hráčom. Ak otvoríte súbor GameScene.swift, všimnete si šikovnú metódu nazývanú aktualizácia (_ currentTime: TimeInterval). V renderovacej slučke sa funkcia aktualizácie volá raz za sekundu. To znamená, že ak vaša aplikácia beží rýchlosťou 60 snímok / s, funkcia sa nazýva 60-krát za sekundu, ak hra beží rýchlosťou 40 snímok / s, volá sa iba 40-krát za sekundu. Do funkcie aktualizácie pridajte tento riadok kódu tak, aby sa váš kód zhodoval s obrázkom O.

// 1
game.update (čas: aktuálny čas)
Obrázok O

Po pridaní tohto kódu by sa mala objaviť červená chyba, aby ste túto chybu opravili do súboru GameManager.swift a pridali tieto riadky kódu tak, aby sa váš súbor zhodoval s obrázkom P.

// 1
var nextTime: Double?
var timeExtension: Double = 1
// 2
aktualizácia func (čas: Double) {
    ak nextTime == nula {
        nextTime = time + timeExtension
    } else {
        ak čas> = nextTime! {
            nextTime = time + timeExtension
            tlač (čas)
        }
    }
}
Obrázok P

Po spustení aplikácie by konzola mala každú sekundu vytlačiť nový čas. Tu je stručný prehľad toho, čo tento kód robí.

  • 1: inicializujte dve nové premenné. nextTime je interval nextTime, ktorý vytlačíme príkazom na konzole, timeExtension je ako dlho budeme čakať medzi každou tlačou (1 sekunda).
  • 2: Táto aktualizačná funkcia sa nazýva 60-krát za sekundu. Chceme aktualizovať pozíciu hráča iba raz za sekundu, aby hra nebola smiešne rýchla. Aby sme to dosiahli, skontrolujeme, či bol nastavený nextTime. Ako vidíte z // 1, nextTime bol inicializovaný ako voliteľná hodnota. „? „Po Double oznámi rýchlemu prekladaču, že chceme, aby bol nextTime dvojnásobný a aby mohol byť nastavený na nulu. Pri volaní funkcie aktualizácie najskôr skontrolujeme, či bol nastavený nextTime, ak nebol nastavený, nastavíme ho na aktuálny čas + časové predĺženie (1 sekunda). Akonáhle aktuálny čas zatmie „nextTime“, potom sa nextTime zvýši o 1 sekundu. Táto funkcia má teraz funkciu nepravidelnej aktualizácie (približne 30 - 60 krát za sekundu) a produkuje výstup iba raz za sekundu.

Teraz máme funkciu, ktorá beží raz za sekundu, ak chcete zvýšiť rýchlosť svojej hry, jednoducho skráťte čas na predĺženie na hodnotu, ktorá je väčšia ako 0, ak chcete hru spomaliť, potom zvýšte hodnotu času. (Poznámka: „1“ == 1 sekunda pre predĺženie času).

Teraz chceme presunúť prehrávač po obrazovke, pridať nasledujúci kód tak, aby sa váš súbor zhodoval s obrázkom Q. Z funkcie aktualizácie, ktorú sme práve vytvorili v GameManager.swift, odstráňte aj riadok „tlačiť (čas)“, bude to spam konzoly a bol skutočne užitočný iba na testovanie platnosti kódu.

// 1
var playerDirection: Int = 1
// 2
updatePlayerPosition ()
// 3
private func updatePlayerPosition () {
    // 4
    var xChange = -1
    var yChange = 0
    // 5
    switch playerDirection {
        prípad 1:
            // left
            xChange = -1
            yChange = 0
            prestávka
        prípad 2:
            // up
            xChange = 0
            yChange = -1
            prestávka
        prípad 3:
            //správny
            xChange = 1
            yChange = 0
            prestávka
        prípad 4:
            // dole
            xChange = 0
            yChange = 1
            prestávka
        default:
            prestávka
    }
    // 6
    if scene.playerPositions.count> 0 {
        var start = scene.playerPositions.count - 1
        zatiaľ čo štart> 0 {
            scene.playerPositions [start] = scene.playerPositions [start - 1]
            začiatok - = 1
        }
        scene.playerPositions [0] = (scene.playerPositions [0] .0 + yZmeniť, scene.playerPositions [0] .1 + xZmeniť)
    }
    // 7
    renderChange ()
}
Obrázok Q

Po pridaní tohto kódu by vaša hra mala vyzerať ako gif z obrázka Q (nastavte presmerovanie hráča na 4, aby ste dostali rovnaký smer pohybu). Keď som to písal, okamžite mi vystúpili dve veci; Po prvé, had sa pohybuje bolestivo pomaly, možno by sme mali zvýšiť rýchlosť hry z 1 sekundy na 1/2 alebo 1/4 sekundy. Po druhé, čo urobíme, keď had udrie na stenu? V niektorých verziách hada sa hráč deformuje okolo obrazovky, v iných verziách má zrážka so stenou za následok smrť. Páči sa mi vzhľad osnovy obrazovky, takže si myslím, že túto metódu použijeme pre túto hru. Teraz ste práve napísali vysvetlenie tohto kódu:

  • 1: Vytvorte premennú, ktorá sa používa na určenie aktuálneho smeru hráča. V kóde je premenná nastavená na 1, v gif na obrázku Q I nastavím smer na 4. Zmeňte túto premennú, aby ste videli všetky rôzne smery.
  • 2: Odstránili sme tlač (čas) a nahradili ju hovorom updatePlayerPosition (), v tejto iterácii voláme aktualizáciu každú sekundu.
  • 3: Táto metóda posúva hráča alebo „hada“ po obrazovke.
  • 4: Nastavte premenné na určenie zmeny, ktorú by sme mali vykonať na x / y prednej strany hada.
  • 5: Toto je príkaz na prepínanie, ktorý berie vstup prehrávačaPosition a upravuje premenné x / y podľa toho, ako sa hráč pohybuje nahor, nadol, doľava alebo doprava.
  • 6: Tento blok kódu posúva pozície dopredu v poli. Chceme posúvať prednú časť chvosta v správnom smere a potom posúvať všetky chvostové bloky dopredu do ďalšej polohy.
  • 7: Vykreslite zmeny, ktoré sme urobili v rade pozícií.

Pokrútenie hada okolo obrazovky

Teraz máme dojemného hráča, pekná práca! Najprv budeme chcieť zvýšiť rýchlosť hry, ukázalo sa, že čakanie 1 sekunda je príliš pomalé na to, aby sme sa zabavili. Toto je lekcia, ktorú sa naučíte v hernom dizajne, je tu veľa vyladení a drobných zmien, ktoré budete musieť urobiť, aby ste dokonalý pocit z hry urobili. Keď pracujem na projekte, často trávim väčšinu času drobnými zmenami na prispôsobenie pocitu, musíte si zdokonaliť svoju mechaniku, aby ste si vytvorili zábavnú hru; akonáhle budete mať dokonalú mechaniku, môžete pracovať na pridávaní efektných doplnkov, ako sú častice a zvuky.

Zmeňte premennú timeExtension na 0,15 a zostavte svoj projekt.

// 1 - GameManager.swift
var timeExtension: Double = 0,15

Teraz môžeme začať pokrývať hada okolo obrazovky a pridať nasledujúci kód tak, aby sa váš projekt zhodoval s obrázkom R. Poznámka: tento kód sa pridá do funkcie updatePlayerPosition () v GameManager.swift, ktorú sme práve napísali.

// 1
if scene.playerPositions.count> 0 {
    nech x = scene.playerPositions [0] .1
    nech y = scene.playerPositions [0] .0
    ak y> 40 {
        scene.playerPositions [0] .0 = 0
    } inak, ak y <0 {
        scene.playerPositions [0] .0 = 40
    } inak, ak x> 20 {
       scene.playerPositions [0] .1 = 0
    } inak, ak x <0 {
        scene.playerPositions [0] .1 = 20
    }
}
Obrázok R

Po zostavení aplikácie by sa mala vaša obrazovka zhodovať s GIF z obrázku R, v GIF som použil playerDirection 4. Had sa teraz môže zdeformovať okolo každej strany obrazovky.

  • 1: Tento kód je pomerne jednoduchý, skontroluje, či poloha hlavy hada prešla hornou, dolnou, ľavou alebo pravou stranou a potom posúva hráča na druhú stranu obrazovky.

Ovládanie pohybu hada pomocou prejdenia prstom

Naša hra sa blíži, teraz potrebujeme metódu na ovládanie smeru hada. Aby sme to mohli implementovať, použijeme gesta pre pohyb vľavo, vpravo, hore a dole. Pridajte tento kód do svojho súboru GameScene.swift tak, aby zodpovedal obrázku S.

// 1
let swipeRight: UISwipeGestureRecognizer = UISwipeGestureRecognizer (target: self, action: #selector (swipeR))
swipeRight.direction = .right
view.addGestureRecognizer (swipeRight)
nechať prejsť prstom doľava: UISwipeGestureRecognizer = UISwipeGestureRecognizer (target: self, action: #selector (swipeL))
swipeLeft.direction = .left
view.addGestureRecognizer (swipeLeft)
let swipeUp: UISwipeGestureRecognizer = UISwipeGestureRecognizer (target: self, action: #selector (swipeU))
swipeUp.direction = .up
view.addGestureRecognizer (swipeUp)
let swipeDown: UISwipeGestureRecognizer = UISwipeGestureRecognizer (target: self, action: #selector (swipeD))
swipeDown.direction = .down
view.addGestureRecognizer (swipeDown)
// 2
@objc func swipeR () {
    print ( "r")
}
@objc func swipeL () {
    print ( "l")
}
@objc func swipeU () {
    print ( "u")
}
@objc func swipeD () {
    print ( "d")
}
Obrázok S
  • 1: Pridajte do funkcie didMove (na zobrazenie: SKView) prejdené gestá.
  • 2: Vytvorte funkcie, ktoré sa vyvolajú, keď používateľ zadá gesto potiahnutia. "@Objc" pred funkciou vytvorí objektívnu funkciu c, je to potrebné, aby ste ju mohli volať cez #selector v pôvodnom UISwipeGestureRecognizer.

Otestujte si kód zostavením aplikácie a potiahnutím prstom vo všetkých štyroch smeroch. Vaša konzola by mala vytlačiť príslušné písmeno pre každé gesto potiahnutia prstom. Teraz, keď máme nastavené rozpoznávače gest, musíme zmeniť smer pohybu hráča, nahradiť tlačové výroky vnútri funkcií potiahnutia týmto kódom a pridať kód do GameManager.swift tak, aby váš projekt zodpovedal obrázku T.

// 1 - GameScene.swift
game.swipe (ID: 3)
game.swipe (ID: 1)
game.swipe (ID: 2)
game.swipe (ID: 4)
// 2 - GameManager.swift
func swipe (ID: Int) {
    ak! (ID == 2 && playerDirection == 4) &&! (ID == 4 && playerDirection == 2) {
        if! (ID == 1 && playerDirection == 3) &&! (ID == 3 && playerDirection == 1) {
            playerDirection = ID
        }
    }
}
Obrázok TObrázok T
  • 1: Po zistení prejdenia prstom sa upozorní trieda gameManager.
  • 2: Ak prejdenie prstom nie je v rozpore s aktuálnym smerom, nastavte smer hráča na vstup pre prejdenie prstom. Ak sa pohybujete nadol, nemôžete okamžite ísť hore. Ak sa pohybujete vľavo, nemôžete sa náhle pohnúť doprava. V niektorých verziách hadího vstupu nevhodného pohybu by to malo za následok smrť, ale v tejto verzii jednoducho ignorujeme cudzie vstupy.

Pridanie bodov do hry a úprava skóre

Teraz máme funkčný systém ponúk, ktorý otvára hernú dosku, pole buniek, pole pozícií hráčov, hráča, ktorý sa môže pohybovať po obrazovke a deformovať sa okolo okrajov, a na rozpoznávanie ovládacích prvkov prejdením prstom. Teraz musíme pridať bodovací mechanizmus, aby bola hra zábavná. Tento mechanizmus vytvorí náhodné body, ktoré zvýšia skóre a predĺžia stopu „hada“ alebo hráča.

Prvý krok: Vytvorte náhodný bod a vykreslite ho na obrazovku. Pridajte nasledujúci kód do svojho súboru GameScene.swift tak, aby sa zhodoval s obrázkom U.

// 1
var scorePos: CGPoint?
Obrázok U

Teraz prejdite do svojho súboru GameManager.swift a pridajte nasledujúci kód tak, aby zodpovedal obrázku V.

// 2
generateNewPoint ()
// 3
private func generatorNewPoint () {
    nechať randomX = CGFloat (arc4random_uniform (19))
    nechať náhodneY = CGFloat (arc4random_uniform (39))
    scene.scorePos = CGPoint (x: randomX, y: randomY)
}
// 4
if scene.scorePos! = nil {
    ak Int ((scene.scorePos? .x)!) == y && Int ((scene.scorePos? .y)!) == x {
        node.fillColor = SKColor.red
    }
}
Obrázok V

Po spustení kódu by mal simulátor zobraziť náhodne umiestnené červené štvorce.

  • 1: Inicializujte premennú pre pozíciu náhodného skóre. „? „Znamená, že je nulová (prázdna alebo ešte nenastavená), kým premennú nenastavíme neskôr.
  • 2: Zavolajte funkciu vo vnútri funkcie initGame (), ktorá vygeneruje nový náhodný bod.
  • 3: Táto funkcia generuje náhodnú polohu v rámci hraníc dosky (20/40), polia sa začínajú počítať od 0, takže počítame od 0 do 19 a od 0 do 39, jedná sa o pole 20x40.
  • 4: Vo vnútri vykresľovacej slučky skontrolujeme, či sa pozícia aktuálneho uzla zhoduje s pozíciou náhodne umiestneného skóre. Ak máme zhodu, nastavíme farbu na červenú. Môžete upraviť farbu podľa svojich predstáv. Premenná, ktorá ukladá pozíciu skóre, je CGPoint, to znamená, že musíme skontrolovať point.x a point.y a porovnať ich s polohami x a y aktuálneho uzla. Všimnite si, že pozície x / y sú prevrátené v poli uzlov, preto porovnávame x == y a y == x.

Teraz musíme priradiť premennú, ktorá drží skóre aktuálnej hry a iterovať ju, keď hráč dosiahne bod. Keď hráč dosiahne bod, musíme vygenerovať nový náhodný bod a zväčšiť dĺžku jeho „chvosta“.

Pridajte nasledujúci kód do svojho súboru GameManager.swift tak, aby sa zhodoval s obrázkom W.

// 1
var currentScore: Int = 0
// 2
checkForScore ()
// 3
private func checkForScore () {
    if scene.scorePos! = nil {
        nech x = scene.playerPositions [0] .0
        nech y = scene.playerPositions [0] .1
        ak Int ((scene.scorePos? .x)!) == y && Int ((scene.scorePos? .y)!) == x {
            currentScore + = 1
            scene.currentScore.text = "Score: \ (currentScore)"
            generateNewPoint ()
         }
     }
}
// 4
zatiaľ čo obsahuje (a: scene.playerPositions, v: (Int (randomX), Int (randomY))) {
    randomX = CGFloat (arc4random_uniform (19))
    randomY = CGFloat (arc4random_uniform (39))
}
Obrázok W
  • 1: Inicializujte premennú na sledovanie aktuálneho skóre v tejto hre.
  • 2: Volanie funkcie checkForScore () vo vnútri funkcie aktualizácie sa nazýva zakaždým, keď sa hráč pohne.
  • 3: Táto funkcia skontroluje, či bol nastavený scorePos, ak áno, potom skontroluje hlavu hada. Ak sa had dotýka bodu, skóre sa iteruje, aktualizuje sa textový štítok ukazujúci skóre a vygeneruje sa nový bod.
  • 4: Tento kód som pridal do metódy createNewPoint (), aby som zaistil, že sa v tele hada nevytvorí bod. Ako had stúpa, budeme s väčšou pravdepodobnosťou naraziť na tento problém, takže tento kódový blok by mal tento problém vyriešiť.

Po spustení kódu si všimnete, že zásah do skóre vygeneruje nové skóre na tabuli a opakuje váš štítok so skóre. Teraz musíme zväčšiť dĺžku hada, aby sa hracie mechaniky dostali bližšie. Ukázalo sa, že je to neuveriteľne jednoduché, jednoducho pridajte tento útržok kódu do funkcie checkForScore (), aby sa váš kód zhodoval s obrázkom X.

scene.playerPositions.append (scene.playerPositions.last!)
scene.playerPositions.append (scene.playerPositions.last!)
scene.playerPositions.append (scene.playerPositions.last!)
Obrázok X

Ukončenie hry

Teraz musíme implementovať metódu, ktorá ukončí hru a vráti sa do systému ponúk. V hre hada sa hra končí, keď sa hráč dostane do vlastného chvosta. Tento efekt môžeme dosiahnuť implementáciou nasledujúcich riadkov kódu do súboru GameManager.swift. Skontrolujte, či sa váš kód zhoduje s obrázkom Y.

// 1
checkForDeath ()
// 2
private func checkForDeath () {
    if scene.playerPositions.count> 0 {
        var arrayOfPositions = scene.playerPositions
        let headOfSnake = arrayOfPositions [0]
        arrayOfPositions.remove (o: 0)
        ak obsahuje (a: arrayOfPositions, v: headOfSnake) {
            presmerovanie prehrávača = 0
        }
    }
}
// 3
if playerDirection! = 0 {
    playerDirection = ID
}
// 4
prípad 0:
    // mŕtvy
    xChange = 0
    yChange = 0
    prestávka
Obrázok YObrázok Y
  • 1: Zavolajte funkciu checkForDeath ().
  • 2: Skontrolujte, či sa hlava hráča nezrážala s niektorou z pozícií chvosta. Ak hráč zomrel, nastavte presmerovanie prehrávača na 0.
Obrázok Z
  • 3: Ak hráč zomrel (presmerovanie hráča = 0), nepovoľte nové vstupné gestá.
  • 4: Pridajte nový prípad do príkazu switch v updatePlayerPosition (), ak je playerDirection nastavený na 0, nemeňte polohu hlavy. To umožní, aby sa polohy chvostov pomaly odstraňovali z pohľadu.

Po implementácii týchto zmien kódu by mala vaša aplikácia fungovať ako pri nahrávaní obrazovky (obrázok Z).

Keď sa hada zrazí so sebou, hra sa skončila, teraz musíme vytvoriť metódu na reštartovanie hry a uloženie skóre ako najvyššieho skóre.

Reštart hry a uloženie údajov s vysokým skóre

Teraz sme vybudovali funkčnú hadovú hru (z väčšej časti). Posledné kroky sú na dohľad! Potrebujeme metódu na reštartovanie hry a návrat do ponuky. Ak je skóre v tomto kole lepšie ako najlepšie skóre, musíme do zariadenia uložiť aj údaje s vysokým skóre.

Najprv implementujme metódu, ktorá sa vráti do ponuky, keď had ukončí svoju záverečnú animáciu. Pridajte nasledujúci kód do svojho súboru GameManager.swift tak, aby sa váš kód zhodoval s obrázkom AA.

// 1
finishAnimation ()
// 2
private func finishAnimation () {
    if playerDirection == 0 && scene.playerPositions.count> 0 {
        var hasFinished = true
        let headOfSnake = scene.playerPositions [0]
        pre pozíciu v scéne.playerPositions {
            if headOfSnake! = position {
                hasFinished = false
            }
         }
     ak splnil {
        tlač („koncová hra“)
        presmerovanie prehrávača = 4
        // animácia bola dokončená
        scene.scorePos = nula
        scene.playerPositions.removeAll ()
        renderChange ()
        // návrat do menu
        scene.currentScore.run (SKAction.scale (do: 0, duration: 0.4) {
        self.scene.currentScore.isHidden = true
}
        scene.gameBG.run (SKAction.scale (do: 0, trvanie: 0,4)) {
            self.scene.gameBG.isHidden = true
            self.scene.gameLogo.isHidden = false
            self.scene.gameLogo.run (SKAction.move (do: CGPoint (x: 0, y: (self.scene.frame.size.height / 2) - 200), trvanie: 0,5)) {
                 self.scene.playButton.isHidden = false
                 self.scene.playButton.run (SKAction.scale (do: 1, trvanie: 0.3))
                 self.scene.bestScore.run (SKAction.move (do: CGPoint (x: 0, y: self.scene.gameLogo.position.y - 50), trvanie: 0,3))
               }
          }
          }
     }
}
Obrázok AA

Vysvetlenie tejto metódy:

  • 1: Zavolajte funkciu finishAnimation ().
  • 2: Táto funkcia skontroluje dokončenie poslednej animácie hada, keď sa uzavrie sama. Hneď ako sa všetky pozície v poli PlayerPositions zhodujú, had sa zmenšil na jeden štvorec. Potom sa nastaví presmerovanie prehrávača na 4 (predtým bolo nastavené na 0 označujúce smrť) a potom zobrazíme objekty ponuky. Tiež skryjeme aktuálny štítok Script a objekt gameBG (mriežku štvorcov).

Pridajme do zariadenia metódu, ktorá ukladá vysoké skóre tak, aby pri ukončení aplikácie nestratili naše údaje o najvyššom skóre. V novej metóde (finishAnimation ()) ste práve napísali tento riadok kódu tak, aby sa váš súbor zhodoval s obrázkom BB.

updateScore ()
Obrázok BB

Teraz otvorte súbor AppDelegate.swift a pridajte nasledujúce riadky kódu, aby sa váš projekt zhodoval s obrázkom CC. Tento útržok kódu používa funkciu UserDefaults na ukladanie údajov do pamäte zariadenia. Ak plánujete stavbu projektu s veľkým množstvom uložených údajov, môže to spôsobiť problém, ale funguje to dobre pre jednoduché veci, ako sú prepínače nastavení a premenné.

let defaults = UserDefaults.standard
let defaultValue = ["bestScore": 0]
defaults.register (predvolené: defaultValue)
Obrázok CC

Teraz sa vráťte do súboru GameManager.swift a vytvorte nasledujúcu metódu, aby sa váš kód zhodoval s obrázkom DD. Tento blok kódu jednoducho kontroluje, či skóre dosiahlo najlepšie skóre a podľa toho aktualizuje.

// 1
private func updateScore () {
     if currentScore> UserDefaults.standard.integer (forKey: "bestScore") {
          UserDefaults.standard.set (currentScore, forKey: "bestScore")
     }
     currentScore = 0
     scene.currentScore.text = "Skóre: 0"
     scene.bestScore.text = "Najlepšie skóre: \ (UserDefaults.standard.integer (forKey:" bestScore "))" "
}
Obrázok DD

Otvorte GameScene.swift a upravte funkciu initializeMenu () tak, aby sa váš súbor zhodoval s obrázkom EE. Toto zabezpečí, že keď sa načíta hra, zobrazí sa najlepšie uložené skóre, nie hodnota 0.

bestScore.text = "Najlepšie skóre: \ (UserDefaults.standard.integer (forKey:" bestScore ")))"
Obrázok EE

Po pridaní tohto nového kódu sa vaše vysoké skóre po uzavretí aplikácie uloží do pamäte zariadenia.

Záverečné myšlienky

Ak chcete odstrániť informácie pre vývojárov v dolnej časti obrazovky, otvorte súbor GameViewController.swift a nastavte view.showFPS a view.showsNodeCount na false.

Teraz ste postavili celú hru pre iPhone od začiatku! Toto je video demonštrujúce konečný produkt.

Ak sa vám projekt páčil, zvážte vyskúšanie mojej aplikácie pre systém IOS! Ak máte nejaké problémy alebo otázky, neváhajte a pošlite mi e-mail na adresu shrader.gavin@gmail.com.

To, čo sme dnes postavili, sotva poškriaba zložitosť, ktorú ponúka herný engine SpriteKit. V budúcnosti plánujem robiť tutoriály týkajúce sa fyziky, dizajnu úrovní a animácií.