Java Tutorial - PONG
Java syntax is similar to C. Comments come in two forms:
/*Multiple
Lines*/
and...
//Single Line
It's a good idea to preface your code with some basic information
like what the heck it does!
/***************************************************
filename: pong.java
version: 1.0
author: Allen Schunk
purpose: replicate the the old favorite 'pong' in a java applet.
usage:
<APPLET CODE="pong.class" NAME="pong" WIDTH="400" HEIGHT="400">
<PARAM NAME="bg_color" VALUE="000000008">
</APPLET>
***************************************************/
Java makes use of classes. Classes are bits of code representing objects with methods and
properties. Well written classes require very little knowledge by the user of what goes
on in their code. The methods and properties are given names that make their usage obvious.
Wee will see some of this in our example but first we have to tell the compiler what external
packages of these classes we will need.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.*;
Java can produce stand alone applications but more frequently and in our example it is used
to make an applet. Applets run within a browser and can accomplish most of the task html cannot.
We will create a new class called "pong" which will extend (inherit properties and methods from)
the class "applet". Our class "pong" will also need to use the mouse and continue to run until
the user decides to quit so we add the classes MouseListener and Runnable. Java has standard
types like boolean, int, double and you can declare variables for classes like Color, String, Image
etc.
public class pong extends Applet implements MouseListener, Runnable{
final static int PADDLE_LEN = 10;
Color bgColor = new Color(0);
int cx,cy,px,py,ax,ay; //c=center,p=player,a=android(computer)
boolean DrawScore = true;
double dx,dy,bx,by; //d=delta, b=ball
int aScore=0,pScore=0;
Thread runner;
Image Buffer; //buffers for flickerless drawing
Graphics gBuffer;
The class "applet" has the methods init,start,stop,update,paint,print and destroy. Here we override the
init method to get the parameter "bg_color" and initialize our variables. We also create a graphics
buffer so we can do flickerless graphics and add a "listener" for mouse events.
public void init( ) { //get parameters and initialize settings
if( getParameter("bg_color") != null)
{bgColor = new Color(Integer.parseInt(getParameter("bg_color")));}
cx = (int)size().width/2;
cy = (int)size().height/2;
bx = (double)cx;
by = (double)cy;
dx = 5;dy = 0;
ay = cy;py = cy;
ax = 10;px = cx*2-10;
Buffer=createImage(size().width,size().height);
gBuffer=Buffer.getGraphics();
addMouseListener( this );
}
To use the mouse "listener" we override it's methods.
When the mouse is clicked we will change the players y position.
We have to override the events mouseClicked,mouseReleased,mouseEntered and mouseExited because they are
virtual methods (no default implementation, just declared). The class MouseListener is called a virtual
class for this reason.
public void mousePressed( MouseEvent e ) {
int y = e.getY( );
py = y; //change the players y position when they press the mouse
}
public void mouseClicked( MouseEvent e ) {} //these other mouse events aren't used
public void mouseReleased( MouseEvent e ) {}
public void mouseEntered( MouseEvent e ) {}
public void mouseExited( MouseEvent e ) {}
When the applet starts and stops we will start and stop running our thread.
In the run method of our thread we will repaint the screen every 50ms.
If the screen is uncover and needs to be updated we will repaint it as well.
public void start() //start the thread
{
if (runner == null){
runner = new Thread (this);
runner.start();
}
}
public void stop() //stop the thread
{
if (runner != null){
runner.stop();
runner = null;
}
}
public void run() //repaint the screen every 50ms
{
while(true){
try {runner.sleep(50);}
catch (Exception e) { }
repaint();
}
}
public void update(Graphics g)
{
paint(g);
}
The repainting of the form is where all the action takes place.
We do all of our work in the buffer (Graphics gBuffer) and then slap the buffer on the screen (Graphics g).
With the "Graphics" class we can set the properties for color and font and use methods to draw strings and rectangles.
The pseudo code is:
Make the android chase the ball.
Redraw the score if neccessary.
Draw the centerline, players and ball.
Move the new image to the screen.
If the android hit the ball make it bounce of.
If the player hit the ball make it bounce of.
If the android scored give him a point.
If the player scored give him a point.
If the ball hits the wall make it bounce off.
If either score is greater than 20 then stop the thread and display GAME OVER.
public void paint (Graphics g)
{
if (ayby){ay-=5;}
gBuffer.setColor(bgColor);
gBuffer.setFont(new Font("Helvetica", Font.BOLD,10));
if (DrawScore) { //only redraw the score if neccessary
gBuffer.fillRect(0,0,size().width,size().height);
gBuffer.setColor(Color.green);
gBuffer.drawString("PONG",cx-15,25);
gBuffer.drawString("Android:"+aScore,25,size().height-25);
gBuffer.drawString("Player:"+pScore,cx+25,size().height-25);
DrawScore = false;
}
else {
gBuffer.fillRect(0,50,size().width,size().height-100);
}
gBuffer.setColor(Color.green);
gBuffer.drawRect(cx-1,50,2,cy * 2 - 100); //center line
gBuffer.drawRect(ax-1,ay-PADDLE_LEN,2,PADDLE_LEN * 2); //android paddle
gBuffer.drawRect(px-1,py-PADDLE_LEN,2,PADDLE_LEN * 2); //player paddle
gBuffer.drawRect((int)bx-1,(int)by-1,2,2); //ball
g.drawImage (Buffer,0,0, this); //copy the buffer to the screen
if (((int)(bx + dx) < 12) && (((int)(by + dy)>(ay-PADDLE_LEN)) && ((int)(by + dy)<(ay+PADDLE_LEN)))){
dx = -dx; //if the android hit the ball change its direction
dy = (by + dy)-(ay);
}
if (((int)(bx + dx) > (size().width - 12)) && (((int)(by + dy)>(py-PADDLE_LEN)) && ((int)(by + dy)<(py+PADDLE_LEN)))){
dx = -dx; //if the player hit the ball change its direction
dy = (by + dy)-(py);
}
if ((int)(bx + dx) < 0) { //player scores
pScore += 1;
bx = cx;
dx = -5;
dy = 0;
DrawScore = true;
}
if ((int)(bx + dx) > cx * 2) { //android scores
aScore += 1;
bx = cx;
dx = 5;
dy = 0;
DrawScore = true;
}
// if the ball hits the wall change its direction
if (((int)(by + dy) < 55) || ((int)(by + dy) > cy * 2 - 55)){dy = -dy;}
bx = bx + dx; //update the ball position
by = by + dy;
if ((aScore>20)||(pScore>20)) {
g.setColor(Color.red);
g.drawString("GAME OVER",cx-30,cy);
runner.stop();
}
}
For more info on java and to download a free compiler go to sun.
This tutorial was written with the jdk 1.1.8.