Home | Tools and articles | Donate
Israeli Space Force | Santa Presents Delivery
 




Ping Pong with GameApplet / Alex Zak


As I promised some time ago, I will make a step by step example on how to use GameApplet to write games in Java.
Today, I will write a PingPong game, using the three classes I described
.
Note: because my hosting will not allow .java files I changed them to .java.txt


Description of the game

The ping pong game will have two components: a bat and a ball. The bat will be controlled
with the mouse, while the ball will bounce off the bat and the boundaries of the applet.

A new Game class

I start by creating a new class, that is called PingPong, and it extends Game.java.
I will not have a constructor for PingPong, all things that should be done in the begining are to be placed in init().
In init(), I resize the applet size, by calling resize(300,300). Now the applet will be 300 pixels wide,
and 300 pixels high (note that most browsers will not resize the applet, so you must define the width and height of the
applet in the html file). I also call setSleepTime(60);, so that 60 milliseconds pass between each call to paint().
I would also want the background to be black, so I override getBackgroundColor() (actualy, the default is also black,
but I add this part to demonstrate how to change backgrounds).
Finaly, I need to override paint(Graphics g) because it's abstract, so I will make it draw the bat. The code, up until now, looks like this:

package pingpong1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;

public class PingPong extends Game {
public static final int BATWIDTH=60;
public static final int BATHEIGHT=20;
private int batX=150, batY=200;

public void init(){
resize(600,600);
setSleepTime(50);

}
public Color getBackgroundColor(){
return Color.black;
}

public void paint(Graphics g) {
g.setColor(Color.red); //To make the bat red
Point mp=gp.getMousePosition(); //point mp will hold the coordinates of the mouse
if(mp!=null)
{
//Then, if the mouse is in the game window, it's coordinates are copied to
//batX and batY. If the mouse is out of the game window, batX and batY will not change.
batX=mp.x;
batY=mp.y;
}
//finaly, to draw the bat, I call the Garphics method fillRect, that draws and fills
//a rectangle.
g.fillRect(batX-BATWIDTH/2,batY-BATHEIGHT/2,BATWIDTH,BATHEIGHT);
}
}

Do not forget to change the game class to PingPong in GameApplet.java:

game=new PingPong();

You can see how the applet should look now here.
By now, you might want to include your applet in a website. To do this, change the package of your classes to
pingpong1 (to do it in eclipse, right click on the package name in the Package Explorer, choose refactor,
and rename). Then create a directory called 'pingpong1', and copy there all the '.class' files. Finaly, put an '.html'
file in the same dirctory where 'pingpong1' directory resides, and put this code there:

<applet code="pingpong1.GameApplet.class" width=600 height=600>
</applet>

The ball

Like the bat, the ball's cordinates will be kept as two ints:

	private int ballX=150, ballY=50;

I will also keep the speed of the ball as two ints:

	private int ballSpeedX=0; //the ball speed on the X axis
private int ballSpeedY=8; //the ball speed on the Y axis

Note that in Java, an increase in Y means going down. Therefore, in the begining the ball will go straight down.
I still did not make the ball move, though. So I add this code in the beggining of paint():

	ballX=ballX+ballSpeedX;
ballY=ballY+ballSpeedY;

I would also want to draw the ball. So in the end of paint, I add this:

	g.setColor(Color.green);
g.fillOval(ballX-BALLRADIUS,ballY-BALLRADIUS,BALLRADIUS*2,BALLRADIUS*2);

Now, the hardest part: making the ball bounce off the bat and the walls. I will write this part in a method
called checkCollisions, and it will be called from paint() to make sure that collisions are checked
each time the scene is repainted. Therefore, the paint method will look like this:

	public void paint(Graphics g) {
ballX=ballX+ballSpeedX;
ballY=ballY+ballSpeedY;
checkCollisions();
g.setColor(Color.red); //To make the bat red
Point mp=gp.getMousePosition(); //point mp will hold the coordinates of the mouse
if(mp!=null)
{
//Then, if the mouse is in the game window, it's coordinates are copied to
//batX and batY. If the mouse is out of the game window, batX and batY will not change.
batX=mp.x;
batY=mp.y;
}
//finaly, to draw the bat, I call the Garphics method fillRect, that draws and fills
//a rectangle.
g.fillRect(batX-BATWIDTH/2,batY-BATHEIGHT/2,BATWIDTH,BATHEIGHT);
g.setColor(Color.green);
g.fillOval(ballX-BALLRADIUS,ballY-BALLRADIUS,BALLRADIUS*2,BALLRADIUS*2);
}

Now, let's implement checkCollisions. Collisions with bounds will be simpler, so let's start with them.
When the ball hits the top bound, or one of the sides, it should bounce back, at the same angle it hit. So that if
it hit the top bound, it's x speed will stay the same, while it's y speed will be reversed:

	public void checkCollisions(){
if(ballX-BALLRADIUS<0){
ballSpeedX=-ballSpeedX;
}
if(ballY-BALLRADIUS<0){
ballSpeedY=-ballSpeedY;
}
if(ballX+BALLRADIUS>600){
ballSpeedX=-ballSpeedX;
}

. . .

}

What happens when the ball falls down? Lets put it back in it's initial position:

	if(ballY+BALLRADIUS>600){
ballX=150;
ballY=50;
ballSpeedX=0;
ballSpeedY=9;
}

Now we must handle the bat hitting the ball. In real life, the ball should bounce back in the same angle it
came, just like it bounces off walls. However, almost all such games make a different calculation:
The ball's x speed is greatest when the ball hits the bat near it's edge, while if the ball hits it exactly in the middle, it's x speed will be 0. Then y speed is calculated using Pithagor's theorem (sorry about the math, but it is required here). We will use this calculation.
In order to find out if the ball hit the bat, I use a java class, called Ellipse2D.Double
This class describes an oval (in my case, a circle), and I use it's intersects method to see if it
intersects the bat. So here is the final checkCollisions method:

	public void checkCollisions(){
if(ballX-BALLRADIUS<0){
ballSpeedX=-ballSpeedX;
}
if(ballY-BALLRADIUS<0){
ballSpeedY=-ballSpeedY;
}
if(ballX+BALLRADIUS>600){
ballSpeedX=-ballSpeedX;
}
if(ballY+BALLRADIUS>600){
ballX=150;
ballY=50;
ballSpeedX=0;
ballSpeedY=9;
}
Ellipse2D.Double ball=new Ellipse2D.Double(ballX-BALLRADIUS,ballY-BALLRADIUS,BALLRADIUS*2,BALLRADIUS*2);
if(ball.intersects(batX-BATWIDTH/2,batY-BATHEIGHT/2,BATWIDTH,BATHEIGHT)){
ballSpeedX=(ballX-batX)/5;
ballSpeedY=-(int)Math.sqrt(81-ballSpeedX^2);
}

}

Do not forget to import the required classes:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.geom.*;

That's it. The game is ready. Here is the end result.

Did you find the article useful? Please donate here to support mysuperiorgames.com

If you want to try and play with the code, I have some possible changes you may want to make, to see
if you understand how the code works:

  1. Make the ball change it's color as the game progresses.

  2. Make the ball bounce correctly off the bottom of the bat (right now it passes through the bat
    when it comes from the bottom).

  3. Replace the bat with a 60x20 image. You will want to use the inherited method readBufferedImage.

  4. Count the number of times the ball falls down, and display it somewhere on the screen. You can use g.drawString.

  5. Add a computer controled bat, make the ball stop bouncing from the top bound, and instead reapear at the center.
    When this happens the player should get a point.



Questions, complaints and requests? Send them to admin@mysuperiorgames.com