The Quadrant-Based Alien SpriteAlienQuadSprite is a subclass of AlienSprite and overrides the playerHasMoved( ) and move( ) methods. AlienQuadSprite has the same basic statechart as AlienSprite (shown in Figure 13-15), but the plan move and move states are different. In the plan move state, the alien calculates a quadrant direction (NE, SE, SW, or NW). The direction is chosen by finding the nearest pickup point to the player, and then calculating that pickup's quadrant direction relative to the alien. This gives the alien a "pickup-guarding" behavior, as the alien then moves towards the pickup that the player (probably) wants to collect. Planning a MoveplayerHasMoved( ) calculates a quadrant direction for the sprite: // global private int currentQuad; public void playerHasMoved(Point playerLoc) { if (world.hasPickupsLeft( )) { Point nearPickup = world.nearestPickup(playerLoc); // return coord of nearest pickup to the player currentQuad = calcQuadrant(nearPickup); } } private int calcQuadrant(Point pickupPt) /* Roughly calculate a quadrant by comparing the pickup's point with the alien's position. */ { if ((pickupPt.x > xTile) && (pickupPt.y > yTile)) return SE; else if ((pickupPt.x > xTile) && (pickupPt.y < yTile)) return NE; else if ((pickupPt.x < xTile) && (pickupPt.y > yTile)) return SW; else return NW; } // end of calcQuadrant( ) calcQuadrant( ) could be more complex, but the emphasis is on speed. playerHasMoved( ) and calcQuadrant( ) will be called frequentlywhenever the player movesso there is no need to spend a large amount of time processing a single move. This is an example of the common tradeoff between accuracy and speed. calcQuadrant( ) is called often, so should be fast and doesn't need to be accurate since any errors will be smoothed out by subsequent calls. Also, I don't want to make the alien's behavior too sophisticated or the player will always be caught, which isn't much fun. This kind of deliberately inaccurate algorithm needs to be tested in real gameplay to ensure that it's not too inadequate, and perhaps to see if it can be simplified more. Moving the AlienQuadSpriteThe sprite tries to move in the currentQuad direction. If that direction leads to a no-go tile or a tile holding a block, then the sprite randomly will try another direction. protected void move( ) { int quad = currentQuad; Point newPt; while ((newPt = tryMove(quad)) == null) quad = getRandDirection( ); // the loop could repeat for a while, // but it should eventually find a way setMove(newPt, quad); }
|