Download Building a Java First-Person Shooter

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
3D Java Game Programming – Episode 17.5
Building a Java First-Person Shooter
Episode 17.5 – Creating an Applet
In this episode CHERNO discusses how to run our game in a web browser. Java can be created to run as
an application or as an applet in a web browser. In order to run as an applet additional code will need to
be added.
Creating a new Class
The new class MinefrontApplet.java shall be added to the project under the package
com.mime.minefront. This class will extend the JApplet class located in
javax.swing.JApplet (CHERNO uses the AWT Applet class but we opt for the Swing version).
An applet gets set up and managed by a browser in an area defined in an html file. From the browser
point of view an applet runs in its own thread. A key point to remember is that a Java applet does not
have a main() method. An applet provides one or more methods to be invoked by the browser thread.
The typical signature for a Java Applet is:
public class MyWildApplet extends JApplet {
:
:
}
There are five key classes an applet implements to perform initialization, starting, stopping, destroying
and painting.
public void init() {
:
}
The web browser first invokes the init() method as soon as the applet completes loading. We would
place into this method the processing of initial parameters that may have been provided in the html file
or the loading of images. You will also create any other objects that will be used to implement the
functionality or logic of the applet.
public void start() {
:
}
The start() method is invoked after the init() method. This method can be invoked several times
during an applet’s lifetime. If the applet was stopped (e.g. paused, user went to another web page,
minimized the screen, etc.) then this is where you would put the code to start the applet up again.
public void stop() {
:
1
3D Java Game Programming – Episode 17.5
}
The stop() method may be invoked by the browser when the user exits the html page the applet is
running on, or you can have a “pause” button on the screen that will invoke stop(). By default, when
the reader leaves a page, any threads the applet has started will continue to run. By implementing logic
in the stop() method you can suspend execution of the thread in which the applet is running.
public void destroy() {
:
}
The destroy() method enables the applet to release resources and clean up. We usually don’t
implement this method.
The key method implemented by an applet is the paint(Graphics g) method:
public void paint(Graphics g) {
:
}
The method above is invoked each time to draw on the screen – it defines what the applet looks and
does for the user. So here is a simple applet.
Table 1 - SimpleApplet01
import javax.swing.JApplet;
public class SimpleApplet01 extends JApplet {
private static final long serialVersionUID = 1L;
}
2
3D Java Game Programming – Episode 17.5
Figure 1 - Resutls of running SimpleApplet01.java
As you can see from running in Eclipse the applet does come up and show an empty window frame
when we have no code for the construction and definition of the window – this is because the contents
in which the applet will run is set up and maintained by the browser.
Here is a version where we implement the methods init() and paint() methods:
Table 2 - SimpleApplet02.java
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JApplet;
public class SimpleApplet02 extends JApplet {
private static final long serialVersionUID = 1L;
private int width;
private int height;
@Override
public void init() {
setBackground(Color.YELLOW);
setForeground(Color.RED);
width = getWidth();
height = getHeight();
}
@Override
public void paint(Graphics g) {
g.drawLine(0, 0, width / 2, height / 2);
}
3
3D Java Game Programming – Episode 17.5
}
Figure 2 - Results of running SimpleApplet02.java
You don’t always need to add a paint() method within the applet class. In the next example we are going
to create a helper class for our SimpleApplet03.java example. In this helper class we will do actual
drawing to the component space.
Table 3- MainDisplay.java
import
import
import
import
import
java.awt.Canvas;
java.awt.Color;
java.awt.Graphics;
java.awt.Point;
java.util.Random;
public class MainDisplay extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
private boolean running = false;
private Thread thread = null;
private Color currentColor;
private Point screenLocation = null;
private Random rng = null;
public MainDisplay() {
rng = new Random();
screenLocation = new Point();
}
public synchronized void start() {
4
3D Java Game Programming – Episode 17.5
if (running ) {
return;
}
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop() {
if (!running) {
return;
}
running = false;
try {
thread.join();
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
@Override
public void run() {
// just to do something ... let's update the color and location we plan
on drawing to
// on the screen
while (running) {
currentColor = new Color(rng.nextInt(256), rng.nextInt(256),
rng.nextInt(256));
screenLocation.x = rng.nextInt(getWidth());
screenLocation.y = rng.nextInt(getHeight());
// sleep a bit
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
// ignore
}
repaint();
}
}
public void paint(Graphics g) {
g.setColor(currentColor);
g.fillRect(screenLocation.x, screenLocation.y, 4, 4);
}
}
The helper class above is similar in spirit to the Minefront Display.java class. It extends the java
Canvas class and implements the Runnable interface. The java Canvas class is a component that
5
3D Java Game Programming – Episode 17.5
represents a blank rectangular area of the screen onto which the application can draw or from which
the application can trap input events from the user. The paint() method must be overridden in order
to perform custom graphics on the canvas screen.
This auxiliary class merely sets a new color and position on the screen (in the portion that would be
equivalent to our game loop) in two field properties: currentColor and screenLocation. The
class constructor merely initializes the random number generator rng and the screenLocation
Point. The start() method gets our independent thread (that runs the game loop) up and running
(same as in Minefront). The stop() method will sent the running flag off and force the game
loop (and therefore the thread) to stop. The game loop is represented in the while loop in the run()
method. It does not do much of anything just update the current color and location we will draw a small
rectangle on the screen. The run() method calls the repaint() method in order to get the new and
updated rectangle drawn whenever the applet container invokes the paint() method for all the
components defined in the applet.
Table 4 - SimpleApplet03.java
import javax.swing.JApplet;
public class SimpleApplet03 extends JApplet {
private static final long serialVersionUID = 1L;
MainDisplay mySimpleDisplay = null;
public void init() {
mySimpleDisplay = new MainDisplay();
add(mySimpleDisplay);
}
public void start() {
mySimpleDisplay.start();
}
public void stop() {
mySimpleDisplay.stop();
}
}
The class SimpleApplet03.java uses our auxiliary class to perform all the work.
Our final version of SimpleApplet04.java uses a slightly different auxiliary class that matches in spirit
(with respect to drawing) the episode’s Display.java class.
6
3D Java Game Programming – Episode 17.5
We don’t use the typical paint() method but follow the technique used in our episodes which is to have
our game loop set up the next screen in the game loop and invoke a render() method to display the next
screen.
Table 5 - MainDisplay2.java
import
import
import
import
import
import
java.awt.Canvas;
java.awt.Color;
java.awt.Graphics;
java.awt.Point;
java.awt.image.BufferStrategy;
java.util.Random;
public class MainDisplay2 extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
private boolean running = false;
private Thread thread = null;
private Color currentColor;
private Point screenLocation = null;
private Random rng = null;
public MainDisplay2() {
rng = new Random();
screenLocation = new Point();
}
public synchronized void start() {
if (running ) {
return;
}
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop() {
if (!running) {
return;
}
running = false;
try {
thread.join();
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
@Override
7
3D Java Game Programming – Episode 17.5
public void run() {
// just to do something ... let's update the color and location we plan
on drawing to
// on the screen
while (running) {
currentColor = new Color(rng.nextInt(256), rng.nextInt(256),
rng.nextInt(256));
screenLocation.x = rng.nextInt(getWidth());
screenLocation.y = rng.nextInt(getHeight());
// sleep a bit
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
// ignore
}
render();
}
}
private void render() {
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
// first set the background
g.setColor(Color.black);
g.fillRect(0, 0, getWidth(), getHeight());
// Draw the random rectangle
g.setColor(currentColor);
g.fillRect(screenLocation.x, screenLocation.y, 4, 4);
g.dispose();
bs.show();
}
}
The differences between MainDisplay2.java and MainDisplay.java are highlighted above. The run()
method now invokes the render() method rather than repaint(). The render() method implements a
buffer strategy in order to draw in one internal buffer screen and switch screens completely in order to
avoid tearing and flickering on the screen. The graphics object is obtained from the BufferStrategy
object and used to draw our screen. The other difference is that here we set the background to black in
order to match the initial background color of the back buffer.
8
3D Java Game Programming – Episode 17.5
In using these simple applets and helper classes we wanted to highlight how the new changes we are
introducing work with the current game engine architecture we are using in these video episodes
without cluttering them with the 3D aspects and input handling elements.
This is how our new Applet class looks like:
Table 6 - MinefrontApplet.java
package com.mime.minefront;
import java.awt.BorderLayout;
import javax.swing.JApplet;
public class MinefrontApplet extends JApplet {
private static final long serialVersionUID = 1L;
private Display display = new Display();
public void init() {
setLayout(new BorderLayout());
add(display);
}
public void start() {
display.start();
}
public void stop() {
display.stop();
}
}
That is it. If you run it (as an applet) you may see a small screen as shown below.
9
3D Java Game Programming – Episode 17.5
Figure 3 - Our application running as an applet
In order get the window size to match in Eclipse to the application window size perform the following
steps:



Right-click on the MinefrontApplet.java file
Select Run As | Run Configurations…
Click on the (x) = Parameters tab
Figure 4 - Setting Screen Size
10
3D Java Game Programming – Episode 17.5


Click on “Apply”
Now “Run”
Your applet will now run in a window that matches the window frame 800 x 600.
What is synchronization all about?
When of the changes we made in the Display.java class was to the methods start() and stop() was to add
the keyword “synchronization” to both. Here they go:
Exporting as Jar File
The next step we want to do is generate a jar file for the Java Applet version in order to be able to run
the game from an Internet html page. We do the following:



Highlight the Minefront project
File | Export
Select Java folder – JAR file
Figure 5 - Exporting an applet JAR file

Click on Next>
11
3D Java Game Programming – Episode 17.5
Figure 6 - JAR file specification



Select src and resources directory
Enter and name and location for the applet JAR file
Click on “Finish”
The JAR file is NOT a runnable JAR file as we created in Episode 16.5.
Creating HTML file to test our JAR file

Open a text editor (e.g. notepad) and enter the following HTML code
Table 7 - Minefront.html
<!DOCTYPE html>
<HTML>
<HEAD>
<TITLE>Minefront Applet</TITLE>
</HEAD>
12
3D Java Game Programming – Episode 17.5
<BODY bgcolor="#222222">
<BR><P></P>
<BR><P></P>
<CENTER>
<APPLET CODE="com.mime.minefront.MinefrontApplet" archive="MinefrontApplet.jar" width="800"
height="600">
</APPLET>
</CENTER>
</BODY>
</HTML>


Save the file as “Minefront.html” in the same directory where you saved the JAR file created for
the applet
Open up with a browser
Figure 7 - Applet running in Chrome web browser
13