FAQ 4f
Updated: 1/18/00
>>>>>> How do I keep the game moving like Huntmaster?
=====================================================
A game that waits for user input before changed the game state or
updating the screen is called an 'event driven' game.
A game that runs continuously, updates the screen frequently, and responds
immediately to game controls is called an 'arcade style' game.
To create an arcade style game, you will need to implement a code loop.
The primary method of operating a code loop is to create a Thread().
You will need to override the Applet functions start() and stop().
These functions are called by the Applet's browser or window to tell the
Applet that it is visible or hidden.
Here is an example of using an external Thread class to continuously
update a game:
// 'TrailsApplet' code file
import java.applet.*;
import java.awt.*;
import java.lang.*;
class TrailsApplet extends Applet {
Point dest,loc;
TrailsThread runner;
TrailsApplet(){
runner = new TrailsThread(this);
dest = new Point();
loc = new Point();
}
public void init(){
dest.setLocation(getBounds().width/2,getBounds().height/2);
loc.setLocation(dest);
}
public void update(Graphics g){paint(g);}
public void paint(Graphics g){
long ticks = System.currentTimeMillis();
g.setColor( // pick a semi-random color
new Color((ticks/4)&255,(ticks/64)&255,(ticks/1024)&255));
g.fillOval(loc.x-10,loc.y-10,20,20);
}
public void mouseDown(Event e,int x,int y){
dest.setLocation(x,y);
return false;
}
public void start(){runner.start();}
public void stop(){runner.stop();}
void moveBall(){
if (loc.x<dest.x-10) loc.x += 10;
else if (loc.x>dest.x+10) loc.x -= 10;
else loc.x = dest.x;
if (loc.y<dest.y-10) loc.y += 10;
else if (loc.y>dest.y+10) loc.y -= 10;
else loc.y = dest.y;
}
}
class TrailsThread extends Thread {
TrailsApplet papa;
TrailsThread(TrailsApplet who){papa=who;}
public void run(){ // called by start, halted by stop
while (true) { // infinite code loop
papa.moveBall();
papa.repaint();
try {sleep(100);} // waits for 100 milliseconds before continuing
catch (InterruptedException e){}
}
}
}
This application will remember where you clicked, then move a ball towards
that place. It will leave a colorful trail behind, since the screen is not
cleared as the ball moves.
Note that every function in these two classes was overwritten with
the sole exception of moveball().
The code loop in TrailsThread.run() has a call to sleep(). The sleep function
will pause the thread for some number of milliseconds before returning to
continue the loop. During this pause, the CPU will go about performing tasks
assigned to other threads (attached to all sorts of other applications).
If you don't include the sleep() function, you will see your CPU usage jump
to 100%. Trying to use other applications (like your browser) will become
difficult.
If you want to create a game with a stable image (not flashing and trailing
like this example) then look at the advanced answer of FAQ_3c. This explains
the use of an offscreen buffer to avoid image flicker.
:::::: Frame Rates
==================
Frame Rate is the number of times per second that your screen gets redrawn.
High frame rates make your animations smooth. Unfortunately, slow systems
will force you to deal with low frame rates.
In the example above, your frame rate has been limited by the sleep
functions. There are 1000 milliseconds in each second. Since we pause for 100
milliseconds each cycle, that means that the most cycles you can have in one
second is 1000 / 10 = 10 fps (frames per second).
I'm usually happy with 12 fps. Movies in the theatre are displayed at 24 fps.
The same movies on your television are displayed at 30-60 fps (but they have to
be faster to cover up their scan line).
You also have to be careful with your game-state updates. If it takes too long to
change your game-state then you could either lose frames or worse, get inconsistent
times between frames.
:::::: Try and Catch
====================
Some functions throw exceptions when there is a problem. If you don't 'catch' the exceptions
then your application will halt. When you catch an exception, you need to decide how to handle it.
Will it cause the function to fail? Will it lead to other code failing? You decide what to do.
'try' has a pair of brackets {} that can encompass as much code as you like.
'catch' will catch the type of exceptions thrown inside the 'try' code.
It also has a pair of brackets {} so you can respond with as much code as you need.
How do you know if a function throws an exception? Once again, open up your JDK folders
(see FAQ_2d) and find the function in question. Here is the definition of the
function that throws the InterruptedException:
public static native void sleep(long millis) throws InterruptedException;
Please remember that Exceptions are CLASSES just like everything else in java. I had to
import java.lang.* at the top of my ImageApplet in order to reference InterruptedException().
I could have been more specific with my import command. I could have done this:
import java.lang.InterruptedException;