swift - 我正在尝试用时间间隔在 Swift 中制作一个计时器

标签 swift xcode timer nstimer countdowntimer

所以我正在尝试为我的游戏制作一个倒数计时器。基本上屏幕底部有一个玩家向其上方的移动物体发射箭头。最终我会有一个结束游戏,如果你用完箭头或时间它就会执行。我无法在代码中正确放置函数和 NSTimer/Timer。请帮助计时器应该从 30 开始,每过一秒减去 1。提前致谢!!!

目标代码:

let timerLabel = SKLabelNode(fontNamed: "The Bold Font")

var timer = Timer()

var counter = 30

func viewDidLoad() {


        timerLabel.text = String(counter)
        timerLabel.fontSize = 250
        timerLabel.fontColor = SKColor.white
        timerLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.center
        timerLabel.position = CGPoint(x: self.size.width/2, y: self.size.height*0.70)
        timerLabel.zPosition = 100
        self.addChild(timerLabel)

        timer = Timer.scheduledTimer(timeInterval: 1, target:self, selector: #selector(GameScene.updateCounter), userInfo: nil, repeats: true)()
    }

    func updateCounter(){

        timerLabel.text = String(describing: counter -= 1)
    }

完整代码:

//
//  GameScene.swift
//  Andrey's Game
//
//  Created by Jeffrey Foster on 12/2/16.
//  Copyright © 2016 Jeffrey Foster. All rights reserved.
//

import SpriteKit
import UIKit




class GameScene: SKScene, SKPhysicsContactDelegate {

var gameScore = 0
let scoreLabel = SKLabelNode(fontNamed: "The Bold Font")

var spermCount = 60
let spermLabel = SKLabelNode(fontNamed: "The Bold Font")

let timerLabel = SKLabelNode(fontNamed: "The Bold Font")
var timer = Timer()
var counter = 30

let andrey = SKSpriteNode(imageNamed: "Andreys_Ass")

let player = SKSpriteNode(imageNamed: "Player_Cucumber")




struct physicsCategories {
    static let None: UInt32 = 0
    static let Arrow : UInt32 = 0b1 //1
    static let Andrey : UInt32 = 0b10 //2
    static let Wall : UInt32 = 0b100 //4

}

var gameArea: CGRect

override init(size: CGSize){

    let maxAspectRatio: CGFloat = 16.0/9.0
    let playableWidth = size.height / maxAspectRatio
    let margin = (size.width - playableWidth) / 2
    gameArea = CGRect(x: margin, y: 0, width: playableWidth, height: size.height)

    super.init(size: size)
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}


override func didMove(to view: SKView) {

    self.physicsWorld.contactDelegate = self


    andrey.setScale(4)
    andrey.position = CGPoint(x: self.size.width/2, y: self.size.height*0.50)
    andrey.zPosition = 2
    andrey.physicsBody = SKPhysicsBody(rectangleOf: andrey.size)
    andrey.physicsBody!.affectedByGravity = false
    andrey.physicsBody!.categoryBitMask = physicsCategories.Andrey
    andrey.physicsBody!.collisionBitMask = physicsCategories.None
    andrey.physicsBody!.contactTestBitMask = physicsCategories.Arrow
    self.addChild(andrey)

    let wall = SKSpriteNode(imageNamed: "wall")
    wall.position = CGPoint(x: self.size.width/2, y: self.size.height*0.31)
    wall.size.height = 0.000005
    wall.size.width = self.size.width
    wall.zPosition = 3
    wall.physicsBody = SKPhysicsBody(rectangleOf: wall.size)
    wall.physicsBody!.affectedByGravity = false
    wall.physicsBody!.categoryBitMask = physicsCategories.Wall
    wall.physicsBody!.collisionBitMask = physicsCategories.None
    wall.physicsBody!.contactTestBitMask = physicsCategories.Arrow
    self.addChild(wall)



    let background = SKSpriteNode(imageNamed: "background")
    background.size = self.size
    background.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
    background.zPosition = 0
    self.addChild(background)


    player.setScale(1)
    player.position = CGPoint(x: self.size.width/2, y: self.size.height*0.05)
    player.zPosition = 2
    self.addChild(player)

    scoreLabel.text = "Score: 0"
    scoreLabel.fontSize = 70
    scoreLabel.fontColor = SKColor.white
    scoreLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.left
    scoreLabel.position = CGPoint(x: self.size.width*0.15, y: self.size.height*0.00)
    scoreLabel.zPosition = 100
    self.addChild(scoreLabel)

    spermLabel.text = "Sperm: 60"
    spermLabel.fontSize = 70
    spermLabel.fontColor = SKColor.white
    spermLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.right
    spermLabel.position = CGPoint(x: self.size.width*0.85, y: self.size.height*0.00)
    spermLabel.zPosition = 100
    self.addChild(spermLabel)

    func viewDidLoad() {


        timerLabel.text = String(counter)
        timerLabel.fontSize = 250
        timerLabel.fontColor = SKColor.white
        timerLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.center
        timerLabel.position = CGPoint(x: self.size.width/2, y: self.size.height*0.70)
        timerLabel.zPosition = 100
        self.addChild(timerLabel)

        timer = Timer.scheduledTimer(timeInterval: 1, target:self, selector: #selector(GameScene.updateCounter), userInfo: nil, repeats: true)()
    }

    func updateCounter(){

        timerLabel.text = String(describing: counter -= 1)
    }




    func moveAndrey(){


            let moveAndreyRight = SKAction.moveTo(x: self.size.width, duration: 0.50)
            let moveAndreyLeft = SKAction.moveTo(x: self.size.width*0.00, duration: 1.00)
            let moveAndreyStart = SKAction.moveTo(x: self.size.width/2, duration: 0.50)
            let andreySequence = SKAction.sequence([moveAndreyRight, moveAndreyLeft, moveAndreyStart])
            let endlessAction = SKAction.repeatForever(andreySequence)
            andrey.run(endlessAction)


    }

    moveAndrey()


}







func addScore(){

    gameScore += 1
    scoreLabel.text = "Score: \(gameScore)"
}


func subtractScore(){
    gameScore -= 1
    scoreLabel.text = "Score: \(gameScore)"
}

func subtractSperm(){
    spermCount -= 1
    spermLabel.text = "Sperm: \(spermCount)"

}



func didBegin(_ contact: SKPhysicsContact) {

    var body1 = SKPhysicsBody()
    var body2 = SKPhysicsBody()

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask{
        body1 = contact.bodyA
        body2 = contact.bodyB
    }
    else{
        body1 = contact.bodyB
        body2 = contact.bodyA
    }

    if body1.categoryBitMask == physicsCategories.Arrow && body2.categoryBitMask == physicsCategories.Andrey{
        //if the arrow hits Andrey

        if body1.node != nil {
        spawnHit(spawnPosition: body1.node!.position)
        }

        addScore()

        body1.node?.removeFromParent()

    }

    if body1.categoryBitMask == physicsCategories.Arrow && body2.categoryBitMask == physicsCategories.Wall{
        //if the arrow hits Wall

        if body1.node != nil {
            spawnMissedShot(spawnPosition: body1.node!.position)
        }

        subtractScore()

        body1.node?.removeFromParent()

    }


}

func spawnHit(spawnPosition: CGPoint){

    let hit = SKSpriteNode(imageNamed: "Andrey_Hit")
    hit.position = spawnPosition
    hit.zPosition = 4
    hit.setScale(3)
    self.addChild(hit)


    let scaleIn = SKAction.scale(to: 1, duration: 0.1)
    let fadeOut = SKAction.fadeOut(withDuration: 0.1)
    let delete = SKAction.removeFromParent()

    let hitSequence = SKAction.sequence([scaleIn, fadeOut, delete])

    hit.run(hitSequence)

}

func spawnMissedShot(spawnPosition: CGPoint){

    let missedShot = SKSpriteNode(imageNamed: "missedShot")
    missedShot.position = spawnPosition
    missedShot.zPosition = 4
    missedShot.setScale(3)
    self.addChild(missedShot)


    let scaleIn = SKAction.scale(to: 1, duration: 0.1)
    let fadeOut = SKAction.fadeOut(withDuration: 0.1)
    let delete = SKAction.removeFromParent()

    let hitSequence = SKAction.sequence([scaleIn, fadeOut, delete])

    missedShot.run(hitSequence)

}





func fireArrow() {

    let arrow = SKSpriteNode(imageNamed: "Arrow_Cucumber")
    arrow.name = "Arrow"
    arrow.setScale(0.75)
    arrow.position = player.position
    arrow.zPosition = 3
    arrow.physicsBody = SKPhysicsBody(rectangleOf: arrow.size)
    arrow.physicsBody!.affectedByGravity = false
    arrow.physicsBody!.categoryBitMask = physicsCategories.Arrow
    arrow.physicsBody!.collisionBitMask = physicsCategories.None
    arrow.physicsBody!.contactTestBitMask = physicsCategories.Andrey | physicsCategories.Wall
    self.addChild(arrow)


    let moveArrow = SKAction.moveTo(y: self.size.height+arrow.size.height, duration: 1.50)
    let deleteArrow = SKAction.removeFromParent()
    let arrowSequence = SKAction.sequence([moveArrow, deleteArrow])
    arrow.run(arrowSequence)

}





override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    fireArrow()
    subtractSperm()



    }
}

最佳答案

您可以使用 Timer 或带有延迟和重复的 SKAction 来执行此操作。

要使用计时器,请调用 scheduledTimer 类方法并指定在触发时调用的方法。

timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(GameScene.updateCounter), userInfo: nil, repeats: true)

此方法应更新一些计数器变量,向用户显示当前时间,并检查是否满足游戏结束条件。

func updateCounter() {
    counter -= 1
    timerLabel.text = "\(counter)"
    if counter == 0 { gameOver() }
}

gameOver 函数中,您可以通过调用停止计时器

timer.invalidate()

随着游戏复杂性的增加,您可能希望以不同的方式重构它。

另一种方法是使用SKAction

let waitAction = SKAction.wait(forDuration: 1)
let fireAction = SKAction.run {
    counter -= 1
    timerLabel.text = "\(counter)"
    if counter == 0 { gameOver() }
}
let actionSequence = SKAction.sequence([waitAction, fireAction])
let repeatAction = SKAction.repeatForever(actionSequence)
self.run(repeatAction, withKey: "timer")

gameOver 函数中,您可以通过调用停止 Action

self.removeAction(forKey: "timer")

希望对您有所帮助!祝你游戏顺利。

关于swift - 我正在尝试用时间间隔在 Swift 中制作一个计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41149556/

相关文章:

iOS Swift Firebase SDK 导入问题

ios - 将文本字段输入表格时出现问题

ios - 如何在 Xcode 8 中更改应用程序显示名称以添加空格

xcode - 'XCBBuildService 意外退出' Xcode 9.3 (Swift 4.1)

c# - 每 24 小时定时一次

c# - 为什么通过 timeBeginPeriod 增加定时器分辨率会影响功耗?

ios - 模拟器(iOS)结果不一致?

ios - 编译器不喜欢 Swift 的 UIScrollViewDelegate

ios - 为什么我拖入 xib 文件中的任何 UIView 都会变成 iPhone XR?

timer - CUDA:CPU 计时器和 CUDA 计时器事件之间的区别?