Je veux ajouter un score au sommet de ma scène dans le jeu sur lequel je travaille. Le score sera basé sur votre temps de vie et augmentera chaque seconde. Merci pour l'aide à l'avance!
import SpriteKit
class easyScene: SKScene {
let scrollBarEasyBottom = SKSpriteNode(imageNamed: "scrollBarEasyBottom")
let scrollBarEasyTop = SKSpriteNode(imageNamed: "scrollBarEasyTop")
let ball = SKSpriteNode(imageNamed: "ball")
var origSBEBpositionX = CGFloat(0)
var origSBETpositionX = CGFloat(0)
var maxSBEBX = CGFloat(0)
var SBEBSpeed = 5
var maxSBETX = CGFloat(0)
var SBETSpeed = 5
var score = 0
var timer: NSTimer?
var scoreText = SKLabelNode(fontNamed: "Kailasa")
override func didMoveToView(view: SKView) {
println("Easy Scene is the location")
self.backgroundColor = UIColor.blackColor()
self.scrollBarEasyBottom.position = CGPoint(x:0, y:270)
self.addChild(self.scrollBarEasyBottom)
self.scrollBarEasyBottom.yScale = 0.2
self.origSBEBpositionX = self.scrollBarEasyBottom.position.x
// end scrollBarEasyBottom
self.scrollBarEasyTop.position = CGPoint(x:20, y:400)
self.addChild(self.scrollBarEasyTop)
self.scrollBarEasyTop.yScale = 0.2
self.origSBETpositionX = self.scrollBarEasyTop.position.x
// end scrollBarEasyTop
self.ball.position = CGPoint(x:40, y:293)
self.addChild(self.ball)
self.ball.yScale = 0.17
self.ball.xScale = 0.17
// end ball
self.maxSBEBX = self.scrollBarEasyBottom.size.width - self.frame.size.width
self.maxSBEBX *= -1
self.maxSBETX = self.scrollBarEasyTop.size.width - self.frame.size.width
self.maxSBETX *= -1
//
self.scoreText.text = "0"
self.scoreText.fontSize = 60
self.scoreText.position = CGPoint(x: CGRectGetMidX(self.frame), y: 500)
self.scoreText.text = String(self.score)
self.addChild(self.scoreText)
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("scoreIncrease") , userInfo: nil, repeats: true)
func scoreIncrease (){
score++
println(score)
}
}
override func update(currentTime: NSTimeInterval){
if self.scrollBarEasyBottom.position.x <= maxSBEBX + 1200 {
self.scrollBarEasyBottom.position.x = self.origSBEBpositionX
}
if self.scrollBarEasyTop.position.x <= maxSBETX + 1200 {
self.scrollBarEasyTop.position.x = self.origSBETpositionX
}
scrollBarEasyBottom.position.x -= CGFloat(self.SBEBSpeed)
scrollBarEasyTop.position.x -= CGFloat(self.SBETSpeed)
// moving bars
var degreeRotation = CDouble(self.SBEBSpeed) * M_PI / 180
self.ball.zRotation -= CGFloat(degreeRotation)
//rotate ball
}
}
Après avoir exécuté ce code, je reçois toujours un "sélecteur non reconnu envoyé à une erreur d'instance".
Vous pouvez en utiliser un comme ceci:
var timer = NSTimer()
override func viewDidLoad() {
scheduledTimerWithTimeInterval()
}
func scheduledTimerWithTimeInterval(){
// Scheduling timer to Call the function "updateCounting" with the interval of 1 seconds
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateCounting"), userInfo: nil, repeats: true)
}
func updateCounting(){
NSLog("counting..")
}
Swift 3:
var timer = Timer()
override func viewDidLoad() { // Use for the app's interface
scheduledTimerWithTimeInterval()
}
override func didMove(to view: SKView) { // As part of a game
scheduledTimerWithTimeInterval()
}
func scheduledTimerWithTimeInterval(){
// Scheduling timer to Call the function "updateCounting" with the interval of 1 seconds
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.updateCounting), userInfo: nil, repeats: true)
}
@objc func updateCounting(){
NSLog("counting..")
}
Il y a quelque chose qui s'appelle NSTimer dans Swift) qui pourrait résoudre votre problème. J'ai donné un exemple de la façon dont vous pouvez l'utiliser. Personnalisez-le en fonction de vos besoins.
var timer = NSTimer.scheduledTimerWithTimeInterval(1.0,
target: self,
selector: Selector("yourMethodToCall"),
userInfo: nil,
repeats: true)
Ajoutez cette ligne à l'endroit où vous devez appeler votre fonction à plusieurs reprises.
1.0
fait référence à 1 seconde.selector
pour appeler votreMethodNamerepeats
est défini sur true
pour appeler cette fonction toutes les secondes.Essayez ceci et laissez-moi savoir si vous êtes coincé quelque part. Merci.
Swift 3
trouver cette solution cela a fonctionné pour moi
weak var timer: Timer?
var timerDispatchSourceTimer : DispatchSourceTimer?
func startTimer() {
if #available(iOS 10.0, *) {
timer = Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { [weak self] _ in
// do something here
}
} else {
// Fallback on earlier versions
timerDispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
timerDispatchSourceTimer?.scheduleRepeating(deadline: .now(), interval: .seconds(60))
timerDispatchSourceTimer?.setEventHandler{
// do something here
}
timerDispatchSourceTimer?.resume()
}
}
func stopTimer() {
timer?.invalidate()
//timerDispatchSourceTimer?.suspend() // if you want to suspend timer
timerDispatchSourceTimer?.cancel()
}
// if appropriate, make sure to stop your timer in `deinit`
deinit {
stopTimer()
}
Je ne pense pas que vous ayez besoin de NSTimer
pour cela.
Puisque vous utilisez SpriteKit, je vais suggérer la solution la plus simple à mon avis:
Déclarer une variable var prevScoreCalcTime:TimeInterval = 0
Dans update
func dans votre GameScene
, configurez-le comme ci-dessous:
override func update(_ currentTime: TimeInterval) {
if currentTime - prevScoreCalcTime > 1 {
prevScoreCalcTime = currentTime
// Any function you put here will execute every second
}
}
Bonne chance!
XCode 10.2 Swift 5:
override func viewDidLoad() {
super.viewDidLoad()
...
Timer.scheduledTimer(timeInterval: 8.0, target: self, selector: Selector(("your @obcj func name")), userInfo: nil, repeats: true)
}// end of viewDidLoad
//Anywhere in the same view controller to stop the loop:
Timer.cancelPreviousPerformRequests(withTarget: your @obcj func name())
// Pour exécuter un morceau de code toutes les secondes
///Runs every second, to cancel use: timer.invalidate()
@discardableResult public static func runThisEvery(
seconds: TimeInterval,
startAfterSeconds: TimeInterval,
handler: @escaping (CFRunLoopTimer?) -> Void) -> Timer {
let fireDate = startAfterSeconds + CFAbsoluteTimeGetCurrent()
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, seconds, 0, 0, handler)
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
return timer!
}
Je préfère
if timer != nil
{
timer?.invalidate()
timer = nil
}
//Your params
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (timer) in
//use your params
}