Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SKAction only runs after sleep or while running debugger

Using SpriteKit I'm trying to make a pause menu that animates (moves) off the screen when the player resumes the game.

I create an SKAction and run it within touches began like so:

let duration = TimeInterval(0.5)
let moveAction = SKAction.move(to: CGPoint(x: 0, y: 495) , duration: 
duration)
pauseScroll?.run(moveAction) 

The pauseScroll is initialised as:

weak var pauseScroll: SKSpriteNode?

override init(size: CGSize) {
  ...
  let pauseScene = SKScene(fileNamed: "PauseMenu")!
  pauseScroll = pauseScene.childNode(withName: "PauseScroll") as? 
  SKSpriteNode
  pauseScroll?.position = CGPoint(x: 0, y: 495)
  pauseScroll?.zPosition = 1000
  pauseScroll?.move(toParent: self)
}

What I'm doing here is laying out the UI of the pauseScroll in another spritekit.scene file as the actual GameScene where this all runs is all done in code. I then bring it over and add it to the GameScene by calling .move(toParent: self).

The thing is I can reference the pauseScroll just fine, I can modify it e.g. change its position, give it a physics body and collision mask, register taps on nodes contained in the pauseScroll etc. Seemingly everything but run SKActions on it.

I'm running SKActions for other SKSpriteNodes at the same time and they are working fine, of course they are initialised differently as they are all set up in code within the .init e.g.:

var background: SKSpriteNode!

override init(size: CGSize) {
  ...
  background = SKSpriteNode(imageNamed: "GameBackground")
  background.size = size
  addChild(background)
}

I then animate them the same way I do anything else within touches began:

let colorAction = SKAction.colorize(withColorBlendFactor: 0.4, 
duration: duration)
background?.run(colorAction)

Interestingly, If I run sleep(1) anywhere else in the function where the SKAction is run on the pauseScroll; then the scroll animates and moves up off the screen as it should. Therefore it seems to be a race condition but I haven't the faintest clue as to what it is waiting on.

When printing the values of pauseScroll and moveAction I get the same result wether I sleep(1) or not.

Here's the bug in action:

enter image description here

If I add sleep(1) to anywhere within touches began then the same thing happens except the whole app waits for 1 second before the scroll moves up off the top of the screen as it's meant to.

I'm happy to provide more code if necessary.

like image 500
Cameron Porter Avatar asked Dec 31 '17 08:12

Cameron Porter


2 Answers

When you are moving the children to the new parent using .move(toParent: self) try setting isPaused to false on each child. I suspect that all the children are paused when you load them from a scene, and perhaps SpriteKit sets isPaused to false automatically when the scene first appears.

tempScene.children.forEach() { child in
            child.isPaused = false
            child.move(toParent: newParentNode)
}
like image 58
iMacHumphries Avatar answered Oct 30 '22 08:10

iMacHumphries


Try setting the isPaused in the init() method on the parent.

Think of it as a UIView - if the parent is set to hidden then the subviews (regardless if they're not hidden) won't show.

like image 25
KiwiJon Avatar answered Oct 30 '22 07:10

KiwiJon