Full-screen Camera Viewfinder in iPhone OS 3.1

iPhone OS 3.1 brought several customization options to the UIImagePickerController. With 3.1, you have the ability to customize the behavior of how the camera viewfinder appears to the user, without having to hack around the UIImagePickerController’s cameraView hierarchy. This has given rise to several augmented reality applications, such as the Monocle feature in the Yelp iPhone app.

I’ve been experimenting with a similar augmented reality prototype for a client recently, and was trying to mimic the full-screen viewfinder you see in Yelp’s Monocle. It was easy enough to set up the UIImagePickerController to display the viewfinder and remove the camera controls:

UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.showsCameraControls = NO;

However, this gives you a black bar with a height of 56px in the space the camera controls once occupied. To remove the black bar, you actually have to apply a scale transformation to the camera view using the cameraViewTransform property. The scale I’m using is 1.132, which is just enough to cover the 56px gap:

CGAffineTransform cameraTransform = CGAffineTransformMakeScale(1.0, 1.132);
imagePicker.cameraViewTransform = cameraTransform;

It’s a 13% scale, which is only slightly noticeable if you’re comparing the same scene through a non-scaled viewfinder. This transformation will apply to any pictures you might try to take programmatically with -takePicture.

From here, just display / release your UIImagePickerController as you normally would, and you should have a full-screen viewfinder. This only works on iPhone devices, as neither the iPhone Simulator nor the iPod Touch will support the UIImagePickerControllerSourceTypeCamera sourceType.

If you’re looking to build an app that can selectively enable this functionality at run-time, you can test for the sourceType compatibility of the device with +isSourceTypeAvailable:.

Comments

Shuffling with Objective-C Categories

One of the neat features of Objective-C programming is categories. Categories give the ability to add discrete bits of functionality on existing classes. Think of them as lightweight inheritance; I can add one or more methods to an existing class without having to create a custom subclass. There’s a bunch more you can do with categories as described in the Mac Dev Center.

In a current project I’m working on, I’m dealing with many arrays whose objects need to be in a random order. There are many ways of accomplishing the randomization of array order, but having implemented the Fisher-Yates shuffling algorithm in other languages and projects, I decided to implement an Objective-C version of it. It’s a deceivingly simple algorithm, and there’s a great post on why the Fisher-Yates method beats the pants off a naive shuffling algorithm over at Coding Horror.

I decided the easiest implementation would be add the category directly into NSArray and NSMutableArray. This way all the shuffling logic is fully encapsulated within those classes. Another article got me started on how to do this with the shuffling algorithm I wanted to use. This got me 90% the way there.

Basically all you do is create a new header and implementation file. For the interface, you define the new category and methods for both NSArray and NSMutableArray:


@interface NSArray (Shuffle)
- (NSArray*) shuffledArray;
@end

@interface NSMutableArray (Shuffle)
- (void) shuffle;
@end

And the implementation:


@implementation NSMutableArray (Shuffle)
- (void) shuffle {
  for (NSInteger i = [self count] - 1; i > 0; --i) {
    [self exchangeObjectAtIndex: arc4random() % (i+1) withObjectAtIndex: i];
  }
}
@end

@implementation NSArray (Shuffle)
- (NSArray*) shuffledArray {
  NSMutableArray* shuffledArray = [NSMutableArray arrayWithArray: self];
  [shuffledArray shuffle];
  return shuffledArray;
}
@end

Note I’m using arc4random() rather than random(). There are a few benefits to using arc4random(), but I like the fact that this randomizer seeds itself.

So that’s pretty much it. Once you include your new header wherever you want to use the shuffle category methods, you can shuffle any NSArray or NSMutableArray you come across.

Imagine a simple image slide-show application:


// Collection of UIImage *s
NSMutableArray *imageArray = [self makeImageArray];

// Shuffle array
[imageArray shuffle];

// Now we have a shuffled array. We can access items from the front.
UIImage *nextImageToDisplay = [imageArray objectAtIndex:0];

// If we don't need to keep track of previously shown images
[imageArray removeObjectAtIndex:0];

Or automatically shuffling a collection of songs a user has picked using the MPMediaPickerController (you can also shuffle songs using the shuffleMode property of the MPMusicPlayerController, but they don’t get shuffled until they are played):

// MPMediaPickerController delegate
- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItemCollection *) mediaItemCollection {

  [self dismissModalViewControllerAnimated: YES];

  // mediaItemCollection.items is an NSArray,
  // so we create a new MPMediaItemCollection using -shuffledArray.
  MPMediaItemCollection *shuffledCollection = [MPMediaItemCollection collectionWithItems:[mediaItemCollection.items shuffledArray]];

  // Now we've got a new collection of shuffled items.
  [self playMediaCollection:shuffledCollection];
}

I’ve glossed over many details here here in an attempt to show a practical use for categories and shuffling. If you’re interested in learning more, I’d recommend checking out the links in this post. They are excellent references.

Comments

Multiplayer Pong Demo using GameKit in iPhone OS 3.0

One of the more interesting features that was announced during the preview of iPhone OS 3.0 was the GameKit framework.

The video above is just a simple demo I wrote a few months ago with a beta version of GameKit and the cocos2d-iPhone framework. The two devices discover one another over Bluetooth, coordinate the client / server relationship, and begin play. There’s currently no scoring, and my protocol implementation is highly inefficient.

While the framework provides many neat features, I was most attracted to the zero-configuration P2P over Bluetooth. Multiplayer applications were previously only possible using Bonjour over WiFi, or some roll-your-own solution over the cell network. These methods provide a significant barrier of entry when you consider that the most popular games on this platform are the pick-up-and-play / get-in-get-out kind, with a typical play session lasting five minutes or less. If I have to fiddle with my network options in order to play an ultra-casual game with you, I most likely won’t.

The bad news? Bluetooth P2P is only available on iPhone 3G and 3Gs, and iPod Touch 2G.

Comments (1)

Off To GDC Next Week

gdc

It has been ten whole months since I decided I wanted to make video games for a living. Since that time I’ve purchased well over $1,000 worth of books, games and consoles in an attempt to immerse myself in an arena I’ve been away from for many years.

By leveraging my existing skills, I was able to get my foot into the door as a developer for a upcoming kids-oriented MMO by day. I am also designing and programming games for the iPhone on my own. I took a little break from iPhone programming during the last quarter of 2008, but the innovation I’ve seen in other apps has brought me back to the land of Objective-C. And yes, I am planning an update for Tiny Violin. :)

All this is to say that I will be attending this year’s Game Developers Conference next week, and couldn’t be more excited! I’m really looking forward to meeting fellow game-makers, especially on the iPhone-front.

Comments

Tiny Violin in Mac|Life

The folks over at Mac|Life contacted me back in early November for a short interview. They were writing an article showcasing a handful of iPhone developers and were interested in including Tiny Violin. The online version of the article was published a few weeks ago, and the print version can be found in the January 2009 issue of Mac|Life.

Many thanks to Leslie and everyone else over at Mac|Life for giving Tiny Violin all the press. And if you haven’t checked out Mac|Life before, know that you are missing out on probably the best all-things-Mac-related publication out there.

Comments

Tiny Violin Approved for the App Store

tinyviolin_iphone_portrait_0708

My first iPhone / iPod Touch application, Tiny Violin, has been approved for the App Store. More details to come, but here is a description of the application:

Play the world’s smallest violin on your iPhone or iPod Touch.

An indispensable tool useful for showing sympathy toward another’s misfortune.

Slide your finger or thumb across Tiny Violin to play one of three short violin riffs, each designed to show sincere condolence for any situation.

Update: I’ve created a page for Tiny Violin.

Comments (2)