Black Art of Java Game Programmingby Joel Fan Sams, Macmillan Computer Publishing ISBN: 1571690433 Pub Date: 11/01/96 Previous Table of Contents Next The UFOManager Class The UFOManage
Trang 1// fire missile from given x coordinate
public void fireMissile(int x) {
if (!missile.isActive()) { // if missile sprite
// update all the parameters associated with the
// gun In this case, only the missile needs to move
// automatically Also the gun manager checks if the
// missile hits anything
public void update() {
missile.update();
}
// paint all sprites associated with gun
public void paint(Graphics g) {
gun.paint(g);
missile.paint(g);
}
// accessor function for gun
public GunSprite getGun() {
Trang 2Previous Table of Contents Next
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/171-177.html (6 von 6) [13.03.2002 13:18:10]
Trang 3Black Art of Java Game Programming
by Joel Fan
Sams, Macmillan Computer Publishing
ISBN: 1571690433 Pub Date: 11/01/96
Previous Table of Contents Next
Notice that the missile is fired by calling its init() method This is much faster than creating a new
MissileSprite object for each mouse click, and it illustrates another general rule when writing games:
Avoid dynamic allocation of objects during game play Try to allocate all the objects you will use at
the very beginning, if possible, so the runtime system doesn’t need to construct one when the game is running
Now, let’s create the aliens!
Defining the UFOManager
The UFOManager is responsible for initializing the individual UFO sprites, and telling them when to
paint and update Let’s create the UFO class first, before defining UFOManager.
The UFO Class
The UFO class will animate the sequence of bitmaps shown in Figure 5-2, so it becomes a subclass derived from the BitmapLoop sprite, which we introduced in Chapter 4, Adding Interactivity
The BitmapLoop Sprite Class
Listing 5-10 shows the current definition of BitmapLoop
Listing 5-10 BitmapLoop class
class BitmapLoop extends BitmapSprite implements Moveable{
protected Image images[]; // sequence of bitmaps
protected int currentImage; // the current bitmap
protected boolean foreground; // are there foreground images? protected boolean background; // is there background image?
// constructor Assumes that background image is already
// loaded (use MediaTracker)
public BitmapLoop(int x,int y,Image b,Image f[],Applet a) {
super(x,y,b,a);
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/177-179.html (1 von 4) [13.03.2002 13:18:10]
Trang 4if (image != null) { // if there's a background image background = true;
if (images == null || images.length == 0) {
foreground = false; // nothing in images[]
// cycle currentImage if sprite is active, and there
// are foreground images
public void update() {
if (active && foreground) {
currentImage = (currentImage + 1) % images.length;
// implement moveable interface
public void setPosition(int x,int y) {
locx = x;
locy = y;
}
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/177-179.html (2 von 4) [13.03.2002 13:18:10]
Trang 5protected int vx;
protected int vy;
public void setVelocity(int x,int y) {
vx = x;
vy = y;
}
// update position according to velocity
public void updatePosition() {
2, Using Objects for Animation; the UFO machine is just a bit more complex By using state
machines, you create a simple kind of machine intelligence in your enemies
The Four UFO Behavioral States
The UFO has four behaviors, each represented by one of the following states :
• Standby When the UFO is in Standby mode, it moves back and forth horizontally
• Attack An attacking UFO moves quickly downward, toward the missile launcher, and it is
invulnerable to your missiles
• Retreat The UFO can break off the attack at any moment, and retreat, which means that it
moves up, toward the top of the screen
• Land Finally, the alien can try to land, and to do this it descends vertically at a slow rate
Figure 5-13 illustrates these various UFO behaviors
Figure 5-13 UFO behaviors
Now let’s describe how the UFO can make transitions from state to state
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/177-179.html (3 von 4) [13.03.2002 13:18:10]
Trang 6Previous Table of Contents Next
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/177-179.html (4 von 4) [13.03.2002 13:18:10]
Trang 7Black Art of Java Game Programming
by Joel Fan
Sams, Macmillan Computer Publishing
ISBN: 1571690433 Pub Date: 11/01/96
Previous Table of Contents Next
Transitioning Between States
The best way to illustrate how the UFO goes from one state, or behavior, to another is with a
transition diagram, in which the circles represent the four possible states, and the arrows indicate allowable transitions, as shown in Figure 5-14
Figure 5-14 UFO transition diagram
Now, the UFO moves from state to state depending on random numbers generated by the static
random() method in java.lang.Math:
double x = Math.random(); // x is assigned a random
// double from 0.0 to 1.0
If the random number is higher than these following constants, the UFO exits the corresponding state:
// probability of state transitions
static final double STANDBY_EXIT = 95;
static final double ATTACK_EXIT = 95;
static final double RETREAT_EXIT = 95;
static final double LAND_EXIT = 95;
Thus, the pattern of UFO behavior is unpredictable, and you can customize it by changing the
probabilities
The UFO’s update() method first checks to see if a collision has occurred with the missile gun
GunSprite implements Intersect, so it can be a target of the UFO sprite:
// this implements the state machine
public void update() {
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/179-185.html (1 von 6) [13.03.2002 13:18:11]
Trang 8// if alien hits target
// gun_y contains the y-coordinate of the top of
// the gun The first test is done to quickly
// eliminate those cases with no chance of
// intersection with the gun
if ((locy + height >= gun_y) &&
Depending on the random numbers, the UFO can go to the Attack state or the Land state The
methods startAttack() and startLand() set the UFO’s velocity for those states
If a state transition doesn’t occur, the UFO continues with the Standby update, which reverses the UFO’s direction if it strays too close to the edges of the screen, or if the random number is above a threshold:
else if ((locx < width) || (locx > max_x - width) ||
(r2 > FLIP_X)) {
vx = -vx;
}
break;
Implementing the UFO Sprite Class
Now take a look, in Listing 5-11, at the complete UFO sprite class, and the update() method in
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/179-185.html (2 von 6) [13.03.2002 13:18:11]
Trang 9particular
Listing 5-11 UFO class
public class UFO extends BitmapLoop implements Intersect {
byte state;
// UFO states
static final byte STANDBY = 0;
static final byte ATTACK = 1;
static final byte RETREAT = 2;
static final byte LAND = 3;
// probability of state transitions
static final double STANDBY_EXIT = 95;
static final double ATTACK_EXIT = 95;
static final double RETREAT_EXIT = 95;
static final double LAND_EXIT = 95;
static final double FLIP_X = 0.9;
static final int RETREAT_Y = 17;
int max_x, max_y; // max coords of this UFO static Intersect target; // refers to the gun
static int gun_y; // the y-coord of gun
public UFO(Image ufoImages[],int max_x,int max_y,
// finish initializing info about the player's gun
static public void initialize(GunManager gm) {
target = gm.getGun(); // refers to gun sprite
gun_y = gm.getGunY(); // get gun y-coordinate
}
// implement Intersect interface:
public boolean intersect(int x1,int y1,int x2,int y2) {
return visible && (x2 >= locx) && (locx+width >= x1)
&& (y2 >= locy) && (locy+height >= y1);
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/179-185.html (3 von 6) [13.03.2002 13:18:11]
Trang 10}
public void hit() {
// alien is invulnerable when it's attacking
// otherwise, suspend the sprite
if (state != ATTACK) {
suspend();
}
}
// this implements the state machine
public void update() {
// if alien hits target
if ((locy + height >= gun_y) &&
// otherwise, update alien state
double r1 = Math.random(); // pick random nums
// else change the direction by flipping
// the x-velocity Net result: ufo moves
// from side to side And if the ufo gets close to
// the left or right side of screen, it always changes // direction
else if ((locx < width) || (locx > max_x - width) ||
(r2 > FLIP_X)) {
vx = -vx;
}
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/179-185.html (4 von 6) [13.03.2002 13:18:11]
Trang 11// flip x-direction if it gets too close to edges
else if ((locx < width) || (locx > max_x - width) ||
// if the ufo is low enough,
// start the landing procedure
else if (locy >= max_y-height) {
Trang 12protected void landingRoutine() {
static public int getRand(int x) {
return (int)(x * Math.random());
}
}
The UFO class is the most complex of this entire chapter, and you can use it as a template for enemies
in your own games
Now let’s discuss the UFOManager class
Previous Table of Contents Next
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/179-185.html (6 von 6) [13.03.2002 13:18:11]
Trang 13Black Art of Java Game Programming
by Joel Fan
Sams, Macmillan Computer Publishing
ISBN: 1571690433 Pub Date: 11/01/96
Previous Table of Contents Next
The UFOManager Class
The UFOManager’s constructor allocates the UFO sprites that will be used during the course of the game, circumventing the need for dynamic allocation during game play In addition, the UFOManager sets the initial position of the UFOs, and tells them when to update and paint If a UFO sprite is hit by
a missile, it becomes inactive, so it disappears from the screen
For this simulation, the UFOManager’s update() method simply restores the sprite at a different
location, making it appear as if a new UFO has entered the fray, but keeping the number of aliens constant In the next chapter, you will learn how to create a UFOManager that will increase the
number of active UFOs as the game progresses, making it harder to play! Listing 5-12 defines the UFOManager class
Listing 5-12 UFOManager class
public class UFOManager {
static int width, height; // applet dimensions
private UFO ufo[];
static final int NUM_UFOS = 7;
public UFOManager(int width,int height,
Image ufoImages[],Applet a) {
this.width = width;
this.height = height;
ufo = new UFO[NUM_UFOS];
for (int i=0; i<ufo.length; i++) {
ufo[i] = new UFO(ufoImages,width,height,a);
initializePosition(ufo[i]);
}
}
// This method tells the UFO class where
// the gun is (so the UFOs know if they’ve
// collided with it)
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/185-188.html (1 von 4) [13.03.2002 13:18:12]
Trang 14public void initialize(GunManager gm) {
// accessor method, so the missile knows where
// the targets are!
public UFO[] getUFO() {
return ufo;
}
public void paint(Graphics g) {
for (int i=0; i<ufo.length; i++) {
ufo[i].paint(g);
}
}
public void update() {
for (int i=0; i<ufo.length; i++) {
Defining the GameManager
The GameManager, the final building block of this chapter, has the following responsibilities, as noted earlier:
• Initializes the GunManager and UFOManager
• Relays player input to the GunManager (event handling)
• Implements the Video Game Loop
As with the animation driver you used at the end of Chapter 4, Adding Interactivity, it uses
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/185-188.html (2 von 4) [13.03.2002 13:18:12]
Trang 15MediaTracker to load the images
Two Responsibilities of the GameManager Class
Let’s examine two responsibilities of this class
Passing Mouse Input to the GunManager
First, here’s the way the GameManager passes mouse input to the GunManager:
public boolean mouseMove(Event e,int x,int y) {
Implementing the Video Game Loop
Next, let’s look at how the GameManager implements the Video Game Loop:
public void run() {
Trang 16Previous Table of Contents Next
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/185-188.html (4 von 4) [13.03.2002 13:18:12]
Trang 17Black Art of Java Game Programming
by Joel Fan
Sams, Macmillan Computer Publishing
ISBN: 1571690433 Pub Date: 11/01/96
Previous Table of Contents Next
Implementing the GameManager Class
Finally, the definition of the GameManager is shown in Listing 5-13 Compile it along with the other classes defined in this chapter, and run the Alien Landing simulation!
Listing 5-13 GameManager class
public class GameManager extends Applet implements Runnable {
Thread animation;
Graphics offscreen;
Image image;
static final int REFRESH_RATE = 80; // in ms
Image ufoImages[] = new Image[6]; // 6 ufo Images
Image gunImage; // gun image
GunManager gm;
UFOManager um;
int width, height; // applet dimensions
public void init() {
showStatus("Loading Images WAIT!");
setBackground(Color.black); // applet background
width = bounds().width; // set applet dimensions
Trang 18}
public void loadImages() {
MediaTracker t = new MediaTracker(this);
Trang 19// override update so it doesn't erase screen
public void update(Graphics g) {
Trang 20Recommended Applet Tag to Run the Alien Landing Game
<applet code=“GameManager.class” width=240 height=300>
Suggestion Box
• Right now, the missile launcher fires only one missile at a time Give it the ability to fire
multiple missiles by defining a MissileSprite array in the GunManager class You’ll also want
to modify the update() and paint() methods so they communicate to all members of this array
• The UFO animation stays the same, regardless of its behavior How would you modify the
UFO class so that the animation loop is different for the attacking state? (We’ll cover the answer to this in the next chapter.)
• Define another UFO class that has the ability to fire back You have all the building blocks,
such as the Intersect interface and the MissileSprite class, to do this easily
• Add sound to the game simulation You know how to do this already, and it’s really easy
Perhaps you can add a sound when collisions occur, and another sound if an alien lands
successfully
• Draw a background image You might want to use a bitmap of a city, in keeping with the
theme of the game
Summary
There’s a lot of code in this chapter, but it is structured into units that have specific responsibilities and consistent behavior This way, your program is understandable and extensible, which cuts down
on the number of bugs, and the amount of time you will need to write a complex game
In the next chapter, we’ll extend the GameManger unit so it also handles the initial and closing
sequences of Alien Landing, and keeps track of the score We’ll also modify the UFOManager so the difficulty level increases as time goes on By the end, you’ll have a real video game!
Previous Table of Contents Next
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/188-192.html (4 von 4) [13.03.2002 13:18:12]
Trang 21Black Art of Java Game Programming
by Joel Fan
Sams, Macmillan Computer Publishing
ISBN: 1571690433 Pub Date: 11/01/96
Previous Table of Contents Next
Chapter 6
Extending Your Video Game
Joel Fan
Goals:
Add features to the Alien Landing simulation using incremental development
Complete the Alien Landing video game
In this chapter, you’ll extend the Alien Landing simulation of the previous chapter into a complete video game, by adding explosions, a status display, levels of play, scoring, and other features In addition, you’ll create an introductory screen, so that new players understand how to play your game, and a closing sequence, so that they know when the game is over
There are two types of extensions you will implement on top of the existing Alien Landing
simulation:
• Extensions that primarily involve a single class
• Extensions that require messaging between classes
For example, explosions will be handled within the UFO class, once the bitmaps are loaded and
passed in On the other hand, scoring will require communication between the UFO and the
GameManager, and when the UFO sprite is hit, it sends a message to GameManager to update the player’s point total
By developing and testing these extensions one at a time, you can build on the game simulation with a
minimum of errors This process is called incremental development, and it can cut down on the
amount of time you spend tracking down nasty bugs! As you progress through this chapter, feel free
to implement and test each extension individually, so you really understand how the pieces fit
together
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/193-199.html (1 von 5) [13.03.2002 13:18:13]
Trang 22Let’s get started First, let’s extend the UFO class so the animation loop changes, depending on the state of the alien.
Changing the UFO Animations
When the alien gets shot by a missile, it should explode in a ball of fire But if the alien is in attack mode, it is invulnerable to the player’s missiles Let’s see how to signify these alien states—exploding and attacking—by changing the animation loop in the UFO class The UFOManager and
GameManager must also be modified to provide the initializations needed
Extending the UFO Class
Figures 6-1A and 6-1B show the sequence of bitmaps that animate attacking and exploding aliens
Figure 6-1A Attacking aliens
Figure 6-1B Exploding aliens
Remember that the UFO class extends the BitmapLoop class, and that it inherits BitmapLoop’s paint() method:
public void paint(Graphics g) {
The images variable refers to the array of bitmaps that comprise the animation Right now, images
refers to the UFO animation, but if we store references to the exploding, attacking, and UFO
sequences, we can switch animations by assigning images the correct image array Thus, the first
change is in the constructor to the UFO class, which now refers to the various animation sequences in
the variables ufo, attack, and explode.
// bitmap animations
protected Image ufo[]; // ufo animation
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/193-199.html (2 von 5) [13.03.2002 13:18:13]
Trang 23protected Image attack[]; // attack animation
protected Image explode[]; // explosion sequence
// constructor: initialize image references, instance vars
public UFO(Image ufoImages[],
Now images will be assigned the appropriate animation sequence, depending on the alien state As
Figure 6-2 shows, the change in the animation loop occurs only when the alien starts or exits the Attack state Thus, only the methods that implement state transitions to and from the Attack state are modified These are the UFO methods startAttack() and startRetreat():
Figure 6-2 UFO transition diagram
// start attack state
protected void startAttack() {
// start retreating state
protected void startRetreat() {
In addition, let’s add a new state, Explode, which signifies an exploding alien, and a method,
startExplode(), which causes a transition to this state:
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/193-199.html (3 von 5) [13.03.2002 13:18:13]
Trang 24static final byte EXPLODE = 4;
// start explosion state
protected void startExplode() {
images = explode; // set bitmap to explosion sequence
currentImage = 0; // start at beginning of animation
explosion_counter = 0; // count the number of frames
um.playExplosion(); // play explosion sound:
// (um is reference to the
Now modify the hit() method of the UFO class so it calls startExplode() Let’s also add a feature so that attacking aliens get repulsed, or pushed upward, by a missile hit This is accomplished by
subtracting a constant from the y coordinate of the attacking alien:
// this is called if a missile hits the alien
public void hit() {
// alien is invulnerable when it's attacking
// but it gets "pushed back"
if (state == ATTACK) {
locy -= 17;
}
// otherwise explode!
else if (state != EXPLODE) {
startExplode(); // start explode state
}
}
Finally, UFO’s update() needs to be changed, so that it takes the Explode state into account and
suspends the sprite after the explosion animation is complete:
case EXPLODE:
explosion_counter++; // bump counter
// suspend once animation
// is finished
if (explosion_counter == explode.length) {
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/193-199.html (4 von 5) [13.03.2002 13:18:13]
Trang 25suspend();
}
You can find these changes to the UFO class in Listing 6-5
Now let’s modify the UFOManager and the GameManager so that they load and pass these new animation sequences to the UFO class
Previous Table of Contents Next
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/193-199.html (5 von 5) [13.03.2002 13:18:13]
Trang 26Black Art of Java Game Programming
by Joel Fan
Sams, Macmillan Computer Publishing
ISBN: 1571690433 Pub Date: 11/01/96
Previous Table of Contents Next
Modifying GameManager and UFOManager
The GameManager needs to register the attacking and exploding animations with the MediaTracker
so that they are loaded prior to the start of the game This is done by declaring new variables and modifying the loadImages() method in GameManager In the following code, all the GIFs are
assumed to be in a directory image/, which is in the same location as the GameManager applet class
Image ufoImages[] = new Image[6]; // 6 ufo Images
Image attackImages[] = new Image[6]; // 6 attack Images
Image explodeImages[] = new Image[4];// 4 explode Images
// load all images used in game
public void loadImages() {
MediaTracker t = new MediaTracker(this);
Trang 27Adding Levels of Difficulty
In video games that pit human players against computer opponents, the strength of the opponents increases as play continues Usually, the game starts at a level that the novice player can handle, but grows more difficult so that an accomplished player will still feel challenged And if you’re charging money each time the game gets played, as with arcade machines, you’ll want to make it almost
impossible to play for a very long time!
There are lots of ways to introduce skill levels into a game, and you’re limited only by your creativity For a game such as Alien Landing, in which state machines try to destroy the player, here are four ways you can increase the difficulty:
• Increase the number of UFOs More aliens will appear on the screen as the game progresses
• Increase the velocity of the UFOs This will make them harder to shoot
• Make the UFOs more intelligent For example, the attacking aliens could aim for the player’s
current location, instead of moving randomly
• Allow the UFOs to gain extra powers They could start firing back at the player, or perhaps
they might gain resistance to the player’s missiles
The possibilities are endless, and they are not difficult to add to the Alien Landing simulation For example, let’s see how you might implement the first option, increasing the number of aliens as the game continues This change will require communication between the UFO sprite and the
UFOManager Figure 6-3 diagrams the communication channel we’ll add between these two classes First, let’s see what changes are needed in the UFOManager
Figure 6-3 Communication between UFO sprite and UFOManager
Define a new variable levels, which represents the number of UFOs active at a given moment The
player will progress from level to level, after killing a certain number of aliens, defined by the
constant KILL_FOR_NEXT_LEVEL The variable ufosKilled tracks the number of UFOs that the
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/199-203.html (2 von 4) [13.03.2002 13:18:14]
Trang 28player has destroyed during the game These variables are initialized in the UFOManager method newGame(), which also suspends the UFO sprites that are not needed for the starting level.
int ufosKilled; // count ufos killed
int level; // the level
// (i.e #ufos on screen)
// kill 13 ufos until next level
static final int KILL_FOR_NEXT_LEVEL = 13;
// initialize parameters of new Game
public void newGame() {
if (i >= level) { // suspend ufos
// above start level
// tracks the number of ufos killed If the
// num_killed is divisible by KILL_FOR_NEXT_LEVEL
// increment the level
public void killed() {
When a UFO sprite is destroyed, it sends the killed() message to the UFOManager The UFO class
stores a reference to the UFOManager in variable um, so it can call killed() after it has been hit() Here
is the change to the UFO’s hit() method:
// this is called if a missile hits the alien
public void hit() {
// alien is invulnerable when it's attacking
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/199-203.html (3 von 4) [13.03.2002 13:18:14]
Trang 29// but it gets "pushed back"
if (state == ATTACK) {
locy -= 17;
}
// otherwise explode!
else if (state != EXPLODE) {
startExplode(); // start explode state
um.killed(); // tell UFOManager
// another UFO's dead
}
}
Previous Table of Contents Next
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/199-203.html (4 von 4) [13.03.2002 13:18:14]
Trang 30Black Art of Java Game Programming
by Joel Fan
Sams, Macmillan Computer Publishing
ISBN: 1571690433 Pub Date: 11/01/96
Previous Table of Contents Next
Finally, the UFOManager methods update() and paint() will take the number of sprites for each level into account:
// paint all ufos in a level
public void paint(Graphics g) {
for (int i=0; i<level; i++) {
ufo[i].paint(g);
}
}
// update all ufos in a level Otherwise start
// ufo if it's not on screen
public void update() {
for (int i=0; i<level; i++) {
Tracking Game Status
The GameManager is responsible for handling input from the player and relaying game information back It will track and display two pieces of information that are vital to the player: the score and the number of aliens landed This will require messaging from the UFO class to the GameManager
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/203-207.html (1 von 5) [13.03.2002 13:18:14]
Trang 31Figure 6-4 diagrams the messaging between the two classes
Figure 6-4 Communication between UFO sprite and GameManager
First, let’s implement a simple scoring system in which each alien is worth UFO_VALUE points GameManager needs a public method that the UFO can call when it has been killed This method is
called incrementScore(), and it increases the score by the appropriate amount:
static final int UFO_VALUE = 130; // 130 points
private int score;
// increase score
public void incrementScore() {
score += UFO_VALUE;
}
The UFO sprite will call incrementScore() from its hit() method The variable game is assigned in the
constructor for UFO, and it refers to the GameManager
// this is called if a missile hits the alien
public void hit() {
// alien is invulnerable when it's attacking
// but it gets "pushed back"
if (state == ATTACK) {
locy -= 17;
}
// otherwise explode!
else if (state != EXPLODE) {
startExplode(); // start explode state
game.incrementScore(); // add to score
um.killed(); // tell UFOManager
// another UFO's dead
}
}
Now score gets updated every time you shoot an alien.
Tracking the number of landed aliens involves similar modifications Define a variable numLanded in
the GameManager that tracks the current number of aliens landed The public method alienLanded()
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/203-207.html (2 von 5) [13.03.2002 13:18:14]
Trang 32provides the interface that the UFO class calls when it lands If too many aliens land, then gameOver() gets called.
static final int MAX_LANDED = 5; // at most 5 aliens
// can land
private int numLanded; // num of aliens landed
// count number of ufo's landed
public void alienLanded() {
The new version of landingRoutine() is defined as
// when the alien lands successfully
protected void landingRoutine() {
game.alienLanded(); // tell game manager that
// the UFO's landed
suspend();
}
The modifications of this section allow GameManager to keep track of the score and the number of
UFOs landed We’ll put the code for displaying score and numLanded into GameManager’s paint()
method In the version in Listing 6-1, the coordinates of the Strings are hardcoded for simplicity You can also use the FontMetrics class, which you saw in Chapter 4, Adding Interactivity, to dynamically compute the coordinates based on the length of the string
If you compile and play the game now, you will rack up pretty good scores, because your missile launcher is immune to alien attacks Let’s change this next!
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/203-207.html (3 von 5) [13.03.2002 13:18:14]
Trang 33Modifying GunManager
There are at least three ways that the missile gun could respond to alien hits:
• The gun blows up You can provide multiple guns, and when they are all destroyed, the
game is over
• The gun’s ability is impaired For example, it fires slower, or more missiles are needed to kill
a UFO
• The gun loses energy When there is no energy left, the game ends
Let’s implement the last option We’ll store the current amount of energy in the GunManager When the GunSprite gets hit, it tells the GunManager, which updates the energy level The diagram in
Figure 6-5 depicts the communication between the GunSprite and the GunManager
Figure 6-5 Communication between GunSprint and GunManager
Now for the details When a UFO collides with the player’s gun, it calls the GunSprite’s hit() method
This, in turn, calls GunManager’s handleHit() In GunSprite’s hit() method, gm refers to the
GunManager:
public void hit() {
gm.handleHit(); // notify manager of hit
}
The GunManager will track the energy level, and decrease it when there is an alien hit This happens
in GunManager’s handleHit():
// handles a hit from an alien
public void handleHit() {
displayHit = true; // set display hit flag
energy -= energyDec; // update energy
if (energy <= 0) { // game over if energy <= 0
game.gameOver(); // notify game manager
gun.suspend(); // turn off sprites
missile.suspend();
}
}
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/203-207.html (4 von 5) [13.03.2002 13:18:14]
Trang 34Previous Table of Contents Next
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/203-207.html (5 von 5) [13.03.2002 13:18:14]
Trang 35Black Art of Java Game Programming
by Joel Fan
Sams, Macmillan Computer Publishing
ISBN: 1571690433 Pub Date: 11/01/96
Previous Table of Contents Next
When energy reaches 0, GunManager invokes the gameOver() method in GameManager, which you
will define in the next section Otherwise, it sets displayHit, which tells GunManager’s paint() to paint
a red flash when a hit occurs The paint() method also provides a status indicator of energy remaining
by drawing a rectangle whose width is equal to energy Thus, the rectangle shrinks as the energy level
decreases (which is cooler than simply displaying a number!)
Here is GunManager’s paint() method:
String energyString = "Energy";
public void paint(Graphics g) {
// if gun is hit, flash a red rectangle
// instead of painting gun
Compile and try out these changes (For now, use an empty stub for the gameOver() method in
GameManager.) As you will see, the game action is basically finished! But there are two steps
remaining before Alien Landing is a complete presentation
Creating an Opening and Closing
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/207-211.html (1 von 4) [13.03.2002 13:18:15]
Trang 36Think of a game as a movie: There are the opening credits, which display the name of the game and the instructions, the actual playing of the game, and the closing credits The James Bond movies hook you, right from the opening action sequence (sometimes the best part of the movie!) In similar
fashion, you can create fantastic opening animations for your games that grab the player
You won’t do that here, but you will see how to modify the GameManager to create openings and closings Figure 6-6 shows the GameManager structure we will implement
Figure 6-6 GameManager structure
The idea is to introduce variables that represent the state of the game, and to paint the game, or the
opening or closing sequences, based on these variables The boolean playing records whether the user
is actually playing The screen variable can be set to either INTRO or GAME_OVER
GameManager’s paint() method will check these variables and draw what’s appropriate
Let’s see how these variables are manipulated The constructor of GameManager first sets the initial values for these variables: The game is not playing, and the introduction screen should be displayed:
playing = false; // not playing
screen = INTRO; // show intro screen
The player will move from the introduction mode to the playing mode, for example, by clicking the mouse By modifying mouseDown(), you enable this behavior:
public boolean mouseDown(Event e,int x,int y) {
if (playing) {
gm.fireMissile(x);
}
else if (screen == INTRO) { // start game for mouse
// down on intro screen playing = true;
Trang 37The other mouse methods will also check if the game is playing before passing input to the
GunManager
Now we need newGame() methods in all the manager classes, which will reset the parameters of the
game For example, GameManager’s newGame() will set the score back to 0; GunManager’s
newGame() replenishes the player’s energy supply
// GameManager’s newGame():
// initialize params for new game
public void newGame() {
score = 0; // no score
numLanded = 0; // no aliens landed
gm.newGame(); // call newGame in
um.newGame(); // manager classes
offscreen.setFont(smallFont); // set font in game
sequence by setting playing and screen:
// handle game over
public void gameOver() {
instructions appear The following excerpt from the GameManager’s paint() method draws the
introductory screen The introString[] contains the text of the instructions.
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/207-211.html (3 von 4) [13.03.2002 13:18:15]
Trang 38The code for the closing sequence follows the same idea The closing animation will be provided by
the UFOManager, and we will overlay the score and a gameOverString The complete code for
GameManager’s paint() is in Listing 6-1
Alien Landing is finished! Now you can show it to your friends
Previous Table of Contents Next
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/207-211.html (4 von 4) [13.03.2002 13:18:15]
Trang 39Black Art of Java Game Programming
by Joel Fan
Sams, Macmillan Computer Publishing
ISBN: 1571690433 Pub Date: 11/01/96
Previous Table of Contents Next
Source Code for Modified Classes
Listings 6-1 through 6-5 show the source of the classes we’ve modified in this chapter: GameManager, GunManager, UFOManager, GunSprite, and UFO
Listing 6-1 GameManager class
// game variables used when playing
static final int UFO_VALUE = 130; // 130 points
static final int MAX_LANDED = 5; // at most 5 aliens
// can land
static final int MAX_LEVEL = 9; //
static final int MAX_ENERGY = 113; //
private int score;
private int numLanded; // num of aliens landed
Image ufoImages[] = new Image[6]; // 6 ufo Images
Image attackImages[] = new Image[6]; // 6 attack Images
Image explodeImages[] = new Image[4];// 4 explode Images
Image gunImage; // gun image
GunManager gm; // refers to gun manager
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch06/211-217.html (1 von 8) [13.03.2002 13:18:16]
Trang 40UFOManager um; // refers to ufo manager
// state of game
private boolean playing; // if game playing
private int screen; // which screen to show
static final int INTRO = 0; // intro screen
static final int GAME_OVER = 1; // game over screen
AudioClip expsound; // explosion sound
// fonts
Font smallFont = new Font("Helvetica",Font.BOLD,12);
Font mediumFont = new Font("Helvetica",Font.BOLD,14);
Font bigFont = new Font("Helvetica",Font.BOLD,18);
FontMetrics fm; // use to center string
int width, height; // applet dimensions
// strings
String scoreString = "Score: ";
String ufoLandedString = "UFOs Landed: ";
String gameOverString = " GAME OVER ";
String clickString = "Shift-Click to Continue";
String alienLandingString = "Alien Landing";
int stringWidth;
String introString[] = new String[8];
public void init() {
showStatus(“Loading Images WAIT!”);
setBackground(Color.black); // applet background
width = bounds().width; // set applet dimensions height = bounds().height;