The Stacker 6: Mouthing Off

Animation, animation, animation and… sound effects! I’m someone who enjoys simple concepts when it comes to gaming, however we can’t overlook all the good stuff that contributes to immersion in a game. In this post we’re going to focus on creating little dialogue bites for our blocks to “talk” complete with a nice “mouthing” animation that is general enough to reuse.

Let’s dive right into the fun part first; recording a bunch of little random mumblings that our blocks can utter, I’m picturing a lot of nonsense words like what you hear in the sims games. I’ll be using the free audio tool Audacity along with a decent condenser mic, the AT2020. Audacity is great for recording sounds, easy clipping, and has tons of filters and plugins so you can change things like speed, pitch, and gain.

Recording:

So I start recording my first gibberishy clip, it’s as easy as hitting the big record button and speaking into the mic. I stop the recording and at this point can clearly see a nice visual wave representing the audio I just recorded. It’s easy enough at this point to clip the ends where I can clearly see there’ no audio. After that I know I’m shooting for voice that’s higher than my own so I play with the pitch filter, tweaking and previewing until it sounds just right. When I believe it sounds right I save it in .wav format in my project directory. I repeat the process for about five more and move on to the next phase.

Mouth Animation:

Let me first state my plan for how I see the mouth animation design going down. I want to create a few different mouth types that can open and close easily by using cocos’ actions as opposed to using frame animations. I can already picture two types of mouths that can fit this criteria:

  • Mouth 1: A simple oval that can be closed by scaling down the y axis.
  • Mouth 2: A mouth consisting of a lower “jaw” and an upper “jaw”, they can both be moved up/down in order to simulate opening/closing.

To make this work, we need simple record structure in the code that will have the .wav file name, the duration, and (assuming 1 open & close per syllable) the number of syllables uttered per phrase. Now this is assuming that each syllable takes roughly the same amount of time to utter…. something we may have to come back and tackle latter; but I would extend rather than replace this planned behavior to make that work.

-Simple mouth we can just modify it’s X and Y scales to make open/close

  -2 moving jaw pieces to simulate open/close


@interface TalkSound : NSObject
{
    NSString    *_file;
    float       _duration;
    int         _syllables;
}

@property (readwrite, retain, nonatomic) NSString *file;
@property (readwrite, assign, nonatomic) float duration;
@property (readwrite, assign, nonatomic) int syllables;

+(id) talkSoundWithFile:(NSString*)file duration:(float)duration syllables:(int)syllables;

@end

So now we just need to set up a few mouth objects that conform to a simple protocol that I call “Mouth”; I say simple because it says objects following it must have one method named “talk” that takes a duration and number of syllables.

@protocol Mouth
-(void) talk:(ccTime)duration syllables:(int)syllables;
@end

@interface SimpleMouth : CCSprite<Mouth>
{
}
@end

@interface TeethyMouth : CCSprite<Mouth>
{
    CCSprite *_other;
}
@end

So now I just need to get these guys talking; ideally I want periodic chatter as well as some “smart” chatter based on events. It should be easy enough to get the periodic random chatter part down so lets start there. I define a class called “TalkManager”; it doesn’t need to do much right now, all it needs is a list of the blocks that should be talking and all the dialogue sound records. After that we can just schedule an method to handle some random chattering.

At the moment I can just have the function look something like this:

-(void) randomTalk
{
    if ([_blocks count])
    {
        Blocky *block = [_blocks objectAtIndex:rand() % [_blocks count]];
        TalkSound *ts = [_talkSounds objectAtIndex:rand() % [_talkSounds count]];

        [block talk:ts.duration syllables:ts.syllables];
        [[SimpleAudioEngine sharedEngine] playEffect:ts.file];
    }
}

As you can see, we’re just using the “SimpleAudioEngine” class that comes with cocos, it works really well! Here’s video of everything pulled together, sorry for the not-so-great sound in the video.

So that’s it for now, next time we should aim for some menu stuff, see you then!

Posted on January 13, 2012, in Game, Technical and tagged , , , , , , , , , , . Bookmark the permalink. Leave a comment.

Leave a comment