In my previous article, I drafted/debugged basic combat behavior in a game prototype. A simple combat system probably needs to account for the following – if only to get animations to sync correctly if character actions are independent.

  • Impact Frame – unless you have fine grained collision detection, the impact frame determines when the opponent actually gets hit.
    I am adding per action impact frames – each action can define it’s own frame/time offset. I’ll probably use a time offset instead later, but that will be part of a general effort on my part to move from frame based to time based modelling.
  • Passive reaction – When an actor gets hit, they cannot enforce their decisions.
  • Impact condition. A simple model can take into account the orientation relative to, and distance from, the target. My model already has this but that seems a little buggy.

Writing a class to hold impact frames is nothing, although you might legitimately want to store your impact frame information anywhere else:

#import “ImpactFrames.h”

#import “Definitions.h” // used for the ‘act’ typedef which is just a NSString*

@implementation ImpactFrames

static NSMutableDictionary* map;

+(void)putFrameOffset:(int)frameOffset forAction:(act)action{

if (map==nil)map=[[NSMutableDictionary alloc]init];

[map setObject:[NSNumber numberWithInt:frameOffset] forKey:action];

}

+(int)getFrameOffset:(act)forAction{

return [((NSNumber*)[map objectForKey:forAction]) intValue];

}

+(void)clear{

[map release];

map=nil;

}

@end

Passive reactions can be implemented using three tags: action, affect and activity

  • Activity represents the current action.
  • Affect represents a passive reaction to an external action
  • Action represents the actor’s decision.

Then each evaluation can be structured as follows:

  1. If an affect is defined, override action with affect
  2. If the current activity matches the current action, continue.
    1. If we have not reached the last frame for this action, continue to the next frame.
    2. If we have reached the last frame, clear the affect and action labels.
  3. If the current activity is the ‘rip state’ return immediately.
  4. If the current action is different from the current activity, initialize this action.

I had to patch my actions a little because I manage motion and activity independently, so I need to replicate some of the logic.