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

Addicus waiting for approval

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

We’ve got some great news! Addicus has been uploaded to the iTunesConnect servers and is now waiting for approval from Apple. With any luck Addicus will be available on the App store in a couple of weeks!

Saving and loading user data and preferences

Oct 7, 2009   //   by Rob Segal   //   Development  //  8 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

What Caught Our Eye This Week – September 6 to September 12, 2009

Sep 13, 2009   //   by Derek van Vliet   //   Weekly Recap  //  No Comments

Here are some of the stories that piqued our interest this week:

Join our Friendfeed group to share and discuss stories like these.

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

What Caught Our Eye This Week – August 30 to September 5, 2009

Sep 7, 2009   //   by Derek van Vliet   //   Weekly Recap  //  No Comments

Here are some of the stories that piqued our interest this past week:

  • We enjoyed the minimalist gameplay of the new iPhone game, Button.
  • Tim Langdell resigned from the IGDA board of directors amid controversy.
  • Larva Labs released sales data that compares their iPhone sales with their Android sales in an effort to shed light on how much the two markets are worth.
  • A new study showed something that we all knew already: Tetris makes your brain bigger.
  • We enjoyed reading about the history of Harmonix from the horses mouth, and how they almost failed twice before hitting the big time.

Join us in our FriendFeed group to share and discuss other news.

Our Games

Latest Tweets