Monthly Archives: January 2011

Catstrict 7

I’ve been prototyping and tweaking my first game to a point where it finally becomes fun and genuine. It’s unique in its category and has some points that put smile on you. It really is!

So, what’s the title? It’s called “Catstrict 7″. The game is about a group of cats who exile from “Cat District 7″ by invasion of street dogs. The goal is to save all the imprisoned cats and kick out the boss dog. The name “Cat District 7″ isn’t really sticky to my tongue so I shorten it to “Catstrict 7″. (I have to confess that the famous movie “District 9” definitely inspires me in many ways.)

“Catstrict 7″ is unique in its own way because the hero cat is going to be you and the friend cats are going to be your friends.  Sounds very interesting right? …..No? That’s fine by now. I’ll open up my vault as the game gets into its shape. For now, let me wrap it up with a screen shot taken from debugging process. ;)

Until later, keep it safe, my friend.

*(update Feb. 5, ’11) I’ve recently noticed that Glu Games is an established, strong game studio developing fantastic mobile games. Colorful Glue wasn’t named with any possibility of developing mobile games back then. Things turn around  however, and here I am putting my day and night into this one. If Catstict 7 goes out under the name of “Glue”, neither I nor Glu Games will be very happy due to the similarity in company names.

On top of that,  most importantly, I don’t want “Catstict 7″ to sound like a clone game from a clone company. I mean, how lame is it to release a super cool game under the name of a copy cat?

So, I’ll have to release the game with a different brand. However bad the new brand might sound, I really need a different, unique name. I’m trying to stir up some cool names that have never been used before…. hmm…

Aggression Test v1.1 is submitted for approval

Version 1.1 of Aggression Test is submitted. After getting lots of muscle on Cocoa and iOS, I could literally see tons of improvements I can make. Since I have few other balls up in the air, I only rebuild application structure and add two important new features: Admob and Facebook sharing.

Facebook sharing will let you share the test result on facebook. Simple and ubiquitous as Facebook is. Admob is there for helping me get some financial aid. Yes, that means Aggression Test is going to be free from version 1.1.

As soon as Aggression Test gets approved, I’ll post few more details! Stay tuned!

First Limit it, then make it complicated.

Recently, I bought “Angry Birds” for iPhone. I know I am late. Then as I play on, I could see Angry Birds is another incarnation of Crush the Castle at Armor Games. I admit I shamelessly pulled all-nighter with crushing castles. I then pulled another all-nighter with screaming birds. Have I not seen the same?

What makes Angry Birds really different is, I think, it limits your options by predefining number and type of birds for hitting a pig castle. By doing so, clearing a stage seems like a very simple and lightweight task you can finish within 5 minutes of bathroom break.

With only few ways to play the game, learning curve is extremely flat. You can throw a bird up in the air; the bird might or might not let you further touch the screen; that is it. We live in a World where each person is hard pressed and so absorbed in handling a lot of life tasks in a day. It’s not likely we are lazy to learn a new trick or two to play a fun game. It’s more likely that we just do not have enough composure to let a game step in our mind. Angry Birds just slips through this huge obstacle with very limited ways to play.

One might say that the power of cute characters does the job. I have to disagree. There are games with even cutter characters out there which just don’t resonate as much as Angry Birds does.

Then Angry Birds turns into slightly challenging circumstances for you to think about. As players get familiar with the birds, reality slows kicks in. In reality, smashing all the pigs in a castle is not so simple because your options of hitting them all is pretty much limited: one or two red birds, another blue bird and so on so. It’s now a bit irritating. Can you just quit? No, because the birds, the pigs, and the castle are already in your mind. You become to think, wonder, and grow obsessed with hitting them all. In the end? you keep playing until all the pigs are dead.

Limiting users’ options, then turning circumstances into something challenging is, I believe, the key to make a quick to learn but addictive game. I then became curious if there were any predecessor who has done same;a very complex, ever challenging game with limited options. Of course there are because there’s nothing new under the Sun.

Quick Googling hands me few of those.

Canabalt

I want to live, by one stoke of key. Platforms keep dodging at me, and I have to jump across to survive. I get to keep playing until I realize few hours are just gone by. What makes me do that? Again, very limited user options, but ever challenging situation. Quick to learn, but addictive.

One Button Bob / One button Arthur

These two games are created by Tom Vencel (Ninjadoodle). These two are just amazing amazing games. You can only do so much as click on screen. Yet, you would be surprised to find yourself in ever challenging circumstances; you might have to jump, turn, and many more. As game goes on, OBB effectively corners you so much to a point where you forget you can only click on screen. Also, the learning curve is extremely flat. I mean there is no learning curve. I guess magic is here to limit your choice but put you in various challenging situations.

I think I can come up with something interesting. Stay tuned.

OpenGL on top of Mapview part 1

It’s been a while since I wrote the second post about 3D on map. I have had to juggle few balls constantly up on air, so please bear with me.

Before moving on, I’d like to point out that there are *MANY* ways to achieve what I am trying here; “draw interesting places/events in 3D on map”. However the case might be, you might have to consider one very important factor, MONEY.

For example, you can buy and store full pre-rendered World map into iPhone. Then load piece by piece like 2D texture into OpenGL space to render from map to stars. Hmmm… I don’t think that I can even buy the map myself.

Another one is to walk straight up to Eric Schmidt and strike a deal for Google 3D map service. If I could do this, I shouldn’t even write these posts.

You can go with full set of map library like Route-me and map tile services like Cloudmade. Route-me is free and Cloudmade is free for small amount of load. Unfortunately even this is rather costly approach for low-profile start-ups like me. Just take rough estimate of workload and monthly service charge when your project goes over the “free” limit. Hmmm…

This post is all about “Make it pretty and make it cheap”. What’s left is then to come up with a way to combine OpenGL and iPhone mapview (MKMapView class). MkMapView is Cocoa class that provides Google map with smooth scroll and zoom. Besides, it calculates latitude and longitude of screen position on Mercator projection and vice versa. As with other native Cocoa classes, subclassing and categorizing it are fine so you have very powerful resource at your disposal already. Let’s get started from the two. By the way, if you have any better idea, let me know. I crave for it all the times.

*A map tile is small piece of Mercator projection of World map at a latitude and longitude. The piece-wise fragmentation of map makes loading World map into lightweight environments like web browsers and iPhone possible and feasible. Meanwhile, you’d need a rather non-trivial amount calculation to place map tiles on correct locations of screen. In addition, the size of entire map tiles for World is humongous. This is why you need map library and map tile service. Offline map tile storage is possible but just take a look at the size of Tom-tom GPS. Don’t forget it does not cover the entire World at various scales.

**Currently Google does not provide map tile service. Microsoft Bing and Yahoo! Map provide it though. You might have to pay handsomely beforehand. Cloudmade isn’t completely free. Nonetheless it is a newcomer compared to three former and price is rather reasonable. Plus, Cloudmade staffs talk with their customers.)

OpenGLES version and EAGLView

Ok, let me pick up from what was left off last time. 3D rendering on iPhone requires to use an OpenGLES (OpenGL for Embedded Systems, A good place for memory refresher is Jeff  Lamarche’s OpenGL ES from the Ground Up.) and a special view, namely EAGLView.

For the version of OpenGLES to use, (Of course, there are versions! Even bible has versions of new and old!) you can choose 1.1 to cover every iPhone/iPod Touch on earth, or 2.0 to cover from iPhone 3GS /iPod Touch 3rd gen. onward. Without a doubt, OpenGLES 2.0 is much more pretty and powerful in displaying 3D objects.

Since I want to reach as broad audiences as there possibly are, my choice is definitely to go with OpenGLES 1.1, and all my examples here are written with OpenGLES 1.1 in mind. If you want to apply them to OpenGLES 2.0, you might have different outcomes than what I have.

Cocoa does not provide native EAGLView class. EAGLView is what Xcode hands you from template when you choose to make an “OpenGL ES Application”. If you take a look inside, you’ll notice it is just a plain UIView subclass with its CALayer configured for custom OpenGL rendering.

EAGLView and MKMapView come together

The first thing you need to do is to stack two views: EAGLView (OpenGLES), and MKMapview (Mapview).

Stacking EAGLView and MKMapView is as simple as adding UIViews into UIViewController. Just add MKMapView first and EAGLView later.


// MKMapView initializing...
MKCoordinateRegion region;
region.center.latitude = 37.712615;
region.center.longitude = -122.472839;
region.span.longitudeDelta = 14.0625;
[(MKMapView *)self.view setRegion:region animated:NO];

//EAGLView (in OpenGLES 1.x) initializing...
EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
self.context = aContext;
[aContext release];
[oglesView setContext:context];
[oglesView setFramebuffer];
[self.view addSubview:oglesView];

Once you stack them up, you might want to run Timer or CADisplayLink to render 60 frames for every second (60 fps). (There might be other ways to animate 3D objects such as using event trigger. But I have not tested yet nor confronted solid examples so I cannot tell you drop timer off.) Since iPhone hardware screen refresh rate is locked into 60 fps, you don’t need go faster than that.

Transparent EAGLView background

Once you start render and draw, what you’ll see is an oscillating colorful rectangle with gray background. In order to see the MKMapView in the back, you need to make EAGLView transparent. You need to touch two places. (Transparent EAGLView does not require OpenGL alpha blending. Unless you really need to use, you don’t have to turn on blending feature.)

// EAGLView.m
//-(id)initWithCoder:(NSCoder*)coder

//UIView background transparency
self.opaque = NO;
self.backgroundColor = [UIColor clearColor];

//Then CAEAGLLayer background transparency
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
eaglLayer.opaque = NO;

//work around for "unavailable error"
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
const CGFloat myColor[] = {0.0, 0.0, 0.0, 0.0};
eaglLayer.backgroundColor = CGColorCreate(rgb, myColor);
CGColorSpaceRelease(rgb);

Then when you draw a frame, you clear the whole screen with alpha value of 0.0. As long as your alpha is 0.0, you can use any color.

//mapviewViewController.m
//-(void)drawFrame
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

Compile it and run, and then things look just fine. The mapview will display bay area of San Francisco, and 3D objects (in this case just a 2D rectangle) will be displayed on top of the map. What a breeze!

MkMapView and Re-routing UIEvent

When you start scroll the mapview, you will notice the mapview doesn’t really budge. You can zoom in and out but that is it.

…..ok. What’s going on?

What’s really peculiar about MKMapView class is it does not want anything to sit on top of it. If a UIView does so, MKMapView will not accept UIEvent. It has behaved this way ever since.

To get around this issue,

1) we need to firstly set EAGLView’s “userInteractionEnabled” to “NO”. Yes, that is right. This will completely block every UIEvent coming through.

2) Then we’ll have to make a UIWindow subclass to re-route touch event to MKMapView.

3) Just in case you still want to receive user event, I put a hole in EAGLView with “-(void) handleTouches:(UIEvent*)event”.

Look at the code below.

// EAGLView.m
-(id)initWithCoder:(NSCoder*)coder
// U don't want this view to listen user touch event
self.userInteractionEnabled = NO;
}

- (void) handleTouches:(UIEvent*)event {
}

UIWindow subclass and how it is implemented in app delegate.

@implementation EventRouteWindow
@synthesize overlayListener;
- (void)sendEvent:(UIEvent*)event {
	[super sendEvent:event];
	if(overlayListener != nil && [overlayListener respondsToSelector:@selector(handleTouches:)])
		[overlayListener performSelector:@selector(handleTouches:) withObject:event];

}
@end

@implementation AppDelegate
-(void)applicationDidFinishLaunching:(NSNotification*)aNotification{
     [self.window addSubview:viewController.view];
     [(EventRouteWindow*)window setOverlayListener:[viewController oglesView]];
     [self.window makeKeyAndVisible];
}
@end

As we get in “-(void)sendEvent:(UIEvent*)event” of UIWindow class, we are touching the lowest possible level of UIEvent delivery chain. With the UIEvent object, you can do just about anything. In fact, touches* function family of UIView handle just derivatives of UIEvent object delivered from here.

If we’re to draw an overview of how this event routing works, it should look like following.

Isn’t this dirty hack of some sort, you just ask? Yes, kind of. ;) However, this is not part of private framework that might put you in a trouble later.

Are there other options to achieve this workaround? Of course, there are many, if not thousands. I just don’t like objects at the same logical level exchanging pointers from one to another.

Ok, let’s compile and run again, and now map will scroll and zoom. You will quickly notice OpenGL will stop rendering whenever you touch the screen.  Just gentle touch will put your renderer in halt. Even if there is no link whatsoever to connect the two views, your renderer will stop until you pull of your finger from screen.

In fact, this is why I started blogging about it. There still remain a few issues to work around. My good friend, I’d like to take a journey with you on conquering those monsters. I’ll cover why this is happening, and how we can get around it next time.

If you have any question, find a mistake, and/or just want to say hello, drop me a line at twitter.com/stkim1. Download and enjoy the example!