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.