Jeff Cooper

Greenhorn
+ Follow
since Apr 02, 2001
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
0
In last 30 days
0
Total given
0
Likes
Total received
0
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Jeff Cooper

Thanks, Cindy and Bosun.
I tested my applet on IE and Netscape on my own machine, then had several friends test on their machines. All but one of twelve Windows users reported that it ran well. Two of two Mac users reported that it didn't run at all, which is an awfully small sampling, but both of them are tech types who have up-to-date machines.
22 years ago
Thank you, Cindy.
Is there any way to test for different browsers without installing all of them on my own machine? For example, a few Web sites offer a service where they test your HTML on different browsers and show you any possible incompatibilites.
22 years ago
I wrote a little applet game that my friends tell me runs well on Windows, but not on Mac.
Is there any software one can use to test a Java applet's compatibilty with various platforms?
What, if anything, tends to cause lack of cross-platform compatibility?
If you're feeling exceptionally generous, please see if you can spot the problem in the actual source code:
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
public class TennisReturnGame extends Applet
{
Graphics offscreen ;
Image imageOffScreen ;
Button newGame;
Choice choice;
String scoreLine, instructions;
static String userscore = "0";
static String proscore = "0";
boolean started = false;
boolean isMoving = false;
boolean gameOver = false;
FontMetrics fm; // needed for centering message
int scoreLoc;
public void init()
{
setBackground( new Color( 0, 120, 0 ) );
setLayout( new BorderLayout( 3, 3 ) );
TennisCanvas court = new TennisCanvas( );
add( court, BorderLayout.CENTER );
Panel controlPanel = new Panel();
controlPanel.setBackground( new Color( 220, 200, 180 ) );
add( controlPanel, BorderLayout.SOUTH );
Panel topPanel = new Panel();
topPanel.setBackground( new Color( 220, 200, 180 ) );
add( topPanel, BorderLayout.NORTH );
fm = getFontMetrics( getFont() );
instructions = "Click once to activate. Spacebar initiates serve. Delays are built in.";
scoreLoc = 240 - ( fm.stringWidth( instructions )/2 );
newGame = new Button( "New Game" );
newGame.addActionListener( court );
newGame.setBackground( Color.lightGray );
topPanel.add( newGame );
choice = new Choice(); // user chooses opponent, which will determine ball speed
choice.addItem( "Greg Rusedski 149 mph" );
choice.addItem( "Venus Williams 127 mph" );
choice.addItem( "Conchita Martinez 98 mph" );
choice.addItem( "PeeWee Phenom 77 mph" );
choice.addItem( "Uncle Seymour 50 mph" );
choice.setBackground( Color.white );
controlPanel.add( new Label( " Opponent:" ) );
controlPanel.add( choice );
imageOffScreen = createImage( getSize().width, getSize().height );
offscreen = imageOffScreen.getGraphics();
court.proChoice = choice;
}

public Insets getInsets()
{
return new Insets( 3, 3, 3, 3 );
}

class TennisCanvas extends Canvas implements ActionListener, Runnable, KeyListener, MouseListener
{
double currX , currY ; // position of ball
double dy = ( Math.random()* 3 ) + 1; // change in ball's y position
double dx = 15;
int speed = 50;
int pointCount;
Thread animator;
Choice proChoice;
TennisCanvas() // constructor
{
setBackground( new Color( 0, 120, 0 ) );
currX = 84;
currY = 125;
addKeyListener( this );
addMouseListener( this );
animator = new Thread( this );
animator.start();
}
public int setSpeed() // speed based on opponenet chosen by user
{
int choiceIndex = proChoice.getSelectedIndex();
switch ( choiceIndex )
{
case 0:
return 75;
case 1:
return 64;
case 2:
return 49;
case 3:
return 39;
case 4:
return 25;
default:
return 50;
}
}

public void actionPerformed( ActionEvent evt ) // New Game button starts new game
{
String command = evt.getActionCommand();
if ( command.equals( "New Game" ) )
startNew();
}
public void startNew() // resets scores and starts new game
{
setBackground( new Color( 0, 120, 0 ) );
pointCount = 0;
isMoving = false;
started = false;
gameOver = false;
userscore = "0";
proscore = "0";
fm = getFontMetrics( getFont() );
scoreLine = "Opponent's score: " + proscore + " Your score: " + userscore;
instructions = "Click once to activate. Spacebar initiates serve.";
scoreLoc = 240 - ( fm.stringWidth( instructions )/2 );
repaint();
}
public void keyPressed( KeyEvent evt ) // hitting space bar initiates serve
{
int code = evt.getKeyCode();
if ( code == KeyEvent.VK_SPACE && isMoving == false && gameOver == false )
{
currX = 84;
if ( pointCount % 2 == 0 )
currY = 125;
else
currY = 110;
animator = new Thread( this );
animator.start();
}
}
public void mousePressed( MouseEvent evt ) // user tries to hit moving ball with mouse click
{
if ( started == false ) // first mouse click activates game but doesn't count as a "swing" at the ball
{
started = true;
newScore();
}
// if user clicks within 20 pixels of ball, user gets the point
else if ( evt.getX() > 324 && Math.abs( evt.getX() - ( currX + 5 ) ) <= 20 && ( Math.abs( evt.getY() - ( currY + 5 ) ) <= 20 ) )
{
dx = -dx;
dy = -dy;
addToUser();
}
else // otherwise, opponent gets the point
{
addToPro();
}
}
public void addToUser() // gives point to user
{
if ( gameOver == false && isMoving == true )
{
if ( userscore.equals( "0" ) )
userscore = "15";
else if ( userscore.equals( "15" ) )
userscore = "30";
else if ( userscore.equals( "30" ) )
userscore = "40";
else if ( userscore.equals( "40" ) ) // user wins game
{
userscore = "GAME!";
gameOver = true;
setBackground( new Color( 204, 102, 0 ) );
}
pointCount++;
newScore();
}
}
public void addToPro() // gives point to opponent
{
if ( isMoving == true && gameOver == false )
{
if ( proscore.equals( "0" ) )
proscore = "15";
else if ( proscore.equals( "15" ) )
proscore = "30";
else if ( proscore.equals( "30" ) )
proscore = "40";
else if ( proscore.equals( "40" ) ) // opponent wins game
{
proscore = "GAME!";
gameOver = true;
setBackground( new Color( 204, 102, 0 ) );
}
pointCount++;
newScore();
}
}
public void newScore() // updates score
{
scoreLine = "Opponent's score: " + proscore + " Your score: " + userscore;
fm = getFontMetrics( getFont() );
scoreLoc = 240 - ( fm.stringWidth( scoreLine )/2 );
repaint();
}

public void run()
{
isMoving = true;
speed = setSpeed();
int cycles = 7000/speed;
dx = ( 15 * speed ) / 100;
double rand = ( Math.random()* 10 ) + 5;
if ( pointCount % 2 == 0 )
dy = -dx/rand;
else
dy = dx/rand;
for ( int i = 0 ; i <= 100 ; i++ ) // delay keeps ball still for a few seconds
{
try
{
Thread.sleep( 10 );
}
catch ( InterruptedException e )
{
}
repaint();
}

for ( int i = 0 ; i <= cycles ; i++ ) // moves ball across tennis court
{
try
{
Thread.sleep( 10 );
}
catch ( InterruptedException e )
{
}
// update the x and y coordinates for the ball
currX = currX + dx;
currY = currY + dy;
repaint();
} //close for loop
isMoving = false;
} //close run
public void update( Graphics g )
{
paint( g );
}
public void paint( Graphics g )
{
offscreen.setColor( getBackground() );
offscreen.fillRect( 0, 0, getSize().width, getSize().height );
offscreen.setColor ( Color.yellow );
offscreen.fillOval( (int)currX , (int)currY , 10, 10 );
offscreen.setColor ( Color.white );
offscreen.drawRect( 84, 66, 312, 108 );
offscreen.drawLine( 240, 66, 240, 174 );
offscreen.drawLine( 156, 120, 324, 120 );
offscreen.drawLine( 156, 66, 156, 174 );
offscreen.drawLine( 324, 66, 324, 174 );
offscreen.setColor( Color.green );
if ( started == true )
offscreen.drawString( scoreLine, scoreLoc, 20 );
else
offscreen.drawString( instructions, scoreLoc, 20 );
g.drawImage( imageOffScreen , 0 , 0 , this );
} // close paint
public void mouseEntered( MouseEvent evt ) { }
public void mouseExited( MouseEvent evt ) { }
public void mouseReleased( MouseEvent evt ) { }
public void mouseClicked( MouseEvent evt ) { }
public void keyTyped( KeyEvent evt ) { }
public void keyReleased( KeyEvent evt ) { }
} // close TennisCanvas
}

22 years ago
I created a little game in which the user can choose an opponent, then try to return that opponent's tennis serve by clicking on the moving ball. The user sometimes needs to hit the New Game button to get the game's attention when it first starts up. After that, the game runs well on my Windows machine and those of several friends, but the two people who have tried it on a Mac say it doesn't work at all. Reportedly, on a Mac with IE, the court appears but doesn't function, and on a Mac with Netscape, only a gray box appears. I don't know which versions of Java the Macs were running, but both were probably quite recent versions.
If you can spot something in the following source code that would make the game fail on a Mac, I would greatly appreciate your help.
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
public class TennisReturnGame extends Applet
{
Graphics offscreen ;
Image imageOffScreen ;
Button newGame;
Choice choice;
String scoreLine, instructions;
static String userscore = "0";
static String proscore = "0";
boolean started = false;
boolean isMoving = false;
boolean gameOver = false;
FontMetrics fm; // needed for centering message
int scoreLoc;
public void init()
{
setBackground( new Color( 0, 120, 0 ) );
setLayout( new BorderLayout( 3, 3 ) );
TennisCanvas court = new TennisCanvas( );
add( court, BorderLayout.CENTER );
Panel controlPanel = new Panel();
controlPanel.setBackground( new Color( 220, 200, 180 ) );
add( controlPanel, BorderLayout.SOUTH );
Panel topPanel = new Panel();
topPanel.setBackground( new Color( 220, 200, 180 ) );
add( topPanel, BorderLayout.NORTH );
fm = getFontMetrics( getFont() );
instructions = "Click once to activate. Spacebar initiates serve. Delays are built in.";
scoreLoc = 240 - ( fm.stringWidth( instructions )/2 );
newGame = new Button( "New Game" );
newGame.addActionListener( court );
newGame.setBackground( Color.lightGray );
topPanel.add( newGame );
choice = new Choice(); // user chooses opponent, which will determine ball speed
choice.addItem( "Greg Rusedski 149 mph" );
choice.addItem( "Venus Williams 127 mph" );
choice.addItem( "Conchita Martinez 98 mph" );
choice.addItem( "PeeWee Phenom 77 mph" );
choice.addItem( "Uncle Seymour 50 mph" );
choice.setBackground( Color.white );
controlPanel.add( new Label( " Opponent:" ) );
controlPanel.add( choice );
imageOffScreen = createImage( getSize().width, getSize().height );
offscreen = imageOffScreen.getGraphics();
court.proChoice = choice;
}

public Insets getInsets()
{
return new Insets( 3, 3, 3, 3 );
}

class TennisCanvas extends Canvas implements ActionListener, Runnable, KeyListener, MouseListener
{
double currX , currY ; // position of ball
double dy = ( Math.random()* 3 ) + 1; // change in ball's y position
double dx = 15;
int speed = 50;
int pointCount;
Thread animator;
Choice proChoice;
TennisCanvas() // constructor
{
setBackground( new Color( 0, 120, 0 ) );
currX = 84;
currY = 125;
addKeyListener( this );
addMouseListener( this );
animator = new Thread( this );
animator.start();
}
public int setSpeed() // speed based on opponenet chosen by user
{
int choiceIndex = proChoice.getSelectedIndex();
switch ( choiceIndex )
{
case 0:
return 75;
case 1:
return 64;
case 2:
return 49;
case 3:
return 39;
case 4:
return 25;
default:
return 50;
}
}

public void actionPerformed( ActionEvent evt ) // New Game button starts new game
{
String command = evt.getActionCommand();
if ( command.equals( "New Game" ) )
startNew();
}
public void startNew() // resets scores and starts new game
{
setBackground( new Color( 0, 120, 0 ) );
pointCount = 0;
isMoving = false;
started = false;
gameOver = false;
userscore = "0";
proscore = "0";
fm = getFontMetrics( getFont() );
scoreLine = "Opponent's score: " + proscore + " Your score: " + userscore;
instructions = "Click once to activate. Spacebar initiates serve.";
scoreLoc = 240 - ( fm.stringWidth( instructions )/2 );
repaint();
}
public void keyPressed( KeyEvent evt ) // hitting space bar initiates serve
{
int code = evt.getKeyCode();
if ( code == KeyEvent.VK_SPACE && isMoving == false && gameOver == false )
{
currX = 84;
if ( pointCount % 2 == 0 )
currY = 125;
else
currY = 110;
animator = new Thread( this );
animator.start();
}
}
public void mousePressed( MouseEvent evt ) // user tries to hit moving ball with mouse click
{
if ( started == false ) // first mouse click activates game but doesn't count as a "swing" at the ball
{
started = true;
newScore();
}
// if user clicks within 20 pixels of ball, user gets the point
else if ( evt.getX() > 324 && Math.abs( evt.getX() - ( currX + 5 ) ) <= 20 && ( Math.abs( evt.getY() - ( currY + 5 ) ) <= 20 ) )
{
dx = -dx;
dy = -dy;
addToUser();
}
else // otherwise, opponent gets the point
{
addToPro();
}
}
public void addToUser() // gives point to user
{
if ( gameOver == false && isMoving == true )
{
if ( userscore.equals( "0" ) )
userscore = "15";
else if ( userscore.equals( "15" ) )
userscore = "30";
else if ( userscore.equals( "30" ) )
userscore = "40";
else if ( userscore.equals( "40" ) ) // user wins game
{
userscore = "GAME!";
gameOver = true;
setBackground( new Color( 204, 102, 0 ) );
}
pointCount++;
newScore();
}
}
public void addToPro() // gives point to opponent
{
if ( isMoving == true && gameOver == false )
{
if ( proscore.equals( "0" ) )
proscore = "15";
else if ( proscore.equals( "15" ) )
proscore = "30";
else if ( proscore.equals( "30" ) )
proscore = "40";
else if ( proscore.equals( "40" ) ) // opponent wins game
{
proscore = "GAME!";
gameOver = true;
setBackground( new Color( 204, 102, 0 ) );
}
pointCount++;
newScore();
}
}
public void newScore() // updates score
{
scoreLine = "Opponent's score: " + proscore + " Your score: " + userscore;
fm = getFontMetrics( getFont() );
scoreLoc = 240 - ( fm.stringWidth( scoreLine )/2 );
repaint();
}

public void run()
{
isMoving = true;
speed = setSpeed();
int cycles = 7000/speed;
dx = ( 15 * speed ) / 100;
double rand = ( Math.random()* 10 ) + 5;
if ( pointCount % 2 == 0 )
dy = -dx/rand;
else
dy = dx/rand;
for ( int i = 0 ; i <= 100 ; i++ ) // delay keeps ball still for a few seconds
{
try
{
Thread.sleep( 10 );
}
catch ( InterruptedException e )
{
}
repaint();
}

for ( int i = 0 ; i <= cycles ; i++ ) // moves ball across tennis court
{
try
{
Thread.sleep( 10 );
}
catch ( InterruptedException e )
{
}
// update the x and y coordinates for the ball
currX = currX + dx;
currY = currY + dy;
repaint();
} //close for loop
isMoving = false;
} //close run
public void update( Graphics g )
{
paint( g );
}
public void paint( Graphics g )
{
offscreen.setColor( getBackground() );
offscreen.fillRect( 0, 0, getSize().width, getSize().height );
offscreen.setColor ( Color.yellow );
offscreen.fillOval( (int)currX , (int)currY , 10, 10 );
offscreen.setColor ( Color.white );
offscreen.drawRect( 84, 66, 312, 108 );
offscreen.drawLine( 240, 66, 240, 174 );
offscreen.drawLine( 156, 120, 324, 120 );
offscreen.drawLine( 156, 66, 156, 174 );
offscreen.drawLine( 324, 66, 324, 174 );
offscreen.setColor( Color.green );
if ( started == true )
offscreen.drawString( scoreLine, scoreLoc, 20 );
else
offscreen.drawString( instructions, scoreLoc, 20 );
g.drawImage( imageOffScreen , 0 , 0 , this );
} // close paint
public void mouseEntered( MouseEvent evt ) { }
public void mouseExited( MouseEvent evt ) { }
public void mouseReleased( MouseEvent evt ) { }
public void mouseClicked( MouseEvent evt ) { }
public void keyTyped( KeyEvent evt ) { }
public void keyReleased( KeyEvent evt ) { }
} // close TennisCanvas
}
22 years ago