RiverMan Media

RiverMan Media 1

Newsletter

Keep up with info on our latest games, articles, and other projects. You can unsubscribe at any time.

Subscribe

XML RSS 2.0 RSS 2.0 

Object Oriented Game Programming: The Behavior System
Object Oriented Game Programming: The Behavior System - Behavior case studies
Written by Paul Stevens   
Thursday, 01 May 2008 07:04
Article Index
Object Oriented Game Programming: The Behavior System
Implementation
Behavior case studies
All Pages

 Behaviors in Action


Here is a very simplified example of Monkeys use behaviors to perform a few tasks.

public class Monkey extends GameObject implements ActionListener
{
  // NOTE: extending GameObject gives Monkeys a bunch of generic
  // methods like getX(), getY(), setImage(), etc, and implements
  // simple related interfaces, like Moves, Draws, etc.

  private AnimationBehavior walk;
  private AnimationBehavior jump;
  private MotionBehavior motion;
  private ClickBehavior clickMe;


  private int state = 0; 
 
  // states
  private static final int  
    FOLLOWING = 0,  // following the character
    CLIMING = 1,    // climbing a vine
    FALLING = 2;    //
free-falling or rising after a throw

  public Monkey()
  {
    // The monkey is both the parent and the listener.
    walk = AnimationBehavior(this, 5, Graphics.monkeyWalkImgs, this);
    walk.setActive(true);

    jump = AnimationBehavior(this, 5, Graphics.monkeyJumpImgs, this);
    jump.setActive(false);   

    // This behavior operates the motion of the monkey while it's
    // in the air.

    motion = MotionBehavior(this);
    motion.setActive(false);

    // Reports when the monkey is clicked.
    // Parameters: (parent, listener).
    clickMe = ClickBehavior(this, this)
    clickMe.active = true;
  }

  public void update()
  {
    // Only the behaviors that are active will actually update.
    // Of course, you could do a switch on the monkey state and 
    // pick the ones you want to update that way.    
    walk.update();
    jump.update();
    motion.update();
    clickMe.uopdate();

    if (state == FALLING && groundCollision() == true)
    {
      state = FOLLOWING;
      motion.setActive(false);
      walk.reset();
    }
  }

  public void throwMe()
  {
    state = FALLING;
    motion.setActive(true);
    motion.setYVel(-15);  // propell the monkey upward
    motion.setYAccel(GRAVITY_CONSTANT);  // apply gravity

    jump.reset();
  }

  // Reset the walk animation here.
  // You could also build a repeating option into the behavior
  // itself.
  public void eventCallback(ActionEvent caller)
  {
    if (caller == walk)
    {
      walk.reset();
    }
    else if (caller == clickMe)
    {
      GameSounds.playMonkeyYell();
    }
  }
}

What we've got so far is just a fraction of what monkeys need to do.  But let's take a look at all that we've accomplished already, with a very small number of statements:

  • The monkey plays its whole jump animation automatically when it's thrown, and stops it when the animation is over.
  • The monkey plays its walk animation while it's walking, and repeats the animation by listening to its callback.
  • MotionBehavior provides upward velocity to the monkey when it's thrown, and automatically applies gravity to the monkey while it's in the air.
  • The monkey will start walking again once it lands on the ground and engage its walking animation.
  • ClickBehavior automatically detects when the monkey is clicked, and the monkey makes a sound.  Okay, this isn't actually in the game, but I wanted to show you how easy it is to make any object into a widget.

 

The behaviors have kept this Monkey class short, organized, bug-resistant, flexible, and simple to code.  The behavior system standardizes the interface to all of this additional functionality so that you don't have to think about it once you've coded it the first time.

Behaviors Vs. Robot Functions

Robot Functions and Behaviors are similar in that they extend the capabilities of a parent object.  They also both make a callback to a listener when they finish their task.  Here are the key differences between the two:

  1. Robot Functions only have a access to one variable of the parent.  Behaviors may have access to all of the parent's variables and methods.
  2. Robot Functions always have a pre-determined end, but not all behaviors do.
  3. Robot Functions just define a special curve for altering a value, whereas Behaviors can do much more with their input.
  4. A Behavior may contain Robot Functions to complete its work, but Robot Functions would never contain Behaviors.

 

When all you need to do is operate on specific variables over time (such as scale, alpha, position, etc.) use Robot Functions.  When you want more complex capabilities or need to coordinate several Robot Functions, use Behaviors.

---

Behaviors by themselves have been a huge asset to my game programming, but I've only shown you HALF of the power of behaviors.  The other half comes when they are used in the context of the Scripted Event System.  If you like the concept behind Behaviors and Robot Functions, you'll really want to check out that article to truly see them in action.

Want to read more?  Here's a link to the first ever discussion of Behaviors at Gamedev.net:
http://www.gamedev.net/community/forums/topic.asp?topic_id=492938&PageSize=25&WhichPage=1

Newsletter

Was this article helpful to you? Subscribe to our newsletter to keep up with our latest games, articles, and other projects. You can unsubscribe at any time.




 
Comments (2)
Just a thought
1 Sunday, 25 July 2010 18:43
You could have the AnimationBehavior be a listener, besides an event (inherited from behavior, though how is an Action event different from an Event?). I thought, when the motion behavior for jump starts, it could fire off an event indicating it started, so the animation could start playing. Having the motion automatically synced with the animation seemed like a good idea, though I'm still trying to think of the possibilities and if this is good idea or not.

Anyway, love this post, great ideas!
RE: Just a thought
2 Wednesday, 28 July 2010 00:11
RiverMan_Paul
Thanks for writing! I'm glad you enjoyed the article.

When I think of an Event, I think of any object whose purpose is to represent something that "just happened", and exists to inform an interested listener. An example would be a MouseEvent--when the mouse moves, the system would create a MouseEvent object than describes where the mouse moved to, and may contain other information (such as where it moved from, the current status of the mouse buttons, etc.).

ActionEvents use the same general idea in the context of Behaviors. When the Behavior (which IS an ActionEvent) is finished running, it informs its listener, and passes itself to the listener in the process. Code-wise, the fundamental reason that Behaviors, RobotFunctions, and Effects are all ActionEvents (meaning they implement the ActionEvent interface) is so that ActionLists and ActionQueues can contain ActionEvents as a single type. An ActionList, for example, is really a collection of RobotFunctions, Behaviors, and Effects, but as far as it knows, they are all just ActionEvents. For a full explanation of this ActionEvent idea, check out the Scripted Event System article (http://rivermanmedia.com/programming/28-object-oriented-game-programming-the-scripted-event-system).

I think you are on the right track with the idea to have an AnimationBehavior also be a listener so that it can sync itself up with other aspects of the animation (such as motion). What I might recommend for this case would be to subclass AnimationBevahior and add that idea in (e.g., JumpAnimation extends AnimationBehavior and also implements ActionListener). This way you can use the AnimationBehavior as-is, but also have a special version that's specific to jumping.

Very cool idea!

Add your comment

Your name:
Your website:
Subject:
Comment: