cocos2d unresponsive scene after opening for the second time - ios

I'm having an issue going back and forth between my Menu scene and Preferences scene in my cocos2d project. I start in the Menu and when a user clicks a button it takes them to the preferences scene.
[[CCDirector sharedDirector] pushScene:[CCTransitionSlideInR transitionWithDuration:.3 scene:prefScene]];
The preferences scene has a back button to take the user back to the menu.
[[CCDirector sharedDirector] popScene];
This works fine unless the user exits the preferences scene and then tries to go back into it. The second time the preferences scene is opened all of the buttons animate when they are touched but are otherwise unresponsive.
Thanks for the help!

I have had something similar, there were two solutions I found:
Quick and Dirty is to create the preferences scene instance as you need it (lazy loading), this will reduce memory of keeping it around unless you need it, but you will have to initialize it each time, however it should be new clean copy each time, and if the user doesn't click preferences every time probably faster to load the whole game.
Make sure the preferences scene cleans itself up before it disappears, this especially means stop all Scheduled selectors or interval timers and remove delegates and touch events.

Related

How do I freeze an AR scene in ARKit and then restore the scene elsewhere - Swift, XCode

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!

How to receive a touch ended event if a finger is already touching the screen when the app loads

I need to track if the user is touching the screen across multiple views and separate screens throughout my app. I have already created a window delegate method to receive every type of touch event. The problem is that if I keep one finger on the first screen and tap a button with a separate finger that takes me to the second screen, when I release my original finger no event is fired.
This problem is the same if you were to hold your finger on the screen before the app loads and then release it once it's started, no event is fired for the touch ending.
I presume there is some in built system in iOS that states you have to start a new touch once the app has started or the screen/view has changed, so if you release a finger that was already touching nothing happens.
Is there a way to detect this? I really need to keep a constant accurate number of touches on the screen throughout the different screens/views within my app, especially if the user takes their finger(s) off the screen.

Presenting a new viewController doesn't seem to unload the previous

The game I'm developing consists of a Main Menu, and Game viewController separately.
However when moving from the game screen to the menu screen, it seems as if the class files from the previous viewController are still in effect?
For example, players start the game by tapping anywhere on the screen whilst in the game viewController, which causes a new bar to be "launched", which in turn plays a small tone which varies depending on the direction. However when returning to the main menu after the game is over (achieved by pressing a button to present the menu viewController), tapping anywhere on the menu screen seems to start the game again from the game viewController?
By this, I mean the bar launch sound is played, despite there being no code available in the main menu viewController to play said sound, pressing play on the menu will take you to the game screen, where the game has been reset, until tapping again, where the sound plays implying a new bar is launched, despite all images being invisible.
I made sure that, when leaving any view, I wipe all subviews from the view, so that whenever the screen is loaded there's nothing being covered up. I also tried dismissing the previous view controller, however nothing seems to take effect. So, I can't tell for certain whether the views are being removed or what... It's simply mind breaking to me.
Unfortunately my descriptions most likely aren't doing myself any justice, so hopefully this video demonstration will help out. Note that at the beginning, I am tapping the screen to show that no sound is played, however of course that won't be visible.
Edit: You'll notice that when returning to the menu, tapping the screen seems to mess up the moving bar in the background, despite the gameBarMovement timer being invalidated upon moving from the game to the menu. The fact that they're using separate class files also should mean the bars shouldn't be effected? Knowing me, I've missed something fairly obvious.
This is how the UIViewController life-cycle works as far as I know. UIViewcontrollers aren't unloaded until the app starts running out of memory. What you probably need is some way, in your game VC, to stop the game loop from running and resume it once a new game is started.

Cocos3d: how to stop the running scene and unload resources

I am developing a Cocos3d based iOS project. I am running a scene once the app is launched and clicked on "Start scene" option. I have a Back button in the scene. Clicking on this Back, will take us to app home screen. Clicking on again "Start scene" option, currently it launches the previous scene itself. But, whenever Back button is clicked , i want to stop the running scene and unlock all the resource. And then again "Start scene" option, it should launch scene freshly.
Could someone advise, how to stop the running scene and unload all resources pod etc.?
Thank you!
You can try the following to stop displaying a Cocos2D CCScene (including any 3D scenes being displayed), and releasing all cached objects:
CC3Texture.shouldCacheAssociatedCCTextures = NO; // Breaks links between Cocos3D textures and Cocos2D textures
[CCDirector.sharedDirector end]; // Removes active CCScene and clears Cocos2D caches
[CC3OpenGL.sharedGL clearOpenGLResourceCaches]; // Clears Cocos3D caches
If you are using a CC3ViewController subclass, and you don't expect to need any OpenGL for a while, then you can also use the terminateOpenGL method to perform all of the above, plus completely shutdown OpenGL. See the CC3DemoMultiScene demo app for examples of doing this.

How to restart game play ( layer ) in cocos2d

I have created one level in cocos2d and i have a pause button on screen . clicking on pause screen it will open Menu ( Resume, Restart, Settings) . i want that when i click on restart menu my level will start from start. what i have tried i have remove that layer class and called it again but it didnt work. i tried to replaceScene . it didnt work either. how can i achieve that?
I have tried this and it works.
[[CCDirector sharedDirector] resume];
[[CCDirector sharedDirector] pushScene:[HelloWorldLayer node]];
But is it write that i am calling pushScene over and over.? will it effect my game. coz till now i am now removing that HelloWorldLayer that i want to restart again.
You have to use replaceScene. With pushScene the app will eventually run out of memory as previous scenes are not deallocating.
Be sure to create a new scene (as in your code sample), do not try to call replaceScene with the already running scene, that will fail.
You should also verify that your scene deallocates after replaceScene. Set a breakpoint in the dealloc method. If it does not deallocate, this means the scene is leaking and that can lead to all kinds of strange issues.

Resources