Cocos2d Changing Scenes: BAD_ACCESS Exception - cocos2d-iphone

I have sincerely tried to understand the error from any remotely related question I have seen here. However, the issue that I am having is that when I try to transition from my level1 scene to levelselector scene, the game crashes with the bad access exception. The menus and transitions worked flawlessly while I was using them among main menu, credits, levelselector and all.
Now I do know that the error is on the main thread.
The selector shows that it is at
int retVal = UIApplicationMain(argc, argv, nil, #"AppDelegate");
now on my level1 scene, I do have three thread using [self schedule] and I have put in the corresponding [self unschedule];
I also have a NSMutableArray which I tried releasing and pointing to nil but I get another error. I put it in the dealloc method of the scene. I did the same with the [self unschedule] as well. Is there a better place to put it?
here is how it looks like, had forgotten to retain the stuff. release is working fine now but still crashes right after the transition. the scene loads as in I can see it, but then it crashes right away.
[enemies release];
[player release];
[accel release];
[pausedLabel release];
[pausedLayer release];
[health release];
[score release];
enemies = nil;
player = nil;
accel = nil;
pausedLabel = nil;
pausedLayer = nil;
health = nil;
score = nil;
[self unschedule:#selector(updateGameLogic)];
[self unschedule:#selector(throwEnemey)];
[self unschedule:#selector(enemyShoot)];
[super dealloc];
I used [[Class init] alloc] retain] this time around for each of the objects above

Related

Collision between a sprite and a tilemap with Cocos2d and Box2d

I have the following map I made in Tiled, and then added to my project:
map = [[CCTMXTiledMap alloc] initWithTMXFile:#"FirstLevel.tmx"];
[self addChild:map];
I also have the following object which contains the player that I can move around:
objectLayer = [CCSpriteBatchNode batchNodeWithFile:#"level.pvr.ccz" capacity:150];
[self addChild:objectLayer z:10];
player = [[[Player alloc] initWithGameLayer:self] autorelease];
[objectLayer addChild:[player ccNode] z:10000];
[player setPhysicsPosition:b2Vec2FromCC(240,150)];
I can see my tilemap in the background, but it doesn't collide with anything. How can I make Player colide with the layers in my Tilemap?
Did it with Rubymotion and Joybox http://joybox.io/

Cocos2d: Black screen when removing sprites

I'm currently doing the tutorial http://www.raywenderlich.com/25736/how-to-make-a-simple-iphone-game-with-cocos2d-2-x-tutorial .
I have a problem on the part that reacts to when a ninja star hits the monsters. My code is:
- (void)update:(ccTime)dt {
NSMutableArray *projectilesToDelete = [[NSMutableArray alloc] init];
for (CCSprite *projectile in _projectiles) {
NSMutableArray *monstersToDelete = [[NSMutableArray alloc] init];
for (CCSprite *monster in _monsters) {
if (CGRectIntersectsRect(projectile.boundingBox, monster.boundingBox)) {
[monstersToDelete addObject:monster];
}
}
for (CCSprite *monster in monstersToDelete) {
[_monsters removeObject:monster];
[self removeFromParentAndCleanup:YES];
}
if (monstersToDelete.count > 0) {
[projectilesToDelete addObject:projectile];
}
[monstersToDelete release];
}
for (CCSprite *projectile in projectilesToDelete) {
[_projectiles removeObject:projectile];
[self removeChild:projectile cleanup:YES];
}
[projectilesToDelete release];
}
which works okay, does not crash, but when I hit a monster with an projectile, the screen turns black on the simulator. No error or anything. I logged the CGRectIntersectRect, and it records as it is supposed to. The problem is that when this happens, it all turns black. Any idea why?
I looked at the tutorial, and the line i identified in the comments above reads :
[self removeChild:monster cleanup:YES];
Try that.
You're doing [self removeFromParentAndCleanup:YES] which removes your current layer from the parent. So you get a black screen.
You probably want to remove the child monster from the layer instead.

Cocos2D - NSMutableArray not accessible in ccTouchBegan?

First, let's be clear on two things. My English is terrible and I'm pretty new in cocos2d. So sorry and sorry again. :D Now for my question.
I have declared these in a .m (Its a CCscene):
//A mutable array global to my class
NSMutableArray *arrayBoutons;
//I use this array like this :
LettreBleue *lettre1 = nil;
lettre1 = [LettreBleue construireObjLettre];
lettre1.position = ccp(80,370);
[self addChild:lettre1];
[arrayBoutons addObject:lettre1];
//The method to register the touch
-(void) registerWithTouchDispatcher
{
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:kCCMenuTouchPriority swallowsTouches:NO];
}
// The classic TouchBegan in which Im trying to access the value Valeur
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
// test!
NSLog(#"Debut test ccTouchBegan4");
int cptLettres = 0;
do {
LettreBleue *unBoutontest=[arrayBoutons objectAtIndex: cptLettres];
NSLog(unBoutontest.Valeur);
cptLettres = cptLettres+1;
} while (cptLettres < 16);
The problem is my arrayBoutons doesn't seem to keep my data in my NsMutableArray.
Have you initialized the NSMutableArray, perhaps in an init method? You need to call something like:
arrayBoutons = [[NSMutableArray alloc] init];
Then, you need to release it in your dealloc method:
[arrayBoutons release];

cocos2d scene retaining issue

There is a scene in my application which has only two labels and a menu item. When I load this scene using replaceScene method it stays for 3-4 seconds and then gets disappeared or released. I want to keep it until cancel button is pressed. How can I do it? code is:
#implementation MyLayer
+ (id)myScene {
CCScene *aScene = [CCScene node];
MYLayer *myLayer = [MyLayer node];
[aScene addChild:myLayer];
return aScene;
}
- (id) init {
if (self = [super init]) {
//labels and menu here
}
return self;
}
And I am calling it from another scene like this:
[[CCDirector sharedDirector] replaceScene: [MyLayer myScene]];
Maybe the problem is that it's your first scene. Then you should use runWithScene method of CCDirector.
did you try replacing that scene with a "empty" init function to see if it still releases itself? It might be because of the amount of textures you are putting into memory
I did have sort of similar problems before because the images used in the new scene is too big and got auto purged by my app delegate, thus returning me an empty scene sometimes

Cocos2d: Preloading animation causes a crash

I am trying to preload an animation in the init method of my layer. I then call the animation if the screen is touched. The app crashes with no error message as soon as I touch the screen and seems it is to do with calling the preloaded animation. I would like to do it this way as it seems expensive to create the animation every time the screen is touched - which does seems to work though. Any tips greatly appreciated.
Sample Code:
In my header:
#interface Test : CCLayer {
NSMutableArray *wake;
CCSprite* ani;
CCAnimate *animate;
}
#end
In my implementation:
-(id) init {
if( (self=[super init])) {
// enable touches
self.isTouchEnabled = YES;
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"ani.plist" texture:[[CCTexture2D alloc] initWithImage:[UIImage imageNamed:#"ani.png"]]];
ani = [CCSprite spriteWithSpriteFrameName:#"ani1.png"]; //comes from .plist file
ani.anchorPoint=ccp(0,0);
ani.position = ccp(700,65);
[self addChild:ani z:30];
wake = [NSMutableArray array];
for(int i = 1; i <= 4; i++) {
[wake addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:#"ani%d.png",i]]];
}
animate = [CCAnimate actionWithAnimation:[CCAnimation animationWithFrames:wake delay:1.0f] restoreOriginalFrame:FALSE];
}
return self;
}
Handling the touch:
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// run the animation
[ani runAction:animate];
}
Animations in Cocos2d are not designed to be reused. You need to create a new one every time.
Problem solved by creating properties for the array and animation on the class using nonatomic,retain.
You only need to retain the animation but the array can be local.
self.myAnimation = [[CCAnimation animationWithFrames:myAniFramesArray delay:0.1f] retain];
Remember to make the property nonatomic, retain as stated by Chev and to release any objects you retain in the appropriate dealloc method.