Archive | April, 2012

iUridium v2.1 update available on App Store!

I am happy to inform you that iUridium v2.1 has been released and is available on App Store!

This version includes:
– Collision detection improvement
– Minor enhancements and bug fixes

Enjoy!


.


Read full storyComments { 0 }

iUridium Source v2.1 released!

I am happy to inform you that version 2.1 of iUridium source has been released and can be found on Source Code page. This update corresponds to app version update as is submitted to App Store.

Major changes introduced in this version:
* Re-implemented collision detection between Manta and Dreadnaught’s obstacles using Box2D. You will learn how to use Box2D for collision detection between main game player and Tiled Map objects.
* Minor enhancements and bug fixing

For all buyers of previous versions: update links will be sent to your email in next few days!.


Read full storyComments { 0 }

iUridium review on app-or-not.com

Guys from app-or-not.com reviewed iUridium. Find it at http://app-or-not.com/?page=view_app&id=79.

I would agree that landing is not very intuitive, but remember that discovering it when playing original back in 80’s was one of the charms of this game.. Feel free to comment…
.


Read full storyComments { 0 }

How to create Box2D collision from a Tiled Map

Initially I just implemented plain bounding box collision detection between my main game player and Tiled Map objects (obstacles on the map), but realized it is not perfect solution since obstacles are not always tailored by tile size. So, I decided to do it using Box2D. When I started working on it and searching for similar implementations or tutorials, I realized that there hard to find any explaining this very common requirement which motivated me to write this tutorial. Note that in my case collision means main game player hits the obstacles on the Map and explodes, not collision in sense of moving on some kind of platform. Also, Tiled Map is placed on top of Parallax, but should not be much of difference in case your Tiled Map is child of main scene layer whatsoever.

This tutorial builds upon basics of using Box2D for collision detection covered in great Ray Wenderlich tutorial, so I suggest reading it first. I will not talk here again about Box2D bodies and ContactListeners.

First, you need to define your collision objects on Tiled Map using Object Layer (I am calling it CollisionOL).

On Tiled Map initialization, we need to create Box2D bodies for collision objects on Tiled Map we have just created on our Object Layer. Note that in my case Tiled Map is not sized over complete scene, and I have more then 1 Tiled Map on it, so needed to do some more calculations (getWorldPosition). If you are not using it on such way, your _point should be defined with x, y as got from Object Layer.

  1. (void) drawCollisionTiles:(CCTMXTiledMap *)tiledMap
  2. {
  3.  CCTMXObjectGroup *collisionObjects = [tiledMap objectGroupNamed:@"CollisionOL"];
  4.  NSMutableDictionary * objPoint;
  5.  
  6.  int x, y, w, h;
  7.  for (objPoint in [collisionObjects objects]) {
  8.   x = [[objPoint valueForKey:@"x"] intValue];
  9.   y = [[objPoint valueForKey:@"y"] intValue];
  10.   w = [[objPoint valueForKey:@"width"] intValue];
  11.   h = [[objPoint valueForKey:@"height"] intValue];
  12.  
  13.   if (y < 0) y = 0;
  14.    
  15.   CGPoint _point = [self getWorldPosition:x withY:y withTiledMap:tiledMap];  
  16.   CGPoint _size  = ccp(w, h);  
  17.   _point = ccpAdd(_point, ccp(_size.x/2, _size.y/2));
  18.  
  19.   [self makeBox2dObjAt:_point withSize:_size dynamic:false];
  20.  }
  21. }
  22.  
  23. (void) makeBox2dObjAt:(CGPoint)p withSize:(CGPoint)size dynamic:(BOOL)d
  24. {
  25.  b2BodyDef bodyDef;
  26.  
  27.  if(d) bodyDef.type = b2_dynamicBody;
  28.  bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);
  29.    
  30.  CollisionGameObject *obstacle = [[CollisionGameObject alloc] init];
  31.  [obstacle setType:kGameObjectObstacle];
  32.  obstacle.position = p;
  33.  bodyDef.userData = obstacle;  
  34.  
  35.  b2Body *body = _world>CreateBody(&bodyDef);
  36.  
  37.  // Define another box shape for our dynamic body.
  38.  b2PolygonShape dynamicBox;
  39.  dynamicBox.SetAsBox(size.x/2/PTM_RATIO, size.y/2/PTM_RATIO);
  40.  
  41.  // Define the dynamic body fixture.
  42.  b2FixtureDef fixtureDef;
  43.  fixtureDef.shape = &dynamicBox;
  44.  fixtureDef.density = 0.0f;
  45.  fixtureDef.friction = 1.5f;
  46.  fixtureDef.restitution = 0;
  47.  fixtureDef.isSensor = true;
  48.  
  49.  body>CreateFixture(&fixtureDef);
  50. }

That’s it. Now, the tricky part. You need to assure that your collision objects (obstacles) are moving with your scene layer, or in my case Parallax Node. So in your tick method, together with scene movement, we should move Box2D objects accordingly.

  1. // parallax movement
  2. CGFloat velx =  backgroundXVelocity * aDelta;
  3. CGPoint newPos = ccp(currentBackgroundPos.x + velx, currentBackgroundPos.y);
  4. [parallaxBackground setPosition: newPos];
  5.  
  6. // moving collision objects as well
  7. [self updateBoxBodyPosition:aDelta vel:velx];

Here I am distinguishing my main Game player (Manta) from obstacles. For obstacles, I am updating its world position according to scene movement and then updating the position of all Box2D objects based on the position of the Cocos2D sprites as is nicely explained in Ray tutorial. Note that my world has only X movement. You will need to take care about Y axe as well.

  1. (void) updateBoxBodyPosition:(float)dt vel:(float)v
  2. {
  3.  int32 velocityIterations = 10;
  4.  int32 positionIterations = 10;
  5.  
  6.  _world>Step(dt, velocityIterations, positionIterations);
  7.  
  8.  for(b2Body *b = _world>GetBodyList(); b; b=b>GetNext()) {
  9.   if (b>GetUserData() != NULL) {
  10.    CCSprite *sprite = (CCSprite *)b>GetUserData();  
  11.    if (sprite != nil) {
  12.        
  13.     // Handling obstacle position according to Parallax movement
  14.     if (sprite.tag != LevelLayerNodeTagManta) {    
  15.      sprite.position = ccpAdd(sprite.position, ccp(v, 0));      
  16.     }
  17.    
  18.     b2Vec2 b2Position = b2Vec2(sprite.position.x/PTM_RATIO, sprite.position.y/PTM_RATIO);
  19.     float32 b2Angle = -1 * CC_DEGREES_TO_RADIANS(sprite.rotation);    
  20.     b>SetTransform(b2Position, b2Angle);                    
  21.    }  
  22.   }
  23.  }  
  24. }

I am sure there are other, maybe better, ways of doing it, so if you have any suggestion of improvement, or this tutorial is not clear enough for you, just write the comment.

I will not include sample project including this code since you could get complete iUridium source from here 😉
.


Read full storyComments { 0 }

iUridium v2.0 update available on App Store!

I am happy to inform you that iUridium v2.0 has been released! It includes several exciting new features:

– Possibility to use any of UNLOCKED levels as game start point

iUridium Level Select Scene


– For each 3 levels finalized, you will get them automatically UNLOCKED
– Possibility to UNLOCK any level using In-App Purchase option
– Landing made easier (not requesting low speed entering landing zone)
– Minor bug fixing (Manta shadow, some collision issues, …)

Enjoy!

Stay tuned, more improvements and new features coming in following weeks!


.


Read full storyComments { 0 }