Archive

Archive for the ‘Uncategorized’ Category

Photo Shoot! Now available on app store!

May 6th, 2010

Forty Seven now on sale!

March 15th, 2010

I finished my first app! It is now on sale in the app store for $.99! Check it out:
http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=360299484&mt=8

Forty Seven is a fast paced top down 2d space shooter. It runs on Cocos2D and Chipmunk.

rjett Uncategorized , , ,

Game Demo Tutorial #2: Hello Space

April 26th, 2009

I've decided to move away from the screencasting approach for this part of the game demo tutorial. Anyways, in this part of our Cocos2d Game Demo tutorial we will be extending the code we developed in Hello World to include some images and movement. By the end of this you will end up with a space background and a moving spaceship that can fire lasers.

The first thing you want to do is to add the art resources for this project. You can find them with the source code (here). Within the project view in X-Code you want to locate the Resources folder, which should be on the the left side of the screen. Right click on Resources, and choose Add->Existing Files...

In the pop-up window select all of the art files included with this source code for the project. Next, go to GameScene.m. We're going to get rid of our label that we used previously, so change the code from this:

-(id) init {
	self = [super init];
	if(self != nil) {
		Label *test = [Label labelWithString:@"Hello World" fontName: @"Helvetica" fontSize: 24];
		test.position = cpv(160, 240);
		[self addChild: test];
	}
	return self;
}

To this:

-(id) init {
	self = [super init];
	if(self != nil) {
	//Add the background:
		Sprite *bg = [[Sprite spriteWithFile:@"bg.png"] retain];
		bg.position = cpv(160,240);
		[self addChild: bg];
 
	}
	return self;
}

This new code should replace the Hello World text with a background image of outer space. Now we're going to add a ship and make it move. So let's update that init method to this:

-(id) init {
	self = [super init];
	if(self != nil) {
	//Add the background:
		Sprite *bg = [[Sprite spriteWithFile:@"bg.png"] retain];
		bg.position = cpv(160,240);
		[self addChild: bg];
 
//Add the ship:
		ship = [[Sprite spriteWithFile:@"ship.png"] retain];
		ship.position = cpv(50,50);
		[self addChild: ship];
 
		//Make it move:
		[self schedule: @selector(moveShip:)];
 
	}
	return self;
}

We loaded another Sprite, called ship, and we set up a scheduler. Schedulers are a nice function provided by Cocos2D that allow you to call a given method over and over again. You can also pass an argument to it called interval to specify how often it should be called. If you don't specify this argument it will be called as often as possible.

After your init method you need to add the moveShip method. The code is as follows:

-(void) moveShip: (ccTime) dt
{
	t += dt; //Specify ccTime t in header
	ship.position = cpv(120*sin(t)+160, 50);
}

Like I mentioned in the comment above, you'll need to switch back to the header for GameScene and then within your GameLayer add a property for ccTime t and Sprite * ship.

Hopefully if you run this code you will see a ship oscillating back and forth over a space background.

Next we want to set up Chipmunk for use in our game. First, go to GameScene.m and after your import statement and before @implementation GameScene add the following C function:

static void
eachShape(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)];
		[sprite setRotation: (float) CC_RADIANS_TO_DEGREES( -body->a )];
	}
}

This function is used to update our physics bodies. Next go to your init method in GameLayer and add this code after the scheduler we added earlier:

//Initialize Chipmunk:
		cpInitChipmunk();
 
		space = cpSpaceNew();
		cpSpaceResizeStaticHash(space, 400.0f, 40);
		cpSpaceResizeActiveHash(space, 100, 600);
 
		space->gravity = cpv(10, 0);
		space->elasticIterations = space->iterations;
 
		//Update Chipmunk
		[self schedule: @selector(step:)];

As you can see we scheduled another method to called, named step. Step will be used to run our physics simulation. We can go ahead and add this method to GameLayer:

-(void) step: (ccTime) delta
{
	int steps = 2;
	cpFloat dt = delta/(cpFloat)steps;
 
	for(int i=0; iactiveShapes, &eachShape, nil);
	cpSpaceHashEach(space->staticShapes, &eachShape, nil);
}

Now, we're going to create bullets for our ship to shoot. Since we want the bullets to be updated by Chipmunk we're going to have create a wrapper object for something called cpBody. cpBody is the Chipmunk structure for modeling our objects in the simulation space. Since cpBody is not an object we cannot store it in an NSArray or NSMutableArray, but if we wrap it, we can store it.

To get started writing the bullet wrapper click on the Classes folder, right click, and select Add->New File. In the prompt, choose NSObject subclass. Click Next and name the class Bullet.

The bullet header file is as follows:

#import
#import "chipmunk.h"
 
@interface Bullet : NSObject {
	cpBody *bulletBody;
	bool ready;
}
-(id) initWithCPBody: (cpBody *) bodyIn;
-(void) fireFromX: (float) x y:(float)y;
-(float) getY;
-(void) resetPosition;
 
@property(readwrite) bool ready;
@end

The implementation for bullet is as follows:

#import "Bullet.h"
 
@implementation Bullet
-(id) initWithCPBody: (cpBody *) bodyIn
{
	self = [super init];
	if(self != nil){
		bulletBody = bodyIn;
		ready = YES;
	}
 
	return self;
}
-(void) fireFromX: (float) x y:(float)y
{
	bulletBody->p = cpv(x,y);
	bulletBody->v = cpv(0, 500);
}
-(float) getY
{
	return bulletBody->p.y;
}
-(void) resetPosition
{
	bulletBody->p = cpv(-50,-50);
	bulletBody->v = cpv(0,0);
}
@synthesize ready;
@end

Now, switch to GameScene.h and add the following property to GameLayer:

NSMutableArray *bullets;

This NSMutableArray will be used to manage the bullets our ship will fire. We will use it to create a seemingly infinite stream of bullets from only 10 actually instantiations of our Bullet class.

Switch over to the GameScene implementation file and scroll down to GameLayer's init method. We're going to add some code to manage our bullets. After the schedule call to step add the following code:

//Bullet Manager, loads 10 bullets
		bullets = [[NSMutableArray alloc] init];
		for(int i = 0; i < 10; i++)
		{
			Bullet *b = [[Bullet alloc] initWithCPBody:[self makeBulletX:-50 y:-50]];
			[bullets addObject: b];
			[b release];
		}

This code sets up the NSMutableArray we declared in the header and creates ten instances of our Bullet class.

Next we want to be able to accept a touch to use to fire the ship's bullets. After the code above add the following line:

//Make it shoot:
		isTouchEnabled = YES;

Now we need to implement that method that will listen for a touch. In GameLayer, somewhere after our init method, add the following method:

- (BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
	for(Bullet *b in bullets)
	{
		if([b ready])
		{
			[b fireFromX:ship.position.x y:ship.position.y+12];
			[b setReady: NO];
			break;
		}
	}
 
	return kEventHandled;
}

ccTouchesBegan is the method that Cocos2D uses to alert you of touches. There are also similar methods for TouchesMoved and TouchesEnded. In the above code we are iterating through our bullets array, looking for the first ready bullet. If a ready bullet is found, we shoot it, set it to not being ready, and break the loop so no more bullets are fired. After our loop we return kEventHandled, this tells Cocos2d that the Touch event was handled.

Now we need to add some code that will keep track of our bullets and reset them when they go off screen. Add the following method to GameLayer to do just that:

-(void) updateBullets
{
	for(Bullet *b in bullets)
	{
		if([b getY] > 500)
		{
			[b resetPosition];
			[b setReady: YES];
			break;
		}
	}
}

In order for this method to be called we will go back to the steps method that we created for Chipmunk. At the very end of the method add this line:

[self updateBullets];

And that's it. Hopefully if you build and run the code you have create you will now see a spaceship oscillating over a background of stars. If you touch the screen you should see some bullets being fired from the ship. If you come across any problems just check out the following source code, it works: Game Demo Tutorial: Entry 2

rjett Uncategorized , ,

Game Demo Tutorial #1: Hello World Screencast

April 25th, 2009

Learn how to get a barebones Cocos2d application up and running in X-Code.


Cocos2d-iphone Hello World app from Ronald Jett on Vimeo.

Full Source Code: Hello World Source

A full resolution Quicktime file for this can be found here.

rjett Uncategorized

Objective-C and Chipmunk’s cpSpaceAddCollisionPairFunc

April 19th, 2009

I've been writing some really inefficient code in the past couple of hours. Mostly because I didn't know how to call methods on my Objective-C object from a C callback function. If you are using Chipmunk with Cocos2d you might come across the need to have some code respond to certain collisions, say a main character in a game and a pit of spikes. Here is the simple solution:

When you call Chipmunk's collision pair function in your Objective-C object you need to utilize that last parameter:

 
cpSpaceAddCollisionPairFunc(space, 0, 2, &damage, self);
 

In the above line &damage would reference a static C function outside of your Obj-C class and have a signature like this:

 
static int damage(cpShape *a, cpShape *b, cpContact *contacts,
int numContacts, cpFloat normal_coef, void *data)
 

In this C function you would then need to cast the pointer to self back to its object type. For example, the object where I called cpSpaceAddCollisionPairFunc was called GameLayer, thus my callback looks like this:

 
static int damage(cpShape *a, cpShape *b, cpContact *contacts,
int numContacts, cpFloat normal_coef, void *data)
{
	 GameLayer *game = (GameLayer *)data;
    //Calls damageTaken function on Obj-C GameLayer object:
       [game damageTaken];
	return 0;
}
 

Now that I've figured out this little trick I need to go back and get rid of a little of ugly global variables and schedulers. :P

rjett Uncategorized , , , , ,

Stanford iPhone Course

April 4th, 2009

This quarter Stanford will be delivering video recordings of lectures from their iPhone course on iTunes. This course is taught by Apple employees. The first lecture is out now, but mostly covers first day class administration stuff. I am looking forward to hopefully finding some value in future lectures. You can check it out here.

rjett Uncategorized , , ,

Removing the status bar from an iPhone application

March 28th, 2009

To remove the status bar from your application simply add the following line of code to your project:

 
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];
 

You can also edit your plist file and add a key for UIStatusBarHidden and set its value to true.

rjett Uncategorized , , ,

Cocos2D for iPhone: Sprites

March 26th, 2009

Setting Cocos2D to portrait mode

Before we get started let's switch to portrait mode.

In XCode, locate your delegate class implementation. If you followed the Monocle Studios example given in the previous post the file you are looking for is named "SimpleGameAppDelegate.m".

Under the applicationDidFinishLaunching function you should find a line of code that looks something like this:

[[Director sharedDirector] setLandscape: YES];

To force your application to be in portrait mode you simple change the YES to a NO:

[[Director sharedDirector] setLandscape: NO];

You could also just delete or comment out the line. That also seems to serve the same function.

Loading Sprites

Cocos2D makes it ridiculously easy to load a sprite. First you want to right click on the Resources folder in your navigation pane in XCode. Then you want to click Add -> Existing files. Locate the .png file you want to load in as your sprite and click ok. In the next window you want to check "Copy items into destination group's folder (if needed)." Then, click "Add".

In a game layer you can easily load the sprite you just added to your project with one line of code:

 Sprite * ninja = [Sprite spriteWithFile:@"ninjaSprite.png"];

If you want to position the sprite you can do so easily by using the following line:

[ninja setPosition:cpv(50, 50)];

To have Cocos display this sprite you have to add it. To do this you would use the following line:

[self addChild: ninja];

In case you missed it elsewhere, cpv creates a Chipmunk vector. Chipmunk vectors are used by Cocos to specify x and y coordinates of objects (e.g. cpv(xCoordinateHere, yCoordinateHere).

Moving a Sprite by using a timer

Once your sprite has been loaded you can easily move it by using a timer. Cocoa has its own timers, but the authors of Cocos2d for iPhone consider using their scheduler to be the best practice for timer based behaviors. To use the Cocos2d scheduler you simply need to specify a function to call. For example:

 
[self schedule: @selector(moveStuff:)];
 

In the above example, moveStuff is the name of the method that the scheduler will call. You can also add an interval when you schedule a function to be called. For example:

 
[self schedule: @selector(moveStuff:) interval: 0.5]; // half second interval
 

In my experience, scheduling a function to be called without specifying an interval tells Cocos2D to call this function as often as possible without affecting performance. The function that the scheduler will call needs to conform to the interface that Cocos2D expects. Here is an example of a moveStuff function:

 
-(void) moveStuff: (ccTime) dt
{
        t += dt; //t is a global float that I initially set to 0.0f
        ninja.position = cpv(10*sin(dt), 380); //moves the sprite back
        //(let's assume we have pointer to ninja in the header file for this class).
        //and forth on the x-axis
}
 

rjett Uncategorized , ,

Cocos2D: An Introduction

March 22nd, 2009

What?

Cocos2D is a framework for creating 2D games in Python. Cocos2D has been ported from Python to Objective-C for use on the iPhone. Cocos2D has a lot of great functionality that a developer can adopt for a mobile game including sprite management, basic menus, 2D physics (via Chipmunk), particle system, parallax scrolling, and more.

Understanding Cocos2D

Cocos2D is based around the concepts of scenes. A scene could be a menu, game level, options, menu, credits screen, etc. Cocos also has something called layers. Layers in Cocos2D are means of organizing your code within your scene.

Getting started

To get started with Cocos2D for iPhone I would highly recommend this tutorial from Monocle Studios. It will get you set up with a nice clean ready to go Cocos2D template. All the examples that I will be giving later in this blog assume that you already have a working Cocos2D template.

rjett Uncategorized , ,

iPhone OpenGL tips

March 22nd, 2009

I'd strongly recommend using Jeff LaMarche's iPhone OpenGL ES template

I'd also recommend you getting your hands on Texture2D.h. This is a file that comes from Apple that you can find attached to various demos or code example. It makes it really easy to load and attach a texture in OpenGL ES.

For 2D game development on the iPhone check out Cocos2d. I've been tinkering with it lately and it is quite good. You don't even have to bother with OpenGL ES if you use Cocos2d and it comes with Chipmunk, an awesome 2D physics engine.

I'm going to post more about how to use Cocos2D for iPhone game development later. I've been busy learning to use it myself.

rjett Uncategorized