The Animation FrameworkAlienTilesPanel is similar to JackPanel in Chapter 12; it uses an active rendering animation loop driven by Java 3D's timer. It displays an introductory image when the game starts, which doubles as a help screen during the course of play. While the help screen is being shown, the game pauses. Managing the Game WorldAlienTilesPanel creates the various game elements in createWorld( ): // globals game entities private WorldDisplay world; private PlayerSprite player; private AlienSprite aliens[]; private void createWorld(ImagesLoader imsLoader) // create the world display, the player, and aliens { world = new WorldDisplay(imsLoader, this); player = new PlayerSprite(7,12, PWIDTH, PHEIGHT, clipsLoader, imsLoader, world, this); // sprite starts on tile (7,12) aliens = new AlienSprite[4]; aliens[0] = new AlienAStarSprite(10, 11, PWIDTH, PHEIGHT, imsLoader, world); aliens[1] = new AlienQuadSprite(6, 21, PWIDTH, PHEIGHT, imsLoader, world); aliens[2] = new AlienQuadSprite(14, 20, PWIDTH, PHEIGHT, imsLoader, world); aliens[3] = new AlienAStarSprite(34, 34, PWIDTH, PHEIGHT, imsLoader, world); // use 2 AStar and 2 quad alien sprites // the 4th alien is placed at an illegal tile location (34,34) world.addSprites(player, aliens); // tell the world about the sprites } // end of createWorld( ) Tile coordinates are passed to the sprites, rather than pixel locations in the JPanel. The two A* and two quad sprites are stored in an aliens[] array to make it easier to send messages to all of them as a group. The player and aliens do not communicate directly; instead, they call methods in the WorldDisplay object, world, which passes the messages on. This requires that sprite references be passed to world via a call to addSprites( ). Dealing with InputThe game is controlled from the keyboard only; no mouse events are caught. As in previous applications, the key presses are handled by processKey( ), which deals with termination keys (e.g., Ctrl-C), toggling the help screen, and player controls. The code related to the player keys is: private void processKey(KeyEvent e) // handles termination, help, and game-play keys { int keyCode = e.getKeyCode( ); // processing of termination and help keys ... // game-play keys if (!isPaused && !gameOver) { // move the player based on the numpad key pressed if (keyCode == KeyEvent.VK_NUMPAD7) player.move(TiledSprite.NW); // move north west else if (keyCode == KeyEvent.VK_NUMPAD9) player.move(TiledSprite.NE); // north east else if (keyCode == KeyEvent.VK_NUMPAD3) player.move(TiledSprite.SE); // south east else if (keyCode == KeyEvent.VK_NUMPAD1) player.move(TiledSprite.SW); // south west else if (keyCode == KeyEvent.VK_NUMPAD5) player.standStill( ); // stand still else if (keyCode == KeyEvent.VK_NUMPAD2) player.tryPickup( ); // try to pick up from this tile } } // end of processKey( ) Three PlayerSprite methods are called: move( ), standStill( ), and TRyPickup( ). These correspond to the three things a sprite can do: move to another tile, stand still, and pick up something. The "standing still" action is fairly trivial: it only changes the sprite's image. The Animation LoopThe animation loop is located in run( ) and unchanged from earlier examples: public void run( ) { // initialization code while (running) { gameUpdate( ); gameRender( ); paintScreen( ); // timing correction code } System.exit(0); } gameUpdate( ) updates the changing game entities (the four mobile aliens): private void gameUpdate( ) { if (!isPaused && !gameOver) { for(int i=0; i < aliens.length; i++) aliens[i].update( ); } } gameRender( ) relies on the WorldDisplay object to draw the surface and its contents: private void gameRender( ) { // create the dbg graphics context // a light blue background dbg.setColor(lightBlue); dbg.fillRect(0, 0, PWIDTH, PHEIGHT); // draw the game elements: order is important world.draw(dbg); /* WorldDisplay draws the game world: the tile floor, blocks, pickups, and the sprites. */ reportStats(dbg); // report time spent playing, number of hits, pickups left if (gameOver) gameOverMessage(dbg); if (showHelp) // draw the help at the very front (if switched on) dbg.drawImage(helpIm, (PWIDTH-helpIm.getWidth( ))/2, (PHEIGHT-helpIm.getHeight( ))/2, null); } // end of gameRender( ) Ending the GameThe game finishes (gameOver is set to true) when the player has been hit enough times or when all the pickups (a cup, flower pot, and watch) have been gathered. The first condition is detected by the PlayerSprite object and the second by the WorldDisplay object; both of them call gameOver( ) to notify AlienTilesPanel when the game should be stopped: public void gameOver( ) { if (!gameOver) { gameOver = true; score = (int) ((J3DTimer.getValue( ) - gameStartTime)/1000000000L); clipsLoader.play("applause", false); } } |