Why doesn't the call to the random function work in the sequence?

三世轮回 提交于 2021-02-10 06:06:18

问题


I am attempting to generate a random X position for a simple object, in order to have it bounce back and forth inside the scene in a Swift SpriteKit game. The repeatForever action should generate a random value and then move the object (a circle) multiple times to different locations, left and right. However, it acts only one time. It is as if the random function, which works correctly, is called only one time, and the action then simply continues to move the object to the same position forever.

let circle = SKSpriteNode(imageNamed: "circle")
circle.run(SKAction.repeatForever(SKAction.move(to:
        CGPoint(x: random(min: minCircleX, max: maxCircleX),
            y: scene.size.height*0.5),
            duration: 0.5)))

The circle moves only one time, to one position, and never seems to be moved after that. I suspect it is simply moving to the same position over and over. Thanks for any suggestions!


回答1:


OK, after multiple efforts, the following works:

let customAction = SKAction.customAction(withDuration: 1000)
{
    circle, _ in
    let newXLocation: CGPoint = CGPoint(x: random(min: minCircleX, max: maxCircleX),
                                        y: scene.size.height*0.5)
    circle.run(SKAction.move(to: newXLocation, duration: 0.5))
}
circle.run(customAction)

Dai was correct in suggesting an anonymous function. The SKAction method customAction allows for that. And then running the actual action inside the function insured that the movement was random every time. Thanks so much!




回答2:


Instead of repeat forever, use the completionblock to establish a new moveTo:

func newLocation(){
    let newXLocation: CGPoint = CGPoint(x: random(min: minCircleX, max: maxCircleX),
                                    y: scene.size.height*0.5)
    circle.run(SKAction.move(to: newXLocation, duration: 0.5){
       [weak self] in self?.newLocation()
    }
}

What this does is upon finishing the moveTo, it will add a new moveTo and the next random location. The only "flaw" is it will start the next move during the same frame as the current move since this is being done in the action phase of the update. If you do not want this effect, then you need to store it in a block to be done during didFinishUpdate

var  finishedUpdates = [()->()]()
func newLocation(){
    let newXLocation: CGPoint = CGPoint(x: random(min: minCircleX, max: maxCircleX),
                                        y: scene.size.height*0.5)
    circle.run(SKAction.move(to: newXLocation, duration: 0.5){
       [weak self] in 
       self?.finishedUpdates.append({weak self] in self?.newLocation()})
    }
}


func didFinishUpdate()
{
    finishedUpdates.forEach{$0()}
    finishedUpdates = [()->()]() //Be sure to clear the array
}

My apologies in advance, this is written from memory alone, and may not be 100% syntactically correct



来源:https://stackoverflow.com/questions/57641747/why-doesnt-the-call-to-the-random-function-work-in-the-sequence

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!