前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >生命系统-在临死前多次受伤

生命系统-在临死前多次受伤

作者头像
iOSDevLog
发布2019-03-11 14:28:11
7400
发布2019-03-11 14:28:11
举报
文章被收录于专栏:iOSDevLog

在本节中,我们将了解生命系统。游戏中生命系统的实现为玩家提供了多次在死亡或重置游戏之前清除等级的机会。有很多方法可以代表这个系统。您可以申请生活酒吧,或者像塞尔达的游戏一样,拥有心形。

下载生命系统

要学习本教程,您将需要Xcode 9,您可以下载最终项目,以帮助您与自己的进度进行比较。

心形容器和心形

这个系统的布局基本上是你场景中一个不可见的矩形容器,我们将在其中插入心形。在Score分区下方,让我们声明心形容器和心形的变量。

代码语言:javascript
复制
// Hearts
var heartsArray = [SKSpriteNode]()
let heartContainer = SKSpriteNode()

heartsArray的括号表示我们正在创建一个空数组。

设置心形容器

didMove方法中,创建一个新的部门并将其命名为:Hearts。设置位置,zPosition并将心形容器添加到cameraNode。

代码语言:javascript
复制
// Hearts
heartContainer.position = CGPoint(x: -300, y: 140)
heartContainer.zPosition = 5
cameraNode?.addChild(heartContainer)

设置心形

容器已设置好。我们需要一个将心形放在容器中的功能。在Action Mark中,添加一个新函数并将其命名为:fillHearts。为心形声明一个变量并设置其位置。然后,将心形添加到心形容器中。

代码语言:javascript
复制
func fillHearts(count: Int) {
    for index in 1...count {
        let heart = SKSpriteNode(imageNamed: "heart")
        let xPosition = heart.size.width * CGFloat(index - 1)
        heart.position = CGPoint(x: xPosition, y: 0)
        heartsArray.append(heart)
        heartContainer.addChild(heart)
    }
}

didMove方法中,将心形容器添加到相机后,调用fillHearts函数并将计数值设置为3。运行模拟器,您将在屏幕的左上角看到三个美丽的心。

心形约束

让失去三颗心的玩家死亡。首先,在布尔分区中声明一个新的布尔值,并将其命名为:isHit。将其值设置为false。与接触陷阱的玩家类似,玩家一次会失去一个以上的心形,我们需要将接触限制为一个。

代码语言:javascript
复制
var isHit = false

失去了一颗心

Action Mark中,添加一个新函数并将其命名为:loseHeart。如果玩家被击中,我们将删除数组中的最后一个元素。两秒钟后,玩家不再被击中。

代码语言:javascript
复制
func loseHeart() {
    if isHit == true {
        let lastElementIndex = heartsArray.count - 1
        if heartsArray.indices.contains(lastElementIndex - 1) {
            let lastHeart = heartsArray[lastElementIndex]
            lastHeart.removeFromParent()
            heartsArray.remove(at: lastElementIndex)
            Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { (timer) in
                self.isHit = false
            }
        }
    }
}

杀戮碰撞

我们需要更新玩家和杀戮对象之间的碰撞,因为我们实现了生命系统。在碰撞标记中,删除玩家与杀戮之间的碰撞内容,因为我们不希望玩家立即死亡。然后,插入loseHeart函数并将isHit设置为true。

代码语言:javascript
复制
if collision.matches(.player, .killing) {
    loseHeart()
    isHit = true
}

运行模拟器,将玩家移动到陷阱,您将看到玩家一次失去多个心形,最小上限为1。

无敌

在大多数游戏中,受伤后,玩家有两秒钟不能再被击中。我们称之为无敌状态。有很多方法可以实现无敌状态,但是到目前为止我发现的最简单的方法是改变玩家的类别掩码。在lostHeart函数之后的Action Mark中,添加一个新函数并命名为:invincible。将玩家的类别掩码设置为0.然后,将计时器设置为两秒的时间间隔,并将玩家的类别掩码设置为2。

代码语言:javascript
复制
func invincible() {
    player?.physicsBody?.categoryBitMask = 0
    Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { (timer) in
        self.player?.physicsBody?.categoryBitMask = 2
    }
}

loseHeart函数内部,调用无敌函数。运行模拟器!当玩家触摸陷阱时,您将看到一次只有一颗心会消失。

垂死

在失去所有三颗心之后让我们让玩家死去。在无敌功能之后,添加一个新功能并命名为:dying。在其中,设置我们之前删除的死亡动作。然后,删除玩家上的所有操作并将fillHeart函数添加到3。

代码语言:javascript
复制
func dying() {
    let dieAction = SKAction.move(to: CGPoint(x: -300, y: 0), duration: 0.1)
    player?.run(dieAction)
    self.removeAllActions()
    fillHearts(count: 3)
}

让玩家死亡

loseHeart功能中,如果我们不能再移除心形,玩家将会死亡。所以,在heartsArrayif语句之后,放一个else并调用垂死的函数。该loseHeart功能应该是这样的:

代码语言:javascript
复制
func loseHeart() {
    if isHit == true {
        let lastElementIndex = heartsArray.count - 1
        if heartsArray.indices.contains(lastElementIndex - 1) {
            let lastHeart = heartsArray[lastElementIndex]
            lastHeart.removeFromParent()
            heartsArray.remove(at: lastElementIndex)
            Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { (timer) in
                self.isHit = false
            }
        }
        else {
            dying()
        }
        invincible()
    }
}

运行模拟器,所有功能都运行正常!

无敌状态

唯一的问题是我们需要一个信号来告诉我们玩家仍处于无敌状态。在玩游戏时很难计算两秒钟的无敌状态。许多游戏在玩家身上使用闪烁的视觉效果来告诉我们玩家是无敌的,就像马里奥一样。在playerStateMachine中,在Stunned State内,声明一个新变量,将其命名为isStunned并将值设置为false。声明isValidNextState方法。如果玩家已经无敌了,他就不能再无敌。然后,添加一个switch语句,如果玩家处于空闲状态,则将该值返回true。否则,返回false。

代码语言:javascript
复制
var isStunned : Bool = false

override func isValidNextState(_ stateClass: AnyClass) -> Bool {

    if isStunned { return false }

    switch stateClass {
    case is IdleState.Type: return true
    default: return false
    }
}

闪烁效果

有许多方法可以在游戏中应用闪烁效果,最常用的方法是更改​​相关对象的alpha。在isValidNextState方法之后,创建闪烁操作并重复操作5次。

代码语言:javascript
复制
let action = SKAction.repeat(.sequence([
    .fadeAlpha(to: 0.5, duration: 0.01),
    .wait(forDuration: 0.25),
    .fadeAlpha(to: 1.0, duration: 0.01),
    .wait(forDuration: 0.25),
    ]), count: 5)

didEnter方法

Stunned ****State中,调用didEnter方法。将isStunned设置为true并在玩家上应用闪烁。放一个计时器并将isStunned设置为false。这样,玩家就不能连续多次被击晕。

代码语言:javascript
复制
override func didEnter(from previousState: GKState?) {

    isStunned = true

    playerNode.run(action)
    Timer.scheduledTimer(withTimeInterval: 0.1, repeats: false) { (timer) in
        self.isStunned = false
        self.stateMachine?.enter(IdleState.self)
    }
}

修复JumpingState

JumpingState中,允许玩家在被击晕时跳跃。在isValidNextState内,将值返回true。

代码语言:javascript
复制
if stateClass is StunnedState.Type { return true }

让玩家闪烁

在玩家和碰撞之间的碰撞匹配中,添加StunnedState。碰撞匹配应如下所示。

代码语言:javascript
复制
if collision.matches(.player, .killing) {

    loseHeart()
    isHit = true

    playerStateMachine.enter(StunnedState.self)
}

运行模拟器,整个生命系统现在应该正常工作!

结论

在本节中,我们学习了生命系统的工作原理。我们在游戏中实现了心形,以及如何让玩家立于不败之地。这是一个非常重要的部分,我希望你到目前为止真的很喜欢这个课程。

原文: https://designcode.io/life-system

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.02.28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 下载生命系统
  • 心形容器和心形
  • 设置心形容器
  • 设置心形
  • 心形约束
  • 失去了一颗心
  • 杀戮碰撞
  • 无敌
  • 垂死
  • 让玩家死亡
  • 无敌状态
  • 闪烁效果
  • didEnter方法
  • 修复JumpingState
  • 让玩家闪烁
  • 结论
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档