The Running Man

So the time came when we had to start thinking about animating our player for our unnamed laser slicing game. We started thinking about the process and basically came up with 2 methods of approaching it.

Frame Animation
This would be more like classic animation, where you’re required to draw every frame of the animation. We have a fairly simple character and it wouldn’t be too-too hard to come up with a bunch of animations for our character. Ultimately, the problem here is flexibility and resources. It would take up a lot of spritesheet real estate and also lock the character into a few sets of animations with no variety.

Skeletal Animation
A much more efficient type of animation that’s relatively simple to implement. The idea behind it being that the character is split up into multiple jointed body parts; in our case there’s a head, torso, arms and legs. Since cocos2d has a nice framework for actions, we can string together a bunch of rotation actions to get a nice repeating animation of running/walking/jumping/etc. And since our character will be aiming a weapon, having joints will fit in nicely with having to rotate the arms based on aim.

So skeletal animation it was, we started putting together 1 simple animation: A running man. This running man animation involved swinging both arms such as a jogger would, and of course legs that moved in a jogging-type fashion.

So far so good, but the next part is a bit tricky. We want to actually tie the speed of the animation to the speed of the character, horizontal speed that is. Now it’s worth noting that there actually is an action in cocos2d already called “CCSpeed” that allows you to programmatically control the speed of another action, however I chose to implement my own action derived from CCRepeatForever that behaved like CCSpeed for various reasons that made this option seem less complicated to me.

Now that looks a lot better! We’re not quite out of the woods yet though, even though the character slows in speed, he still looks like he’s running albeit in slow motion. This is going to require some trickery, we don’t really want to throw a whole separate walking animation into the mix because we want the transition to be smooth and since walking is really just the same animation except with smaller rotations we devised an interesting plan of action. Based upon the speed set, we’d calculate a percentage and apply that to an angle span; we’d dampen the value applied so that the transition was smooth and voila!.. ok well a bit of tweaking, but soon after we had a nice animation that included running and walking in one.

There’s still a bunch more to do, like when the character stops get him to actually stand, but that will probably be a matter of making sure the angles are zero and the speed comes close to a halt. That’s it for now.

A Thought About Menus

Doing the menu system for your game can sometimes be a bit rough, and can sometimes be almost as much work as creating the gameplay itself. Thinking about this came about as we were wondering what to do for our Laser Slicing game concept (still unnamed). So I had a thought, why not create the menus based on all the glorious gameplay code I’ve already written; I already have a level editor so placement and layout will be a snap!

So I start looking at what I’d need to add to have this thought come to fruition. What are all menu’s made up of? Buttons of course! Ok so that’s not so bad, I just need a way in the editor to identify an object as a button. Since it’s trivial to place text anywhere in the editor I decide that I’ll just mark objects by placing special text over them; in this case I put down something like “button:Play” over an arbitrarily sized polygon dangling from a rope. In my game I can easily identify this special strings and do the appropriate actions to make it perform like a button.

In the Laser Slicing game I have one game class that encapsulates all the gameplay logic. Making menu’s work with this required identifying all the different pieces of the gameplay and making sure that they were uncoupled into their own overrideable functions. This allowed me to create a subclass, “Menu” that could them hook into the game object as necessary and do things like: prevent the player from being created, move the camera to different sections of the menu, etc.

In all, the most time consuming part of this was making sure buttons acted liked buttons: highlighting selected buttons, handling different touch behaviours. The logic of what a button can due is all based upon the label it has, a few simple rules in the Menu class was all it took. The other time-consuming component of this was creating a slider object; in this case it was an actual box you dragged around (thumb of the slider). Keep in mind everything in this game is based upon a physics simulation engine (chipmunk). In the end we basically have marked slider thumb objects with the “-” text and have special code that lets you pick up and drag them around, updating a percentage label on the side. We used these sliders for controlling the volume.

Overall, I think this method worked out very well. I was able to quickly come up with some menus using the level editor and I get all the perks of cool physics style action, I could even insert some slicing and other interactions found in the game. So I hope next time you start to think of doing the sometimes monotonous task of creating boring menus, you instead think about dipping into what you probably already have at your fingertips.


Slicing Physics Prototype

We’ve been prototyping a new game on the side of other things for a little while now. It started with playing a lot of slicing based games and working through a wenderlich tutorial. We thought it might be fun to make a portalesque type game where the object was to manipulate the environment to get out the room, except instead of a portal gun you got an awesome laser gun that could cut through almost anything.


One of the hardest parts to getting the slicing to work properly was getting the joints to work properly, when a shape is sliced in two you are essentially creating two new shapes at new locations with new vertices and things can get kind of tricky fast. Luckily I think we’ve ironed out most of the kinks and I’m hoping at one point we can make the slicing library available.

For now more work will be going into creating levels and new mechanics, like forcefields and the like. Here’s a nice little video showing on of the levels that has reflective objects and forcefields:

On a side note, things are also moving along bit by bit with stacker and I hope to talk next about how we made the app universal. Here’s a somewhat recent screencap of sleeping blocks.

Until next time…

We’re still here!

Hello all, it’s been a very busy few months working on other people’s projects, and we apologize for going postless for so long. We’re trying hard to get back into the swing of things, looking to get “The Stacker” out somewhat soon and we’ll have some more posts on that as follows. I’m going to be more diligent about posting content at least every other week, even if that means non-AppTinker related news in the indie game dev world.

We also have a few other projects started as well. Here’s a few screenshots of one of them, where the aim is cut physical objects with a powerful laser and move the player safely to the door. The player is the upright rectangle with beveling at the bottom.

Annnnd that’s it for now!

The Stacker 8: Menus

Sometimes it’s nice not having to reinvent the wheel and in this case we’re looking for a nice simple menu to pick levels from. After doing a little searching around, I found this nice little blog entry by a Mr. Brandon Reynolds who created an Angry Bird’s style sliding menu:

http://brandonreynolds.com/blog/2011/01/09/cocos2d-sliding-menu-grid/

He’s got a link to the source code and an example at the bottom of that entry. After taking a look at the code in the example it’s quite clear how to get this working within our own project. Simply copy and drop the “SlidingMenuGrid.h/.m” files into our Stacker project and we’re well on our way.

In order to start using this class I decided to start by subclassing SliderMenuGrid so that I’d be able to encapsulate the button press logic within the class. Quite simply we just want to fire up the appropriate level when a button is pressed.

@interface LevelMenu : SlidingMenuGrid
{
}
+(CCScene*) scene;
+(LevelMenu*) levelMenu;
<p>-(void) selectLevel:(int)level;
@end
+(LevelMenu*) levelMenu
{
    LevelMenu* levelmenu = [LevelMenu alloc];
    int max = 30;
    NSMutableArray* allItems = [NSMutableArray array];
    for (int i = 1; i &lt;= max; ++i)
    {
        NSString* image = [NSString stringWithFormat:@"levbutton"];
        NSString* normalImage = [NSString stringWithFormat:@"%@.png", image];
        NSString* selectedImage = [NSString stringWithFormat:@"%@.png", image];
        CCSprite* normalSprite = [CCSprite spriteWithFile:normalImage];
        CCSprite* selectedSprite = [CCSprite spriteWithFile:selectedImage];
        CCMenuItemSprite* item =[CCMenuItemSprite itemFromNormalSprite:normalSprite
                                                        selectedSprite:selectedSprite
                                                                target:levelmenu
                                                              selector:@selector(selectLevelFromButton:)];
        item.tag = i;
        [allItems addObject:item];
    }
    
    LevelMenu* menuGrid = [[levelmenu initWithArray:allItems 
                                              cols:5 
                                              rows:3 
                                          position:CGPointMake(70.f, 280.f) 
                                           padding:CGPointMake(90.f, 80.f) 
                                    verticalPaging:NO] autorelease]; 
    
    return menuGrid;
}

-(void) selectLevelFromButton:(id)sender
{
    [self selectLevel:[sender tag]];
}

-(void) selectLevel:(int)level
{
    [[CCDirector sharedDirector] replaceScene:[Game scene]];
}

The bulk of the code comes from the example provided, we’re just setting up 30 buttons (15 to each “page”). I set it up to tag each button so that when the button is pressed we can tell which level to load up. This lets us define one nice little method that will eventually pass the level number on to the game (It doesn’t use it above). Before this code will actually run correctly I also need to provide “levbutton.png” in the project; a 90×90 png seems to be about the right size…. although I’ll probably end up making it a little bit bigger.

It’d be nice to get some numbers on those button icons (at the very least!) so the gamer can identify a level quickly. Luckily that’s a two minute process of just adding a label to the button; I’m going to use a little trick I’ve employed a few times to get a drop shadow going on it even.

So right after the button item creation, we add this code:

        NSString* labelStr = [NSString stringWithFormat:@"%d", i];
        
        //Shadow
        CCLabelTTF *label = [CCLabelTTF labelWithString:labelStr fontName:@"Marker Felt" fontSize:16];
        label.position = ccpAdd(ccpMult(ccpFromSize(normalSprite.contentSize), 0.5), ccp(2,-2));
        label.color = ccBLACK;
        [item addChild:label];

        //Actual
        label = [CCLabelTTF labelWithString:labelStr fontName:@"Marker Felt" fontSize:16];
        label.position = ccpMult(ccpFromSize(normalSprite.contentSize), 0.5);
        label.color = ccWHITE;
        [item addChild:label];

As you can see, I create a black label first that’s centered in the button but then offset by 2 px right and down; and then we place a white one right on top of that. The result looks quite glorious (and yes I did redraw the button image a bit):

Maybe I’m a stickler, but starting at 10 and up the label looks a bit off-center; I quickly added a 2-liner if statement to correct that by a few pixels.

Alright, things are looking pretty good at this point; right now a click on the button just fires up the default/debug game so I believe this is a good point to leave off. Next time we’ll prob end up talking about some more game mechanics.

The Stacker 7: QR-Code’in

Sorry for the long break; I’ve been distracted by some other work recently. So let’s get to it, I’ve been trying to think of a great standout feature for this game, something to distinguish it a bit from the rest of the pack. I settled upon a feature that would let users generate a set of randomized levels given some sort of seed event and save that set to their device. They could then bring up a QR code so that other users could scan in their levels that they had “made”.

This all sounds sort of complex for such a ho-hum feature doesn’t it? Well I did some looking around and it turns out there’s a great open-source project on google code called Zxing that even comes with a nice little iOS example. It’s able to read QR codes with the device camera and also help generate a QR code image given a string. Hard part over right!?

Well ok sure, but we need to get it into our project first. So if you download Zxing, you’ll notice that there is an iphone folder in the root; dive into that and you’ll see a “ZXingWidget” folder and inside that there’s an xcode project to build it.

To get this widget into our project we need only do two things:

  1. Drag the widget project into our project; I put it under the “libs” group
  2. Make sure we add the ZXingWidget library as a dependency to our target (“Build Phases” in project settings).

Here’s a nice little screenshot of both those things:

Everything should compile now with no problems (Edit: I forget, but I may have needed to add those  3 frameworks on left there as well).

Now that we have it in there, we need to take advantage of this new class in our code. To get started we need only create a simple delegate class that looks like this:

#import <UIKit/UIKit.h>
#import "ZXingWidgetController.h"

@interface ZXingController : NSObject <ZXingDelegate>
{
    NSString *_results;
    ZXingWidgetController *_widController;
}

@property (nonatomic, copy) NSString *results;

- (void)scan;
@end

and this in the implementation:

#import "ZXingController.h"
#import "QRCodeReader.h"
#import "cocos2d.h"

@implementation ZXingController

@synthesize results = _results;

- (void) scan
{
    _widController = [[ZXingWidgetController alloc] initWithDelegate:self showCancel:YES OneDMode:NO];
    QRCodeReader* qrcodeReader = [[QRCodeReader alloc] init];

    _widController.readers = [NSSet setWithObjects:qrcodeReader,nil];

    //Add to the root view
    [[[[CCDirector sharedDirector] openGLView] superview] addSubview:_widController.view];

    [qrcodeReader release];
}

- (void)dealloc
{
    [_widController release];
    [_results release];
    [super dealloc];
}

- (void)zxingController:(ZXingWidgetController*)controller didScanResult:(NSString *)result
{
    _results = [result retain];

    [_widController.view removeFromSuperview];
}

- (void)zxingControllerDidCancel:(ZXingWidgetController*)controller
{
    [_widController.view removeFromSuperview];
}

- (void)viewDidUnload {}

@end

As you can see it’s farily straightforward to use. And now someone using this new class need only create this object and call scan; it will immediately present a viewfinder type screen and wait until the user either hits cancel or succesfully reads in a QRCode. From there that same someone can pull off the results property and decide what to do with it.

In our case the results string will represent our level packs somehow; I’m thinking it will store 3 things: a pack title, the level of difficulty, and a seed value to recreate the pack of levels…. nothing’s set in stone at this point though and this will have to continue in another post.

Last time I said we should start looking some menus, we still should and perhaps that will be next post’s topic; see you next time.

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!

The Stacker 5: Level Format

I know that last time we said we’d try to get to some more animation aspects but alas I was distracted a little by another task: designing a simple file format for the levels. I did however refactor eyeball-looking code a bit and added some slowly waving flowers so let’s take a look real quick.

To reiterate, I had the eyes following whatever was being dragged around at any given moment for all the blocks. It had a few design flaws: it was a behavior that wanted to be separated out, this became apparent when I found myself writing some code in the Game class very specific to the block behavior when ideally the Game doesn’t want anything to do with it, especially since I want to have multiple sets of behaviors and swap them around and such. Bottom line, we had to encapsulate the behavior.

Luckily for us, cocos2d has a nice little facility for running user defined actions. It’s as simple as creating a class that’s derived from one of cocos’ base action classes. It looks like this in the header:

@interface EyesFollow : CCAction
{
    Game    *_game;
    Blocky  *_block;
}

+(id) actionWithBlocky:(Blocky*)block game:(Game*)game;
-(id) initWithBlocky:(Blocky*)block game:(Game*)game;

@end

And then with just a few function overrides like this:

-(void) step:(ccTime) dt
{
    [self rotateEye:_block.rightEyeBall dt:dt];
    [self rotateEye:_block.leftEyeBall dt:dt];
}

-(BOOL) isDone
{
    return NO;
}

(The rotateEye is the same code from the last post) And now we have a simple action that will run just like any other cocos action. I have the isDone function return NO for now which will basically cause it to never end for now, I can change it later to only run for a given amount of time.

Ok, so let’s move on and quickly discuss the slowly waving flowers that were added to the bottom of the screen. Now ideally if you can split a character or object into several different images then it usually will give you more flexibility in the end as far as animation and re-useability. In this case I’m going to be splitting my flower into several pieces: stalk, leaves, petals, and flower bud. This will give me the ultimate in re-useability because now I will be able to change petal color and rotate and position parts of the flower differently across multiple instances….. so everything doesn’t just look the same!

                   

Notice anything weird? Yep, the petals are grayish; this allows me to programmatically set any color on them easily thru cocoos2d. Put everything together and run a few repeating actions to move things back and forth and we have an simple effective “background” animation.

Lets move on to the file formatting of the levels. Ideally we want something that can easily be modified by hand, so that means human-readable without being too lengthy. XML is the popular choice and luckily for us Apple supplies us with a nice super fast SAX parser called “NSXMLParser”.

This class is very simple to use, you need only define a delegate that conforms to one method, my interface for it looks like this:

@class Game;

@interface XMLLevelLoader : NSObject <NSXMLParserDelegate>
{
}
@end

Since I’ve declared myself a parser delegate I then need to make sure I implement one important function and it’s signature looks like this:

     -(void)parser:(NSXMLParser *)parser 
   didStartElement:(NSString *)elementName 
      namespaceURI:(NSString *)namespaceURI 
     qualifiedName:(NSString *)qName 
        attributes:(NSDictionary *)attributeDict;

It’s a bit crazy looking I know, but really we only care about elementName and attributeDict. Alright we’re all setup now, so let’s create an xml file:

<stacker>
    <block name="greenblock"/>
    <block name="pinkblock"/>
    <block name="orangeblock"/>
    <block name="greenblock"/>
    <block name="pinkblock"/>
    <block name="orangeblock"/>
    <block name="blueball"/>
    
    <platform x="240" y="40" type="1" angle="0"/>
    <bar x="240" y="35" x2="240" y2="-5"/>    
</stacker>

So, simple is the name of the game here, we have a block tag that is distinguished by it’s name attribute; this way I can easily create a block based on that. There is also a platform with an x and y and angle, and the type is just so I can determine which platform to put down. The bar tag is just the bar sprite you see “holding up” the platform.

Now in my parser function I need merely place a few if statements in to check the tag and it’s attributes and create the appropriate item. Done! Well ok not done, but it’s a good start.

Next time let’s plan on getting into more animation stuff and doing some menus so we can start bringing this game to fruition! See you then.

The Stacker 4: Animation

Upgrade Note: I upgraded to iOS 5 and was having some really strange cryptic errors in header files such as CFLocale and CFDictionary….. it took awhile to track down but it was essentially because I chose a pretty bad name for the block’s class, “Block”, Doh! I renamed it to “Blocky”.

So far I’ve been using some quickly sketched shapes which needed a bit of a facelift, so I switched over to the windows machine and fired up Paint.net. I suppose my choice of painting program deserves some explanation; first of all it’s completely free…. should I continue? Simply put it has quite the advanced feature set while still maintaining a simple to use interface, it supports layers, it has a ton of effects and plugins, and it’s easy to learn and get started with.

Using layers when creating a drawing/painting is a must as it will ultimately be the tool that gives you the most flexibility. It will let you tweak and delete portions of your image without having to undo your changes or hurting other parts of the image. Also for our purposes, we need to componentize things so we can easy separate them out into their own png files.

Before I move on I must tout one of the tools I use the most; it’s called AA’s Assistant and it will essentially cleanup rough edges making things smooth and curvy. It’s quite awesome.

After I’ve separated out all the components of my block (block, eyes, spots, etc.) I then use Texture Packer (“Essential” version is free) to create a spritesheet that I will [finally] use in my project!

First up for some simple animation is the eyes; I want to move the eyes based on several conditions, but for now let’s just focus on one: When a block is grabbed, the other shapes should all look at that block as it’s being dragged.

I’m pretty sure that since I plan on having a bunch of different “behaviors” I should find a way to abstract that away from the block itself so I can easily swap around “behavior objects”. However, I’m not sure what that will need to entail yet so I’m just going to jump right in and associate this particular behavior with the block itself, for now.

Setup of the eyes is a snap, place the 2 eyes accordingly as children of the block. Then place the eyeballs as children of the eyes; an important thing I did hear was adjust the anchor of the eye ball to be: (1.05, 0.5). This allowed me to place the eyeball directly in the center of the eye BUT it appeared to be looking directly to the right. I did this because directly to the right is zero degrees and it will mean that I merely have to set the rotation on the eyeball to get it to look at any angle I want, simple!

Now we just need a function to rotate the eyeball towards a given block.

-(void) rotateEye:(CCSprite*)eyeball dt:(ccTime)dt lookAtShape:(cpShape*)lookAt
{
    int     speed = 5;
    float   damping = 0.97;
    float   dt_mult = cpfmin(dt*speed, 1.0f); //don't let it get too large

    //Calc the angle the eye should be pointing to
    float angle;

    //If we have a shape, use it, otherwise just look down
    if (lookAt)
    {
        CGPoint bodyPos = [self convertToNodeSpace:cpBodyGetPos(lookAt->body)];
        angle = -CC_RADIANS_TO_DEGREES(ccpToAngle(ccpSub(eyeball.parent.position, bodyPos)));
    }
    else
        angle = -90;

    //Trim the angle
    float startAngle = eyeball.rotation;
	if (startAngle > 0)
		startAngle = fmodf(startAngle, 360.0f);
	else
		startAngle = fmodf(startAngle, -360.0f);

    //Calculate the difference, and find the smallest angle
	float diffAngle = angle - startAngle;
	if (diffAngle > 180)
		diffAngle -= 360;
	if (diffAngle < -180)
		diffAngle += 360;

    //Move the eyeball toward the direction it should face
    eyeball.rotation += diffAngle * damping * dt_mult;
}

It may look a bit complex but really all this function does is calculate the angle between the shape we’re looking at and the eyeball and then start rotating the eyeball towards that angle at a given speed; with a few point conversions and smallest angle finding code helping out.

We can now just schedule a routine that will call this method for both eyeballs… BUT in order for this to work we have know what shape the block should be looking at. Luckily I have a routine in my Game class that gets called by the shape touch controller when a shape is moving, so I can just modify it to do this:

    for (Blocky *block in _blocks)
        block.lookAtShape = record.shape;

Doing something like this raises a bit of concern and further tells me I need to separate these behaviors into their own objects; but anyway for now it looks great!

It’s impossible to tell just from the picture but I have also animated those light spots on all the blocks (except the circle), they bounce around on the inside of the blocks, spinning, and scaling up/down. It was a fairly simple animation involving only a few cocos2d actions and code to check the bounds on where they could move, I also tweak the velocities periodically so the movement is non-linear. This is all reminding me I need to get us a youtube account.

On that note I think we can leave off here. Our goal for next time is to continue the animation aspects. See you then.

The Stacker 3: Sidebar & Rotation

Rotation:

So first off let’s address the rotation problem. I tried a bunch of different ways to get a two finger touch to rotate a shape. Already in place was a system for attaching chipmunk pivot joints and having shapes be dragged around like that. One might think that simply ensuring that the second touch always attached a pivot to the same shape as the first would work…. and that person would be right to a certain extent. The problem is that the two touches are very rarely always at the same distance apart, creating a quite visible pull/push on the shape that can become quite sporadic. Going down the route of trying to reposition the pivots on the shape led to even more frustration (though I’m pretty sure there’s probably a solution using it!).

Well anyway, I suddenly fell upon a pretty simple solution to all this pivot madness. If I just always made the second touch form a very long chipmunk groove joint that went through the first touch. What the heck is a groove joint you say? You can picture it basically as a zipline: there’s two points and between those two points you can slide [a body] back and forth freely, but you must stay on the imaginary line that passes thru those two points and not go past either point. In our case we’re going to form a very long zipline that goes thru and beyond our two touch points (anchored to the shape) and let the second touch zip around anywhere on that line effectively letting the touches get closer to or further from each other but forcing the shape to rotate if the angle between the touch points changes.

This all might be too hard to visualize, so here’s a picture of it in action:

The gray circles are the touch points and the blue line is the groove joint; the two ends of the groove joint go way offscreen ensuring that the touch will never hit them.

I’ll just mention that there is a sticky scenario that you have to consider with this method. If the user lifts their first touch, the original mobile bro’s code would delete the joint associated with that touch. This creates a weird problem where the shape will basically just fall away from you a la’ the zip line (groove joint). So instead, we must always delete the groove joint first, and swap around a few variables so the controller object thinks that you have just one touch again.

Sidebar:

Phew, that rotation problem was stickier than I imagined. On to our next objective: Get the sidebar in better operating condition. So right now there’s just a background with a sidebar thing painted on it. That’s fine for now because I’m not really sure what that will visually entail, but I do know that I will need some sort of object to handle its behavior no matter what.


@interface ShapeSideBar : CCSprite<CCTargetedTouchDelegate>
{
    Game *_game;
    NSMutableArray *_blocks;
}

+(id) shapeSideBarWithGame:(Game*)game;
-(id) initWithGame:(Game*)game;
@end

I start with this as my object, figuring a sprite implementation will probably be the best idea if I want to still leverage the power of batched sprite sheet drawing method and pass the blocks back and forth between the sidebar and the “world” easily. I just make a transparent sprite in the sprite sheet to use for now.

Simple goals first: let’s just write some code to be able to drop shapes onto the sidebar (and have them stick) and be able to drag them off again.

-(void) world2SideBar:(Block*)block
{
    CGPoint pt = ccp(30, 10+[_blocks count]*30);

    [_blocks addObject:block];
    [block runAction:[CCMoveTo actionWithDuration:.4 position:pt]];
    block.sideBarMode = YES;
}

I originally was removing the block from it’s parent and adding it to the sideBar as a child, but for some reason that pauses the block’s actions and doesn’t unfreeze them no matter what I do…. this is a potential cocos2d bug. So instead I just leave it with its original parent for now.

You’re probably wonder what the sideBarMode property is; well I realized a cpCCSprite instance for our blocks wasn’t enough and created a derived class called Block. “sideBarMode” just removes the shape from SpaceManager (not delete), rotates the shape to 0 degrees, and scales the shape to 0.5f. When it’s off it just reverses those effects.

Ok, now to get some touch code to get it back off:

- (BOOL)ccTouchBegan:(UITouch*)touch withEvent:(UIEvent *)event
{
    CGPoint pt = [self convertTouchToNodeSpace:touch];

    for (Block *block in _blocks)
    {
        if (CGRectContainsPoint([block boundingBox], pt))
        {
            [self sideBar2world:block];
            return NO;
        }
    }

    return  NO;
}

Here we do a little bit of trickery that works pretty well. Loop over all the blocks and find the one that the touch is in, get that block out of the sidebar and return NO. Returning NO will let our other touch controller get the touch and since the shape is right under it, it will start dragging it around!

I think we fulfilled all our goals for today, they were a bit painful so let’s outline a fun goal for next time:

  • Draw some more art assets and….
  • Begin animating the blocks with goofy “personalities”

See you next time!

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: