How would you go about pausing and resuming a UIDynamicAnimator's physics simulation? There is no way to programmatically pause and resume. There is a "paused" state when all items are at rest however I am am looking for something different. For example, I'd like to have an item being pulled by a gravity field, then press a pause button to pause the simulation, and then press a resume button and have the simulation resumed as if nothing happened. The item maintains it's trajectory, velocity, etc.
My hunch is that I have to somehow save the item's physics properties, remove the dynamic behaviors, and then add the dynamic behaviors back to mimic the saved physics properties from before. Is this the right approach?
You can do this only by removing all behaviours using removeAllBehaviors().
To restart the simulation you have to add each behavior
Related
I have an AR scene (built as a node with children nodes) that I want the user to walk inside it.
Because it can be large, I added a pause button in the corner so that if the user hits an obstacle in the real world, he'll just need to press-and-hold that button to freeze the scene, move elsewhere in the real world, and when the button will be released the scene would have moved as-is to that new location, retaining the same relative position and rotation inside that scene.
What I did is very simple. When button is touched down I just did:
sceneView.session.pause()
And when the button is Touch Up Inside I ran:
sceneView.session.run(configuration)
This seemed to do the trick.
However, after I clicked and moved once or twice more and moved back to where I was before, my whole AR scene suddenly jumped back to its previous location in the real world. So it did freeze and showed up in the new location for a second or two, but then it jumped back.
I tried to resume the session with several of the available options.
If I ran:
sceneView.session.run(configuration, options: [.resetTracking])
the whole scene would move to the new location, but it would be set to its initial position and rotation as if I was standing at (0,0,0) when I started the app, but now moved to the new location. In other words, it lost the current location and rotation that I was at when I pressed the pause button and just reset the scene.
All the other options that I tried had the same effect as if I didn't add any options.
I should add that I'm not using any anchors (so far) nor any ray casting.
I didn't try different combinations of those options (except removeExistingAnchors and resetTracking together), but I doubt that that would help. Am I wrong?
What am I doing wrong?
Anyone have a solution for my problem?
Or will I need to manually record the current position and rotation when pressing the pause button and then restore those with some position change of the node? I was hoping I could skip having to do it this way.
And if I do need to do it manually, any tips on how to achieve this?
Thanks for your help!
I am writing a clone of the old Space Invaders game. The invaders are moved during update() and drop bombs randomly; the player ship moves when the screen is touched. If an invader bomb hits the player, I want everything to stop except for the player's ship death animation. Once this is complete, I want everything to start again.
What the best way to achieve this? I considered enumerating over all nodes, setting the paused property to true; adding a check in update() to see if the death animation was running on the player and skip movement if it was and similarly ignoring user input if the animation was running.
Another approach would have been to have a world node of which everything is a child. I could then pause the world node and add a copy of the player's ship to the scene which runs the animation, making it look like everything has stopped except the player's ship death animation.
Both these seem a lot of work for the effect I want. Any suggestions?
You could make two invisible ,rootNode where your enemies, your objects and all your game enviroments (labels, coins..) are childs:
self.rootNode.addChild(enemy1)
and another rootShipNode where you have added your player.
With this approach you can stop all when you pause self, or put in pause the invisible nodes whenever you want.
You can adopt this process to add also a pauseNode (SKNode) to your scene:
var pauseNode: SKNode! // a node with resume, go to menu, buttons
self.addChild(pauseNode)
When you press your pause button, you can open your pauseNode and launch:
self.rootNode.paused = true
self.rootPlayerNode.paused = true
but all animations and object added to self, pauseNode elements and animations included, are in running.
This seems like such a basic concept but there is really no good answer.
I currently have a pretty basic setup, in my game's scene, I have an enum gameState which is currently either inGame or gamePaused.
I have my button set up, and I have it so pressing simply toggles gameState.
Then, to make it work, I have two separate update methods: One for when gamePaused, one for when inGame.
This works for 95% of my game, as the updates in my game can be pretty readily started and stopped without any issues. There are some issues I cannot tackle though.
First and foremost are actions. I use SKActions for a bit of my project (some movement, scaling, fading...) and this method does NOT pause them. This can be catastrophic in certain points. Secondly, this doesn't handle particles, physics, and a few other things that are not directly associated to my update methods.
The only clue I have is self.view.paused = YES, but that isn't going to work either.
First off, this DOES fix my actions, particles, and physics problem... kinda. But This question suggests that SKActions aren't actually PAUSED by this, but actually STOPPED completely. Is this true? If it is, then it won't work smoothly either because my actions are thrown out of whack.
Also, pausing the view seems to do what it says: stop everything. EVERYTHING. Newbie question here, but how am I supposed to get any code to run at that point? It's all cut off. Is this where I need subViews? I have never used a subView yet, but it sounds like its what I want in this case.
Simply put, there are a lot of unanswered questions for me, and I don't know how to proceed. I'm hoping there's some 'standard procedure' for pausing in Sprite Kit, but with pausing the view halting actions I truly have no idea where to proceed.
Should I move away from using actions? Is my idea of a pause subView sound?
I don't want to babble, all I want to know is how you go about pausing in your average Sprite Kit project. Additional info provided upon request.
Pausing a node will pause (not stop) the node's actions, and i suppose pause will also be applied to all children of the paused node in the same way. All other unpaused nodes will continue to run their actions to completion.
You should have a "game layer" node with all game nodes in them that you want to pause, and then just pause that "game layer" node. Then have a "pause game menu" node where you add all the pause menu stuff you need which will continue to function normally even if the game layer is paused.
Be very sure you do not use performSelector or NSTimer or GCD or any other scheduling methods besides actions or the scene's update: method because those will not adhere to a node's paused state.
Pausing the view effectively freezes everything in it, pausing the scene according to some will not pause the update: calls - but I have not verified this myself. If this were the case you can always check inside the update method whether a given node that you send a message to is paused and if so, decide not to send certain messages to that node.
I just called a map function on all children of the scene and set the paused property to true
self.children.map{($0 as SKNode).paused = false}
By setting it to true you can easily undo the freeze.
EDIT:
Better use a for-loop to iterate over the children.
for node in self.children as [SKNode] {
node.paused = false
}
I can tell you what I did in my game:
Pause the SKView on -applicationWillResignActive: (or equivalent, using NSNotifications),
Un-pause the SKView on -applicationDidBecomeActive: (or equivalent, using NSNotifications),
For the actual game scene only, I set a boolean flag _isPaused when resigning active, and if it is true I just skip the -update: method (frame updates). (I also show the "paused" menu when the user resumes the app).
...But my game is a simple puzzle game, and there's no long actions that should continue past the pause/resume. I can not confirm right now that all actions are aborted, but I think it's not the case.
I also used self.children.map{($0 as SKNode).paused = false} and it does work if you create a var layer of type SKSpriteNode and add it on top of the scene. But I also have an NSTimer I'm using to spawn sprites on the scene. Everything currently on the scene is paused, but sprites keep appearing and moving across the screen. It is not pausing the spawning.
I tried pausing the NSTimer when I call the above code by setting repeats to false, then setting it to true when I remove the layer but it doesn't work. I also tried self.scene?.view?.paused = true but that freezes everything and the layer I create does not even appear onscreen.
You need to set the delegate for the View!
func PauseGame(){
self.scene.view.paused = true
}
fun playGame(){
self.scene.pause = false
}
This function is work perfectly if you are not using the NSTimer to call a function. If you use NSTimer your view will pause perfectly but when you play the game again by play game functionality you see that all the functions that use the NSTimer function that runs in the back end and your screen full with your sprite-kits. So when you use NSTimer in the function you have to first pause the NSTimer functions also after that this function work perfectly.
//For Pause
func pauseGame() {
scene?.view?.paused = true
}
//For play.
func playGame() {
scene?.view?.paused = false
}
My game has a pause screen which doubles as the main title screen with high scores. It is semi-transparent so the user can see what state the game-round was in. They can see the last message such as "Win" or "Loss". In the case of an interruption or pause they see "Redo". My game already handles interruptions gracefully, saving state and restoring last round so that the user can try again.
Question; when the user closes the app (hits home button) or if the app is interrupted with an incoming phone call during game-play, when the app comes back into the foreground should I show the pause screen or should I take them back to the game? Another way to phrase this question would be, should the home button and the pause button behave virtually the same for game-play interruption? (I presume that if the user were in a sub-screen, non-game-play, they would be taken back to that sub-screen).
Question 2; What does it mean to pause? I believe all sounds should cease but can I get away with keeping some minimal animation going? I do know that if the app were to go into the background that the OpenGL ES 2 animation would have to cease. Do you think users would prefer to have no animations during pause? I question the extent to which battery life should influence the answer.
I think this is a very subjective question. I'll try to give you some input.
I would say the good rule of thumb is: Will it affect your game play if you don't pause the game? For example, if your game is a chess or sudoku game, it wouldn't really matter if you pause the game when the user exit to home screen. However if your game is an action game that each mili second is very important and will decide whether the user will win, then in that case you would need to pause the game.
What does it mean to pause: It depends on your implementation. It can be anything you want. You can even continue the animation in the background if you want. This is all up to you.
I am trying to completely reload a gamepage in monogame - simply by touching a sprite on the page. I cannot find any solution for this.
In Android, I can call finish for the gameactivity, and then recreate a new one. How can I do that in monogame?
I am using WP8.0 SDK, monogame with XNA 4 framework.
I'm not familiar with Android development, or specifically what you mean by "gamepage", but typically this type of thing is handled with "states" in game development. You can have a playing state, paused state, Main Menu state, etc, and you just pass the game object to each state class and have it override the update/draw methods with its own information.
So, in your case, you would be in the playing state of the game, and if the sprite is touched, you might want to go back to the main title, you can pass the game object to the Title Screen State. The Title SCreen can have a call to LoadContent() which will reload all assets (effectively restarting the game completely).
Not sure if that helps. =X