cocos2d: maintain state through levels

Quick hack if you don’t want to bother to add a singleton to your project and want to reload or swap a level while maintaining some data.

-(void) nextLevel {
	CCScene *scene = [[game_ class] scene];

	for (CCNode *node in scene.children) {
		if ([node isKindOfClass:[game_ class]]) {
			GameNode *gn = (GameNode*)node;
			gn.level = game_.level;
			gn.totalScore = game_.totalScore;

			break;
		}
	}
	[[CCDirector sharedDirector] replaceScene: [CCTransitionMoveInT transitionWithDuration:1.0f scene:scene]];
}
Advertisements

cocos2d: animation – updating the sprite every X pixels of movement

-(void) updateFrames:(CGPoint)direction
{		
	unsigned int length = sqrtf( powf(position_.y, 2) + powf(position_.x, 2) );
	unsigned int index = (length / 5) % 2; // 2 = the number of sprites for the character's walk sequence

	// increase frame index, since frame names start in "1" and not "0"
	index++;
	NSString *str = [NSString stringWithFormat:@"Anim-player-walk_%02d.png", index];
	CCSpriteFrame *frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:str];
	if (frame) [self setDisplayFrame:frame];
}

cocos2d textured poly

https://github.com/asinesio/cocos2d-PRKit

cocos2d box2d destructible wall contact example

-(void) beginContact:(b2Contact *)contact{
	[super beginContact:contact];

	b2Fixture* fixtureA = contact->GetFixtureA();
	b2Fixture* fixtureB = contact->GetFixtureB();
	NSAssert( fixtureA != fixtureB, @"Bullet: Box2d bug");

	b2Body *bodyA = fixtureA->GetBody();
	b2Body *bodyB = fixtureB->GetBody();

	NSAssert( bodyA != bodyB, @"Bullet: Box2d bug");

	// Box2d doesn't guarantees the order of the fixtures
	b2Body *otherBody = (bodyA == body_) ? bodyB : bodyA;
	b2Fixture *otherFixture = (bodyA == body_) ? fixtureB : fixtureA;

	// ignore sensonrs
	if( ! otherFixture->IsSensor() ) {
	BodyNode *bNode = (BodyNode*) otherBody->GetUserData();
	if ([bNode isKindOfClass:[Bullet class]]) {
			if([(Bullet*)bNode canKill]){
				hitCount_--;

				if (hitCount_ >= 0) {
					CCSpriteFrame *frame = nil;

					switch (hitCount_) {
						case 2:
							frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"structure-damaged.png"];
							break;
						case 1:
							frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"structure-destroyed.png"];
							break;
						case 0:
							[game_ removeB2Body:self.body];
							[[game_ arrayEnemyWall] removeObject:self];
							break;
					}
					if (frame) [self setDisplayFrame:frame];
				}
			}
		}
	}
}

cocos2d: using CCEaseBounce to make a simple scroll view control

This is for vertical scroll, but it is easy to change to horizontal.

To use this, just create a CCLayer object (such as CCLayer *l1…, then instantiate with ScrollLayer *scroller = [[ScrollLayer alloc] initWithLayers:[NSMutableArray arrayWithObjects: l1,l2,l3,nil]];

ScrollLayer.h

#import <Foundation/Foundation.h>
#import "cocos2d.h"

@interface ScrollLayer : CCLayer {

	// Holds the current height and width of the screen
	int scrollHeight;
	int scrollWidth;
	int startHeight;
	int startWidth;
	int currentScreen;
	int totalScreens;
	int startPos;	
}

-(id) initWithLayers:(NSMutableArray *)layers;

@end

ScrollLayer.m

#import "ScrollLayer.h"

@implementation ScrollLayer

-(id) initWithLayers:(NSMutableArray *)layers
{

	if ( (self = [super init]) )
	{
		[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];

		currentScreen = 1;

		scrollWidth = [[CCDirector sharedDirector] winSize].width;
		scrollHeight = [[CCDirector sharedDirector] winSize].height;
		startWidth = scrollWidth;
		startHeight = scrollHeight;

		int i = 0;
		for (CCLayer *l in layers)
		{			
			l.anchorPoint = ccp(0,0);

			l.position = ccp(0, -(i*scrollHeight));
			[self addChild:l];
			i++;
		}

		totalScreens = i;		
	}
	return self;
}

-(void) move
{
	float dest = ((currentScreen-1)*scrollHeight);
	id changePage = [CCEaseBounce actionWithAction:[CCMoveTo actionWithDuration:0.2 position:ccp(0,dest)]];
	[self runAction:changePage];
}

- (void)onExit
{
	[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
	[super onExit];
}

-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
	CGPoint touchPoint = [touch locationInView:[touch view]];
	touchPoint = [[CCDirector sharedDirector] convertToGL:touchPoint];

	startPos = touchPoint.y;
	return YES;
}

- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{

	CGPoint touchPoint = [touch locationInView:[touch view]];
	touchPoint = [[CCDirector sharedDirector] convertToGL:touchPoint];

	self.position = ccp(0, ((currentScreen-1)*scrollHeight)+(touchPoint.y-startPos));
}

- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
	CGPoint touchPoint = [touch locationInView:[touch view]];
	touchPoint = [[CCDirector sharedDirector] convertToGL:touchPoint];

	int newY = touchPoint.y;

	if ( (newY - startPos) > 50 && (currentScreen+1) <= totalScreens )
		currentScreen++;
	else if ( (newY - startPos) < -50 && (currentScreen-1) > 0 )
		currentScreen--;

	[self move];
}

- (void) dealloc
{
	[super dealloc];
}

@end

box2d: following a moving target body

CGFloat speed = 0.6;
b2Vec2 velocity = target.body->GetLinearVelocity();
b2Vec2 p1 = target.body->GetPosition();
float y = p1.y * b2dPTMRatio;

if (sqrtf(powf(velocity.x, 2) + powf(velocity.y, 2)) < 1)

        b2Vec2 p2 = body_->GetPosition();
        CGFloat x = p1.x - p2.x;
	CGFloat y = p1.y - p2.y;

	speed /= 3;
	if (x != 0) {
		CGFloat oldX = x;
		x = x/fabsf(x) * speed;
		y = x/oldX * y;
	}
	else if(y != 0) {
		CGFloat oldY = y;
		y = y/fabsf(y) * speed;
		x = y/oldY * x;
	}

	body_->SetLinearVelocity(b2Vec2(x,y));
	return;
}

Simple Pacman Demo Source Code

This pacman game/demo with full source code contains the following features:

– uses only the standard SDK
– uses the accelerometer for player movement
– basic enemy AI
– simple level format
– supports multiple levels
– reset the game

Download the Source code