如何在 swift 中制作倒数计时器或正数计时器?
How to make a reversed countdown or a count up timer in swift?
我正在开发一款 2d 平台游戏,我需要的是一个计数计时器,也就是进度条或进度计数节点。它应该像倒计时一样工作,除了它应该从 0 开始并无休止地上升。我将根据该数字的高低来确定游戏 speed/difficulty。我知道在 SO 中提问你应该总是提供一些代码,但我知道如何进行倒计时。现在有人如何创建如下面的屏幕截图所示的内容吗?
编辑
我已经设法实现了我想要的。我刚刚创建了一个 SKLabelNode,它有一个 int 变量作为文本,并且在更新方法中增加了 int 变量,就像 --score++--。但是分数标签的值增加得非常快,有人知道如何减慢一点,然后随着游戏的进行,一段时间后让它慢慢变快吗?
提前谢谢你。
您可以使用 NSTimer 并每 x 秒更新一次值。在游戏开始时创建你的 NSTimer
var timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: #selector(MyGame.countUp), userInfo: nil, repeats: true)
然后在同一个 class 中创建一个函数来计算值,例如1
func countUp() {
self.myCountLabel.text == "\(1 + self.myCountLabel.text ?? 0)"
}
也许是这样的:
import SpriteKit
class Player:SKSpriteNode {
override init(texture: SKTexture?, color: UIColor, size: CGSize) {
super.init(texture: texture, color: color, size: size)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var gameStarted = false
var player = Player(texture: nil, color: UIColor.brownColor(), size: CGSize(width: 50, height: 100))
var levelTimerLabel = SKLabelNode()
var levelTimerValue: Int = 0 {
didSet {
if levelTimerValue == 10 { self.increaseScore(withDelay: 0.1)}
levelTimerLabel.text = "\(levelTimerValue)m"
}
}
override func didMoveToView(view: SKView) {
self.player.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame))
addChild(self.player)
levelTimerLabel.zPosition = 200
levelTimerLabel.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame))
levelTimerLabel.text = "\(levelTimerValue)m"
addChild(levelTimerLabel)
}
//MARK: SCORELABEL METHOD
func increaseScore(withDelay delay:NSTimeInterval = 0.5) {
let block = SKAction.runBlock({[unowned self] in
self.levelTimerValue += 1 // Swift 3 yo
})
let wait = SKAction.waitForDuration(delay)
let sequence = SKAction.sequence([wait,block])
self.runAction(SKAction.repeatActionForever(sequence), withKey: "countUp")
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if gameStarted == false {
gameStarted = true
startWorld()
increaseScore()
}
player.physicsBody?.velocity = CGVectorMake(0, 0)
player.physicsBody?.applyImpulse(CGVectorMake(0, 150)) // Jump Impulse
}
func startWorld(){
print("startWold method invoked")
}
}
当 levelTimerValue
达到 10 时,countUp
动作将被替换为新的动作,速度将提高 5 倍。我想这就是你想要达到的目标。我稍微修改了您的代码以避免强引用循环,删除了不需要的 update:
方法调用和一些小的东西。另请注意,现在您没有名为 "wait" 的 SKAction 属性。该操作现在在本地创建。
编辑:
根据您的评论,您可以像这样暂停计时器:
func pauseTimer(){
if let countUpAction = self.actionForKey("countUp") {
countUpAction.speed = 0.0
}
}
取消暂停也是一样...只需将 countUpAction.speed
设置为 1.0
如果您想暂停整个游戏,请查看 SO 问题。看看@Knight0fDragon 的回答。这是一个很好的方式,而且 IMO,它比完全暂停场景或视图更灵活。
此外,我建议您不要使用字符串 "countUp",而是创建一个这样的常量:
let kCountUpActionKey = "countUp"
因此您在重复使用此操作键时不会出现拼写错误。
我正在开发一款 2d 平台游戏,我需要的是一个计数计时器,也就是进度条或进度计数节点。它应该像倒计时一样工作,除了它应该从 0 开始并无休止地上升。我将根据该数字的高低来确定游戏 speed/difficulty。我知道在 SO 中提问你应该总是提供一些代码,但我知道如何进行倒计时。现在有人如何创建如下面的屏幕截图所示的内容吗?
编辑
我已经设法实现了我想要的。我刚刚创建了一个 SKLabelNode,它有一个 int 变量作为文本,并且在更新方法中增加了 int 变量,就像 --score++--。但是分数标签的值增加得非常快,有人知道如何减慢一点,然后随着游戏的进行,一段时间后让它慢慢变快吗?
提前谢谢你。
您可以使用 NSTimer 并每 x 秒更新一次值。在游戏开始时创建你的 NSTimer
var timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: #selector(MyGame.countUp), userInfo: nil, repeats: true)
然后在同一个 class 中创建一个函数来计算值,例如1
func countUp() {
self.myCountLabel.text == "\(1 + self.myCountLabel.text ?? 0)"
}
也许是这样的:
import SpriteKit
class Player:SKSpriteNode {
override init(texture: SKTexture?, color: UIColor, size: CGSize) {
super.init(texture: texture, color: color, size: size)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var gameStarted = false
var player = Player(texture: nil, color: UIColor.brownColor(), size: CGSize(width: 50, height: 100))
var levelTimerLabel = SKLabelNode()
var levelTimerValue: Int = 0 {
didSet {
if levelTimerValue == 10 { self.increaseScore(withDelay: 0.1)}
levelTimerLabel.text = "\(levelTimerValue)m"
}
}
override func didMoveToView(view: SKView) {
self.player.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame))
addChild(self.player)
levelTimerLabel.zPosition = 200
levelTimerLabel.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame))
levelTimerLabel.text = "\(levelTimerValue)m"
addChild(levelTimerLabel)
}
//MARK: SCORELABEL METHOD
func increaseScore(withDelay delay:NSTimeInterval = 0.5) {
let block = SKAction.runBlock({[unowned self] in
self.levelTimerValue += 1 // Swift 3 yo
})
let wait = SKAction.waitForDuration(delay)
let sequence = SKAction.sequence([wait,block])
self.runAction(SKAction.repeatActionForever(sequence), withKey: "countUp")
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if gameStarted == false {
gameStarted = true
startWorld()
increaseScore()
}
player.physicsBody?.velocity = CGVectorMake(0, 0)
player.physicsBody?.applyImpulse(CGVectorMake(0, 150)) // Jump Impulse
}
func startWorld(){
print("startWold method invoked")
}
}
当 levelTimerValue
达到 10 时,countUp
动作将被替换为新的动作,速度将提高 5 倍。我想这就是你想要达到的目标。我稍微修改了您的代码以避免强引用循环,删除了不需要的 update:
方法调用和一些小的东西。另请注意,现在您没有名为 "wait" 的 SKAction 属性。该操作现在在本地创建。
编辑:
根据您的评论,您可以像这样暂停计时器:
func pauseTimer(){
if let countUpAction = self.actionForKey("countUp") {
countUpAction.speed = 0.0
}
}
取消暂停也是一样...只需将 countUpAction.speed
设置为 1.0
如果您想暂停整个游戏,请查看
此外,我建议您不要使用字符串 "countUp",而是创建一个这样的常量:
let kCountUpActionKey = "countUp"
因此您在重复使用此操作键时不会出现拼写错误。