Modeling a Limb


The Commands Panel

CommandsPanel creates the panel at the bottom of the GUI containing the text field and Reset button. Much of the code deals with the parsing of the input from the text field, which takes two forms. A limb command has the following format:

     ( <limbName> | <limbNo> ) (fwd | f | turn | t | side | s) [ angleChg ]

A figure command has this format:

     (fwd | f | back | b | left | l | right | r | up | u | down | d | clock | c | cclock | cc)

Each moveable limb is assigned a name and number, and either one can be used to refer to the limb. As a convenience, the name/number mappings are printed to standard output when Mover3D is started.

The principal difference between the limb and figure commands is that a limb command needs to refer to a particular limb, and a figure command applies to the entire figure. A limb command can include a rotation value (angleChg).

The rotation operations refer to the three axes:


fwd (or f)

Rotation around x-axis


turn (or t)

Rotation around y-axis


side (or s)

Rotation around z-axis

If an angleChg value isn't included, a rotation of +5 degrees will be carried out.


Each limb has a predefined maximum positive and negative rotation, and a rotation command will only move a limb to the prescribed limit.

An advantage of text field input is the ability to group several limb and/or figure commands together, separated by commas. These are processed before the figure is redrawn. By pressing Enter, a complex sequence of commands is repeated. This can be seen in action in the example that started this chapter when several parts of the figure were rotated in unison.

Processing a Command

The string entered in the text field is tokenized in processComms( ), which separates out the individual commands and extracts the two or three argument limb action or single argument figure operation:

     private void processComms(String input)     { if (input == null)         return;       String[] commands = input.split(",");  // split into commands       StringTokenizer toks;       for (int i=0; i < commands.length; i++) {         toks = new StringTokenizer( commands[i].trim( ) );         if (toks.countTokens( ) == 3)         // three-arg limb command           limbCommand( toks.nextToken( ), toks.nextToken( ),                                            toks.nextToken( ) );         else if (toks.countTokens( ) == 2)    // two-arg limb command           limbCommand( toks.nextToken( ), toks.nextToken( ), "5");         else if (toks.countTokens( ) == 1)    // one-arg figure command           figCommand( toks.nextToken( ) );         else           System.out.println("Illegal command: " + commands[i]);       }     }

limbCommand( ) must extract the limb number, the axis of rotation, and the rotation angle from the command string. If a limb name has been entered, then the corresponding number will be obtained by querying the Figure object:

     private void limbCommand(String limbName, String opStr, String angleStr)     { // get the limb number       int limbNo = -1;       try {         limbNo = figure.checkLimbNo( Integer.parseInt(limbName) );       }       catch(NumberFormatException e)       {  limbNo = figure.findLimbNo(limbName);  }   // map name to num       if (limbNo == -1) {         System.out.println("Illegal Limb name/no: " + limbName);         return;       }       // get the angle change       double angleChg = 0;       try {         angleChg = Double.parseDouble(angleStr);       }       catch(NumberFormatException e)       { System.out.println("Illegal angle change: " + angleStr); }       if (angleChg == 0) {         System.out.println("Angle change is 0, so doing nothing");         return;       }       // extract the axis of rotation from the limb operation       int axis;       if (opStr.equals("fwd") || opStr.equals("f"))         axis = X_AXIS;       else if (opStr.equals("turn") || opStr.equals("t"))         axis = Y_AXIS;       else if (opStr.equals("side") || opStr.equals("s"))         axis = Z_AXIS;       else {         System.out.println("Unknown limb operation: " + opStr);         return;       }       // apply the command to the limb       figure.updateLimb(limbNo, axis, angleChg);     }   // end of limbCommand( )

The handling of possible input errors lengthens the code. The limb number is checked via a call to checkLimbNo( ) in Figure, which scans the limbs to determine if the specified number is used by one of them. The mapping of a limb name to a number is carried out by Figure's findLimbNo( ), which returns -1 if the name is not found amongst the limbs. Once the correct input has been gathered, it is passed to updateLimb( ) in the Figure object.

A figure command is processed by figCommand( ), which uses lots of if/else statements to convert the command into a correctly parameterized call to Figure's doMove( ) or doRotateY( ) method:

     private void figCommand(String opStr)     { if (opStr.equals("fwd") || opStr.equals("f"))         figure.doMove(FWD);       else if (opStr.equals("back") || opStr.equals("b"))         figure.doMove(BACK);       else if (opStr.equals("left") || opStr.equals("l"))         figure.doMove(LEFT);       else if (opStr.equals("right") || opStr.equals("r"))         figure.doMove(RIGHT);       else if (opStr.equals("up") || opStr.equals("u"))         figure.doMove(UP);       else if (opStr.equals("down") || opStr.equals("d"))         figure.doMove(DOWN);       else if (opStr.equals("clock") || opStr.equals("c"))         figure.doRotateY(CLOCK);       else if (opStr.equals("cclock") || opStr.equals("cc"))         figure.doRotateY(CCLOCK);       else {         System.out.println("Unknown figure operation: " + opStr);         return;       }     } // end of figCommand( )



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