iT邦幫忙

2021 iThome 鐵人賽

DAY 20
1
Mobile Development

從零開始的8-bit迷宮探險!Swift SpriteKit 遊戲開發實戰系列 第 20

從零開始的8-bit迷宮探險【Level 20】搜集水晶可以召喚神龍嗎?

不知道跑了多久,可能有一世紀的感覺,山姆終於累得停了下來。
上帝關起了一道門,總會為你開啟另一扇窗。
一片藍色、發光的物體印入眼簾。
「難道這就是傳說中的水晶!」山姆興奮地拿起這個得來不易的珍寶。

今日目標

  • 新增收集物類別
  • 在迷宮中加入水晶
  • 讓主角可以收集水晶,碰觸後水晶消失

PS. 這裡是開發 iOS 手機遊戲的系列文,如果還沒看過之前 劇情 文章的朋友,歡迎先點這邊回顧唷!


新增收集物類別

我們新增一個共用的收集物類別,可以讓水晶、魔幻水晶、香菇共同使用
首先新增一個 swift 檔案

  • 首先點選新增檔案
    https://imgur.com/DyRgPfA.png

  • 選擇 Swift File -> Next
    https://imgur.com/IJukGWI.png

  • 將檔案命名為 Collection,點擊 Create 按鈕,完成 .swift 檔的新增

引入 SpriteKit

請記得先 import SpriteKit

import SpriteKit

類別內容

記錄收集物的屬性:

  • node:紀錄收集物的 SKSpriteNode 資訊
  • gridX:紀錄收集物的格子點 x
  • gridY:紀錄收集物的格子點 y
  • isGotten:紀錄收集物是否已經被收集

在建構子 (init) 寫上初始化時需帶入的參數:

  • gridWH:一格的寬度
  • gridX:收集物的格子位置 x
  • gridY:收集物的格子位置 y
  • imageName:收集物的圖片

在建構子中,儲存帶入的參數值,並新增一個 SKSpriteNodeimageNamed 帶入圖片名稱,並將定位點 (anchorPoint)、尺寸 (size)、位置 (position)、層級 (zPosition) 都設定好。

新增 setGotten 方法

  • 讓外部能設定 isGotten 的值
  • 判斷 isGotten 值,如果被收集了,就將 node 的 zPosition 設定為 ZPosition.HIDE。反之則將 zPosition 設定為 ZPosition.COLLECTION
class Collection {
    var node: SKSpriteNode
    var gridX: Int = 0
    var gridY: Int = 0
    var isGotten: Bool = false
    
    init(gridWH: Int, gridX: Int, gridY: Int, imageName: String) {
        self.gridX = gridX
        self.gridY = gridY
        
        self.node = SKSpriteNode(imageNamed: imageName)
        self.node.anchorPoint = CGPoint(x: 0.5, y: 0.5)
        self.node.size.width = CGFloat(gridWH)
        self.node.size.height = CGFloat(gridWH)
        self.node.position = CGPoint(x: gridWH * gridX + (gridWH/2), y: -gridWH * gridY - (gridWH/2))
        self.node.zPosition = CGFloat(ZPosition.COLLECTION)
    }
    
    func setGotten(isGotten: Bool) {
        self.isGotten = isGotten
        if isGotten {
            self.node.zPosition = CGFloat(ZPosition.HIDE)
            return
        }
        self.node.zPosition = CGFloat(ZPosition.COLLECTION)
    }
}

在迷宮中加上水晶

地圖陣列加上水晶

在先前的章節已經設定過我們地圖上要畫的圖片代號,想複習的朋友可以點這邊

  • 我們使用 . 代號代表這個位置要畫上水晶
  • GameScene.swift
let mapDraw = [
    "ccccccccpccccccci",
    "   .....e*......b",
    "aam.1ji.s.11.zy.b",
    "  d.3gh....1.wx.b",
    "jcl.....ji.1....b",
    "d*...11.gh...rt.b",
    "d.11.nm....2....b",
    "d..1.kl.22.1.naah",
    "ot...       .b   ",
    "d..1.jcu vci.b   ",
    "d.12.d     b.kccc",
    "d+...gaaaaah.    ",
    "gaam.       .11.n",
    "   d.rt.1#.q....b",
    "   d....21.e.ji.b",
    "cccl.ji....e.gh.b",
    "    .gh.13.s....b",
    "aaam....1....21.b",
    "   d...23.rt.1..b",
    "   d.1.........3b",
    "jccl.1.rft.3.1.1b",
    "d*.............*b",
    "gaaaaaaaaaaaaaaah",
]

準備水晶圖片

請準備好圖片,並且拖拉進專案中

https://imgur.com/J0cxMBk.png

加上水晶

  • 先宣告水晶陣列的變數 crystals,準備將所有畫面上的水晶存在這邊
  • 在先前的 drawMap 方法裡,再加上 "." 的 case
  • 新增收集物類別 Collection 的實體,將需要的參數帶入
  • mapNode 裡加入收集物的 node
  • 將水晶的實體存在 crystals 陣列中
  • GameScene.swift
class GameScene: SKScene {
    ...
    var crystals: [Collection] = []
    ...
    func drawMap() {
        for i in 0..<gridYCount {
            let mapRowArr = Array(mapDraw[i]);
            for j in 0..<gridXCount {
                let mapKeys = wallMapping.keys
                switch mapRowArr[j] {
                ...
                case ".":
                    let crystal = Collection(gridWH: self.gridWH, gridX: j, gridY: i, imageName: "crystal")
                    self.mapNode!.addChild(crystal.node);
                    self.crystals.append(crystal)
                default:
                    break
                }
            }
        }
    } 
}

執行結果

https://imgur.com/j1XPcCO.gif

水晶成功出現啦!
角色的層級也正常的顯示在水晶上方。
接著再加上主角經過時,水晶消失的效果,就ok了!


主角與水晶碰觸後,水晶消失

  • update 方法裡,再加上主角跟水晶之間的位置判斷,當主角跟水晶的格子位置一樣時,並且還沒有被收集時,就將水晶設定成被收集了 setGotten(isGotten: true)
  • GameScene.swift
class GameScene: SKScene {
    override func update(_ currentTime: TimeInterval) {
        ...
        for crystal in self.crystals where !crystal.isGotten && crystal.gridX == sam.gridX && crystal.gridY == sam.gridY {
            crystal.setGotten(isGotten: true)
        }
    }
}

執行結果

https://imgur.com/N3kOpwy.gif

成功出現水晶被收集的效果了!


今日小結

有了收集物類別,明日來繼續新增另一個魔幻水晶的類別吧!/images/emoticon/emoticon07.gif


上一篇
從零開始的8-bit迷宮探險【Level 19】這個相遇我等了一輩子了-偵測主角與怪物接觸
下一篇
從零開始的8-bit迷宮探險【Level 21】進擊的主角!暴風雨來吶,你坐啊!
系列文
從零開始的8-bit迷宮探險!Swift SpriteKit 遊戲開發實戰30

尚未有邦友留言

立即登入留言