SKScene becomes unresponsive while being Idle
Asked Answered
S

1

1

Hello I have a SceneKit game. All the game play is in one scene and when the game is over the sprit kit overlay acts as a game over screen and when they hit play again the sprite kit labels disappear and the game resets all in the same scene.

My issuing is coming in the game over. If the user hits the replay button within a few seconds then everything goes well. But if the user sits on the game over place for over five seconds then the scene freezes. I am really confused as the app is idle when it freezes and I am receiving no errors. Also the memory and CPU usage are much lower during game over that during game play. Also that app itself is not frozen as if I click the menu button it transitions to a new view controller just fine.

With no memory leaks or errors I really have no idea where to begin looking for whats wrong? Can someone point me in the right direction

A little more insight to whats going on: The game is a short half minute action game that uses the physics simulation. There is a timer set to fire every 0.01 seconds that affects the game play. When the game is over (caused by one node colliding with another) the players node is removed, a variable is set to false so that when the game timer fires nothing happens, and a bunch of label nodes are created in the sprit kit overlay that act as the game over menu.

Again everything works great if the user clicks replay within fivish seconds. Clicking replay hides all the labels, creates the players node in the starting position, and sets the timers variable back true.

Here is the code for setting up the scene

// create a new scene
scene = SCNScene()
sceneView = SCNView()
sceneView.frame = self.view.frame
sceneView.autoresizingMask = UIViewAutoresizing.allZeros
sceneView.scene = scene
sceneView.autoenablesDefaultLighting = false
sceneView.allowsCameraControl = false
sceneView.showsStatistics = false
sceneView.backgroundColor = UIColor.blackColor()
scene.physicsWorld.gravity = SCNVector3Make(0, -30, 0)
scene.physicsWorld.contactDelegate = self
self.view = sceneView
self.MarbleGeo = SCNSphere(radius: 1.3)
hud = Hud(size: self.view.frame.size, game: self)
sceneView.overlaySKScene = hud

Edit

I have located where the code is breaking down. When the again button is clicked all the labels are supposed to move or fade out or some effect along those lines. Anyways the method call to restart the game is in the completion of the last of one of those effects. Here is the code

println("Before check")
MenuLabel.runAction(moveButtonsOut, completion: { () -> Void in
    self.scoreLabel.removeFromParent()
    self.MyGame.Setup()
    self.MyGame.Restart(true, Level: self.MyGame.level)
    self.startTimer()
    println("should have called the game to begin by now")
    //self.playing = true
    //self.MyGame.addMarble()
})

The first statement is logged, but the one on the inside of the completion block is not. So I guess the my question now changes to why aren't these actions being run and completed once the game freezes?

Edit

It appears that the SKActions are being kicked from the que. While in the game over scene some labels are enlarging and shrinking over and over and some fade in and out and what not. Anyways when all this is going on the replay button works great, no errors. When all these actions freeze that is when the button no longer works because the restart methods never get called on upon completion. I tried placing the restart methods outside of completion and when they were called all the actions because unfrozen and they all rush to complete and it looks awful. So to sum up something is pausing the SKActions

Hope this helps.

Sabinasabine answered 25/1, 2015 at 21:32 Comment(19)
we can only help if you can post code that at least may cause the issue. You should also log and use breakpoints to see what is really going on.Gastrotomy
I've tried commenting out every chuck of code that could be the causeSabinasabine
see edit for more insight on issue @LearnCocos2DSabinasabine
Do you have any timers you use in your GameOver scene? Have you tried to NSLog to see what methods (if any) are called after 5 seconds? Would be a good start for self-troubleshooting.Doss
@Doss nothing is happening in the game over scene. The app is literally idle. The only change happening is a label is growing and shrinking repetitively but I have already tried to comment that out. The app is doing nothing but waiting for the user to make a decision to play again or notSabinasabine
As far as lower memory and CPU usage goes it makes sense because there is much less going on on the game over scene I assume. Have you tried cleaning the build? Cmd+option+shift+k. After that maybe try and make a new SKScene subclass with just a touchesbegan method and see if that works after 5 seconds. If that doesnt work im all out of ideas without seeing some code snippets.Doss
@Doss I agree with you, I mentioned those figures to show that something out of the usual bad memory or cpu usage was going onSabinasabine
@Doss I tried the clean and it was sadly unsuccessful, I have provided the code on how the scene is set up, but other than that I do not think any other code is worth posting since I have already tried commenting it all out at different timesSabinasabine
When you touch a second time, does it fix the issue?Overdose
@Overdose to answer your question, no. When I touch the play again button nothing happens, but I do get the log outputting it registered the touch. When the menu button is touched the view is dismissed and the menu appears no problemSabinasabine
@Doss Please see my latest edit, I have found where the error is coming from more specificallySabinasabine
I'm not sure if you can send messages to null pointers without a crash in Swift or not but you might check to see that the properties you are interacting with are non-null. My gut is telling me that you have something setup to change during that period of time and something is not allocated properly.Doss
@Doss I have a feeling that the sprite kit actions are being kicked off the que if that makes sense. When the app appears to be frozen that could just be that all the effects (SKActions) have been stopped for some reason. Also to clarify the action is not being run, so that code is never being executedSabinasabine
But both MenuLabel and moveButtonsOut are non-null at the time the program isn't functioning correctly? You can check with an if statement and NSLog if it's non-null or setup break points and check the debugger to see if they are non-nullDoss
I would try to send the restart action to the main thread, feels to me like it's being sent to a back thread. What is the SKAction queue you are refering to, did you create an array for example and playing the first bit wile adding to the end?Overdose
@Doss they are both non-null. I just checked as suggestedSabinasabine
@Overdose Im sorry for being unclear the SKAction que were probably the wrong words for what I was trying to say. I was talking about when the update runs through and sees what actions it needs to handle as all actions take more than just one run to be done with. So I am speculating that when an action is called to happen it is added to an external array that the update runs throughSabinasabine
Should I maybe start a new question about why an SKAction that is repeating forever stops or why other SKAction calls are being ignored when nothing is nil?Sabinasabine
I wouldn't start a new thread unless no viable answer comes and thanks for the clarification ;)Overdose
N
0

is your SceneKit scene playing ? A scene is playing when you either have

  • scene.playing = YES
  • SCNAction instances running
  • implicit or explicit animations running

The SpriteKit scene overlay is refreshed only when the SceneKit scene is. So if the SceneKit scene does not redisplay the actions set in the overlay might not run.

A solution might be to set the playing property or to add actions to SceneKit objects instead of SpriteKit objects.

This is unrelated but try to keep away from timers. SceneKit provides several game loop callbacks that will allow you to do what you want.

Neely answered 26/1, 2015 at 10:3 Comment(6)
when it freezes playing is false, to fix I should just have a scene kit action repeating?Sabinasabine
any of the 3 ways will do. I find setting the playing property more elegant than running an empty action repeatedly.Neely
I agree Id like to just go with the property way, but wouldn't setting playing to true when game over happens be pointless because playing does not turn false until five to ten seconds later?Sabinasabine
I don't understand your question. What is this 5-10s interval for? Why are you changing the property after that amount of time?Neely
the interval is not intentional. Game over happens. Five to ten seconds later against my wish the scene turns to not playingSabinasabine
I replaced my game timer with an SCNAction and killed two birds with one stone. I got rid of the timer as suggested and now the action keeps the scene from pausingSabinasabine

© 2022 - 2024 — McMap. All rights reserved.