The Ball Sprite


Specifying a Sprite with a Statechart

A sprite is a reactive object: it responds dynamically to events, changing its state and modifying its behavior. For all but the simplest example, specify the sprite's behavior before becoming entangled in writing code. The UML statechart is an excellent tool for defining a sprite, and there are even utilities for automatically generating Java code from statecharts.

The rest of this section gives a brief introduction to statecharts and explains how they can be translated to Java. However, this isn't a book about UML, so I refer the interested reader to UML Distilled (Addison-Wesley Professional) by Martin Fowler. For a UML text with a Java slant, check out UML for Java Programmers (Prentice Hall) by Robert C. Martin (http://www.objectmentor.com). Martin's web site offers SMC, a translator that takes textual statechart information and generates Java (or C++) code.

A simple statechart for a subway turnstile is shown in Figure 11-4. (This example comes from a tutorial by Robert C. Martin.)

Figure 11-4. A subway turnstile statechart


The states are inside rounded rectangles; the transitions (arrows) indicate how the system responds to events. The syntax for a transition is:

     event [ condition ] / action

An event arrives when the system is in a given state, causing the associated transition to be executed. First, the condition is evaluated if one is present. If the result is TRue, the associated action is carried out and the system follows the transition to a new state. The solid black circle points to the starting state for the system.

The statechart in Figure 11-4 specifies what happens when a pass or coin event occurs in the locked or unlocked states for a turnstile. A coin event corresponds to a customer placing a coin in the turnstile; a pass event is generated when the turnstile rotates to allow the customer to pass through.

Statecharts can be more sophisticated than this example. For instance, they can represent activities carried out when a state is entered and exited, states can be nested to form hierarchies, states can be grouped together to model concurrent actions, and there is a history mechanism.

Translating a Statechart to Code

There are various approaches for translating a statechart into executable code. One of the simplest is to convert the graphical notation into table form, called a State Transition Table (STT). Table 11-1 shows the STT for the turnstile statechart.

Table 11-1. Turnstile STT

Current state

Event

Action

New state

Locked

Coin

Unlock

Unlocked

Locked

Pass

Alarm

Locked

Unlocked

Coin

Thanks

Unlocked

Unlocked

Pass

Lock

Locked


An imperative-style translation of the table converts it to a series of if statements (see makeTransition( ) in Example 11-1).

Example 11-1. Turnstile STT as code
     public class TurnStile     {       // state constants       private static final int LOCKED = 0;       private static final int UNLOCKED = 1;       // event constants       private static final int COIN = 2;       private static final int PASS = 3;       public static void main(String args[])       {         int currentState = LOCKED;         int event;         while (true) {           event = /* get the next event */;           currentState = makeTransition(currentState, event);         }       } // end of main( )       private static int makeTransition(int state, int event)       // a translation of Table 1       {         if ((state == LOCKED) && (event == COIN)) {           unlock( );           return UNLOCKED;         }         else if ((state == LOCKED) && (event == PASS)) {           alarm( );           return LOCKED;         }         else if ((state == UNLOCKED) && (event == COIN)) {           thanks( );           return UNLOCKED;         }         else if ((state == UNLOCKED) && (event == PASS)) {           lock( );           return LOCKED;         }         else {           System.out.println("Unknown state event");           System.exit(0);         }       }  // end of makeTransition( )       // methods for the actions: unlock, alarm, thanks, lock     } // end of Turnstile class

The translation strategy is to represent states and events as integers and transition actions as method calls. If a transition has a condition, it will be added to the if-test for that transition. The drawback of this approach is the generation of long sequences of if tests, often with multiple conditions. Fortunately, the code can often be rewritten to make it easier to understand, e.g., makeTransition( ) could be divided into several smaller methods.

As states become more complex (e.g., hierarchical, with internal activities), it's more natural to map a state to a class and a transition to a method. The SMC translator takes this approach (http://www.objectmentor.com/resources/downloads/).

A third coding solution is to employ a set of existing statechart classes (e.g., State, transition), subclassing them for the particular application. Excellent examples of this approach can be found in Practical Statecharts in C/C++ (CMP Books) by Miro Samek (http://www.quantum-leaps.com). As the book's title suggests, its emphasis is on C and C++, but the author's web site contains a Java version of the software, which requires a password generated from the book.



Killer Game Programming in Java
Killer Game Programming in Java
ISBN: 0596007302
EAN: 2147483647
Year: 2006
Pages: 340

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net