Part 2: What About Threads?
Java Game Programming Tutorial
Getting Started
To program in the Java language, you will need to install the free Java Development Kit (JDK) on your system.
You can find the latest version of the JDK, documentation, and online tutorials here at the JDK Download Site.
You will also require a Java-enabled web browser to view the tutorial examples.
My aim is not to teach every aspect of Java programming but to help those with a bit of programming knowledge with graphics and game programming issues in Java relating to web pages and the internet. I hope you find it helpful.
Download javaGameProgrammingTutorialClasses.zip to receive the following classes:
- DBuffer.class
- Flicker.class
- FXCycle.class
- FXImage.class
- Hello.class
- Lines.class
Part 2: What About Threads?
Programs run from start to finish, executing a single thread of
control. Tasks are performed in linear sessions, where one task
must wait for another task to be completed before it can have its
turn. This is the schematic of a single-threaded program.
Naturally, multithreading is the execution of several threads at
the same time where each task is performed in parallel with other
tasks. Each thread receives a priority value and is allocated a
certain amount of system time or attention based on this.
Threads apply well to Java because each applet can run in its own
thread without interferring with or hogging system resources. On
web pages, this enables users to download files in the background
while listening to sounds and viewing animations. More than one
applet can run on the same page and each will receive an amount
of time to advance in its current task.
I will now step through parts of the next thread example (Lines.java):
public class Lines extends Applet implements Runnable {
The format here is the same as for the class Hello in Part 1 except
it now implements the runnable interface, meaning that Lines is a
multithreaded applet class.
Thread lineThread;
This is a thread variable declaration for the operation of
recalculating and drawing lines. When an operation continues
for a long time, as an animation, it is often given its own
thread separate from the applet thread.
int x1 = 0;
int y1 = 0;
int x2 = 0;
int y2 = 0;
float red, green, blue;
Color lineColor;
These are just variable declarations for the line coordinates,
drawn from (x1,y1) to (x2,y2) and the line color arguments.
public void init() {
setBackground(Color.black);
}
As discussed in Part 1, this is the first stage in the applet's
activity; the init method. Here, our method will override the
default init method, and set the background color to black.
public void start() {
if(lineThread==null) {
lineThread = new Thread(this);
lineThread.start();
}
}
The next stage is the start method above which creates a new
thread if it has not already been created. The new keyword
helps to allocated dynamic memory for the line's thread before
it is called to start.
public void stop() {
if(lineThread!=null) {
lineThread.stop();
lineThread = null;
}
}
The stop method is the second to last stage of the applet life
cycle which mirrors the start method. It checks to see if the
thread is still running and if so, it is stopped and de-allocated.
public void paint(Graphics g) {
g.setColor(lineColor);
g.drawLine(x1,y1,x2,y2);
}
This is the paint method which receives the graphics context or
applet window as a parameter. After the window is erased, this
method is called to draw graphics whenever the window is changed.
Our method simply sets the drawing color to the current line
color and draws a single line, using the variable coordinates.
The next method is more complex so I will try to break it down
into parts. All the code within it runs within its own thread.
This is the run method, required because we declared the class
as runnable.
public void run() {
while(true) {
This statement starts an infinite loop within the run method to
keep the thread going forever until the applet is shut down.
x1 = (int)(Math.random() * this.size().width);
x2 = (int)(Math.random() * this.size().width);
y1 = (int)(Math.random() * this.size().height);
y2 = (int)(Math.random() * this.size().height);
red = (float)Math.random();
green = (float)Math.random();
blue = (float)Math.random();
lineColor = new Color(red,green,blue);
These code fragments are less important to threads but I will
explain. The next line coordinates are random numbers within
the applet window boundaries. Three random color arguments
are also generated to reset the line color.
repaint();
Calling repaint ensures that our paint method is called, which
draws a new line using the freshly calculated coordinates/color.
try {
lineThread.sleep(50);
}
catch(InterruptedException e) {}
}
}
This is the end of the run method but the code above is very
important. Without this part in the infinite loop of the run
method, the line would be drawn too fast and not allow other
applets to execute as efficiently. Thus, the line thread is
told to go to sleep for 50 milliseconds. This conveniently
delays our drawing and allows other threads to go to work.
This is a common way of doing things for simple applets.
}
Already, we've reached the end of the applet!
<HTML>
<APPLET CODE="Lines.class" WIDTH=100 HEIGHT=100>
</APPLET>
</HTML>
Here's the complete Java code:
// Lines.java
// by Garry Morse
import java.awt.*;
import java.applet.*;
public class Lines extends Applet implements Runnable {
Thread lineThread;
int x1 = 0;
int y1 = 0;
int x2 = 0;
int y2 = 0;
float red, green, blue;
Color lineColor;
public void init() {
setBackground(Color.black);
}
public void start() {
if(lineThread==null) {
lineThread = new Thread(this);
lineThread.start();
}
}
public void stop() {
if(lineThread!=null) {
lineThread.stop();
lineThread = null;
}
}
public void paint(Graphics g) {
g.setColor(lineColor);
g.drawLine(x1,y1,x2,y2);
}
public void run() {
while(true) {
x1 = (int)(Math.random() * this.size().width);
x2 = (int)(Math.random() * this.size().width);
y1 = (int)(Math.random() * this.size().height);
y2 = (int)(Math.random() * this.size().height);
red = (float)Math.random();
green = (float)Math.random();
blue = (float)Math.random();
lineColor = new Color(red,green,blue);
repaint();
try {
lineThread.sleep(50);
}
catch(InterruptedException e) {}
}
}
}
|