Tải bản đầy đủ (.pdf) (98 trang)

Black Art of Java Game Programming PHẦN 3 doc

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (6.13 MB, 98 trang )

Black Art of Java Game Programming:Building a Video Game
}
else {
gun.setPosition(x-gun_width,gun_y);
}
}
// fire missile from given x coordinate
public void fireMissile(int x) {
if (!missile.isActive()) { // if missile sprite
// isn't active
if (x <= min_x) {
missile.init(mis_min_x);
}
else if (x >= max_x) {
missile.init(mis_max_x);
}
else {
missile.init(x-2); // initialize missile
}
}
}
// 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() {
return gun;
}
public int getGunY() {
return gun_y;
}
}
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/171-177.html (5 von 6) [13.03.2002 13:18:10]
Black Art of Java Game Programming:Building a Video Game
Previous 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]
Black Art of Java Game Programming:Building a Video Game

Black 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]
Black Art of Java Game Programming:Building a Video Game
if (image != null) { // if there's a background image
background = true;
}
else {
background = false;
}
images = f;
currentImage = 0;
if (images == null || images.length == 0) {
foreground = false; // nothing in images[]
}
else {

foreground = true;
if (!background) { // if no background
width = images[0].getWidth(a); // get size of images[0]
height = images[0].getHeight(a);
}
}
}
// cycle currentImage if sprite is active, and there
// are foreground images
public void update() {
if (active && foreground) {
currentImage = (currentImage + 1) % images.length;
}
updatePosition();
}
public void paint(Graphics g) {
if (visible) {
if (background) {
g.drawImage(image,locx,locy,applet);
}
if (foreground) {
g.drawImage(images[currentImage],locx,locy,applet);
}
}
}
// 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]
Black Art of Java Game Programming:Building a Video Game
protected int vx;
protected int vy;
public void setVelocity(int x,int y) {
vx = x;
vy = y;
}
// update position according to velocity
public void updatePosition() {
locx += vx;
locy += vy;
}
}
The UFO reuses most of the code from the BitmapLoop, but it overrides update() to provide alienlike
behaviors. The new update() implements a state machine that permits the alien to switch behavior at
random moments. You saw a simple example of state machines in the DancingRect classes of Chapter
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]
Black Art of Java Game Programming:Building a Video Game
Previous 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]
Black Art of Java Game Programming:Building a Video Game

Black 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]
Black Art of Java Game Programming:Building a Video Game
// 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) &&
target.intersect(locx,locy,locx+width,locy+height)) {
target.hit();
suspend();
return;
}
If no collision occurs with the gun, the UFO executes behaviors according to its state. Let’s examine
the Standby state:
double r1 = Math.random(); // pick random nums
double r2 = Math.random();
switch (state) {
case STANDBY:
if (r1 > STANDBY_EXIT) {
if (r2 > 0.5) {
startAttack();
}
else {
startLand();

}
}
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]
Black Art of Java Game Programming:Building a Video Game
particular.
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,
Applet a) {
super(0,0,null,ufoImages,a);
this.max_x = max_x;
this.max_y = max_y;
currentImage = getRand(5); // start at random image
startStandby();
}
// 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]
Black Art of Java Game Programming:Building a Video Game
}
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) &&
target.intersect(locx,locy,locx+width,locy+height)) {
target.hit();
suspend();
return;
}
// otherwise, update alien state
double r1 = Math.random(); // pick random nums
double r2 = Math.random();
switch (state) {
case STANDBY:
if (r1 > STANDBY_EXIT) {
if (r2 > 0.5) {
startAttack();
}
else {
startLand();
}
}
// 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]
Black Art of Java Game Programming:Building a Video Game
break;
case ATTACK:
// retreat if the alien flies too close to
// the ground
if ((r1 > ATTACK_EXIT) || (locy > gun_y - 17)) {
startRetreat();
}
// flip x-direction if it gets too close to edges
else if ((locx < width) || (locx > max_x - width) ||
(r2 > FLIP_X)) {
vx = -vx;
}
break;
case RETREAT:
if (r1 > RETREAT_EXIT) {
if (r2 > 0.5) {
startAttack();
}
else {
startStandby();
}
}
// stop retreat if ufo goes too close
// to top of screen
else if (locy < RETREAT_Y) {

startStandby();
}
break;
case LAND:
if (r1 > LAND_EXIT) {
startStandby();
}
// if the ufo is low enough,
// start the landing procedure
else if (locy >= max_y-height) {
landingRoutine();
}
break;
}
super.update(); // BitmapLoop update draws the
// appropriate image
}
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/179-185.html (5 von 6) [13.03.2002 13:18:11]
Black Art of Java Game Programming:Building a Video Game
protected void landingRoutine() {
System.out.println("ufo landed") ;
suspend();
}
protected void startStandby() {
vx = getRand(8)-4 ;
vy = 0;
state = STANDBY;
}
protected void startAttack() {
vx = getRand(10)-5;

vy = getRand(5)+4;
state = ATTACK;
}
protected void startRetreat() {
vx = 0;
vy = -getRand(3) - 2;
state = RETREAT;
}
protected void startLand() {
vx = 0;
vy = getRand(3) + 2;
state = LAND;
}
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]
Black Art of Java Game Programming:Building a Video Game

Black 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]
Black Art of Java Game Programming:Building a Video Game

public void initialize(GunManager gm) {
UFO.initialize(gm);
}
private void initializePosition(Moveable m) {
m.setPosition(UFO.getRand(width - 100)+50,
UFO.getRand(height - 150)+10);
}
// 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++) {
if (ufo[i].isActive()) {
ufo[i].update();
}
else { // restore ufo
// at different location
initializePosition(ufo[i]);
ufo[i].restore();
}
}
}
}

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]
Black Art of Java Game Programming:Building a Video Game
MediaTracker 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) {
gm.moveGun(x);
return true;
}
public boolean mouseDrag(Event e,int x,int y) {
gm.moveGun(x);
return true;
}
public boolean mouseDown(Event e,int x,int y) {
gm.fireMissile(x);
return true;
}
Each event handler passes the x coordinate of the mouse location to the appropriate method of the
GunManager. mouseDrag must be handled, so that the player can move the gun even if the mouse
button is pressed.
Implementing the Video Game Loop

Next, let’s look at how the GameManager implements the Video Game Loop:
public void run() {
while (true) {
repaint();
updateManagers();
Thread.yield();
try {
Thread.sleep (REFRESH_RATE);
} catch (Exception exc) { };
}
}
As you see, this code is pretty general, and you can adapt a loop like this for your own games.
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/185-188.html (3 von 4) [13.03.2002 13:18:12]
Black Art of Java Game Programming:Building a Video Game
Previous 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]
Black Art of Java Game Programming:Building a Video Game

Black 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
height = bounds().height;
loadImages();
um = new UFOManager(width,height,ufoImages,this);
gm = new GunManager(width,height,gunImage,
um.getUFO(),
this);
um.initialize(gm); // initialize gun parameters
image = createImage(width,height); // make offscreen buffer
offscreen = image.getGraphics();
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/188-192.html (1 von 4) [13.03.2002 13:18:12]
Black Art of Java Game Programming:Building a Video Game
}
public void loadImages() {
MediaTracker t = new MediaTracker(this);
gunImage = getImage(getCodeBase(),"image/gun.gif");
t.addImage(gunImage,0);
for (int i=0; i<6; i++) {
ufoImages[i] = getImage(getCodeBase(),

"image/ufo" + i + ".gif");
t.addImage(ufoImages[i],0);
}
// wait for all images to finish loading //
try {
t.waitForAll();
} catch (InterruptedException e) {
}
// check for errors //
if (t.isErrorAny()) {
showStatus("Error Loading Images!");
}
else if (t.checkAll()) {
showStatus("Images successfully loaded");
}
// initialize the BitmapLoop
}
public boolean mouseMove(Event e,int x,int y) {
gm.moveGun(x);
return true;
}
public boolean mouseDrag(Event e,int x,int y) {
gm.moveGun(x);
return true;
}
public boolean mouseDown(Event e,int x,int y) {
gm.fireMissile(x);
return true;
}
public void start() {

showStatus("Starting Game!");
animation = new Thread(this);
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/188-192.html (2 von 4) [13.03.2002 13:18:12]
Black Art of Java Game Programming:Building a Video Game
if (animation != null) {
animation.start();
}
}
public void updateManagers() {
gm.update();
um.update();
}
// override update so it doesn't erase screen
public void update(Graphics g) {
paint(g);
}
//
public void paint(Graphics g) {
offscreen.setColor(Color.black);
offscreen.fillRect(0,0,width,height); // clear buffer
gm.paint(offscreen);
um.paint(offscreen);
g.drawImage(image,0,0,this);
}
public void run() {
while (true) {
repaint();
updateManagers();
Thread.currentThread().yield();
try {

Thread.sleep (REFRESH_RATE);
} catch (Exception exc) { };
}
}
public void stop() {
showStatus("Game Stopped");
if (animation != null) {
animation.stop();
animation = null;
}
}
}
file:///D|/Downloads/Books/Computer/Java/Blac 20Java%20Game%20Programming/ch05/188-192.html (3 von 4) [13.03.2002 13:18:12]
Black Art of Java Game Programming:Building a Video Game
Recommended 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]
Black Art of Java Game Programming:Extending Your Video Game

Black 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]
Black Art of Java Game Programming:Extending Your Video Game
Let’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) {
if (visible) {
if (background) {

g.drawImage(image,locx,locy,applet);
}
if (foreground) {
g.drawImage(images[currentImage],locx,locy,applet);
}
}
}
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]
Black Art of Java Game Programming:Extending Your Video Game
protected Image attack[]; // attack animation
protected Image explode[]; // explosion sequence

// constructor: initialize image references, instance vars
public UFO(Image ufoImages[],
Image attackImages[],
Image explodeImages[],
int max_x,int max_y,
UFOManager um,
Applet a) {

ufo = ufoImages;
attack = attackImages;
explode = explodeImages;


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() {
vx = getRand(10)-5;
vy = getRand(5)+7;
images = attack; // change to attack animation loop
state = ATTACK;
}
// start retreating state
protected void startRetreat() {
vx = 0;
vy = -getRand(3) - 2;
images = ufo; // change to usual animation loop
state = RETREAT;
}
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]
Black Art of Java Game Programming:Extending Your Video Game
static 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
// UFOManager class)
state = EXPLODE;
}
The startExplode() method is called when the alien is hit by a missile and the alien is not in the Attack
state (so it is vulnerable). startExplode() also calls the UFOManager method playExplosion(), which
plays the explosion sound.
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]
Black Art of Java Game Programming:Extending Your Video Game
suspend();
}
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]

×