Preloading assets in cocos2D - iphone

I have some assets for my game that are being loaded when the gameplay layer is loaded. I'd prefer to load them when the application launches in a loading screen, which is obviously a pretty standard thing to do.
My problem is the way in which new scenes are launched within cocos2D. Consider the following code which occurs (with some variations) in several places throughout the project:
[[CCDirector sharedDirector] replaceScene:[CCTransitionShrinkGrow transitionWithDuration:0.5f scene:[GameplayLayer scene]]];
This is the standard way of replacing the current scene with a new one. My question is, given that format, how would I pass a preloaded asset to the new GameplayLayer? Is there an accepted way of doing this in cocos2D? I have a feeling that I'm missing something incredibly simple, but as of now it's a mystery to me.

Cocos2d uses a texture cache that persists between scenes. You can preload assets into this cache in a loading scene and they will still be available from your game scene. How you load these are up to you. For images you can opt to do it asynchronously, to allow your loading scene to maintain a decent framerate and render a progress bar.
This post gets the basic idea across.
This thread may also be of use to you in that regard: http://www.cocos2d-iphone.org/forum/topic/2242
If you have your own class of assets (i.e. not a supported cocos2d image, or something), you could create your own cache singleton class (look at how the sharedManager instances of various cocos2d classes are implemented) and load your assets into that. As far as memory management goes you'd have to release those assets yourself whenever you deem necessary, but that's rather beyond the scope of this question.

Related

Efficient way to Load the scene and Scene Render optimization

Our unity3d Most of the Scenes are too heavy. What is the right way and efficient way to load the scene.?? Please dont refer me LoadLevelAsync I have already see that! What is the best practice to load heavy scene without any problem and un-smoothness.
For which platform you are building?
The heaviest thing to load in Unity are Textures. If you are using too much of them in the scene, make sure that they are compressed and try to reduce their max size in the inspector. If you can't see any improvement, consider creating a loading screen transition after calling Application.LoadLevel("YourBigLevel").
You can add an Activity indicator if you are running the app on iOS or Android devices.

cocos2d using gobs of memory

I'm having the absolute worst time with running out of memory in my game with cocos2d.
I have 4 scenes. two vanish from memory when I switch scenes using
[[CCDirector sharedDirector]replaceScene:sceneWithTransition]
I've tried push/pop and it makes the problem about 10x worse.
2 of the scenes however are like a virus. The conditions under which I can remove them from memory do not exist.
I am using the ARC alterations. I was hoping they would help, they did not.
I've overridden the cleanup method to make sure I get rid of references to everything in the scenes. The first one is the game play scene, and I can imagine how it might be possible that I've missed something that is somehow holding on to the scene. However the other one is the settings scene. It has 5 parts. they all get tossed and yet the scene will not purge. before converting to ARC the app was unusable it crashed so often and when it wasn't crashing it was running out of memory. After ARC it lasts about 4x longer than before but still runs out of memory regularly. Crashes however are almost non-existant.
I suppose first off, what is the correct way to switch between scenes?
Second, how does one remove something from memory when using arch because object = nil does nothing. All of my other programs using ARC run like dreams. None of them use the cocos2d engine. I'd not seen a memory error since the introduction of arc until I made the mistake of converting my quartz2d game in to cocos2d. The only reason I don't o back to a platform that actually functions is that I really like the effects possible in cocos that I simply cannot make work in quartz.
It seems that cocos2d had some issues with ARC that got fixed only recently.
I don't know if this has to do with your memory problems, but you might check which cocos2d version you are using.
Anyway, it seems that cocos2d will fully support ARC only from version 2.0. So, you might be better off not using ARC and getting your memory management right by properly using release. As far as I know, cocos2d has no memory problem, so you should be able to accomplish it.
push/pop from what I understand use a "stack" model thus memory is not erased when new scenes are pushed or popped, which would explain why that gets worse when using this method.
one way you can help save memory, especially during a transition, is to transition to a loading scene and then from there transition to the actual scene you want. This is because during a normal transition, both scenes occupy memory simultaneously for at least 1 frame, whereas a cheap loading scene will instead take each of their places, reducing the horrible memory spike that often occurs when transitioning between two intense scenes.

MonoTouch OpenGL app loses texture data when moved to background

I have a MonoTouch OpenGL app that has a bunch of textures. When the user hits the iPhone button to move the app to the background, all my texture data seems to go away. I just see a solid color filling the triangles that I'm drawing with the textures that were loaded originally.
Any new textures that I load after resuming from the background state show up properly. It's just the textures that were loaded before the app was moved to the background that show up solid.
The docs state that "Your application should keep textures, models and other assets in memory" when it is moved to the background. I'm not doing anything to my textures, but something is forcing them out.
Any ideas?
My solution was to not use iPhoneOSGameView. That fixed all problems related to textures disappearing when my app went background. The code to manage the framebuffers and update timer yourself is pretty simple and I found the extra clarity (and working restore-from-background) to be worth the effort.
Not using iPhoneOSGameView also makes me feel better about the application's timer actually running at full speed when the app is active:

iPhone Opengl game with ads == fps problem?

I have a game that runs fine as is (around 30fps), but fps went down the drain when I tried to implement ads. I tried Greystripe and iAds but with same result (iAds were maybe bit worse). Average fps is almost same, but there are huge spikes all the times (1-2 spikes per second) and game is unplayable.
I guess it is because ad is in another view. I read somewhere that opengl apps on iphone don't like having another views with them, but there is plenty of games with ads on app store. How do they do it?
My implementation should be ok. I did everything as documentation and samples told me. I have my opengl view and ad view as subviews in app window, adview being in front of opengl view and thus covering part of it. Could this be the problem? Is it better to make opengl view smaller to left space for ad so they don't overlap? Do you have any other ideas what could be wrong?
Lope, I've created a gist at this link with a singleton "AdManager" class I wrote to handle iAds using cocos2d. Cocos2d sits on top of OpenGL, of course, and I've found that this code doesn't affect FPS even for relatively complicated games.
You'll have to modify this a bit to work with your application, changing out the cocos2d calls, etc, but this will give you asynchronous loading of iAds, which should help the FPS issue.
To use this class, include its header and call
[[AdManager sharedManager] attachAdToView:self.view];
wherever you need iAds. The ads will remain hidden until an ad loads, at which time they'll pop up at the top of screen. (The class works for iOS 4.0, 4.1 and 4.2).
Also, I should add that I have cocos2d running inside of an overall UIViewController that I call "Cocos2DController". When I attach the ads to a cocos2d view, I'm using
[[AdManager sharedManager] attachAdToView:[[CCDirector sharedDirector] openGLView]];
Best of luck!
We can hit and miss with apple's choices, but go for the sure thing and implement the ads in other parts to be appealing and not intrusive. It will be better for the framerate, and for you.
Try downloading the ads in a seperate, low priority, thread. You can, thus, nsure that the ads loading does not take too much CPU time. With a bit of CPU synchronisation you can make sure you don't try to display the new ad until it is completely ready to display. Sure it will suck some CPU time away from what you are trying to do but set your priorities right and it should only suck time when you are busy doing nothing.
Please excuse the thread necro'ing here, but I've used Stack Overflow a lot to help me through the problems I've had during coding, and thought my experience might be useful to someone in the future.
My simple cocos2d game ran with decent FPS (rarely changed the FPS display at all) until I implemented AdWhirl (integrating AdMob + iAd only). It would then run OK for the first few iterations, but upon upon the 9th or 10th scene refresh (single screen game, time in each scene < 5 seconds on average) the FPS would dive to ~20FPS, and drop again each time the scene refreshed.
Turns out, in my n00biness (this may be particular to me :) ), I was calling the scene from within itself. That is, once the actions had finished, the last action was to call the main scene again (a lazy way of rebuilding the scene for the user to have another go). This init'd the views and view controllers I had inserted to handle the AdWhirl ads all over again, and not only did I have a memory leak, I had 10+ view controllers all trying to request and service ads from AdWhirl. Once I got a clue and took that self-referring loop out, all was good.

Load an OpenGl view in the background. iPhone

I have an OpenGL view that renders a 3D model. It is a basic modification on Apples EAGLView. This view is added to a controller's .view and displayed with presentModalViewController: . I would like to do all of the model loading, and OpenGL state configuration in a background thread at app launch before the user chooses to display the view. Is this possible? Can I load textures, setup lighting, and generally just get everything ready to render in a background thread? My fear is that the Cocoa touch portions of the app on the main are going to manipulate the OpenGL state while I am setting up my renderer in the background. The controller will be displayed from the main thread of course. This level of understanding of OpenGl-ES is not something I deal with often, so please be gentile if my question is strange in any way :)
You absolutely can do background loading on a thread. Some of the key points:
- There is probably not much of a win to moving OGL state setup to a background thread - the total amount of change you'd induce in a context before the start of the first draw doesn't add up to a ton of time. Background loading is useful for textures and VBOs, as well as the load time that has to happen first to get the data to feed to the GL.
- You'll need to detach the context from the main thread and move it to the worker thread. We do this using pthreads to "send" the context to the worker.
- In our use, we hide the GL view to ensure that it doesn't need to be drawn while in a load state. (Frankly during load it may not contain anything useful.) So during async load the visible UI is all non-GL Cocoa.
This approach is more difficult than what you would do on the desktop: simply share the objects in two contexts (so that you can load and draw at the same time). When we looked at that approach more than a year ago, it wasn't possible on IOS; it may be possible now, I do not know.