所以我试图为我的游戏制作一个倒数计时器。基本上,屏幕底部有一个玩家,它在其上方的移动物体上发射箭头。最终我将有一个结束游戏,如果你用完箭头或时间它将执行。我在代码中正确放置功能和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()
}
}
答案 0 :(得分:1)
您可以使用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
功能中,您可以通过调用
self.removeAction(forKey: "timer")
希望有所帮助!祝你的游戏好运。