abitofcode

#1GAM January entry – Repetitive (free)

Repetitive

Apple has finally approved my #1GAM entry for January, it was initially rejected for a metadata issue and some confusion as to what the app actually was.

It’s pretty simple and isn’t written in cocos2d this time but I did get it submitted to the app store within the onegameamonth.com January deadline. I’d initially resigned myself on the 31st January to missing the submission and getting a late one in but a quick change of heart (and project idea) and I was off. The game is an audio version of Simon Says and was designed to minimise the need to look at the screen. This enabled a quicker development time as I didn’t need visual assets or screen transitions and meant that with headphones on, the game could be played while in your pocket.

OneGameAMonth

If you’ve not signed up for #1GAM it’s not too late, head over to http://onegameamonth.com and jump in, it’s a great way to break out of a rut and get those project ideas that don’t seem to fit in anywhere out into the world.

In all the game plus submission took around 3.5 hours to write.

Development notes

The audio assets were created using the terminal command ‘say’

say -vTrinoids Left, Right, Up, Down, Tap


During development I threw together a quick script so I could try out different voices, this created a caf file named after the spoken work within it.

mkdir audio2
 
cat lines.txt | while read line
do
   # do something with $line here
   say -vTrinoids $line -o audio2/$line.aiff
   afconvert -d LEI16 -f 'caff' audio2/$line.aiff audio2/$line.caf   
   rm audio2/$line.aiff
done

Where lines.txt is a simple text file containing the words I needed, not so good with multiple words on a line :S

up,
down,
left,
right, 
tap,
play,

Grabbing the gestures was simple using apples gesture recognisers;

-(void) addGestures
{
    // Single Tap
    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:<span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre=""><span class="hiddenGrammarError" pre="">self
                                                                                    action</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>:@selector(onViewSingleTap:)];
    tapRecognizer.numberOfTapsRequired = 1;
 
    // Swipe up
    UISwipeGestureRecognizer* swipeUpGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
    swipeUpGestureRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
 
    // Swipe left
    UISwipeGestureRecognizer* swipeLeftGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
    swipeLeftGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
 
    // Swipe right
    UISwipeGestureRecognizer* swipeRightGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
    swipeRightGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
 
    // Swipe down
    UISwipeGestureRecognizer* swipeDownGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
    swipeDownGestureRecognizer.direction = UISwipeGestureRecognizerDirectionDown;
 
 
    [self.view addGestureRecognizer:tapRecognizer];
    [self.view addGestureRecognizer:swipeUpGestureRecognizer];
    [self.view addGestureRecognizer:swipeLeftGestureRecognizer];
    [self.view addGestureRecognizer:swipeRightGestureRecognizer];
    [self.view addGestureRecognizer:swipeDownGestureRecognizer];    
}

While handling the audio was made a lot easier using ObjectAL for iPhone by Karl Stenerud. The only issue I had with the audio was needing to know when one sound had finished so I could start the next, I opted in the end to schedule an NSTimer to play them one by one after a delay that gave enough time for the previous time to finish.

#import "ObjectAL.h"
 
// create NSArray of actions
@property (nonatomic, strong) NSArray    *actions;
self.actions = @[@"up", @"down", @"left", @"right", @"tap"];
 
// This loads the sound effects into memory so that
// there's no delay when we tell it to play them.
for (NSString *action in _actions) {
  NSString *filename = [action stringByAppendingPathExtension:@"caf"];
  [[OALSimpleAudio sharedInstance] preloadEffect:filename];
}
 
// Grab a random action from the actions array
-(NSString*)randomAction
{
    return [_actions objectAtIndex:(arc4random() % _actions.count) ];
}
 
// Here we play 'play.caf' but we could be playing a sound returned by the
// randomAction method (remember to add .caf onto the end first)
[[OALSimpleAudio sharedInstance] playEffect:@"play.caf"];

Then it just needed a simple state machine to get the gestures and audio playback/capture happening in the right order.

The scoring display was added later initially as a way for me to test it was working.

There’ll shortly be an update to address a couple of issues including a minor audio bug (and the mis-alignment of the headphones in the icon which is annoying @creativewax)

Repetitive

Download_on_the_App_Store_Badge_US-UK_135x40

Comments are closed.

%d bloggers like this: