Monthly Archives: October 2012

Cocos2d – How to Get the Position of Collision in Box2d (iPhone Dev)

Posted by admin at iPhone Dev

In article Cocos2d Example – Box2d, I simply presented how to use Box2d to simulate the physics world. In this article, I will show you how to get the position of collisions. As we know, collisions play an important role in game development. Sometimes we need to make effects or changes when objects collide.

In Box2d, if you want to handle the events of collision, you first need to implement your own Contact Listener (i.e., derive from b2ContactListener), then register your listener using the b2world object (SetContactListenermethod) in initialization.  For example,

// MyScene.mm
#import "MyScene.h"
#import "cocos2d.h"

class MyContactListener : public b2ContactListener
{
public:
void Add(const b2ContactPoint* point)
{
//Handle add point
}

void Persist(const b2ContactPoint* point)
{
// handle persist point
}

void Remove(const b2ContactPoint* point)
{
// handle remove point
}

void Result(const b2ContactResult* point)
{
// handle results
}
};

@implementation MyScene

#define PTM_RATIO 32

-(id) init {

world = new b2World(worldAABB, gravity, doSleep);
world->SetContactListener(new MyContactListener);

}

In your own contact listener, you need to determine which function (Add, Persist, Remove or Result) should be implemented. These functions will be called when a contact point is created, when it persist or when it is deleted. You can get the position of collision and some other important information (e.g., velocity, etc ) with thepoint object.

Cocos2d 0.8 rc Released (iPhone Dev)

Posted by admin at iPhone Dev

Cocos2d 0.8 rc was released today. I tried to compile the example in my last post but encountered three compiling errors (type incompatible) in IntervalAction.m. If you met the same problem, please check out the update r1140. BTW, if you are working with SDK 3.0, you can ignore this.

Cocos2d Example – Box2d (iPhone Dev)

Posted by admin at iPhone Dev

Another excellent physics simulation library Box2d was integrated into Cocos2d 0.8 Beta. Box2d is written in C++, so if you are familiar with C++, Box2d may be a better choice than Chipmunk because of its object oriented design and interface. In addition, Box2d provides more detailed documentation than Chipmunk in its official website. In this tutorial, I will present how to use Box2d in Cocos2d by rewriting the Bouncing Ball example.

Step 1: Download Cocos2d 0.8 Beta project template from here. It should noted the installation method for 0.8 is slightly different from previous version because it introduces static linking. The project template will not include Cocos2d source codes any more. Instead, you need to add a Source Tree in xCode Preferences to point to the location where your Cocos2d library sits. Anyway, strictly follow the installation steps in the downloading page.

Step 2: Add Box2d Direct Dependency and Linked Library. By Default, the project template has already added Cocos2d and Chipmunk dependencies and Linked Libraries, but Box2d is not included. So you have to add it yourself. After you create a new project called Box2dBouncingBall, right click the Target Box2dBouncingBall, and select Get Info. You will see the following dialog.

In the screen shot above, we have added the box2d direct dependency and libbox2d.a library. If you don’t add the library correctly, you will get some linking errors during build.

Step 3: Add the ball image to Resources.

Step 4: Rename the implementation files Box2dBouncingBallAppDelegate.m and MyScene.m to Box2dBouncingBallAppDelegate.mm and MyScene.mm because you need to mix objective C and C++ codes together.

Step 5: Define PTM_RATIO constant. It’s equal to 32. This constant is used to convert pixel to Box2d unit. Add the line of code below to MyScene.mm.

@implementation MyScene

#define PTM_RATIO 32

Step 6: Add some instance variables to class MyScene.

#import <Foundation/Foundation.h>
#import “Scene.h”
#import “Box2D.h”
#import “Sprite.h”

@interface MyScene : Scene {
b2World* world; //world is similar to space in Chipmunk
b2Body* body; //body has the same meaning of body in Chipmunk

Sprite* ball;
}
@end

Step 7: Initialization. Update init function of MyScene class with the following codes:

-(id) init {
self = [super init];

if (self != nil) {
//Create sprite and add it to layer
ball = [Sprite spriteWithFile:@”ball.png”];
[ball setPosition:CGPointMake(150, 400)];
[self addChild:ball z:0];

//Create a world
CGSize screenSize = [Director sharedDirector].winSize;
b2AABB worldAABB;
float borderSize = 96/PTM_RATIO;
worldAABB.lowerBound.Set(-borderSize, -borderSize);
worldAABB.upperBound.Set(screenSize.width/PTM_RATIO+borderSize, screenSize.height/PTM_RATIO+borderSize);
b2Vec2 gravity(0.0f, -30.0f);
bool doSleep = true;
world = new b2World(worldAABB, gravity, doSleep);

//Create a ground box, the ground is defined as a rectangle.
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(screenSize.width/PTM_RATIO/2, -1.0f); //set with mid point, so /2
b2Body* groundBody = world->CreateBody(&groundBodyDef);
b2PolygonDef groundShapeDef;
groundShapeDef.SetAsBox(screenSize.width/PTM_RATIO/2, 1.0f);
groundBody->CreateShape(&groundShapeDef);

//Create ball body and shape
b2BodyDef ballBodyDef;
ballBodyDef.position.Set(150.0f/PTM_RATIO, 400.0f/PTM_RATIO);
ballBodyDef.userData = ball; //user data, will be used in world updating function

body = world->CreateBody(&ballBodyDef);
b2CircleDef ballShapeDef;
ballShapeDef.radius = 20.0f/PTM_RATIO; //radius
ballShapeDef.density = 1.0f; //density
ballShapeDef.friction = 0.3f; //friction
ballShapeDef.restitution = 0.5f; //elasticity
body->CreateShape(&ballShapeDef);
body->SetMassFromShapes(); //The function will help to calculate the mass

[self schedule:@selector(tick:)];
}
return self;
}

Step 8: World updating function.

-(void)tick:(ccTime) dt{
world->Step(dt, 10, 8);
for(b2Body* b = world->GetBodyList();b;b=b->GetNext())
{
if(b->GetUserData()!=NULL)
{

Sprite* ballData = (Sprite*)b->GetUserData();

ballData.position = CGPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO);
}
}
}

Step 9: Dealloc the resources.

-(void)dealloc{
delete world;
body = NULL;
world = NULL;
[super dealloc];
}

All right, these are the general steps when you are writing games using Box2d. For more details of some variables and functions, please refer to the Box2d documentation.

———————————–

Download: You can download the codes from here

Cocos2d Example – Accelerometer (iPhone Dev)

Posted by admin at iPhone Dev

In this tutorial, we will utilize Accelerometer in the Bouncing Ball example. The ball will move when you rotate or tilt your iPhone. To complete this tutorial, you need to get the certificate to put your app on a device. It is because when your application asks for updates from Accelerometer, the simulator will not response.

Generally, you need three steps to make your Cocos2d app to have accelerometer capability. Before that, we need to make walls and roof to prevent the ball moving out of the screen.  Add the following codes at the end of setChipmunk function:

floorShape = cpSegmentShapeNew(floorBody, cpv(0,0), cpv(0,480), 0);
floorShape->e = 0.5;
floorShape->u = 0.1;
floorShape->collision_type = 0;
cpSpaceAddStaticShape(space, floorShape);

floorShape = cpSegmentShapeNew(floorBody, cpv(0,480), cpv(320,480), 0);
floorShape->e = 0.5;
floorShape->u = 0.1;
floorShape->collision_type = 0;
cpSpaceAddStaticShape(space, floorShape);

floorShape = cpSegmentShapeNew(floorBody, cpv(320,0), cpv(320,480), 0);
floorShape->e = 0.5;
floorShape->u = 0.1;
floorShape->collision_type = 0;
cpSpaceAddStaticShape(space, floorShape);
Step 1: Enable accelerometer in Cocos2d app. Add the following code at the end of init method of BallLayerclass.

isAccelerometerEnabled = YES;

Step 2: Set update interval. This interval determines how frequently we get the data from accelerometer. It is also how frequently the updating function (implemented in Step 3) will be called. In this example, we choose 0.033. You should choose appropriate interval based on the types of your application. Add the following code at the end of init method of BallLayer class.

[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / 30)];

Step 3: Implement updating function. You should acquire the data from accelerometer in this function. Add the following function to the implementation of class BallLayer.

#define kFilterFactor 0.05
– (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration{
static float prevX=0, prevY=0;

float accelX = acceleration.x * kFilterFactor + (1- kFilterFactor)*prevX;
float accelY = acceleration.y * kFilterFactor + (1- kFilterFactor)*prevY;

prevX = accelX;
prevY = accelY;

cpVect v = cpv( accelX, accelY);
space->gravity = cpvmult(v, 2000);
}

Line 2 and 3 of the codes should be noted. Here we use low-pass filter (0.05) to reduce the influence of sudden movement (i.e., less sensitive). For more information about low-pass and high-pass filter, please refer to iPhone Application Programming Guide or related books. In this function, Z axis is ignored. According to the new values of X and Y, the gravity of ChipMunk space is calculated. Note: The value of gravity determines the direction which the ball moves to.

Now, the Bouncing Ball app owns accelerometer capability.

Cocos2d Example – Collision (iPhone Dev)

Posted by admin at iPhone Dev

In my last article Cocos2d Example – Bouncing Ball, a little ball bounces up and down on the floor. Continue with that article, some effects will be made when the ball hits the floor. In order to achieve this, we first need to detect collisions between the ball and floor. Fotunately, ChipMunk can do this for us. What we need to do here is just using function cpSpaceAddCollisionPairFunc to register our callback function which can response the collision event.

Step 1: add the codes below to the end of method setupChipmunk.

cpSpaceAddCollisionPairFunc(space, 1, 0, &ballCollision, self);

The function above means callback function ballCollision will be invoked when two physical objects collide, whose collision_type are 1 and 0. Do you remember collision_type? It is the parameter of Shape. In the example of Bouncing Ball, the collision_types of ball and  floor are set to 1 and 0 respectively. (Note: When two physical objects whose collision_type are not 1 and 0 collide, ballCollision will not be called.). self is the address of ballLayer. It will be passed to ballCollision as the data.

Step 2: Define the callback function ballCollision.

int ballCollision(cpShape *a, cpShape *b, cpContact *contacts, int numContacts, cpFloat normal_coef, void *data)
{

BallLayer *layer = (BallLayer*) data;

ParticleSystem* emitter = [ParticleExplosion node];
emitter.position = cpv(contacts->p.x, contacts->p.y);
emitter.life = 0.1f;
emitter.duration = 0.1f;
emitter.lifeVar = 0.1f;
emitter.totalParticles = abs(a->body->v.y)*0.05;

[layer addChild:emitter];

return 1;
}

The return value of callback function plays an important role here. If the return value is 0, the collision will be discarded (Note: but the callback function will be called). You will see the ball pass through the floor. The effects of collision we want to make is emitting particles, so an ParticleExplosion object is created. For the details of properties (e.g., life, duration, etc) of ParticleSystem object, please refer to the Cocos2d documentation. It should be noted that the totalParticles is determined by the falling speed. Therefore, when the ball bounces up and down on the floor, the explosion will become more and more weak.

After the two steps above, the explosion effect is made when the ball collide with floor.

—————————————

Update: You can download the sourcecode from hereNote: ParticleExplosion class will use fire.png to initialize. This file is in Resources/images fold of Cocos2d library. Please add fire.png to the project, otherwise, an exception will happen when the ball hits the floor.

Cocos2d Example – Bouncing Ball (iPhone Dev)

Posted by admin at iPhone Dev

In this example, we will use Cocos2d and ChipMunk physics engine to implement a bouncing ball. A ball falls towards the ground because of the force of gravity. The basic idea of ChipMunk is that you define some physical objects (including bodies and shapes, but they are invisible) in the space, then ChipMunk will simulate what happens to these objects. You should setup a callback function to update these objects’ visual representation (e.g., a sprite created with image).

Step 1Create a Cocos2d Application and name it with “BouncingBall”. We assume you have installed Cocos2d project template properly.
1

Step 2Add this image to Resources Group.

Step 3Define the class BallLayer, which is a subclass of Layer. The codes are shown below:
// BallLayer.h

#import “cocos2d.h”
#import “Layer.h”
#import “chipmunk.h”

@interface BallLayer : Layer {
Sprite* ballSprite;
cpSpace* space;
}
@end
// BallLayer.m

#import “BallLayer.h”

void updateShape(void* ptr, void* unused){

cpShape* shape = (cpShape*)ptr;

Sprite* sprite = shape->data;

if(sprite){

cpBody* body = shape->body;

[sprite setPosition:cpv(body->p.x, body->p.y)];

}

}

@implementation BallLayer

-(void)tick:(ccTime)dt{

cpSpaceStep(space, 1.0f/60.0f);

cpSpaceHashEach(space->activeShapes, &updateShape, nil);

}

-(void)setupChipmunk{

cpInitChipmunk();

space = cpSpaceNew();

space->gravity = cpv(0,-2000);

space->elasticIterations = 1;

[self schedule: @selector(tick:) interval: 1.0f/60.0f];

cpBody* ballBody = cpBodyNew(200.0, INFINITY);

ballBody->p = cpv(150, 400);

cpSpaceAddBody(space, ballBody);

cpShape* ballShape = cpCircleShapeNew(ballBody, 20.0, cpvzero);

ballShape->e = 0.8;

ballShape->u = 0.8;

ballShape->data = ballSprite;

ballShape->collision_type = 1;

cpSpaceAddShape(space, ballShape);

cpBody* floorBody = cpBodyNew(INFINITY, INFINITY);

floorBody->p = cpv(0, 0);

cpShape* floorShape = cpSegmentShapeNew(floorBody, cpv(0,0), cpv(320,0), 0);

floorShape->e = 0.5;

floorShape->u = 0.1;

floorShape->collision_type = 0;

cpSpaceAddStaticShape(space, floorShape);

}

-(id)init{

self = [super init];

if(nil != self){

ballSprite = [Sprite spriteWithFile:@”ball.png”];

[ballSprite setPosition:CGPointMake(150, 400)];

[self add:ballSprite];

[self setupChipmunk];

}

return self;

}

@end

In class BallLayer, we defined a pointer ballSprite to point to a ball sprite that is initialized in init method. We also defined a cpSpace pointer space which points to a ChipMunk space. In init method, we invokedsetupChipmunk function to setup ChipMunk stuff.

In setupChipmunk method, we first created a Chipmunk space and assigned some paremeters. (Note: The parameter elasticIterations should be greater than 1 if you want the ball bounces off the ground). We usesschedule:interval: method to schedule a selector tick: with an interval time. tick: function will callcpSpaceStep to update the space. In addition, cpSpaceHashEach function will call updateShape on each active shape. You will have chance to update the sprite’s (i.e., the ball’s) position in updateShape function (updateShape function is the callback function we metioned at the begining of this tutorial).

Next, the ball’s body and shape are created. We add ball’s shape to the ChipMunk space.  In this case, we used segment to describe the shape of the ground and set the thickness of segment to be 0. Because the ground doesn’t move, the function cpSpaceAddStaticShape is used to add the shape of ground to the space. (Note: You can adjust the elasticity value (i.e., parameter e) of ball and ground to determine how high the ball can bounce).

Step 4: The project template has created MyScene class by default. We need to make the following modifications:

// MyScene.h

#import

#import “Scene.h”

#import “BallLayer.h”

@interface MyScene : Scene {

BallLayer* ballLayer;

}

@property (nonatomic, retain) BallLayer* ballLayer;

@end

// MyScene.m

#import “MyScene.h”

@implementation MyScene

@synthesize ballLayer;

-(void)dealloc{

[ballLayer release];

[super dealloc];

}

-(id)init{

self = [super init];

if(nil != self){

BallLayer* layer = [[BallLayer alloc]init];

self.ballLayer = layer;

[layer release];

[self add:ballLayer];

}

return self;

}

@end

Step 5: In BouncingBallAppDelegate.m file, applicationDidFinishLaunching method, change the following code:

[director setLandscape:YES];

to

[director setLandscape:NO]; 

Build&Go. You will see the following result:

Update: You can download the sourcecodes from here. In addition, in the codes above, -> was not displayed properly, now fixed.

Cocos2d Example – Move Sprite (iPhone Dev)

Posted by admin at iPhone Dev

Cocos2d engine significantly simplifies the process of iPhone game development. In this example, we will use an image of red square as the sprite. When we touch a position on the screen, the sprite will smoothly move to this position. Before starting this tutorial, we should first make sure the Cocos2d envirenment has been built up. In order to simplify this process, you can download Cocos2d 0.7.2 project template from here and install it at a proper location.

Step 1Create a Cocos2d project. If you have properly installed the Cocos2d project template, you will see the option shown in the image below.
1

Select Cocos2d Application, and name the project “BoxMove”.

Step 2Add this image to Resources Group.

Step 3Define the class BoxLayer, which is a subclass of Layer. The codes are shown as follows:

//  BoxLayer.h #import "cocos2d.h" #import "Layer.h"  @interface BoxLayer : Layer { 	Sprite* boxSprite; } @end
//  BoxLayer.m  #import "BoxLayer.h"  @implementation BoxLayer  -(id)init{ 	self = [super init]; 	if(nil!=self){ 		isTouchEnabled = YES; 		boxSprite = [Sprite spriteWithFile:@"box.png"]; 		[boxSprite setPosition:CGPointMake(25, 25)]; 		[self add:boxSprite]; 	} 	return self; }  - (BOOL) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *) event { 	UITouch *touch = [touches anyObject]; 	CGPoint point = [touch locationInView: [touch view]]; 	[boxSprite runAction:[MoveTo actionWithDuration:1 position:[[Director sharedDirector]convertCoordinate:point]]]; 	return YES; } @end

In the init method of class BoxLayer, we created a Sprite object with image box.png and set its initial position. (Note: We defined a Sprite pointer boxSprite in the class BoxLayer, and it is initialized at the end of init method.) In addition, we implemented ccTouchesBegan:withEvent method, which means the layer will response the touch event. In this method, we first get the position of the touch. Then we use the runActionmethod of boxLayer to move the sprite to this position. It should be noted that the method convertCoordinateconverts UIKit coordinate to Cocos2d coordinate (Note: The touch event uses UIKit coordinate, which is different from Cocos2d coordinate).

Step 4: The project template has created MyScene class by default. We need to make the following modifications:

//  MyScene.h  #import #import "Scene.h" #import "BoxLayer.h"  @interface MyScene : Scene { 	BoxLayer* boxLayer; } @property (nonatomic, retain) BoxLayer* boxLayer; @end
//  MyScene.m  #import "MyScene.h"  @implementation MyScene @synthesize boxLayer; -(void)dealloc{ 	[boxLayer release]; 	[super release]; } -(id)init{ 	self = [super init]; 	if(nil != self){ 		BoxLayer* layer = [[BoxLayer alloc]init]; 		self.boxLayer = layer; 		[layer release]; 		[self add:boxLayer]; 	} 	return self; } @end

In the codes above, we defined a BoxLayer pointer boxLayer in MyScene class, which is assigned in the initmethod. In the end, we add boxLayer to the scene.

Step 5Build & Go. You will see the running result in the following image:

How Can I Be Productive Without Everyone Else Piling On More Work? (Lifehacker)

Posted by Alan Henry at Lifehacker

Dear Lifehacker, More »

REComposeViewController (Cocoa Controls)

Posted by Cocoa Controls at Cocoa Controls
Replicates functionality of SLComposeViewController introduced in iOS 6.0. You can create composers for any social network out there. REComposeViewController doesn’t provide logic for sharing, only its visual part.

image of this control

View all of your Google Contacts on a Map (Lifehacker)

Posted by David Galloway at Lifehacker

If you keep all of your contacts in Google you might be interested in seeing a map showing their locations. Tech weblog Digital Inspiration shows how you can use their script to connect to your Google account and display a map of your contacts in Google Maps or Google Earth. More »

WP Like Button Plugin by Free WordPress Templates