cocos2d add free memory display to showFPS

Replace CCDirector.m with the content:

http://go.pastie.org/2187329

This is for cocos2d 1.0.0-beta.  If using another version, use a diff tool and integrate relevant changes.

The modified showFPS method will also display free memory in MB with the frame rate.

Advertisements

cocos2d, run an animation then remove the sprite

The interesting part here is

[CCCallFunc actionWithTarget:fixedSprite selector:@selector(removeFromParentAndCleanup:)]

Most online examples will add a new callback method and pass the sprite to it, then remove from within the callback.

You can see clearly also how to add an animation over an existing sprite by setting (the class used is a subclass of CCSprite, so self refer’s to a sprite). All sprite’s have a contentSize, so positioning it is clean.

-(void) animateAndRemove
{
	CCSprite *fixedSprite = [CCSprite spriteWithSpriteFrameName:@"fixed_01.png"];

	fixedSprite.position = ccp(self.contentSize.width/2,self.contentSize.height/2);
	[self addChild:fixedSprite];

	NSMutableArray *animFrames = [NSMutableArray array];
	for(int i = 1; i <= 6; ++i) {

		[animFrames addObject: [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName: [NSString stringWithFormat:@"fixed_%02d.png", i]]];
	}

	CCAnimation *anim = [CCAnimation animationWithFrames:animFrames delay:0.05f];
	CCActionInterval *animAction = [CCAnimate actionWithAnimation:anim restoreOriginalFrame:NO];
	id seq = [CCSequence actions: animAction, [CCCallFunc actionWithTarget:fixedSprite selector:@selector(removeFromParentAndCleanup:)], nil];
	[fixedSprite runAction:seq];
}

box2d preSolveContact

if you have similar requirements:

– can’t use a sensor, because you want the object to still react to some other objects in the world
– can’t use collision filter, because you want to listen to the contact

you can use preSolveContact.

An example, where I want to remove the node as I’m about to hit it. Unlike beginContact, preSolve may be called many times on a single colision, so once we have the class from the presolve contact node’s userData, we set a isDead property of that class to true so that we don’t try and remove the same node from the box2d world many times.

Example:

-(void) preSolveContact:(b2Contact*)contact  manifold:(const b2Manifold*) oldManifold
{
	b2WorldManifold worldManifold;
	contact->GetWorldManifold(&worldManifold);
	b2Fixture *fixtureA = contact->GetFixtureA();
	b2Fixture *fixtureB = contact->GetFixtureB();
	NSAssert( fixtureA != fixtureB, @"preSolveContact bug");
	
	b2Body	*bodyA = fixtureA->GetBody();
	b2Body	*bodyB = fixtureB->GetBody();
	NSAssert( bodyA != bodyB, @"preSolveContact bug");
	b2Body *otherBody = (bodyA == body_) ? bodyB : bodyA;
	b2Fixture *otherFixture = (bodyA == body_) ? fixtureB : fixtureA;
	
	if( !otherFixture->IsSensor() ) {
		BodyNode *bNode = (BodyNode*)otherBody->GetUserData();
		Class tClass = [Tank class];
		
		if([bNode isKindOfClass:tClass])
		{
			contact->SetEnabled(false);
			Tank *t = (Tank*)bNode;
			
			if(!t.isDead) {
				t.isDead = YES;
				[arrayTanksToRemove_ addObject:t];
			}
		}	
	}
}

pass a native object to selector withObject

In this case, I wanted to pass a CGPoint object.  This can be completed using [NSValue valueWith..]

-(void) removeBadGuy:(BadGuyNode*)badGuy delay:(float)delay
{

    b2Vec2 pos = [badGuy body]->GetPosition();
    CGPoint cPos = CGPointMake(pos.x * kPhysicsPTMRatio, pos.y * kPhysicsPTMRatio);
    NSValue *vPos = [NSValue valueWithCGPoint:cPos];
    [self increaseBadGuysWaitingForRemoval];
    id bgRemovedAnimation = [CCCallFuncO actionWithTarget:self selector:@selector(badGuyRemovedAnimation:) object:vPos];
    id removeBadGuy = [CCCallFuncO actionWithTarget:self selector:@selector(removeBadGuy:) object:badGuy];
    id decrWaitingCount = [CCCallFuncO actionWithTarget:self selector:@selector(decreaseBadGuysWaitingForRemoval)];

    id seq = [CCSequence actions: [CCDelayTime actionWithDuration:delay], badGuyRemovedAnimation, removeBadGuy, decrWaitingCount, nil];
    [game_ runAction: seq];
}