home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Java 1.2 How-To
/
JavaHowTo.iso
/
code
/
ch09.txt
< prev
next >
Wrap
Text File
|
1998-12-14
|
26KB
|
1,212 lines
Dialer.java:
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
* the dialer applet
*/
public class Dialer extends Applet implements ActionListener {
AudioClip touchTones[] = new AudioClip[12];
public Button NumberButton1;
public Button NumberButton2;
public Button NumberButton3;
public Button NumberButton4;
public Button NumberButton5;
public Button NumberButton6;
public Button NumberButton7;
public Button NumberButton8;
public Button NumberButton9;
public Button NumberButton0;
public Button PoundButton;
public Button StarButton;
/*
* called when the applet is loaded
* load audio clips and add the keypad panel
*/
public void init () {
int i;
String name;
for (i=0; i<10; i+=1) {
name = "touchtone."+i+".au";
showStatus ("Getting "+name);
touchTones[i] = getAudioClip (getCodeBase(), name);
}
name = "touchtone.star.au";
showStatus ("Getting "+name);
touchTones[10] = getAudioClip (getCodeBase(), name);
name = "touchtone.pound.au";
showStatus ("Getting "+name);
touchTones[11] = getAudioClip (getCodeBase(), name);
setLayout(new BorderLayout());
//add ("Center", keypad = new Keypad (touchTones));
//Font font = new Font ("Times", Font.BOLD, 14);
Color miscColor = new Color (0, 0, 255);
//setFont (font);
NumberButton1 = new Button ("1");
add ("South",NumberButton1);
NumberButton2 = new Button ("2");
add ("South", NumberButton2 );
NumberButton3 = new Button ("3");
add ("South", NumberButton3 );
NumberButton4 = new Button ("4");
add ("South", NumberButton4);
NumberButton5 = new Button ("5");
add ("South", NumberButton5);
NumberButton6 = new Button ("6");
add ("South", NumberButton6 );
NumberButton7 = new Button ("7");
add ("South", NumberButton7);
NumberButton8 = new Button ("8");
add ("South", NumberButton8 );
NumberButton9 = new Button ("9");
add ("South", NumberButton9 );
PoundButton= new Button ("*");
add ("South", PoundButton );
PoundButton.setBackground (miscColor);
NumberButton0 = new Button ("0");
add ("South", NumberButton0);
StarButton = new Button ("#");
add ("South", StarButton);
StarButton.setBackground (miscColor);
setLayout (new GridLayout (4, 3, 4, 4));
NumberButton1.addActionListener(this);
NumberButton2.addActionListener(this);
NumberButton3.addActionListener(this);
NumberButton4.addActionListener(this);
NumberButton5.addActionListener(this);
NumberButton6.addActionListener(this);
NumberButton7.addActionListener(this);
NumberButton8.addActionListener(this);
NumberButton9.addActionListener(this);
NumberButton0.addActionListener(this);
PoundButton.addActionListener(this);
StarButton.addActionListener(this);
}
public void actionPerformed (ActionEvent ev)
{
Object object1 = ev.getSource();
if (object1 == StarButton)
touchTones[10].play ();
else if (object1 == PoundButton)
touchTones[11].play ();
else if (object1 == NumberButton0)
touchTones[0].play ();
else if (object1 == NumberButton1)
touchTones[1].play ();
else if (object1 == NumberButton2)
touchTones[2].play ();
else if (object1 == NumberButton3)
touchTones[3].play ();
else if (object1 == NumberButton4)
touchTones[4].play ();
else if (object1 == NumberButton5)
touchTones[5].play ();
else if (object1 ==NumberButton6)
touchTones[6].play ();
else if (object1 == NumberButton7)
touchTones[7].play ();
else if (object1 ==NumberButton8)
touchTones[8].play ();
else if (object1 == NumberButton9)
touchTones[9].play ();
}
}
Bounce.java:
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.awt.image.ImageObserver;
/*
* a class describing a single ball
*/
class Ball {
/*
* the image for this ball
*/
Image img;
/*
* x position and velocity
*/
double x, dx; // x position and velocity
/*
* y position and velocity
*/
double y, dy; // y position and velocity
/*
* initialize the position and velocity
* to random values
*/
void random () {
x = 10 + 380*Math.random ();
y = 10 + 200*Math.random ();
dx = 5 - 10*Math.random ();
dy = 5 - 10*Math.random ();
}
/**
* calculate the next position of this ball
* and make sure it bounces off the edge of the panel
* @param d - dimension of the bounding panel
*/
void compute (Dimension d) {
if (x <= 0 || x > d.width) dx = -dx; // bounce horizontal
if (y <= 0 || y > d.height) dy = -dy; // bounce vertical
x += dx;
y += dy;
}
/**
* draw the ball image
* @param g - destination graphics object
* @param obs - parent image observer
*/
public void paint (Graphics g, ImageObserver obs) {
g.drawImage (img, (int) x-10, (int) y-10, obs);
}
}
/*
* the panel containing the bouncing balls
*/
class BouncePanel extends Panel implements Runnable {
/*
* the number of balls
*/
final int nballs = 4;
/*
* the array holding all the balls
*/
Ball balls[] = new Ball[10];
/*
* offscreen image
*/
Image offimg;
/*
* size of offscreen image
*/
Dimension offsize;
/*
* graphics object associated with offscreen image
*/
Graphics offg;
/*
* thread for periodic updating
*/
Thread thread;
/*
* The thread recalculates each ball position and
* redraws them
*/
public void run() {
offsize = getSize();
offimg = createImage (offsize.width, offsize.height);
offg = offimg.getGraphics();
while (true) {
for (int i=0; i<nballs; i+=1) {
balls[i].compute (offsize);
}
repaint ();
try {
Thread.sleep (25);
} catch (InterruptedException e) {
break;
}
}
}
/**
* Override update to avoid erase flicker
* @param g - destination graphics object
*/
public synchronized void update (Graphics g) {
offg.setColor (Color.lightGray);
offg.fillRect (0, 0, offsize.width, offsize.height);
for (int i = 0 ; i < nballs ; i++)
balls[i].paint (offg, this);
offg.setColor (Color.black);
offg.drawRect (0, 0, offsize.width-1, offsize.height-1);
g.drawImage(offimg, 0, 0, this);
}
/*
* Start the update thread
*/
public void start() {
thread = new Thread(this);
thread.start();
}
/*
* Stop the update thread
*/
public void stop()
{
if (thread != null)
thread = null;
}
}
/*
* the applet proper
*/
public class Bounce extends Applet implements ActionListener
{
/*
* instance of BouncePanel
*/
BouncePanel panel;
/*
* an array containing the images for the balls
*/
Image img[] = new Image[4];
/*
* the audio clip to be played in a loop
*/
AudioClip sound;
Button btnStart;
Button btnStop;
/*
* Called when the applet is loaded
* Create an instance of bounce panel and add the start button
* and load images
*/
public void init() {
setLayout(new BorderLayout());
panel = new BouncePanel ();
add ("Center", panel);
Panel p = new Panel ();
add ("South", p);
btnStart = new Button("Start");
p.add (btnStart);
btnStop = new Button("Stop");
p.add (btnStop);
btnStart.addActionListener(this);
btnStop.addActionListener(this);
sound = getAudioClip(getCodeBase(), "sound.au");
img[0] = getImage (getDocumentBase(), "whiteball.gif");
img[1] = getImage (getDocumentBase(), "redball.gif");
img[2] = getImage (getDocumentBase(), "blueball.gif");
img[3] = getImage (getDocumentBase(), "greenball.gif");
for (int i=0; i<panel.nballs; i+=1) {
panel.balls[i] = new Ball ();
panel.balls[i].img = img[i & 3];
}
}
/*
* Called when the applet is started
* Don't do anything
*/
public void start () {
}
/*
* Called when the applet is stopped
*/
public void stop() {
panel.stop();
sound.stop ();
}
/*
* Handle start button press by randomizing balls
*/
public void actionPerformed(ActionEvent ev)
{
Object object1 = ev.getSource();
if (object1 == btnStart)
{
for (int i=0; i<panel.nballs; i+=1)
panel.balls[i].random ();
panel.start ();
sound.loop ();
}
if (object1 == btnStop)
{
sound.stop ();
}
}
}
Guitar.java:
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
* the applet class
*/
public class Guitar extends Applet implements ActionListener {
/*
* the guitar chords
*/
AudioClip chords[] = new AudioClip[7];
/*
* the drum clip
*/
AudioClip drum;
String chordnames[] = {"a", "c", "d", "low_e", "high_e", "g", "chaa"};
String drumbeat = "drum";
Button chordbuttons[] = new Button[7];
Button btnStart;
Button btnStop;
/*
* Called when the applet is loaded
* Load all sounds and add user interface
*/
public void init () {
String name;
int i;
Panel keyboard = new Panel();
Panel controls = new Panel();
this.setLayout(new BorderLayout());
keyboard.setLayout(new FlowLayout());
controls.setLayout(new FlowLayout());
add ("Center", keyboard);
add ("South", controls);
for (i=0; i<7; i+=1) {
name = chordnames[i]+".au";
showStatus ("Getting " + name);
chords[i] = getAudioClip (getCodeBase(), name);
chordbuttons[i] = new Button (chordnames[i]);
keyboard.add (chordbuttons[i]);
chordbuttons[i].addActionListener(this);
}
showStatus ("Getting " + drumbeat + ".au");
drum = getAudioClip (getCodeBase(), drumbeat + ".au");
btnStart = new Button ("Start");
controls.add (btnStart);
btnStop = new Button ("Stop");
controls.add (btnStop);
btnStop.addActionListener(this);
btnStart.addActionListener(this);
}
/*
* Handle button presses
* @param ev - event object
* @param arg - target object
*/
public void actionPerformed (ActionEvent ev)
{
Object object1 = ev.getSource();
if (object1 == chordbuttons[0])
{
chords[0].play ();
}
else if (object1 == chordbuttons[1])
{
chords[1].play ();
}
else if (object1 == chordbuttons[2])
{
chords[2].play ();
}
else if (object1 == chordbuttons[3])
{
chords[3].play ();
}
else if (object1 == chordbuttons[4])
{
chords[4].play ();
}
else if (object1 == chordbuttons[5])
{
chords[5].play ();
}
else if (object1 == chordbuttons[6])
{
chords[6].play ();
}
else if (object1 == btnStart) {
drum.loop ();
}
else if (object1 == btnStop)
{
drum.stop ();
}
}
}
InvaderApp.java:
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
import java.awt.image.*;
/**
* A class that describes a target "invader"
* This hold a single invader
*/
class Invader {
/*
* this invader's position and velocity
*/
double x, y, dx, dy;
/*
* this invader's missile position and velocity
* only one missile allowed per invader
*/
int mx, my, mdy;
/*
* The images for an invader
*/
Image img[] = new Image[4];
/*
* inplay is true if this invader has not been killed
*/
boolean inplay;
/*
* fired is set to true when this invader fires a missile
*/
boolean fired = false;
/*
* state is used to cycle through the four images
* of this invader
*/
double state;
/*
* value is the score value; it depends on the speed
*/
int value;
/*
* Initialize position and speed for this invader
*/
void random (int speed, int w, int h) {
x = 10 + (w-20)*Math.random ();
y = 10 + ((h>>1)-20)*Math.random ();
dx = (speed>>1) - speed*Math.random ();
dy = (speed>>1) - speed*Math.random ();
inplay = true;
state = 3 * Math.random ();
fired = false;
mdy = 20;
value = speed * 10;
}
/*
* Calculate new invader and missile position
* Also fires a missile at random
* @param w panel width
* @param h panel height
*/
void compute (int w, int h) {
if (x <= 0 || x > w) dx = -dx;
if (y <= 0 || y > h>>1) dy = -dy;
if (my > h-20) fired = false;
if (fired) my += mdy;
else my = 0;
if (inplay && !fired && Math.random () > 0.99) {
fired = true;
mx = (int) x; my = (int) y+25;
}
x += dx; y += dy;
}
/*
* paint invader and missile (if it has been fired)
* @param g - destination graphics object
* @param obs - imageobserver associated
* with this graphics context
*/
public void paint (Graphics g, ImageObserver obs) {
int whichImage;
if (inplay) {
whichImage = (int) state;
g.drawImage (img[whichImage & 0x3], (int) x-25,
(int) y-25, obs);
state += .25;
}
if (fired) {
g.setColor (Color.green);
g.drawLine ((int) mx, (int) my, (int) mx, (int) my-10);
}
}
/*
* Tests whether the player's missile has hit this invader
* Returns true if invader is hit
* @param pmx - player's missile x position
* @param pmy - player's missile y position
*/
boolean killer (int pmx, int pmy) {
int deltaX, deltaY;
if (!inplay) return false;
deltaX = (int) Math.abs (x-pmx);
deltaY = (int) Math.abs (y-pmy);
if (deltaX < 20 && deltaY < 20) {
inplay = false;
return true;
}
return false;
}
}
/**
* A class to describe the player, very similar to Invader
* except in reverse
*/
class Player {
/*
* position of the player
*/
int x, y=-100;
/*
* position of the player's missile
*/
int mx, my, mdy = -20;
/*
* two different player images
*/
Image img1, img2;
/*
* fired is true if player has fired a missile
* inplay is true if the game is not over
*/
boolean fired = false, inplay=true;
/*
* called when a player fires a missile
*/
void fire () {
if (fired || !inplay) return;
mx = x; my = y;
fired = true;
}
/*
* Calculate next missile position
*/
void compute () {
if (my < 0) fired = false;
if (fired) my += mdy;
else my = y;
}
/**
* Paint player and missile
* @param g - destination graphics object
* @param obs - image observer
*/
public void paint (Graphics g, ImageObserver obs) {
if (fired) {
if (inplay) g.drawImage (img2, x-25, y, obs);
g.setColor (Color.white);
g.drawLine (mx, my, mx, my+10);
} else if (inplay) g.drawImage (img1, x-25, y, obs);
}
/**
* Returns true if the player has been killed
* @param bmx, bmy - position of enemy missile
*/
boolean killer (int bmx, int bmy) {
int dx, dy;
if (!inplay) return false;
dx = (int) Math.abs (x-bmx);
dy = (int) Math.abs (y-bmy);
if (dx < 20 && dy < 20) {
return true;
}
return false;
}
}
/*
* much of the game logic is here
*/
class Playfield extends Panel implements Runnable, MouseListener, MouseMotionListener
{
static final int PLAYER_HIT = 1;
static final int INVADER_HIT = 2;
InvaderApp invaderApp;
/*
* the number of invaders in play
*/
int NInvaders=0;
/*
* the maximum number of invaders possible
*/
final int MaxInvaders = 32;
/*
* array of invaders
*/
Invader invaders[] = new Invader[MaxInvaders];
Player player;
/*
* offscreen image for double-buffering
*/
Image offscreen;
/*
* dimension of offscreen graphics image
*/
Dimension psize;
/*
* graphics object associated with offscreen image
*/
Graphics offgraphics;
/*
* game action thread
*/
Thread theThread;
/*
* the playfield background color
*/
Color bgcolor = new Color (51, 0, 153);
int score, playerLives, playLevel;
Font font;
/**
* constructor saves instance of the applet
* @param invaderApp - instance of the applet
*/
public Playfield (InvaderApp invaderApp) {
this.invaderApp = invaderApp;
addMouseListener(this);
addMouseMotionListener(this);
}
/*
* game action thread
*/
public void run() {
psize = getSize();
offscreen = createImage (psize.width, psize.height);
offgraphics = offscreen.getGraphics ();
font = new Font ("TimesRoman", Font.BOLD, 18);
offgraphics.setFont (font);
while (true) {
compute ();
repaint ();
try {
Thread.sleep(25);
} catch (InterruptedException e) { }
}
}
/*
* calculate new positions for all objects
*/
synchronized void compute () {
for (int i=0; i<NInvaders; i+=1) {
invaders[i].compute (psize.width, psize.height);
if (invaders[i].killer (player.mx, player.my)) {
invaderApp.hit (INVADER_HIT);
player.fired = false;
score += invaders[i].value;
}
if (player.killer (invaders[i].mx, invaders[i].my)) {
invaderApp.hit (PLAYER_HIT);
invaders[i].fired = false;
playerLives -= 1;
if (playerLives < 1) player.inplay = false;
}
}
player.compute ();
}
/**
* override default update
* draw into offscreen image and then copy it to the screen
* @param g - destination graphics object
*/
public synchronized void update(Graphics g) {
offgraphics.setColor (bgcolor);
offgraphics.fillRect (0, 0, psize.width, psize.height);
for (int i = 0 ; i < NInvaders ; i++)
if (invaders[i].inplay) invaders[i].paint (offgraphics, this);
player.paint (offgraphics, this);
offgraphics.setColor (Color.green);
offgraphics.drawString ("Score", 10, 20);
offgraphics.drawString (Integer.toString (score), 60, 20);
offgraphics.drawString ("Level", psize.width>>1, 20);
offgraphics.drawString (Integer.toString (playLevel),
(psize.width>>1)+50, 20);
offgraphics.drawString ("Lives", psize.width-80, 20);
offgraphics.drawString (Integer.toString (playerLives),
psize.width-30, 20);
if (playerLives < 1) offgraphics.drawString ("Game Over",
(psize.width>>1)-30, psize.height>>1);
g.drawImage (offscreen, 0, 0, null);
}
/*
* Start the game thread
*/
public void start() {
theThread = new Thread (this);
theThread.start ();
}
/*
* Stop the game thread
*/
public void stop() {
if (theThread != null)
theThread = null;
}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseMoved(MouseEvent e)
{
int x =e.getX();
int y =e.getY();
player.x = x;
player.y = psize.height-45;
if (player.x < 20) player.x = 20;
if (player.x > psize.width-20) player.x = psize.width-20;
}
public void mousePressed(MouseEvent e)
{
player.fire ();
}
public void mouseDragged(MouseEvent e)
{
}
}
/*
* the applet class
*/
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
public class InvaderApp extends Applet implements ActionListener
{
/*
* the playfield instance
*/
Playfield panel;
Button btnNewGame;
/*
* temporary storage for images
*/
Image img[] = new Image[4];
/*
* the speed of the game
* the number of invaders in this round
*/
int speed, NInvadersInPlay;
/*
* Called when the applet is loaded
* Load the images
*/
public void init() {
int i;
MediaTracker tracker = new MediaTracker (this);
setLayout(new BorderLayout());
panel = new Playfield (this);
add("Center", panel);
Panel p = new Panel();
add("South", p);
btnNewGame = new Button("New Game");
p.add(btnNewGame);
btnNewGame.addActionListener(this);
showStatus ("Getting Invader images...");
for (i=0; i<4; i+=1) {
img[i] = getImage (getDocumentBase(), "T"+(i+1)+".gif");
tracker.addImage (img[i], 0);
}
try {
tracker.waitForID(0);
} catch (InterruptedException e) { }
for (i=0; i<panel.MaxInvaders; i+=1) {
panel.invaders[i] = new Invader ();
panel.invaders[i].inplay = false;
panel.invaders[i].img[0] = img[0];
panel.invaders[i].img[1] = img[1];
panel.invaders[i].img[2] = img[2];
panel.invaders[i].img[3] = img[3];
}
panel.player = new Player ();
showStatus ("Getting player images...");
panel.player.img1 = getImage (getDocumentBase(),"Player1.gif");
panel.player.img2 = getImage (getDocumentBase(),"Player2.gif");
tracker.addImage (panel.player.img1, 1);
tracker.addImage (panel.player.img2, 1);
try {
tracker.waitForID (1);
} catch (InterruptedException e) { }
showStatus ("Ready to play!");
}
/*
* Start the action thread
*/
public void start() {
panel.start();
}
/*
* Stop the action thread
*/
public void stop() {
panel.stop();
}
public void actionPerformed(ActionEvent ev)
{
speed = 10;
panel.player.inplay = true;
panel.playerLives = 3;
panel.score = 0;
panel.playLevel = 1;
NInvadersInPlay = 2 * panel.playLevel + 1;
panel.NInvaders = NInvadersInPlay;
for (int i=0; i<panel.NInvaders; i+=1)
panel.invaders[i].random (speed,
panel.psize.width, panel.psize.height);
play (getCodeBase(), "gong.au");
if (NInvadersInPlay >= panel.MaxInvaders)
NInvadersInPlay = panel.MaxInvaders;
}
/**
* Play the appropriate sound when something is hit
* @param which - which sound to play
*/
public void hit (int which) {
switch (which) {
case Playfield.INVADER_HIT:
NInvadersInPlay -= 1;
if (NInvadersInPlay < 1) {
play (getCodeBase(), "gong.au");
panel.playLevel += 1;
NInvadersInPlay = 2 * panel.playLevel + 1;
speed += 4;
panel.NInvaders = NInvadersInPlay;
for (int i=0; i<panel.NInvaders; i+=1)
panel.invaders[i].random (speed,
panel.psize.width, panel.psize.height);
} else {
play (getCodeBase(), "drip.au");
}
break;
case Playfield.PLAYER_HIT:
play (getCodeBase(), "doh2.au");
break;
}
}
}
BallSpin.java:
import java.applet.*;
import java.awt.*;
import java.net.*;
/*
* the applet class
*/
public class BallSpin extends Applet implements Runnable {
/*
* the number of sub-images in the entire image
*/
int nImages;
/*
* the full-size image
*/
Image theImage;
/*
* the animation thread
*/
Thread thread;
/*
* the position of the displayed image
*/
int xOffset;
int yOffset;
/*
* offscreen image for double-buffering
*/
Image offImage;
/*
* graphics object associated with the offscreen image
*/
Graphics offg;
/*
* dimension of the offscreen image
*/
Dimension offSize;
/*
* the sub-image to be drawn
*/
int whichImage;
/*
* the dimension of each sub-image
*/
Dimension imageDim = new Dimension ();
/*
* Initializes the applet
* Loads the entire image
*/
public void init () {
int i;
thread = null;
offSize = getSize ();
offImage = createImage (offSize.width, offSize.height);
offg = offImage.getGraphics ();
nImages = 7;
imageDim.width = 48;
imageDim.height = 53;
MediaTracker tracker = new MediaTracker (this);
String name = "ballspin.gif";
theImage = getImage (getDocumentBase(), name);
tracker.addImage (theImage, 100);
showStatus ("Getting image: "+name);
try {
tracker.waitForID (100);
} catch (InterruptedException e) { }
xOffset = nImages * 30;
yOffset = 3 + offSize.height - imageDim.height;
whichImage = nImages;
repaint ();
thread = new Thread (this);
thread.start ();
}
/*
* Start the animation
*/
public void start () {
xOffset = nImages * 30;
yOffset = 3 + offSize.height - imageDim.height;
whichImage = nImages;
if (thread != null)
thread = null;
thread = new Thread (this);
thread.start ();
}
/*
* Stop the animation
*/
public void stop ()
{
if (thread != null)
thread = null;
}
/**
* call update for efficiency
* @param g - destination graphics object
*/
public void paint (Graphics g) {
update (g);
}
/**
* draw the sub-image at xOffset, yOffset
* @param g - destination graphics object
*/
public void update (Graphics g) {
Graphics offgClip;
offg.setColor (Color.white);
offg.fillRect (0, 0, offSize.width, offSize.height);
offgClip = offg.create (xOffset, yOffset, imageDim.width,
imageDim.height);
offgClip.drawImage (theImage, 0 - (whichImage * imageDim.width),
0, this);
g.drawImage (offImage, 0, 0, this);
}
/*
* Animation thread forces repaint every 100ms
*/
public void run () {
int i;
for (i=0; i<nImages; i+=1) {
xOffset -= 30;
whichImage -= 1;
repaint ();
try {
Thread.sleep (100);
} catch (InterruptedException e) { }
}
}
}