📄 the java game programming tutorial part iii.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0057)http://www.intergate.bc.ca/personal/iago/javatut/jtp3.htm -->
<HTML><HEAD><TITLE>The Java Game Programming Tutorial: Part III</TITLE>
<META content="text/html; charset=windows-1252" http-equiv=Content-Type>
<META content="Garry Morse" name=Author>
<META content="MSHTML 5.00.2614.3500" name=GENERATOR>
<META content="An expanding tutorial on Java 2D/3D game programming"
name=Description>
<META
content=Java,Java,Java,Java,Java,Java,Java,Java,Java,Java,Java,Java,Java,Java,Java,Java,Java
name=KeyWords></HEAD>
<BODY aLink=#ff0000 bgColor=#ffffdf link=#0000ee text=#000000 vLink=#551a8b>
<H1><A href="http://www.intergate.bc.ca/personal/iago/javatut/index.htm"><IMG
align=ABSCENTER border=0 height=85
src="The Java Game Programming Tutorial Part III_ficheiros/coffee.gif"
width=116></A><FONT color=#804040><FONT size=+2><A
href="http://www.intergate.bc.ca/personal/iago/javatut/index.htm">The Java Game
Programming Tutorial</A></FONT></FONT></H1>
<H1>
<HR width="100%">
</H1>
<H2>Part III: What about Images?</H2>
<UL>
<P>One of the most important aspects of animation are images in<BR>various
formats. From 2D to 3D software, they are often used<BR>to simulate motion and
reduce calculations. Eons ago, little<BR>flipbooks were the technology whereby
each page of the book<BR>had a different drawing and the rapid flipping
created the<BR>illusion that a character was moving. </P>
<P>It is such a simple principle now inherent in best selling<BR>games and
block buster movies. Each image frame just gets<BR>fancier and the 'flipper'
has ranged from projection reels<BR>to computers in the past. Now, through the
magic of Java<BR>programming, we can build our own animations on the
internet<BR>for the entire world to see. I'll show you how. </P>
<P>Since we're going to be dealing with images from this point<BR>forward, I
must explain another aspect of building user<BR>friendly applets: the
MediaTracker class. </P>
<P>The MediaTracker class monitors the status of media types,<BR>such as
images, sounds, etc. A common concern with applets<BR>is that images are
sometimes referred to before they are<BR>fully loaded, which has unpredictable
results. </P>
<P>MediaTracker can load data asynchronously (in the background)<BR>or
synchronously (waits for data to load first). Image loading<BR>is sped up by
threads which dedicate themselves to a group of<BR>images identified by a
selected ID. </P>
<P>Since the Flicker class adopts many techniques used in <A
href="http://www.intergate.bc.ca/personal/iago/javatut/jtp2.htm">Part
2</A>,<BR>I will only go over the changes relevant to image loading
and<BR>rendering. This applet also introduces you to parameters which<BR>give
applets their flexibility. I will explain these as well. </P><PRE><B> MediaTracker flickerTracker;
Image[] flickerImages;</B></PRE>
<P>The applet requires the variables above: an instance of the<BR>MediaTracker
class and an array of image objects. </P><PRE><B> String paramString;
int flickerStart=0, flickerCount=0;
int flickerDelay=0, flickerFrame=0;</B></PRE>
<P>paramString is a string object for storing each parameter value and<BR>the
integers are numbers relevant to the image displaying process. </P><PRE><B> paramString = getParameter("FLICKERDELAY");
flickerDelay = Integer.parseInt(paramString);</B></PRE>
<P>This is code in the init method showing how parameters are
accessed.<BR>Parameters are defined in web page HTML code, making them
variable<BR>without recompiling applets to change some small feature.
<BR>getParameter returns the parameter name in the HTML applet tag by<BR>its
name ("FLICKERDELAY") as type String. In the case above, a<BR>number is
required for the animation delay so we use an Integer<BR>object to convert the
parameter string and put it in our variable. </P><PRE><B> flickerImages = new Image[flickerCount];</B></PRE>
<P>Here, the parameter FLICKERCOUNT will tell the applet how many images
<BR>to animate and allocate the dynamic memory for the array of images. </P><PRE><B> flickerTracker = new MediaTracker(this);</B></PRE>
<P>The MediaTracker object must also be allocated for usage. </P><PRE><B> for(int i=0; i>flickerCount; i++) {
flickerImages[i] = getImage(getCodeBase(),
paramString + flickerStart + ".gif");</B></PRE>
<P>This is a loop which requests each image in the array be loaded from<BR>the
specified file. getCodeBase is the URL location of the applet<BR>and the image
filename is reset for the next file. eg.) image1.gif </P><PRE><B> flickerTracker.addImage(flickerImages[i],0);
flickerStart++;
}</B></PRE>
<P>In the same loop, each image object is added to the MediaTracker<BR>object
as part of the group ID zero. The counter is incremented<BR>to the next image
number. </P><PRE><B> flickerTracker.checkID(0,true);
repaint();
}</B></PRE>
<P>Above, checkID asks the MediaTracker object to load the images
<BR>specified by the ID zero and returns immediately. This <BR>asynchronous
loading which will occur in the background while <BR>the applet continues its
respective stages. Note that repaint <BR>is called which calls the applet's
default update method. </P><PRE><B> public void update(Graphics g) {
paint(g);
}</B></PRE>
<P>We will override the default update method because it erases
the<BR>background before calling the paint method. Our images will
be<BR>scaled to fit the entire applet window so we will just call the
<BR>paint method. </P><PRE><B> if(!flickerTracker.checkAll()) {
g.drawString("Please wait, images loading...",
20,this.size().height/2);
}</B></PRE>
<P>This is inside our customized paint method. The MediaTracker<BR>object will
return false from checkAll() until all the images<BR>are loaded so this
information is used to paint a message for<BR>the user. </P><PRE><B> else {
g.drawImage(flickerImages[flickerFrame],0,0,
this.size().width,this.size().height,this);
}</B></PRE>
<P>Now, when the images have all been loaded, drawImage will be <BR>called to
draw the current image in the array at (0,0), scaled <BR>to the applet width
and height. </P><PRE><B> repaint();
flickerFrame++;
if(flickerFrame >= flickerCount) flickerFrame=0;</B></PRE>
<P>In <A href="http://www.intergate.bc.ca/personal/iago/javatut/jtp2.htm">Part
2</A>, the applet methods are discussed along with the run<BR>method so I've
listed just the animation actions above in the<BR>run method. </P>
<P>Repaint calls update which calls paint which draws the image in<BR>the
array. The image counter is incremented to the next image<BR>number and reset
to the first if the last image is reached. This <BR>cycles through the images
for the life of the applet. </P>
<P>You can reuse this applet with your own gif images numbered in<BR>sequence,
(anim1.gif, anim2.gif, anim3.gif, etc...) Here is <BR>example HTML for running
this applet using parameters for gif<BR>files anim1.gif to anim3.gif with a
delay of 10 milliseconds<BR>between frames: </P>
<UL>
<P><B><APPLET CODE="Flicker.class" WIDTH=50 HEIGHT=50><BR><PARAM
NAME="FLICKERNAME" VALUE="anim"><BR><PARAM NAME="FLICKERSTART"
VALUE="1"><BR><PARAM NAME="FLICKERCOUNT" VALUE="3"><BR><PARAM
NAME="FLICKERDELAY" VALUE="10"><BR></APPLET></B></P></UL>
<P>Here is the applet code in its entirety: </P><PRE><B>// Flicker.java
// by Garry Morse
import java.awt.*;
import java.applet.*;
public class Flicker extends Applet implements Runnable {
Thread flickerThread;
MediaTracker flickerTracker;
Image[] flickerImages;
String paramString;
int flickerStart=0, flickerCount=0;
int flickerDelay=0, flickerFrame=0;
public void init() {
// get parameter for wait delay between images
paramString = getParameter("FLICKERDELAY");
flickerDelay = Integer.parseInt(paramString);
// get parameter for number of image to start with
paramString = getParameter("FLICKERSTART");
flickerStart = Integer.parseInt(paramString);
// get parameter for number of images to load
paramString = getParameter("FLICKERCOUNT");
flickerCount = Integer.parseInt(paramString);
// get parameter for image path and prefix name
paramString = getParameter("FLICKERNAME");
// allocate memory for an array of image objects
flickerImages = new Image[flickerCount];
// create a media tracker object for this applet
flickerTracker = new MediaTracker(this);
// loop for number of images
for(int i=0; i<flickerCount; i++) {
// load each graphic file into memory
flickerImages[i] = getImage(getCodeBase(),
paramString + flickerStart + ".gif");
// add image to list of monitored images with ID zero
flickerTracker.addImage(flickerImages[i],0);
// increment image number to next
flickerStart++;
}
// load images into memory
flickerTracker.checkID(0,true);
repaint();
}
public void start() {
if(flickerThread==null) {
flickerThread = new Thread(this);
flickerThread.start();
}
}
public void stop() {
if(flickerThread!=null) {
flickerThread.stop();
flickerThread = null;
}
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
// if images not loaded yet, inform user
if(!flickerTracker.checkAll()) {
g.drawString("Please wait, images loading...",
20,this.size().height/2);
}
// otherwise erase last image and draw next image in queue
else {
g.drawImage(flickerImages[flickerFrame],0,0,
this.size().width,this.size().height,this);
}
}
public void run() {
while(true) {
repaint();
// reloop through list of images to display
flickerFrame++;
if(flickerFrame >= flickerCount) flickerFrame=0;
// try to shut down thread for milliseconds
try {
flickerThread.sleep(flickerDelay+1);
}
// if exception, output error message
catch(InterruptedException e) {
System.out.println("Thread would not go to sleep.");
}
}
}
}</B></PRE></UL>
<P><FONT size=+1><A
href="http://www.intergate.bc.ca/personal/iago/javatut/flicker.htm">Click here
to see the Flicker animation applet in action!</A></FONT></P>
<P><FONT color=#808080><FONT size=-2>The Java Game Programming Tutorial and all
tutorials within are created by Garry Morse, Copyright
1997</FONT></FONT></P></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -