web-dev-qa-db-ja.com

関数を1秒ごとに迅速に実行させるにはどうすればよいですか?

私が取り組んでいるゲームのシーンの一番上にスコアを追加したいです。スコアは、あなたがどれだけ長く続くかに基づいて、1秒ごとに増加します。事前に助けてくれてありがとう!

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


    }


    }

このコードを実行した後、常に「認識されないセレクターがインスタンスに送信されました」というエラーが表示されます。

45
Ryan Allen

次のようなものを使用できます。

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..")
}

スウィフト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..")
}
77
Mohammad Nurdin

Swiftには NSTimer と呼ばれるものがあり、問題を解決できます。使用方法のような例を挙げました。目的に合わせてカスタマイズしてください。

var timer = NSTimer.scheduledTimerWithTimeInterval(1.0, 
                                                   target: self, 
                                                   selector: Selector("yourMethodToCall"), 
                                                   userInfo: nil, 
                                                   repeats: true)

関数を繰り返し呼び出す必要がある場所にこの行を追加します。

  1. 1.0は1秒を指します。
  2. selectorを変更してyourMethodNameを呼び出します
  3. repeatstrueに設定され、その関数を毎秒呼び出します。

これを試してみて、あなたがどこかで立ち往生しているなら教えてください。ありがとう。

29
Shaik MD Ashiq

スイフト3

それが私のために働いたこの解決策を見つける

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()
}
8
Amr Angry

これにはNSTimerは必要ないと思います。

SpriteKitを使用しているので、私の意見では最も簡単な解決策を提案します。

変数を宣言するvar prevScoreCalcTime:TimeInterval = 0

update内のGameScene func内で、以下のように設定します。

override func update(_ currentTime: TimeInterval) {
    if currentTime - prevScoreCalcTime > 1 {
        prevScoreCalcTime = currentTime
        // Any function you put here will execute every second
    }
}

幸運を!

2
sc13

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())
2
Brian M

// 1秒ごとにコードを実行するため

///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!
}
0
Pratyush Pratik

私は好む

if timer != nil
{
    timer?.invalidate()
    timer = nil
}

//Your params

timer =  Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (timer) in

          //use your params

}
0
Rincha