Browsing articles in "Development"

Automatically Insert Your SVN Revision Number Into Your Xcode Project

Oct 21, 2009   //   by Derek van Vliet   //   Development  //  No Comments

Wouldn’t it be handy for your iPhone app to have access to its subversion revision number at run-time? Of course it would!

Being able to access the current revision number in your app is especially useful for testing. We use it to display the current rev on our test builds so our testers can reference the build that they discover bugs in, like so:

IMG_01632

Here’s how to do it

1. In Xcode, add an empty header file to your project’s “Other Sources” group called “revision.h”.

2. Add a “New Run Script Build Phase” to your target.

3. When defining your build phase, use “/bin/sh” for the Shell value and enter the following script:

REV=`svnversion -n`
echo "#define kRevision @\"$REV\"" > ${PROJECT_DIR}/revision.h

4. Ensure that the new build phase happens before your “Compile Sources” build phase.

5. Build your app.

That’s it! From now on you can use a string define called kRevision wherever you would like to reference your revision number at run-time.

IMPORTANT: Do NOT add your revision.h file to your subversion repository. It will be generated automatically each time you build your app.

Screen shots of Addicus release build

Oct 16, 2009   //   by Matt Coombe   //   Development  //  No Comments

Here are  a few screengrabs of the build we  submitted to Apple. Enjoy :)

Addicus-14

fourofakind

overdrive

Addicus-09

Screenshot 2009.10.14 01.04.04

Saving and loading user data and preferences

Oct 7, 2009   //   by Rob Segal   //   Development  //  6 Comments

There is a collectively recognized method for storing application data and preferences which is NSUserDefaults.  The API for this is a bit unconventional and I thought an appropriate wrapper class would work well in this case.  While not completely understanding the full details of NSUserDefaults I developed a singleton class which we can use in our games to save/load data.  The interface is simple…

SettingsManager.h

#import <Foundation/Foundation.h>
 
@interface SettingsManager : NSObject {
	NSMutableDictionary* settings;
}
 
-(NSString *)getString:(NSString*)value;
-(int)getInt:(NSString*)value;
-(void)setValue:(NSString*)value newString:(NSString *)aValue;
-(void)setValue:(NSString*)value newInt:(int)aValue;
-(void)save;
-(void)load;
-(void)logSettings;
 
+(SettingsManager*)sharedSettingsManager;
@end

SettingsManager.m

#import "SettingsManager.h"
 
@implementation SettingsManager
 
static SettingsManager* _sharedSettingsManager = nil;
 
-(NSString *)getString:(NSString*)value
{	
	return [settings objectForKey:value];
}
 
-(int)getInt:(NSString*)value {
	return [[settings objectForKey:value] intValue];
}
 
-(void)setValue:(NSString*)value newString:(NSString *)aValue {	
	[settings setObject:aValue forKey:value];
}
 
-(void)setValue:(NSString*)value newInt:(int)aValue {
	[settings setObject:[NSString stringWithFormat:@"%i",aValue] forKey:value];
}
 
-(void)save
{
        // NOTE: You should be replace "MyAppName" with your own custom application string.
        //
	[[NSUserDefaults standardUserDefaults] setObject:settings forKey:@"MyAppName"];
	[[NSUserDefaults standardUserDefaults] synchronize];	
}
 
-(void)load
{
        // NOTE: You should be replace "MyAppName" with your own custom application string.
        //
	[settings addEntriesFromDictionary:[[NSUserDefaults standardUserDefaults] objectForKey:@"MyAppName"]];
}
 
// Logging function great for checkin out what keys/values you have at any given time
//
-(void)logSettings
{
	for(NSString* item in [settings allKeys])
	{
		NSLog(@"[SettingsManager KEY:%@ - VALUE:%@]", item, [settings valueForKey:item]);
	}
}
 
+(SettingsManager*)sharedSettingsManager
{
	@synchronized([SettingsManager class])
	{
		if (!_sharedSettingsManager)
			[[self alloc] init];
 
		return _sharedSettingsManager;
	}
 
	return nil;
}
 
+(id)alloc
{
	@synchronized([SettingsManager class])
	{
		NSAssert(_sharedSettingsManager == nil, @"Attempted to allocate a second instance of a singleton.");
		_sharedSettingsManager = [[super alloc] init];
		return _sharedSettingsManager;
	}
 
	return nil;
}
 
-(id)autorelease {
    return self;
}
 
-(id)init {	
	settings = [[NSMutableDictionary alloc] initWithCapacity:5];	
	return [super init];
}
 
@end

Values can then be saved/retrieved in code like so…

[[SettingsManager sharedSettingsManager] saveValue:@"hiscore" newValue:@"10000"];
NSString* myValue = [[SettingsManager sharedSettingsManager] getValue:@"hiscore"];
int myInt = [[SettingsManager sharedSettingsManager] getInt:@"challenges_won"];

To save our values on an incoming call or other system interruption we can put save/load calls in the appropriate callbacks of the app delegate…

- (void)applicationDidFinishLaunching:(UIApplication *)application
 
{
  // ...  (some code) ...
 
  // Load settings on initial startup
  //
  [[SettingsManager sharedSettingsManager] load];
 
  // ...  (more code) ...
}
 
- (void)applicationWillResignActive:(UIApplication *)application
{
  [[SettingsManager sharedSettingsManager] save];
  [[Director sharedDirector] pause];
}
 
- (void)applicationDidBecomeActive:(UIApplication *)application
{
  [[SettingsManager sharedSettingsManager] load];
  [[Director sharedDirector] resume];
}
 
- (void)applicationWillTerminate:(UIApplication *)application
{
  [[SettingsManager sharedSettingsManager] save];
  [[Director sharedDirector] end];
}

This basic class is great for storing arbitrary user state values that you want to preserve for the next time someone plays your game.  Hi scores, level progression, number of lives are a few of the possibilities this class could be used for.

Sneak Peek

Oct 3, 2009   //   by Matt Coombe   //   Development  //  7 Comments

Here’s an early render of some characters from an unannounced game we currently have in development.

Orc_02_013

Addicus – First App from Get Set Games

Sep 24, 2009   //   by Matt Coombe   //   Development  //  4 Comments

Welcome to Addicus, the first game we will release on the App Store. Development has been going full pace, especially after a good weekend sprint with the entire team locked up together for three days straight. It’s been extremely productive and we’re now in the final testing phases before submission to Apple.

Some screenshots can be found below.

Get Set Games Addicus iPhone Game

Custom cocos2d Action For Animating an AtlasSprite’s TextureRect

Sep 23, 2009   //   by Derek van Vliet   //   Development  //  1 Comment

While working on our coming-soon first iPhone game, we have been having a lot of success with cocos2d. One area in particular that we have been impressed with is the ability to run “Actions” on sprites, string them together in sequences and wrap them in modifiers such as ease-in, ease-out etc. This has made it easy to make our UI lively and animated as well as animate our game objects.

Recently we had a need to animate an AtlasSprite’s texture rect in order to pan around an atlas sprite. We ended up creating a custom cocos2d action to do this and we figured it would be a good thing to give back to the community.

This will allow you to transform an AtlasSprite’s texture rect’s origin and size over the length of a provided duration. You can also wrap this in a modifier action such as ease-in or repeater.

Here is the code

TransformTextureRect.h:

#import "cocos2d.h"
 
@interface TransformTextureRect : IntervalAction {
	CGRect fromRect;
	CGRect toRect;
}
+(id) actionWithDuration:(ccTime)d toRect:(CGRect)rect;
-(id) initWithDuration:(ccTime)d toRect:(CGRect)rect;
 
@end

TransformTextureRect.m:

#import "TransformTextureRect.h"
 
@implementation TransformTextureRect
+(id) actionWithDuration:(ccTime)d toRect:(CGRect)rect {
	return [[[self alloc] initWithDuration:d toRect:rect] autorelease];
}
 
-(id) initWithDuration:(ccTime)d toRect:(CGRect)rect {
	if ( (self=[super initWithDuration:d] ) )
		toRect = rect;
	return self;
}
 
-(id) copyWithZone: (NSZone*) zone
{
	Action *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] toRect: toRect];
	return copy;
}
 
-(void) start
{
	[super start];
	fromRect = [(AtlasSprite*)target textureRect];
}
 
-(void) update: (ccTime) t
{	
	[(AtlasSprite*)target setTextureRect:CGRectMake(fromRect.origin.x + (toRect.origin.x - fromRect.origin.x) * t,
													fromRect.origin.y + (toRect.origin.y - fromRect.origin.y) * t,
													fromRect.size.width + (toRect.size.width - fromRect.size.width) * t,
													fromRect.size.height + (toRect.size.height - fromRect.size.height) * t)];
}
 
@end

Example Usage

This transforms an AtlasSprite’s texture rect to the position (25,25) and with a width and height of 50 over the course of 1 second:

[sprite runAction:[TransformTextureRect actionWithDuration:1 toRect:CGRectMake(25,25,50,50)]];

This does something similar to the above example, only it eases in and out of the action as well.

[sprite runAction:[EaseExponentialInOut actionWithAction:[TransformTextureRect actionWithDuration:2 toRect:CGRectMake(480,0,480,320)]]];

New Gameplay in Development

Sep 16, 2009   //   by Matt Coombe   //   Development  //  No Comments

Well it’s been a couple of weeks since the last game development update. The good news is that development on our first game has actually gone in a new and interesting direction and there’s been a huge amount of work done in that time.

After playtesting the first tech demos a whole bunch we’ve decided to actually split the gameplay into two different games. The first of these games is shown below. This game is a number based puzzler with very simple but very addictive gameplay. You are given a series of goal numbers and must pop mushrooms on the screen to create the sum of the goal number. As you achieve each goal number a new one will be presented. Pressure is applied to the player in the form of a timer that will countdown for each goal number.

Of course there are tons of chain and timer bonuses along the way so there’s big opportunities to rack up huge amounts of points as you go. Coloured mushrooms also play a big part in the game too.

Sounds simple but it’s actually pretty hard to put down once you start. We’ll have a video of some of the gameplay in the near future.

The latest incarnation of our mushroom popping game

The latest incarnation of our mushroom popping game

Versions and using an external diff/merge tool

Sep 10, 2009   //   by Rob Segal   //   Development  //  4 Comments

Subversion has been around for a while now and there are some very reliably maintained Windows clients, most notably Tortoise SVN. Unfortunately the same can not be said for OSX. There is one client that seems to stand out quite a bit from the others, Versions. Keep in mind that Versions is not free like Tortoise SVN but so far it has proven to be well worth the money.

Versions is a great tool but one of things it lacks is integration into one of my preferred diff/merge tools KDiff. Thankfully the developers of Versions have exposed hooks to allow people to write scripts which will allow users to integrate their preferred diff/merge application. I’ll show you how I was able to do that and how you can integrate your preferred application.

Versions has great support forums and after posting a question about how to integrate kDiff I was led to this page detailing how I could do just that.

The key steps to get your diff script to work…

  1. Copy your script to the folder “~/Library/Application Support/Versions/Compare Scripts”
  2. In Versions preferences in the file comparison drop down select your compare script

That’s it you should be set to go.  Here’s a screenshot of how kDiff is integrated in my preferences screen.

VersionsPreferencesKDiffSetup

Dev Video Diary – September 1, 2009

Sep 2, 2009   //   by Derek van Vliet   //   Development  //  No Comments

It has been a few weeks since our last video update and the game has progressed in leaps and bounds since then. It now features, among other things:

  • new intro video
  • new sound effects
  • multiple levels
  • decorative sprites throughout levels
  • scrolling levels
  • scoring
  • multiple icon pairs per level
  • treasure, bling and jewels

Also be sure to check out our first foray into screencasting with the hilarious PhoneFinger app.

The Objective-C Singleton

Aug 30, 2009   //   by Derek van Vliet   //   Development  //  28 Comments

One of the most useful patterns that we have employed in our iPhone game is the singleton. For those who don’t know, singletons are a class that only gets instantiated once in your application’s run-time. They often take the form of manager or factory classes. A good example of a singleton is the web-based resource manager class that we posted about recently.

We have been using singletons for a variety of things in our cocos2d-based game. Including:

  • Resource management
  • Atlas sprite managers
  • User settings management
  • Score management

Below is a template for the singletons that we use in objective-c.

MySingleton.h:

#import <Foundation/Foundation.h>
 
@interface MySingleton : NSObject {
 
}
+(MySingleton*)sharedMySingleton;
-(void)sayHello;
@end

MySingleton.m:

@implementation MySingleton
static MySingleton* _sharedMySingleton = nil;
 
+(MySingleton*)sharedMySingleton
{
	@synchronized([MySingleton class])
	{
		if (!_sharedMySingleton)
			[[self alloc] init];
 
		return _sharedMySingleton;
	}
 
	return nil;
}
 
+(id)alloc
{
	@synchronized([MySingleton class])
	{
		NSAssert(_sharedMySingleton == nil, @"Attempted to allocate a second instance of a singleton.");
		_sharedMySingleton = [super alloc];
		return _sharedMySingleton;
	}
 
	return nil;
}
 
-(id)init {
	self = [super init];
	if (self != nil) {
		// initialize stuff here
	}
 
	return self;
}
 
-(void)sayHello {
	NSLog(@"Hello World!");
}
@end

Example Usage

Using the methods of the singleton is then as easy as this:

[[MySingleton sharedMySingleton] sayHello];

Pages:«123456»

Our Games

What People are Saying

Latest Tweets

FriendFeed