山姆再次勇闯黑森林,但是这次他大意了!
在旁埋伏的 Storm 跟 Lightning 趁山姆一不注意,使出了闪电暴风雨。
淋湿的山姆倒在地上。
幸好,这里是从零开始的游戏世界,山姆不只一条命。
於是山姆又重新站了起来,再次从起点出发。
PS. 这里是开发 iOS 手机游戏的系列文,如果还没看过之前
剧情文章的朋友,欢迎先点这边回顾唷!
目前主角一被怪物攻击後,就会直接游戏结束,但是这样的节奏太快了,因此我们为主角新增生命值的机制,让主角除了一开始的生命外,还有额外三条命 (共 4 条命)。
samLife
纪录还有几条生命lifeNode
、lifeIconNode
、lifeLabel
节点来显示主角的图示及剩下的生命值
lifeNode
里"X \(self.samLife)"
,设定文字的颜色、尺寸、字体、位置,让他垂直置中,水平置左,并加到 lifeNode
里applySafeArea
方法,校正 position
,让生命值的外层节点 lifeNode
的位置在地图节点下方class GameScene: SKScene {
...
var samLife: Int = 3
var lifeNode: SKSpriteNode?
var lifeIconNode: SKSpriteNode?
var lifeLabel: SKLabelNode?
override func didMove(to view: SKView) {
...
self.lifeNode = SKSpriteNode(color: .clear, size: CGSize(width: CGFloat(self.size.width), height: CGFloat(30)))
self.lifeIconNode = SKSpriteNode(imageNamed: "sam_down_1")
self.lifeLabel = SKLabelNode(text: "X \(self.samLife)")
if let lifeNode = self.lifeNode, let lifeIconNode = self.lifeIconNode, let lifeLabel = self.lifeLabel {
lifeNode.anchorPoint = CGPoint(x: 0, y: 0.5)
self.addChild(lifeNode)
lifeIconNode.anchorPoint = CGPoint(x: 0, y: 0.5)
lifeIconNode.size.width = CGFloat(25)
lifeIconNode.size.height = CGFloat(25)
lifeIconNode.position = CGPoint(x: 5, y: 0)
lifeNode.addChild(lifeIconNode)
lifeLabel.fontColor = UIColor.white
lifeLabel.fontSize = CGFloat(22)
lifeLabel.fontName = "Copperplate"
lifeLabel.position = CGPoint(x: 35, y: 0)
lifeLabel.verticalAlignmentMode = .center
lifeLabel.horizontalAlignmentMode = .left
lifeNode.addChild(lifeLabel)
}
}
func applySafeArea() {
...
if let mapNode = self.mapNode, let scoreNode = self.scoreNode, let lifeNode = self.lifeNode {
mapNode.position = CGPoint(x: 0, y: -self.topSafeArea - scoreNode.size.height)
scoreNode.position = CGPoint(x: 0 ,y: -self.topSafeArea - scoreNode.size.height/2)
lifeNode.position = CGPoint(x: 0, y: -self.topSafeArea - scoreNode.size.height - mapNode.size.height - 15)
}
}
}
游戏中已经出现显示生命值的画面罗!
有了计算剩余生命值的变数後,可以依照剩余的生命数量,让游戏重新开始或是真的游戏结束。今天我们会先带大家实作游戏重新开始的部分,游戏结束明天会再说明
在这边我们可以建立游戏重新开始的流程,需要做的事情有:
gameStop
方法 (在主角被怪物攻击时会触发),加上以下程序码:
samLife
生命值减 1gameReset
gameReset
resetPosition
方法,将主角及怪物设定回到游戏初始时的位置.ATTACK
self.isSamFall = false
class GameScene: SKScene {
func gameStop() {
...
self.samLife -= 1
if self.samLife < 0 {
print("游戏结束")
} else {
Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(gameReset), userInfo: nil, repeats: false)
}
}
@objc func gameReset() {
self.lifeLabel?.text = "X \(self.samLife)"
for weather in self.weathers {
weather.resetPosition()
weather.setMode(mode: .ATTACK)
}
if let sam = self.sam {
sam.resetPosition()
}
self.isSamFall = false
}
}
在共用的角色类别中新增 resetPosition
方法
gridX
及 gridY
设定回初始格子点position
class GameCharacter {
...
func resetPosition() {
self.gridX = startGridX
self.gridY = startGridY
self.node.position = CGPoint(x: self.gridWH * self.startGridX + (self.gridWH/2), y: -self.gridWH * self.startGridY - (self.gridWH/2))
self.playAnimation(imageName: self.imageName, num: 2)
}
}
主角被攻击 3 秒後,角色们都回到原本的位置,主角生命值减 1
考量到游戏的流程是会不断循环的,我们可以新增一个共用的游戏开始
方法,在一进游戏时、以及在主角减一条生命後,都可以呼叫
gameStart
方法,让游戏开始後有一段时间的缓冲,让玩家可以看一下地图,才游戏开始。请设定 Timer,5 秒後执行游戏开始动作 gameStartAction
didMove
的开始游戏後的动作移到 gameStartAction
,包含设定角色们可以移动、让怪物开始移动,以及产生随机时间後变成玩耍模式的 Timerclass GameScene: SKScene {
...
func gameStart() {
Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(gameStartAction), userInfo: nil, repeats: false)
}
@objc func gameStartAction() {
for weather in self.weathers {
weather.setCanMove(isCanMove: true)
weather.startMove(direction: .NONE)
}
if let sam = self.sam {
sam.setCanMove(isCanMove: true)
}
let randomTime = Int.random(in: 10...50)
self.randomTimer = Timer.scheduledTimer(timeInterval: TimeInterval(randomTime), target: self, selector: #selector(attackToPlayModeAction), userInfo: nil, repeats: false)
}
}
gameStart
方法gameRestart
里呼叫 gameStart
class GameScene: SKScene {
...
override func didMove(to view: SKView) {
...
self.gameStart()
}
@objc func gameRestart() {
...
self.gameStart()
}
}
游戏成功加上生命值机制了!在生命值没有归零前,可以不断重新开始游戏,之前收集的水晶跟分数也都还会保留
目前已经加上重新开始游戏的流程了,明日会继续将游戏结束後的流程加上
我们预计在游戏结束时,会切换到另外一个场景,并且显示玩家这场的游戏得分,再加上重新开始游戏的按钮
我们明日见罗~
<<: Day 19 - 将 NEWS 後台储存资料提取後,送至前台渲染画面 (上) - News List Page CTE 暂存表应用 - ASP.NET Web Forms C#
Introduction Type Signature of :: Applicative f =&...
TorchServe TorchServe 是 PyTorch 提供给开发者部署 models 的工...
Yo!这应该就是我的最後一篇的铁人文啦!撒花 其实Git真的很多东西可以说,一下子要讲一些细节的操作...
面量图介绍 面量图又称分层设色图、区域密度图(Choropleth map),高中地理课本的说明是在...
今天要介绍 TypeScript 的基本型别,TypeScript 跟 JavaScript 一样拥...