I have used
[[CCDirector sharedDirector] replaceScene:[CCBReader sceneWithNodeGraphFromFile:#"SongScene.ccbi"] ];
For load the next scene. It take a little delay to load the scene. When the second time loading, there is no delay. How can i fix the issue. Songs scene consist of many graphic sprites.
When you first start your game, create an Intro Scene showing a splash image or loading image, etc. While that scene is showing, load up the resources that will take a long time to load so that they are already in the cache.
When they are done loading, transition to your main scene(s). The resources will already be loaded and they will go faster.
You can even create entire scenes like this, you just need a place to store them off temporarily, such as the child of a CCNode that you use for holding scenes. Then use them when you need them.
I only learned this recently. Before that I was loading them at the start of the App, which is a poor choice.
Related
Thanx in advance..I have a problem , how we release memory in cocos2dx ??
In my game, my first scene takes a lot of memory because there are so many animations run at a single time on this scene,there are so many animations , so i am satisfied with this but when we go to next scene, it does not release previous memory used,this is my problem so how we release memory used by previous scene when we change the scene?
To go between scenes you can either call pushScene or replaceScene.
Push Scene
If you're pushing between scenes then I recommend that you have a loading scene in between. It should be lightweight so that you have a chance to release everything from your old scene. This is where the onEnter(DidFinish) and onExit(DidStart) methods come in handy.
The chain of calls would be:
oldScene->onExitDidStart()
loadScene->onEnter()
oldScene->onExit() <-- this is where you release everything
loadScene->onEnterDidFinish() <-- this is where you load up the new scene
newScene->onEnter()
and so on... If you've managed your memory correctly then you shouldn't have 2 heavy scenes at once.
Replace Scene
This is a much easier scenario. You simply need to make sure that for the new scene you load as little as possible until the old scene has completely disappeared. I.e. when onEnterDidFinish() is called, or even 1 frame after it.
Cocos2d-x supports auto release memory. For example, when you create a sprite by calling Sprite::create() it will add this sprite to the auto-release pool. If you don't add this sprite to become the child (or n-th leveled child) of the current scene, it will be released.
Do not create an object using new,use create() instead when you call the next scene, everything from the last scene are released.
I have a cocos2d game that has a loading scene where we load a bunch of assets. The game starts with the splash screen, and then launches the loading scene. The loading scene starts by loading the background, so the user sees the loading scene background while the assets are being loaded.
I load the loading scene background by calling CCSprite::spriteWithFile: and passing the filepath: loadingbackground.pvr.ccz
It seems to work differently on different devices:
On iphone (3gs) simulator, I see the loading scene as expected.
On iphone retina simulator, I don't see the loading scene (there aren't many assets yet, so may be happening quickly) and it goes directly to the main menu scene.
On the ipad 3 device, the splash screen comes up, and then there is a half second of black screen, and then the main menu scene shows up.
I want to see what I can do to avoid that black screen showing up on iPad 3. I suspect this is because of the time taken to load the loading background.
I have tried the following optimizations (mostly based on #Steffen's blog post on memory optimization):
Moved the loading background (originally 2.3 MB RGB8 png file) into a pvr.ccz spritesheet by itself, which reduced its size to 1.8 MB.
Removed the image from the texture soon after use.
I still see a black screen on iPad 3. Any suggestions?
Update: Found the issue - I had some code where I was overriding OnEnter and calling [[CCDirector sharedDirector]replaceScene] in it, and also calling the same from the background thread. Removed the OnEnter overload and it worked without flicker.
Thanks
Ignore whatever happens in Simulator. That's not relevant, focus on the device.
When the loading scene initializes and you add the loading scene's background, make sure you schedule update and load your assets in the update method. Otherwise if you load the assets in init, the background won't be drawn because you're loading all the assets before cocos2d gets to redraw the screen.
If this still fails, simply send the visit message to the background sprite followed by [[CCDirector sharedDirector] drawScene]. This forces a redraw of the scene.
Is this cocos2d-iphone or cocos2d-x ? make sure the tags are correct :)
I think you're referring to the startup flicker, there are a few ways to avoid that.
first thing you need to make sure you're handling the rootViewController correctly for iOS 6 and iOS 5 and below, there are a little changes for each.
You can find a little reference here:
http://www.cocos2d-iphone.org/forum/topic/34471
Second thing you need to know that simulator's behaviour is not stable, you should always rely on real devices for testing, but it's very likely you'll still have the flicker issues.
Sorry I didn't provide example code, but you haven't supported enough information to know what's the real issue here.
I am using cocos2d to create a simple arrow shooting game.On reset button I am replacing the scene to The same play scene i.e i am loading the images again and again on reset button. But this is not the optimized way to do. Can somebody help me or give me an Idea to reset the game without loading the images again and again.
Many Thanks
are you sure that you are loading this textures into memory every time? if so, retain your textures before restart to be sure that it is not unloaded from CCTextureCache. loading textures into memory is the longest process.
Just wondering how Cocos manages the CPU cycle and graphics engine for CCSprites that are offscreen, including those in the middle of an animation. If you have many animated sprites going on and off the screen, I could check and stop each animation when it's off the screen then restart it when it is about to come back on, but I'm wondering if this is necessary?
Suppose you had a layer with a bunch of them and you make the layer invisible, but don't stop the sprite animations. Will they still use CPU time?
I just did a quick test (good question :) ), in a game where i can slide the screen over a large map that contains images of soldiers performing an 'idle' animation. They continue running when off-screen (I tacked a CCCallFunc in a sequence in a repeat forever, to a simple selector that logs).
I suspect they would also run when the object is not visible. It kind of makes sense, especially for animations. If you look at my use case, if the animation were stopped, it could cause a cognitive disconnect if the user slided the soldier in and out of view, especially when the soldier is doing a walk on the map - he could actually walk-in the view without the user having done any interaction with the screen.
I have a question with regards to using replace scene in cocos2d.
Assume my game menu has the following structure:
Main Menu
Play
2.1 Strategy levels
2.2 Accuracy levels
Settings
Tutorial
Is the recommended method of navigation between the menus, "replace scene" or "push/pop"?
I've read in some places that its good to avoid push/pop in cocos2d. But my concern in using replace scene is that i have the impression that im just stacking up scenes instead of having a proper navigational flow.
Push and pop scene is going to stack your scenes. Each time you push a new scene, the old scene remains in memory and you need the exact same amount of popScene to get back to the initial scene.
So yes, using replaceScene is the standard and recommended method of switching scenes. While replaceScene removes the original scene from memory, there is a short time of overlap where both scenes remain in memory. So if you have two very memory intensive scenes, it is recommended to go through a temporary loading scene instead to allow the previous scene enough time to release its memory.
Note also that you cannot call replaceScene within the init method of a scene. That will cause CCDirector to crash.