A Basic Game Tutorial – Part I

This game is written by John Croucher.

In this and following tutorials you will learn about Applets, Threads, Graphics and a few other things. By the end of this tutorial you should have the skills to make basic games in Java. For this tutorial you will be making a simple ‘space invaders’ type game.

I assume that you have basic knowledge of Java as I wont be going into the basic details of how some things work.

First we will be starting by creating an applet and drawing a circle to the applet area.

1. Create a file called ‘Game.java’.
2. Open the file.

The next step is to import the necessary packages. For now we will only be requiring 2 packages:
import java.applet.*;
import java.awt.*;

Now that the importing has been taken care of we will need to set up the Java applet by the following:

public class Game extends Applet implements Runnable
{
}

This basically gives access to the Applet class and the ‘Runnable’ makes it so we can implement threads.

The variables come next as we wish to make these ones global:

Thread gameThread;
int width=400, height=400, MAX=1;
int currentX[] = new int[MAX];
int currentY[] = new int[MAX];

I have decided to use arrays for the X and Y cords now because they will be used at a later stage. It makes it easier to set it up now rather than changing it later.
Next comes the methods. I have included methods that are currently not used at this stage but they are used later.

Start() is used for starting a new thread for the class.

public void start()
{
Thread gameThread = new Thread(this);
gameThread.start();
}

init() is used for setting the initial values

public void init()
{
currentX[0]=0;
currentY[0]=0;
}

run() is the main method we will use later. It is initialised after a new thread is started.

public void run()
{
}

paint() calls update().

public void paint(Graphics g)
{
update(g);
}

update () is where all the actual drawing is done.

public void update(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;

// Set the background color.
g2.setBackground(Color.black);

// Clear the applet.
g2.clearRect(0, 0, width, height);

// Set the drawing color to green.
g2.setColor(Color.green);

//(X pos, Y pos, Width, Height)
g2.fillOval(currentX[0], currentY[0], 20,20);
}

If you compile and run this applet it will draw a green circle on a black background. This is pretty simple and pretty boring but it sets the basis up for doing things later. At this stage you do not even need the Thread but I thought I would put it in now to make it more easy later.

Now I will go into something more interesting but still rather useless. We will now make the circle bounce around the screen.

In this version I have added more global variables:

int speed=10; // Speed at which we will move the objects

// Which direction to move the object
int directionX[] = new int[MAX];
int directionY[] = new int[MAX];

These variables are used for making sure the applet doesn’t go psycho fast on very fast computers and also to make sure it doesn’t run to slow on slow computers.

long start=0;
long tick_end_time;
long tick_duration;
long sleep_duration;

static final int MIN_SLEEP_TIME = 10;
static final int MAX_FPS = 20;
static final int MAX_MS_PER_FRAME = 1000 / MAX_FPS;

float fps=0;

Only two functions are modified in this version. The first modification is a simple one. All it does is sets the value in directionX[0] to 1 which means that it will travel to the left first, and directionY[0] to 0 which means it will travel to the top first:

public void init()
{
currentX[0]=100;
currentY[0]=0;

directionX[0]=1;
directionY[0]=0;
}

This module as I said earlier this is the main function and as you will notice this one has the biggest amount of code in it now, so this may take a bit to explain. First here is the run() code in full.

public void run()
{
while(true){
start = System.currentTimeMillis();

for(int i=0; i < MAX; i++){
if(directionX[i]==1)
currentX[i]+=speed;

if(directionX[i]==0)
currentX[i]-=speed;

if(currentX[i] = width)
directionX[i]=0;

if(directionY[i]==1)
currentY[i]+=speed;

if(directionY[i]==0)
currentY[i]-=speed;

if(currentY[i] = height)
directionY[i]=0;
}

repaint();

tick_end_time = System.currentTimeMillis();
tick_duration = tick_end_time - start;
sleep_duration = MAX_MS_PER_FRAME - tick_duration;

if (sleep_duration < MIN_SLEEP_TIME)
{
sleep_duration = MIN_SLEEP_TIME;
}
fps = 1000 / (sleep_duration + tick_duration);

try{
Thread.sleep(sleep_duration);
} catch(InterruptedException e) {}

}
}

Now onto explaining the function. First this function will continually loop. This is what gives our game moving objects.
The next line is:
start = System.currentTimeMillis();

This line is part of our frame rate calculations. It will set the start time to the system time at the start of the frame.

The next section is a for loop containing the code for calculating the objects position and where to move it to next. The X and Y cords are similar so I will only explain the X cord:

These first two if statements are used for calculating the new position in relation to its current X value:

if(directionX[i]==1)
currentX[i]+=speed;

This says if the current object is moving right then add ‘speed’ to the current position of the object. Basically if the object is at X:0 and the speed is 10, then the new X position will be 10 (0 + 10).

if(directionX[i]==0)
currentX[i]-=speed;

This section does the opposite to the previous if statement (moves to left).

These last two detect if the object has hit the side of the applet and if so change the direction:
if(currentX[i] <= 0)
directionX[i]=1;

If the current X position is less than or equal to zero then change the direction so it now moves to the right.

if(currentX[i]+20 >= width)
directionX[i]=0;

Again this one does similar but it detects if the object has hit the right side of the applet. This one has a small variation in the checking tho. You will notice it has:

currentX[i]+20

The current X value of the object is at cord 0 of the object (its left most side). This means that X will only be greater than or equal to the width after all of the right hand size has gone out of the applet. So we must add 20 which is the width of the object. Feel free to remove the +20 or change it to higher and smaller values to observe the effects it has.

That concludes the collision detection section.
Next you will see:
repaint();

Basically all this line does is calls the functions for painting on the screen paint() and update(). I think it does some internal calculations before going to those functions first tho.

You are probably thinking this is all a bit much right now, but don’t worry, only 2 more sections to go.

tick_end_time = System.currentTimeMillis();
tick_duration = tick_end_time - start;
sleep_duration = MAX_MS_PER_FRAME - tick_duration;

if (sleep_duration < MIN_SLEEP_TIME)
{
sleep_duration = MIN_SLEEP_TIME;
}
fps = 1000 / (sleep_duration + tick_duration);

This code is pretty simple and self explanatory so I won’t go into details. But basically it works out how long it has taken to draw the current frame. If the system is lagging it will ‘sleep_duration’ reduce ‘sleep_duration’ and if it’s going to fast it will increase ‘sleep_duration’. The sleep time is done in this final section:

try{
Thread.sleep(sleep_duration);
} catch(InterruptedException e) {}

This will simply pause the thread for the value in ‘sleep_duration’. This is all done to make sure the game runs at its best on all systems.

If you want you can display the current frame rate by placing this line of code in your paint(Graphics g) function:
g.drawString("FPS: "+fps,1,400);

Also be aware that that calculation doesn’t always give the correct frame rate. It is simply to regulate the speed of the app.

Well if you compile all that and run it you should get a green circle bouncing around your screen.
You will also notice that it flickers a lot especially if you increase the frame rate. This is because you can actually see the computer drawing the objects to the screen. In the next tutorial I will explain how to do frame buffering which will make your objects run smooth, and more.

5 Responses to A Basic Game Tutorial – Part I

  1. Joshua says:

    I cant get this to compile, could you please include your src?

  2. frozenade says:

    sure. i’ll upload the source for you.
    but i’m kinda little busy right now. i am now doing my final assignment as my college.
    please remind me if i probably forgot.😉

  3. Joshua says:

    Yea man its been over a week now and im really eager to check this thing out :)heres the reminder

  4. frozenade says:

    sorry buddy,it late..😉

    i’ve posted a new post. check it out!🙂

  5. Joshua says:

    Thanks, can you add me to MSN i need help with 1 little part of my game. porchemasi@hotmail.com

    thanks again!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: