Monthly Archive for March, 2010

Notifications in OpenGL (Like OpenFeint but without lag)

I (manucorporat) have developed a notification system for cocos2D. It’s very useful when your game uses OpenFeint or another social network.

OpenFeint has his own notification system, and probably you wonder, Why am I going to use this new system?

The answer is easy. The new system is designed in OpenGL and the performance is higher.

No more lag, when a friend connect!!!

In addition, It has a lot of advantages.

  • You can customize the notification design. (Friendly to the rest of the interface)
  • High Performance, because it uses OpenGl instead of UIKit.
  • Personalized animations (in and out).
  • cocos2d based. (Easy integration)
  • Personalized notification position (Top and bottom)
  • Easy way to play sounds when a notification is showed.
  • Easy implementation with OpenFeint.
  • Callback when it’s pressed. (Like Openfeint)

AbstractWar 2.0 uses this system.

Are you interested?

Integrating this feature in your game/app is very easy:
In CCDirector.m::mainloop
You must add [[CCNotifications sharedManager] visit]; after [runningScene_ visit];
And #import "CCNotifications.h"

/* draw the scene */
 
[runningScene_ visit];
[[CCNotifications sharedManager] visit]; //<<<<<<<<
if( displayFPS )
[self showFPS];

Ok, now you can push a notification if you write this code:

[[CCNotifications sharedManager] addNotificationTitle:@"Game Name:" message:@"Running in 1.4 version" image:nil tag:0 animate:YES];

Openfeint integration:

Open (ProyectName)AppDelegate.m
It must implement <OpenFeintDelegate, OFNotificationDelegate, CCNotificationsDelegate> protocols.

- (void) applicationDidFinishLaunching:(UIApplication *)application {
 
//Openfeint init
NSDictionary* settings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight], OpenFeintSettingDashboardOrientation,
@"Name", OpenFeintSettingShortDisplayName,
window, OpenFeintSettingPresentationWindow,
nil
];
 
OFDelegatesContainer* delegates = [OFDelegatesContainer containerWithOpenFeintDelegate:self andChallengeDelegate:nil andNotificationDelegate:self];
 
[OpenFeint initializeWithProductKey:@"yourkey"
andSecret:@"yourpassword"
andDisplayName:@"your proyect name"
andSettings:settings
andDelegates:delegates];
 
//CCNotifications delegate
[[CCNotifications sharedManager] setDelegate:self];
}
 
#pragma mark OpenFeint Delegate methods
 
- (BOOL) isOpenFeintNotificationAllowed:(OFNotificationData*)notificationData{
 
return NO;
 
}
 
- (void)handleDisallowedNotification:(OFNotificationData*)notificationData{
 
[[CCNotifications sharedManager] addNotificationTitle:@"Openfeint:" message:[notificationData notificationText] image:@"openfeintLogo.png" tag:1 animate:YES];
 
}

Delegate methods:

- (void) notificationChangeState:(char)state tag:(int)tag {
if(state == kCCNotificationStateShowing){
//Play sound
}
}
- (BOOL) touched:(int)tag{
//Example
/*
if(tag==kTagOpenfeint) {
	[OpenFeint launchDashboard];
}
*/
}

Customize:
You can customize the notification design in CCNotificationDefaultDesign class.

  • The position:
[[CCNotifications sharedManager] setPosition:kCCNotificationPositionBottom]; //kCCNotificationPositionTop
  • Animations:

Animation (In):

[[CCNotifications sharedManager] setAnimationIn:kCCNotificationAnimationMovement time:0.4f];

Animation (Out):

[[CCNotifications sharedManager] setAnimationOut:kCCNotificationAnimationMovement time:0.4f];

Both:

[[CCNotifications sharedManager] setAnimation:kCCNotificationAnimationMovement time:0.4f];
  • Time:
[[CCNotifications sharedManager] setShowingTime:3.2f];

Other usages:

  • Show app version.
  • Music now playing
  • New DLC content. (In-app purchase)

Conclusion: If you have got a game with cocos2D and it uses OpenFeint, I recommend that you implement this feature. It’s also a plus to get Openfeint Gold.

Forum discussion
Check here to download the code.

For further updates, follow me on Twitter or keep an eye on my blog.

VertexHelper: A physics body editor

VertexHelper is a nifty little tool I (jfahrenkrug) have put together while developing a cocos2d iPhone app that used a lot of different sprites. All those sprites needed a counterpart for the physics engine, namely vertices. After defining the vertices of the 2nd sprite by hand, I knew that I’d go nuts if I had to define all 40 sprite vertices like that. So I wrote a tool: VertexHelper.

It lets you graphically define vertices of sprites for Box2D and Chipmunk bodies/shapes. You can find it on github or you can download a tarball of the source.

It is really easy to use VertexHelper:

  • First, you need an evenly spaced sprite sheet (every sprite in the image file has to be of the same size). For example, if your sprite sheet image is 250 x 120 pixels and every sprite is 50 x 60 pixels, then you’d have 10 sprites on your sheet (2 rows and 5 columns). Perfect.
  • Simply drag the sprite sheet image onto VertexHelper and enter the number of rows and columns. You’ll see a grid appear.
  • Now check the “Edit Mode” checkbox and click “around” each sprite to define it’s vertices. It’s that easy.
  • VertexHelper will generate the code for either Chipmunk or Box2D that you can simply cut and paste into your project.

A word of caution: You have to make sure not to define concave polygons, since both Chipmunk and Box2D don’t support them. VertexHelper won’t warn you if you do. Also, you have to make sure that you define your coordinates in the correct order: For Box2D, they have to be counter-clockwise and clockwise for Chipmunk.

But enough of the talking, this video gives you a much better impression of what VertexHelper does and how it works:

I hope it’s useful for you and please feel free to fork it on github and make it better for everyone!

For further updates, follow me on Twitter or keep an eye on my blog.

cocos2d v0.99.1 released

cocos2d for iPhone v0.99.1 has just been released!

Download:

New features:

  • Automatic Z ordering in Tile maps (isometric and orthogonal maps)
  • New radial transition (clockwise and counter-clockwise)
  • Updated Box2D (SVN r66) and Chipmunk (v5.2)
  • Tint and opacity work at the same time with premultiplied alpha images

Release Notes:

Full Changelog:

Many thanks to all the developers, contributors, beta-testers!

Assorted cocos2d games

If you were wondering what kind of games you could make with cocos2d, here is a summary of recently released cocos2d games:

Zombie Games

Flying Hero Games

Shooter Games

Racing Games

Puzzle Games

Strategy Games

Artistic Games

Doodle/Stick Games

Kids Games

To see more cocos2d games, please visit: Games powered by cocos2d

Previous posts about cocos2d games: More than 100 games using cocos2d, 3 games in the top 10

The Chipmunk SpaceManager

Cocos2d and Chipmunk

Cocos2d-iphone and Chipmunk

A while ago when I (MobileBros) was just beginning to use Cocos2d-iphone, I also started playing around with Chipmunk; at the time this was the only physics library that came with Cocos2d and I wasn’t really aware of anything else out there. Very quickly I discovered that I was writing a lot of repetitive code in order to use Chipmunk and what was more was that it was in C, making me have consider two languages now! Sound familar?

Chipmunk:
Chipmunk is actually very simple in concept. There is a chipmunk “space”, you add shapes/bodies/constraints to the space, you ask the space to simulate a specific amount of time. Thats it! The last step performs all the magic that is rigid-body physics.

Cocos2d Integration – Basic Approach:
Cocos2d is very good at a lot of things, its a very good at displaying sprites, particles, actions, touches, and a number of other things. Chipmunk is very good a simulating rigid-body physics. The common approach to “glueing” both components together usually involves running chipmunk and telling it to update Cocos2d nodes (setting position and rotation); pretty much a basic model-view approach. Modifying the constraints, and modifying collision behavior in the chipmunk system would result in different behavior; your game logic.

The SpaceManager attempts to step in as this glue and automate much of the process.

What is SpaceManager?

There are actually two distinct parts of the Chipmunk-SpaceManager project. There is the core SpaceManager class and then there are a number of “helper” classes targeting Cocos2d-iphone and used for representing shapes and constraints with CCNode types. In fact most people do not realize that these two parts are independent of each other.

Core:
The goal of the core SpaceManager class was to provide an encapsulation around the basic tasks we (at least) found ourselves performing over and over. Theses tasks included:

  • making basic shapes (rects, circles, polys)
  • removing shapes (especially a mechanism for during collisions)
  • advancing time within the chipmunk space
  • negligible API difference in Static and Active shapes
  • updating our views with our “model” (Chipmunk –> Cocos2d)
  • updating our model with our controller/view (Cocos2d –> Chipmunk)
  • non invasive to chipmunk (you can combine native chipmunk calls with spacemanager calls)
  • window containment walls (sounds dumb, but it’s tedious)

Our aim was not exactly to wrap exising objects and functionality (In fact slembcke just released an obj-c wrapper suite). Instead we wanted something to manage common tasks/patterns.

Cocos2d Helpers:
The goal of the “helper” classes was to provide a simple solution to associating a shape/constraint with a corresponding CCNode type. By doing this we could also accomplish a number of other common tasks including: automatic cleanup of shape/body from chipmunk upon node deletion, as well as being able to control the position and rotation of shapes thru CCAction's or even just calling setPosition or setRotation on the node.

cpShapeNode and cpConstraintNode are somewhat special in that they will draw their corresponding shape/constraint respectfully. For instance you just created a cpConstraintNode with a spring constraint, by adding this node type to a CCLayer or other CCNode it will correctly draw a spring constraint between the attached bodies (it uses OpenGL to draw a zig-zag line).

A base class called cpCCNode is provided for anyone wishing to derive their own class implementation. It provides:

  • shape property: your associated shape
  • integrationDt: if other than zero, any call to setPosition (not coming from chipmunk) will result in velocity being calculated
  • spaceManager: a reference to the owning spaceManager
  • autoFreeShape: cleanup the shape, needs the spaceManager property set
  • applyImpulse: apply an impulse to the shape’s body
  • applyForce: apply a continuous force to the shape’s body
  • resetForces: reset any continuous forces to zero

Give me an Example!

Lets assume you are working on a CCLayer that you’ve just subclassed and want to integrate Chipmunk with. This layer will act as your space and any CCNodes added will represent your shapes and constraints.

First off, lets create our space and add a containment rect (so other shapes can’t go offscreen).

smgr = [[SpaceManager alloc] init];       //SpaceManager* smgr declared in header file
[smgr addWindowContainmentWithFriction:0.8 elasticity:0.7 inset:cpvzero];

Well it doesn’t look like much, but chipmunk was just initialized and a cpSpace was created and set up with default values and gravity. We then created a containment rect, thats somewhat bouncy with the friction coefficient of concrete, a concrete room if you will.

Our First Shape:
Well thats all well and good, but lets add a ball next; lets use a cpShapeNode (a “helper” class) for this example because it only uses OpenGL primative calls to draw itself.

cpShape *ball = [smgr addCircleAt:cpv(240,160) mass:5.0 radius:15];
 
ballNode = [cpShapeNode nodeWithShape:ball];       //cpShapeNode *ballNode declared in header file
ballNode.color = ccBLUE;
 
ballNode.autoFreeShape = YES;
ballNode.spaceManager = smgr;
 
[self addChild:ballNode];

We just asked the SpaceManager to create a circle shape for us, placed in the middle of the screen with a mass of 5 and a radius of 15; it gave us back a cpShape* which we then attached it to a cpShapeNode, colored it blue, and added to self (our CCLayer). Also important here is that we told the ballNode to auto-free it’s shape (when ballNode is released) and also who our SpaceManager instance was. This frees you from worrying about clean-up later.

Crank it up:
At this point, things are starting to sound interesting, however if you ran the code right now, you’d wonder why there is a blue circle just sitting in the middle of the screen. Oh yeah! We need to tell chipmunk to start simulating our space.

[smgr start:1.0/60.0];

Woo-Hoo! We did it, a blue ball should fall from the center of the screen and bounce up and down a few times on the bottom of the screen. Well ok, thats not very interesting is it.

Touches:
Perhaps we can make it do something in our touch methods. Don’t forget to set up your layer as a touch delegate…

-(BOOL) ccTouchBegan:(UITouch*)touch withEvent:(UIEvent*)event
{
   CGPoint pt = [self convertTouchToNodeSpace:touch];
 
   [ballNode applyImpulse:ccpMult(ccpSub(pt, ballNode.position), 3)];
 
   return YES;
}

This will give the ball a jolt in the direction you touch, stronger the further away you touch. Now if you only had a target to hit…. you’d have a game!

A Game Idea…
$1,000,000 Game Idea: A ball and a target; touch to launch the ball at the target; the less touches it takes to hit the target, the more points you get!

Ok so lets get a target going, perhaps a nice red square?

cpShape *target = [smgr addRectAt:cpv(440,160) mass:STATIC_MASS width:20 height:20 rotation:0];
 
targetNode = [cpShapeNode nodeWithShape:target];       //cpShapeNode *targetNode declared in header file
targetNode.color = ccRED;
 
targetNode.autoFreeShape = YES;
targetNode.spaceManager = smgr;
 
[self addChild:targetNode];

Nothing too dramatic here, EXCEPT whats this STATIC_MASS thing? Well in chipmunk terms STATIC_MASS == INFINITY, the former just seemed a little more definitive sounding. In chipmunk land there are shapes that are “active” and then there are shapes that are “static”, static shapes are never supposed to move; they are immovable as far as chipmunk sees things. Well what better use than for our target rectangle shape? Passing a STATIC_MASS for mass will make the SpaceManager perform the necessities it takes to set one up, everything else will look the same as when we created our ball above.

Collision Callbacks:
We now have a ball, touch logic, and a target. All we need now is to know when the target has been hit. First off, we need to define a method to handle this.

-(BOOL) handleCollision:(CollisionMoment)moment arbiter:(cpArbiter*)arb space:(cpSpace*)space
{
   if (moment == COLLISION_BEGIN)
   {
      CCLabel *label = [CCLabel labelWithString:@"You Win!" fontName:@"Helvetica" fontSize:32];
      label.position = ccp(240,160);
      label.color = ccBLACK;
      [self addChild:label];
}
 
//other moments: COLLISION_PRESOLVE, COLLISION_POSTSOLVE, COLLISION_SEPARATE
 
return YES;
}

If you’re familar with chipmunk callback functions, you’ll notice that this is slightly similar but you are now passed a CollisionMoment variable as well. This enum tells you what collision moment we are at, in this case we only care about when the objects first begin touching.

Now don’t forget…. we need to register this callback with our SpaceManager instance:

ballNode.shape-&gt;collision_type = 1;
targetNode.shape-&gt;collision_type = 2;
 
[smgr addCollisionCallbackBetweenType:1
                            otherType:2
                               target:self
                             selector:@selector(handleCollision:arbiter:space:)];

Thats it! If we just keep track of how many touches, perhaps display them too our game is all done. If anyone is interested in this example, the complete source is given here: SpaceManager Example

The SpaceManager can do a whole lot more than discussed here including: scheduling shapes for deletion, fragmenting shapes, morphing shapes between active and static, detecting persistent contacts, etc. The project web page can be found at http://code.google.com/p/chipmunk-spacemanager/ and a more in-depth example is included with the source code.

Learning cocos2d with samples

Arguably the most unknown cocos2d feature is the tests/samples.
cocos2d contains almost a test for each feature that it has. These tests are grouped by component. eg:

  • Sprite Test: It tests the CCSprite and CCSpriteSheet functionality like anchorPoint, visibility, parenting, reordering, honor Transform, etc…
  • Action Test: It tests the CCMove, CCRotate, CCTint, CCCamera, CCSequence, CCSpawn, etc..
  • Menu Test: It tests all kind of menus
  • CocosDenshion: It tests the Sound Engine
  • Chipmunk Accel Touch Test: It tests integration with Chipmunk physics engine using accelerometer and multi touches.
  • Particle Test: It tests all kind of particles (quad particles, point particles, sun, meteor, galaxy, smoke, fire, etc…)
  • etc…

Although these tests were coded for testing purposes they can also be used as examples. Not only they use the API in the recommended way, but some of them, also contain useful tips in the commentaries.

In order to run the tests, you should do:

  1. Open the cocos2d Xcode project
  2. Select the test target: Xcode -> Project -> Set Active Target -> eg: TransitionTest
  3. Make sure that the running executable is correct: Xcode -> Project -> Set Active Executable -> eg: TransitionTest
  4. Build and run: Xcode -> Build and run

Another quick way of doing it by customizing the toolbar:

  1. Xcode -> Right click on the toolbar -> Customize Toolbar
  2. Drag & drop the Active Target button to the toolbar
  3. Drag & drop the Active Executable button to the toolbar

The source code of the samples are in the tests subdirectory.

So, let’s say you want to learn how to use Tiled maps. What you should do is:

  1. Select the TileMapTest target
  2. Make sure that the TileMapTest executable is selected
  3. Build & Run.
  4. Try all the subtests. The TileMapTest has more than 10 subtests. Eg: Hexagonal test, Isometric test, Orthogonal tests, read-write tile tests, etc…
  5. See the TileMapTest source code: tests/TileMapTest.m
  6. Modify the source code and go to step 2. :-)

Hiding the images from your game

Sometimes it is needed to hide certain images in your game from opportunists. One possible way of doing it, is to subclass CCTextureCache and override the addImage method.

For example:

//pseudo code
-(CCTexture2D*) addImage:(NSString*)path
{
   if( file_exists( path + ".enc" )  {
       mem = decrypt( path + ".enc", secretKey );
       uiimage = [[UIImage alloc] initWithData:mem];
       texture = [[CCTexture2D alloc] initWithImage:uiimage];
   }
}

Basically, if it finds an encrypted file, it will decrypt it with a secret key. So the .app bundle will have the crypted images, and opportunists won’t be able to look at them easily.

User mhussa created a sample project that includes these ideas. The project includes:

  • CCEncryptedTextureCache.m (subclass of CCTextureCache )
  • CryptUtils.cpp (helper functions to encrypt/decrypt files)
  • The ‘Encrypt’ build phase: It encrypts files at build time. You don’t need to encrypt them manually!

To customize which files to encrypt, you have to edit the ‘Encrypt’ build phase:

  • Xcode -> Targets -> CCRadialTransitionDemo -> Encrypt
  • Right click over ‘Encrypt’ -> Get Info

For further info regarding mhussa’s implementation, please read: How to use CCEncryptedTextureCache

Download: Xcode CCEncryptedTextureCache project




Social Widgets powered by AB-WebLog.com.