Category Archives: Sparrow

Tribus, Graduation Project

On Wednesday 20 th, I made my last orals for school. Some weeks ago, I’ve finished my training at Swad‘s web agency in Annecy. Since Wednesday my sandwich course at Gobelins school (Annecy) is finished, and now I’m in “holiday”. It means that I’m working on my new Portfolio and looking for a job probably at Lyon, France 😉

Let me introduce Tribus, the first game which use bus public transportation as gamification!
We were 4 people behind this project, Pauline the Graphic Designer, Coraline the Designer, Lory the Project Manager / Developer and me as the lead Developer.
Tribus is based on a simple observation : public transportation are boring time for many people. The idea was to play in real time with the bus public transportation and break the boredom thanks to the Gamification.
The Tribus’ concept is to gamify the bus route using its own elements : location, speed, line, bus stop… and offer a game!

The concept was there, but what type of game offer? A real time massive multi-players space opera? Impossible for a small team in 4 – 6 months, we aren’t Electronic Arts. A survival game with zombies? I loved this idea, it could have been awesome if we have worked on subway : safe point, network lost… all the ingredients were already present. However we wanted a game for everyone : fun, easy to play, stress-free… yep, one more casual game.

Tribus is a Canabalt type of game, it is close to Jetpack Joyride. But how are bus elements injected in the gameplay?
It is very difficult to have information on the bus, bus’ companies don’t disclose these informations. So we used the smartphone’s GPS. Thanks to it we could know our position and so the bus one. We have located bus stop in a database and so we knew if a user follow the bus route and then suppose that he is using the bus! The GPS is also used to know the bus speed and thus change the speed of the game.

We developed for iPhone, using Chipmunk and Sparrow for the game (not the app interface) and made a simple port of the Citrus Engine. Since this is my first project using Objective-C the port is not very “user friendly” and it can be improved a lot. Anyway, that was a very rewarding experience.
All the source code is available on GitHub.

A short video :

Screenshots :

Sparrow Framework, AnimationSequence class

Coming from AS3 & Starling framework, it is really easy to handle Sparrow. I was surprised to don’t find a class to manage several animations (like the gotoAndPlay in as3) in Starling and it is the same with Sparrow. So I’ve ported the AnimationSequence class (used in the Citrus Engine V3) from Starling to Sparrow.

Basically, the class extends SPSprite with all SPMovieClip animations added into a Dictionary which are addChild/removeChild (with the Juggler).

An AnimationSequence is defined with a texture atlas, an array with animation states and a simple string with the first animation :

AnimationSequence *mc = [[AnimationSequence alloc] initWithTextureAtlas:[SPTextureAtlas atlasWithContentsOfFile:@"Hero.xml"] andAnimations:[NSArray arrayWithObjects:@"walk", @"jump", @"idle", nil] andFirstAnimation:@"idle"];

To change an animation :

[mc changeAnimation:@"walk" withLoop:YES];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#import "SPSprite.h"
 
@interface AnimationSequence : SPSprite {
 
    NSMutableDictionary *mcSequences;
 
    SPTextureAtlas *textureAtlas;
    NSArray *animations;
    NSString *previousAnimation;
}
 
@property (nonatomic) NSMutableDictionary *mcSequences;
@property (nonatomic) SPTextureAtlas *textureAtlas;
@property (nonatomic) NSArray *animations;
@property (nonatomic) NSString *previousAnimation;
 
- (id) initWithTextureAtlas:(SPTextureAtlas *) textAtlas andAnimations:(NSArray *) multiAnimations andFirstAnimation:(NSString *) firstAnim;
 
- (void) changeAnimation:(NSString *) animation withLoop:(BOOL)animLoop;
 
@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//
//  AnimationSequence.m
//  ChipmunkWrapper
//
//  Created by Aymeric Lamboley on 06/03/12.
//
 
#import "AnimationSequence.h"
 
@implementation AnimationSequence
 
@synthesize mcSequences, textureAtlas, animations, previousAnimation;
 
- (id) initWithTextureAtlas:(SPTextureAtlas *)textAtlas andAnimations:(NSArray *)multiAnimations andFirstAnimation:(NSString *)firstAnim {
 
    if (self = [super init]) {
 
        textureAtlas = textAtlas;
        animations = multiAnimations;
        mcSequences = [[NSMutableDictionary alloc] init];
 
        for (NSString *animation in multiAnimations) {
 
            if ([textureAtlas texturesStartingWith:animation].count == 0) {
                NSLog(@"One object doesn't have the %@ animation in its TextureAtlas", animation);
            }
 
            [mcSequences setObject:[[SPMovieClip alloc] initWithFrames:[textureAtlas texturesStartingWith:animation] fps:25] forKey:animation];
        }
 
        [self addChild:[mcSequences objectForKey:firstAnim]];
        [[SPStage mainStage].juggler addObject:[mcSequences objectForKey:firstAnim]];
 
        previousAnimation = firstAnim;
    }
 
    return self;
}
 
- (void) changeAnimation:(NSString *)animation withLoop:(BOOL)animLoop {
 
    if (!([mcSequences objectForKey:animation])) {
 
        NSLog(@"One object doesn't have the %@ animation set up in its initial array?", animation);
    }
 
    [self removeChild:[mcSequences objectForKey:previousAnimation]];
    [self.stage.juggler removeObject:[mcSequences objectForKey:previousAnimation]];
 
    [self addChild:[mcSequences objectForKey:animation]];
    [self.stage.juggler addObject:[mcSequences objectForKey:animation]];
    ((SPMovieClip *)[mcSequences objectForKey:animation]).loop = animLoop;
    ((SPMovieClip *)[mcSequences objectForKey:animation]).currentFrame = 0;
 
    previousAnimation = animation;
}
 
- (void) dealloc {
 
    [self removeChild:[mcSequences objectForKey:previousAnimation]];
    [self.stage.juggler removeObject:[mcSequences objectForKey:previousAnimation]];
}
 
@end

Be careful, this version uses the ARC mode!