I've got two apps that I have written that I want to "bundle" in the same app. What's the procedure for unloading the game that you're currently playing, going to the main menu, and loading the other game that you'd like to play?
Bundling games
(12 posts) (6 voices)-
Posted 2 years ago #
-
If you mean as two executables, it's not allowed. Otherwise, I guess you have to be more clear about what you want to achieve.
Posted 2 years ago # -
No, i'm not meaning two executables. I downloaded a game for my son and it has three different "mini-games", i call it, in the same application: like a puzzle, or a connect the dots, or a coloring game. He picks a game from a menu, then it loads and he plays it, goes back to the menu and picks a different game.
I tried copy/pasting the code from my two apps into their own class files in a separate project, created individual scenes and layers. then made a menuscene class which I load when the application launches. using replaceScene I am able to load up the first game but the menulayer doesn't go away and that causes the program to behave erratically. It seems as though the layer where I have my touch events is not unloading when the scene is being replaced.
Posted 2 years ago # -
Your replaced scene must be retaining something and therefore still around. Is dealloc being called?
Posted 2 years ago # -
jd is correct. If some layers aren't going away, they're being retained and not released on exit. You need to go through your project and look for instances of retain, alloc, or copy which are not complemented by a release or autorelease. Beware of selectors as well - scheduled selectors DO retain their targets, so if you have any selectors scheduled on a layer, you MUST unschedule them when the layer leaves the scene (onExit is a good place) or the layer will not dealloc.
Hope that helps. It sounds like you're taking the right approach, you just need to fix some memory management issues.
Posted 2 years ago # -
I've been kicking this thing around for the past day and I'm still not getting anywhere. I have dealloc methods in all of my classes, and they're being called whenever replaceScene is called.
Perhaps I'm not replacing the scene correctly, here is a code example:
-(BOOL)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint tmpLoc = [touch locationInView: [touch view]];
CGPoint location = [[Director sharedDirector] convertCoordinate:tmpLoc];if([CastleSprites SomethingWasTouched:location]){
NSArray *mySprites = [CastleSprites allMySprites];
NSUInteger i, count = [mySprites count];for (i=0; i<count; i++){
CastleSprites *obj = (CastleSprites *)[mySprites objectAtIndex:i];if(CGRectContainsPoint([obj rect], location) && [obj GetCanTrack]){
switch([obj tag]){
case HIT_RIGHT_SIGN:
NSLog(@"Hit Menu Sign");MenuScene *ms = [MenuScene node];
MenuLayer *ml = [MenuLayer node];[ms addChild:ml];
[[Director sharedDirector] replaceScene:ms];
break;
default:
NSLog(@"This touch event not handled yet.");
break;
}
}
}
}
return kEventHandled;
}What happens is whenever I hit the sign, if I've gone to the menu and back a few times, the log displays "Hit Menu Sign" multiple times. Say, the first time i go out and back in it'll show twice, the second time will be 4x, and the 3rd will be 6x.
I'm really really really green when it comes to obj-c, I'll admit I need much more work in that area. Any thoughts would be greatly appreciated.
Posted 2 years ago # -
I'm not sure I fully understand your problem, but have you thought of perhaps changing to the menuscene and then adding the layer from within the scene (in the scene init)? Although perhaps not a solution to your problem I think this is the generally accepted way to go.
Posted 2 years ago # -
I think i've isolated my issue down to how I'm handling touches. I'm using a method that I found here: http://juanmunozar.blogspot.com/2009/02/cocos2d-iphone-dynamically-touch.html
All of the sprites that i'm using that accept touch events are added to the allMySprites array when the layer is added to a scene. What isn't happening is when the current scene is replaced, the array is not released. Help anyone?
Posted 2 years ago # -
I set up my arrays like this:
in .h:
NSMutableArray *array;in init:
array = [[NSMutableArray alloc] initWithCapacity: numberHere];This dealocs fine for me.
Posted 2 years ago # -
Jonathan, I don't know how that's properly deallocating for you, because it really shouldn't. Unless you release or autorelease that array somewhere else in your program, it will never get deallocated and anything left in it will not get deallocated either.
OP: That code you linked to is... not the best. The problem is definitely as you stated; the array isn't released when the scene changes. The fix is easy, though. Just add the following code to the class which contains "allMySprites:"
- (void) onExit { [allMySprites release]; [super onExit]; }That way, allMySprites will be released when the scene changes, which will cause it to deallocate and in turn release any remaining items in it. That should solve your problem. If it doesn't, let me know.
Edit: For the OP or anyone else who is having trouble finding memory management issues, run your project through the Clang-LLVM static analyzer. It basically does all the work for you and produces very reliable results. If you've got Snow Leopard, it's built into XCode 3.2 - just change your compiler to Clang-LLVM in Project Settings and then select Build and Analyze from the build menu. (Do a clean first to ensure all files get rebuilt and analyzed.) The analyzer will point out any reference count increments without obvious matching decrements, among other things.
If you're not running Snow Leopard you can still do this, though it is a bit more work... see this thread: http://www.cocos2d-iphone.org/forum/topic/1662#post-10410
Posted 2 years ago # -
@Mitch: So after I put the project on hold for 7 months, I dug it back out ( with a bit more knowledge of obj-c) and found the source of my problem:
//My Original Code +(void)track: (TouchableSprites *)aSprite { @synchronized(allMySprites){ NSUInteger i, count = [allMySprites count]; //NSLog(@"aSprite: %@", aSprite); for(i=0;i<count;i++){ TouchableSprites *obj = (TouchableSprites *) [allMySprites objectAtIndex:i]; if([obj tag] = [aSprite tag]){ return; } } [[TouchableSprites allMySprites] addObject:aSprite]; } }What was happening is in the if([obj tag] = [aSprite tag]), the compare was always false (even when it should've been true). By changing it to if([obj tag] == [aSprite tag]), the problem was resolved. My new code now looks like this:
+(void)track: (TouchableSprites *)aSprite { @synchronized(allMySprites){ NSUInteger i, count = [allMySprites count]; //NSLog(@"aSprite: %@", aSprite); for(i=0;i<count;i++){ TouchableSprites *obj = (TouchableSprites *) [allMySprites objectAtIndex:i]; if([obj tag] == [aSprite tag]){ return; } } [[TouchableSprites allMySprites] addObject:aSprite]; } }maybe someone could explain to me why comparing objects requires == and not a single =?
Posted 2 years ago # -
because = is for assignment and == is for comparing.
doing something like this:
int i; if ((i = [self getValue])) { }is perfectly valid, because its the same as doing this:
int i; if ((i = [self getValue]) != 0) { }how is the compiler going to know what you mean, unless you use something else... like ==
Posted 2 years ago #
Reply
You must log in to post.