2018-02-26 游戏中实现倒计时功能

在游戏中实现倒计时功能按照以下步骤:

1. 新建HUD类,用于存储一些预置信息,比如可将字体配置及一些提示语以枚举的形式添加到其中(在class以外添加)

enum HUDSettings {
    
    static let font  = "Noteworthy-Bold"
    
    static let fontSize:CGFloat = 50.0
    
}

enum HUDMessages {
    
    static let tapToStart = "Tap to Start"
    
    static let win = "You Win!"
    
    static let lose = "Out of Time!"
    
    static let nextLevel = "Tap for Next Level"
    
    static let playAgain = "Tap to Play Again"
    
    static let reload = "Continue Previous Game?"
    
    static let yes = "Yes"
    
    static let no = "No"
    
}

2. 创建成员变量

var timeLabel:SKLabelNode?

3. 编写创建label的方法如下,设置label的相关属性

func add(message: String,
             position:CGPoint,
             fontSize:CGFloat = HUDSettings.fontSize) {
        
        let label:SKLabelNode
        
        label = SKLabelNode(fontNamed: HUDSettings.font)
        
        label.text = message
        
        label.name = message
        
        label.zPosition = 100
        
        addChild(label)
        
        label.fontSize = fontSize
        
        label.position = position
        
    }

4. addTimer和updateTimer的作用为初始化timeLabel并将整型的time按照“分:秒”、以String的方式赋值于timeLabel?.text,详情查看注释:

func updateTimer(time: Int) {
        
        let minutes = (time/60)%60
        
        let seconds = time % 60
        
        let timeText = String(format:"%02d:%02d",minutes,seconds)
        
        timeLabel?.text = timeText
        
        
    }
    
    func addTimer(time: Int) {
        
        guard let scene = scene else {
            return
        }
        
        let position = CGPoint(x: 0, y: self.frame.size.width/2 - 10)
        
        //创建了一个name为“Timer”的label
        add(message: "Timer", position: position, fontSize: 24)
        
        //通过查找name为“Timer”的label并赋值于timeLabel,是一个好套路
        timeLabel = childNode(withName: "Timer") as? SKLabelNode
        
        
        timeLabel?.verticalAlignmentMode = .top
        
        timeLabel?.fontName = "Menlo"
        
        
        /*updateTimer主要是将整型的time格式化为“分:秒”的格式并赋值给timeLabel,
        可以理解为addTimer的作用是初始化label本身的相关属性,updateTimer是初始化并实时改变timeLabel的值。
        */
        updateTimer(time: time)
        
    }

5. 在HUD中准备好timeLabel的相关属性后,在GameScene中实例化HUD对象

var hud = HUD()

6. 本案例中倒计时是从10秒开始的,elapsedTime的初始值为0,所以设置成员变量如下:

    var timeLimit:Int = 10
    
    var elapsedTime: Int = 0
    
    var startTime: Int?

7.本案例是接着上篇教程intermediate map写的,因为相机照到的区域并非整个场景,所以我们需要将timeLabel放在镜头的中央。故创建HUD如下:

    func setupHUD() {
        //添加hud为camera的child
        camera?.addChild(hud)
        
        //hud加上初始化10秒的倒计时,也就是从10秒开始倒数
        hud.addTimer(time: timeLimit)
        
        
    }

然后将setupHUD()添加至didMove方法中。

8. 更新当前剩余时间,详情查看备注:

    func updateHUD(currentTime:TimeInterval) {
        
        //如果startTime不为空,则流逝的时间 = 当前的时间 - 起始时间
        if let startTime = startTime {
            
            elapsedTime = Int(currentTime) - startTime
            
        }
            
            
        //否则(startTime为空,即初始状态),起始时间 = 当前的时间 - 流逝的时间
        else {
            startTime = Int(currentTime) - elapsedTime
            
        }
        
        //不断的向hud中timeLabel.text赋值当前剩余的时间 = 总时间 - 流逝的时间
        hud.updateTimer(time: timeLimit - elapsedTime)
        
    }

9.将updateHUD方法添加到update中即可

下图是完成后的效果


2018-02-26 游戏中实现倒计时功能_第1张图片
image.png
注:这样写能正确从10秒开始倒计时,但截至到当前,时间到0秒后会变为负数。该问题将在下篇文章中得以解决,当时间为0时,控制游戏状态的gameState就会切换为.lose,isPaused变为true。整个游戏将会暂停。

你可能感兴趣的:(2018-02-26 游戏中实现倒计时功能)