The Quadrant-Based Alien Sprite


The Alien Sprite

AlienSprite implements the basic behavior of an alien sprite and is subclassed to create the AlienAStarSprite and AlienQuadSprite classes. AlienSprite is a subclass of TiledSprite.

Alien behavior can best be understood by considering the statechart in Figure 13-15.

The plan move state is entered by the WorldDisplay object, notifying the alien that the player has moved. This gives it the opportunity to recalculate its current direction or destination, but the precise algorithm will vary from one AlienSprite subclass to another.

The other activity is the usual update/draw cycle driven by the animation loop in AlienTilesPanel. The alien tries to hit the player while in the attack state. A successful hit is reported to the WorldDisplay object, and the alien stays where it is. Otherwise, the alien updates its position, in the hope of getting closer to the player. In the draw state, the sprite's tile coordinates are mapped to a pixel location and the sprite's image is rendered.

Figure 13-15. Alien statechart


Responding to a player's movement is sprite-specific, so playerHasMoved( ) is empty in AlienSprite:

     public void playerHasMoved(Point playerLoc)     { }

PlayerLoc contains the current tile coordinates for the PlayerSprite object.

Updating the AlienSprite

The attack, stationary, and move states are encapsulated in update( ):

     // globals     private final static int UPDATE_FREQ = 30;     private int updateCounter = 0;     public void update( )     {       updateCounter = (updateCounter+1)%UPDATE_FREQ;       if (updateCounter == 0) {   // reduced update frequency         if (!hitPlayer( ))           move( );       }     }

update( ) is called from AlienTilesPanel's animation loop, which executes at 40 FPS. This makes the aliens respond too quickly. The solution is to use a counter to reduce the update frequency.

This issue only became apparent when the game was first tested without the alien movement being slowed down. At 40 FPS, the aliens always caught the user's sprite quickly, even when the user kept the move keys constantly pressed.

The A* pathfinding algorithm in AlienAStarSprite becomes deadly accurate when it's recalculated so frequently. There's no way to avoid capture, even if the user randomly changes direction at frequent intervals.


hitPlayer( ) checks if the alien is on the same tile as the player. If it is, then the WorldDisplay object will be informed of a hit:

     private boolean hitPlayer( )     {       Point playerLoc = world.getPlayerLoc( );       if (playerLoc.equals( getTileLoc( ) )) {         world.hitByAlien( );  // whack!         return true;       }       return false;     }

The details of the move state will vary from one alien to another, which translates to the alien subclasses overriding the move( ) method.

AlienSprite's move( ) carries out a random walk. getrandDirection( ) (a method inherited from TiledSprite) returns a quadrant, and this is tried out with TiledSprite's tryMove( ) method:

     protected void move( )     {       int quad = getRandDirection( );       Point newPt;       while ((newPt = tryMove(quad)) == null)         quad = getRandDirection( );         // the loop could repeat for a while,         // but it should eventually find a direction       setMove(newPt, quad);     }

The new tile coordinate is use to update the sprite's position in setMove( ):

     protected void setMove(Point newPt, int quad)     {       if (world.validTileLoc(newPt.x, newPt.y)) {   // should be ok         setTileLoc(newPt);         if ((quad == NE) || (quad == SE))           setImage("baddieRight");         else if ((quad == SW) || (quad == NW))           setImage("baddieLeft");         else           System.out.println("Unknown alien quadrant: " + quad);       }       else         System.out.println("Cannot move alien to (" + newPt.x +                                                ", " + newPt.y + ")");     }  // end of doMove( )

setMove( ) double-checks the validity of the new tile and changes the sprite's appearance. The method is protected since only subclasses of AlienSprite will use it (as part of the subclasses' versions of move( )).

update( ) handles the attack, stationary, and move states of the alien statechart. This leads to the question: Where is the draw state processed? As with the PlayerSprite class, this task is part of the drawing operation carried out by WorldDisplay through its WorldItems object.



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