Here's some stuff for you. The code is untested and probably has syntax errors since I haven't typed it into xcode, but you should get a good idea of what's needed ;-)
Create a CocosNode subclass that contains your progress bar, along with a property that allows you to set the progress:
@property(readwrite,assign) int percentComplete;
In your setter, move your progress bar:
// Leftmost and rightmost position of the loading bar sprite in pixels
#define kLoadingBarPosition0 25.0f
#define kLoadingBarPosition100 238.0f
#define kLoadingBarSpread (kLoadingBarPosition100 - kLoadingBarPosition0)
- (void) setPercentComplete
{
percentComplete = value;
float xPosition = (kLoadingBarSpread * value) / 100.0f;
loadingBar.position = ccp(xPosition + kLoadingBarPosition0, loadingBar.position.y);
loadingComplete.visible = value >= 100;
}
Somewhere in your code, make a list of resources you want to load:
NSArray* imagesToPreload;
...
imagesToPreload = [self getImagesWeWantToPreload];
There are two ways to load things asynchronously. The easier way is to use the async convenience methods available in cocos:
int nextImageIndex = 0;
- (void) imageLoaded:(Texture2D*) tex
{
myLoadingBar.percentComplete = (nextImageIndex * 100) / [imagesToPreload count];
if(nextImageIndex >= [imagesToPreload count])
{
// All images loaded. Do something like let the user tap to continue.
return;
}
NSString* nextFilename = [imagesToPreload objectAtIndex:lastImageIndex];
nextImageIndex++;
[[TextureMgr sharedTextureMgr] addImageAsync:nextFilename target:self selector:@selector(imageLoaded:)];
}
Now just call [self imageLoaded:nil] to start it going.
Another method is to put the whole thing into a separate thread using NSOperation. The code below is a bit more generic because I used this pattern to load all sorts of things asynchronously and send an update containing the proportion of resources that have been loaded.
Note that you MUST create your own autorelease pool since this is a different thread, and you must set the GL context. As well, you must call selectors using the main thread.
@interface PreloadOperation : NSOperation
{
NSArray* imagesToPreload;
id target;
SEL selector;
}
// init methods omitted
@end
@implementation PreloadOperation
- (void)main
{
NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
EAGLContext* oldContext = [EAGLContext currentContext];
EAGLContext* context = [[EAGLContext alloc]
initWithAPI:kEAGLRenderingAPIOpenGLES1
sharegroup:[[[[Director sharedDirector] openGLView] context] sharegroup]];
if(nil == context)
{
NSLog(@"ResourcePreloader: could not create EAGL context");
goto done;
}
if(![EAGLContext setCurrentContext:context])
{
NSLog(@"ResourcePreloader: could not set EAGL context");
goto done;
}
int totalResources = [imagesToPreload count];
int loadedResources = 0;
float lastCompleteAmount = 0;
for(NSString* filename in imageFilenames)
{
if([self isCancelled])
{
goto done;
}
[[TextureMgr sharedTextureMgr] addImage:filename];
loadedResources++;
float complete = ((float)loadedResources) / totalResources;
if(1.0 == complete)
{
complete = 0.99999999;
}
if(complete >= lastCompleteAmount + kCompletionUpdateThreshold)
{
lastCompleteAmount = complete;
[target performSelectorOnMainThread:selector withObject:[NSNumber numberWithFloat:lastCompleteAmount] waitUntilDone:NO];
}
}
done:
[[ResourcePreloader sharedInstance] notifyAsyncOperationComplete];
[EAGLContext setCurrentContext:oldContext];
[context release];
if(![self isCancelled])
{
[target performSelectorOnMainThread:selector withObject:[NSNumber numberWithFloat:1.0] waitUntilDone:YES];
}
[autoreleasepool release];
}
@end
To start it going, make an operation queue and add the operation. You can make the queue in a global context and make use of it as needed. You can also call cancel on the operation if you need to stop it.
NSOperationQueue * queue = [[NSOperationQueue alloc] init];
preloadOperation = [PreloadOperation operationWithTarget:target selector:selector animations:animationResources sounds:soundResources images:imageResources];
[queue addOperation:preloadOperation];