⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch7.htm

📁 21天学会用JAVA开发网络游戏 书籍语言: 简体中文 书籍类型: 程序设计 授权方式: 免费软件 书籍大小: 287 KB 书籍等级: 整理时间: 2004-1
💻 HTM
📖 第 1 页 / 共 4 页
字号:
&nbsp;&nbsp;// Add spider?<BR>
&nbsp;&nbsp;if (action.get(Tarantula.SA_ADDTARANTULA))<BR>
&nbsp;&nbsp;&nbsp;&nbsp;return new Tarantula(component, new Point(position.x,
position.y));<BR>
&nbsp;&nbsp;return null;<BR>
}</FONT></TT>
</BLOCKQUOTE>
<P>
<TT><FONT FACE="Courier">addSprite</FONT></TT> checks for the
<TT><FONT FACE="Courier">SA_ADDTARANTULA</FONT></TT> action flag
and creates the new tarantula if it is set. The newly created
<TT><FONT FACE="Courier">Tarantula</FONT></TT> object is then
returned so that it can be added to the sprite list.
<P>
The next extended sprite class used in Sim Tarantula is the <TT><FONT FACE="Courier">Tarantula</FONT></TT>
class, which you might have suspected models a tarantula. The
following are the member variables defined in the <TT><FONT FACE="Courier">Tarantula</FONT></TT>
class:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public static final int SA_ADDTARANTULA
= 3,<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SA_ADDSPIDERLING
= 4,<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SA_ADDSPIDERCIDE
= 5;<BR>
public static Image[][] image;<BR>
protected static Random rand = new Random(<BR>
&nbsp;&nbsp;System.currentTimeMillis());</FONT></TT>
</BLOCKQUOTE>
<P>
Probably the most important aspect of the <TT><FONT FACE="Courier">Tarantula</FONT></TT>
class is the addition of the custom sprite actions. These three
actions define a mechanism to add <TT><FONT FACE="Courier">Tarantula</FONT></TT>,
<TT><FONT FACE="Courier">Spiderling</FONT></TT>, and <TT><FONT FACE="Courier">Spidercide</FONT></TT>
objects. Notice that the actions are assigned increasing integer
values beginning with <TT><FONT FACE="Courier">3</FONT></TT>.
This is extremely important because the standard sprite actions
defined in the <TT><FONT FACE="Courier">Sprite</FONT></TT> class
are already assigned the values <TT><FONT FACE="Courier">0</FONT></TT>,
<TT><FONT FACE="Courier">1</FONT></TT>, and <TT><FONT FACE="Courier">2</FONT></TT>.
If you recall, the sprite actions are actually flags used in a
<TT><FONT FACE="Courier">BitSet</FONT></TT> object to pass actions
back and forth between individual sprites and the sprite list.
<P>
The <TT><FONT FACE="Courier">Image</FONT></TT> member variable,
<TT><FONT FACE="Courier">image</FONT></TT>, is simply used to
hold the array of images for the sprite. The <TT><FONT FACE="Courier">Tarantula</FONT></TT>
class also contains a <TT><FONT FACE="Courier">Random</FONT></TT>
object member variable, <TT><FONT FACE="Courier">rand</FONT></TT>.
This member variable is defined as static and is used to provide
random numbers for all <TT><FONT FACE="Courier">Tarantula</FONT></TT>
objects. It is seeded with the current system time, which is a
useful way to help guarantee randomness.
<P>
The constructor for <TT><FONT FACE="Courier">Tarantula</FONT></TT>
is very simple and alleviates having to pass a bunch of specific
parameters:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public Tarantula(Component comp, Point
pos) {<BR>
&nbsp;&nbsp;super(comp, image, 0, 1, 2, pos, new Point(1, 1),
50,<BR>
&nbsp;&nbsp;&nbsp;&nbsp;Sprite.BA_WRAP, 0);<BR>
}</FONT></TT>
</BLOCKQUOTE>
<P>
The tarantula is given a bounds action of <TT><FONT FACE="Courier">BA_WRAP</FONT></TT>,
which means that it can roam off one side of the applet window
and back onto the other side.
<P>
Similar to the one in <TT><FONT FACE="Courier">Spiderling</FONT></TT>,
the <TT><FONT FACE="Courier">initResources</FONT></TT> method
for <TT><FONT FACE="Courier">Tarantula</FONT></TT> loads all the
images used by the class:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public static void initResources(Applet
app, MediaTracker tracker,<BR>
&nbsp;&nbsp;int id) {<BR>
&nbsp;&nbsp;image = new Image[8][2];<BR>
&nbsp;&nbsp;for (int i = 0; i &lt; 8; i++) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;for (int j = 0; j &lt; 2; j++) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;image[i][j] = app.getImage(app.getCodeBase(),
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;Res/Tarant&quot;
+ i + j + &quot;.gif&quot;);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tracker.addImage(image[i][j],
id);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;}<BR>
}</FONT></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">update</FONT></TT> method is where
most of the action takes place in <TT><FONT FACE="Courier">Tarantula</FONT></TT>.
Listing 7.1 shows the source code for the <TT><FONT FACE="Courier">update</FONT></TT>
method.
<HR>
<BLOCKQUOTE>
<B>Listing 7.1. The </B><TT><B><FONT FACE="Courier">Tarantula</FONT></B></TT><B>
class's </B><TT><B><FONT FACE="Courier">update</FONT></B></TT><B>
method.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public BitSet update() {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Randomly change direction<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if ((rand.nextInt() % 10) == 0) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;velocity.x = velocity.y =
1;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setDirection(direction + rand.nextInt()
% 2);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Call parent's update()<BR>
&nbsp;&nbsp;&nbsp;&nbsp;BitSet action = super.update();<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Give birth?<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if (rand.nextInt() % 250 == 0) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action.set(Sprite.SA_ADDSPRITE);
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action.set(Tarantula.SA_ADDSPIDERLING);
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Die?<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if (rand.nextInt() % 250 == 0) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action.set(Sprite.SA_KILL);
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action.set(Sprite.SA_ADDSPRITE);
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action.set(Tarantula.SA_ADDSPIDERCIDE);
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;return action;<BR>
&nbsp;&nbsp;}</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The <TT><FONT FACE="Courier">update</FONT></TT> method first handles
giving the tarantula its ability to roam by randomly altering
the direction. The superclass <TT><FONT FACE="Courier">update</FONT></TT>
method is then called so that all the default handling can take
place. The <TT><FONT FACE="Courier">update</FONT></TT> method
then randomly decides whether a new <TT><FONT FACE="Courier">Spiderling</FONT></TT>
object should be created. If so, the <TT><FONT FACE="Courier">SA_ADDSPRITE</FONT></TT>
and <TT><FONT FACE="Courier">SA_ADDSPIDERLING</FONT></TT> flags
are set. Similarly, <TT><FONT FACE="Courier">update</FONT></TT>
randomly decides whether a <TT><FONT FACE="Courier">Spidercide</FONT></TT>
object should be created. If so, the <TT><FONT FACE="Courier">SA_KILL</FONT></TT>,
<TT><FONT FACE="Courier">SA_ADDSPRITE</FONT></TT>, and <TT><FONT FACE="Courier">SA_ADDSPIDERCIDE</FONT></TT>
flags are set. The <TT><FONT FACE="Courier">SA_KILL</FONT></TT>
flag takes care of killing the <TT><FONT FACE="Courier">Tarantula</FONT></TT>
object itself, while the other two cause the new <TT><FONT FACE="Courier">Spidercide</FONT></TT>
object to be created.
<P>
The last method in <TT><FONT FACE="Courier">Tarantula</FONT></TT>
is <TT><FONT FACE="Courier">addSprite</FONT></TT>, which handles
creating <TT><FONT FACE="Courier">Spiderling</FONT></TT> and <TT><FONT FACE="Courier">Spidercide</FONT></TT>
objects that are to be added to the sprite list:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">protected Sprite addSprite(BitSet action)
{<BR>
&nbsp;&nbsp;// Add spiderling?<BR>
&nbsp;&nbsp;if (action.get(Tarantula.SA_ADDSPIDERLING))<BR>
&nbsp;&nbsp;&nbsp;&nbsp;return new Spiderling(component, new Point(position.x,
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position.y));<BR>
<BR>
&nbsp;&nbsp;// Add spidercide?<BR>
&nbsp;&nbsp;else if (action.get(Tarantula.SA_ADDSPIDERCIDE))<BR>
&nbsp;&nbsp;&nbsp;&nbsp;return new Spidercide(component, new Point(position.x,
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position.y));<BR>
<BR>
&nbsp;&nbsp;return null;<BR>
}</FONT></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">addSprite</FONT></TT> method checks
the sprite action flags and creates a new sprite, if necessary.
<TT><FONT FACE="Courier">addSprite</FONT></TT> then makes sure
to return the newly created sprite so that it can be added to
the sprite list.
<P>
Last but not least is the <TT><FONT FACE="Courier">Spidercide</FONT></TT>
class, which models a dying tarantula with a simple frame animation.
The <TT><FONT FACE="Courier">Spidercide</FONT></TT> class is very
similar to <TT><FONT FACE="Courier">Spiderling</FONT></TT>, because
they both act effectively as temporary animations. Listing 7.2
contains the source code for the <TT><FONT FACE="Courier">Spidercide</FONT></TT>
class.
<HR>
<BLOCKQUOTE>
<B>Listing 7.2. The </B><TT><B><FONT FACE="Courier">Spidercide</FONT></B></TT><B>
class.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public class Spidercide extends Sprite
{<BR>
&nbsp;&nbsp;protected static Image[] image = new Image[4];<BR>
<BR>
&nbsp;&nbsp;public Spidercide(Component comp, Point pos) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;super(comp, image, 0, 1, 20, pos, new
Point(0, 0), 30,<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sprite.BA_DIE);<BR>
&nbsp;&nbsp;}<BR>
<BR>
&nbsp;&nbsp;public static void initResources(Applet app, MediaTracker
tracker,<BR>
&nbsp;&nbsp;&nbsp;&nbsp;int id) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt; 4; i++) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;image[i] = app.getImage(app.getCodeBase(),
&quot;Res/Spcide&quot; +<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i + &quot;.gif&quot;);
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tracker.addImage(image[i],
id);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;}<BR>
<BR>
&nbsp;&nbsp;public BitSet update() {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;BitSet action = new BitSet();<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Die?<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if (frame &gt;= 3) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action.set(Sprite.SA_KILL);
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return action;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Increment the frame<BR>
&nbsp;&nbsp;&nbsp;&nbsp;incFrame();<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;return action;<BR>
&nbsp;&nbsp;}<BR>
}</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
You can undoubtedly see a lot of similarities between <TT><FONT FACE="Courier">Spidercide</FONT></TT>
and <TT><FONT FACE="Courier">Spiderling</FONT></TT>. As a matter
of fact, the only significant difference between the two is that
the <TT><FONT FACE="Courier">Spidercide</FONT></TT> class doesn't
add new sprites. Of course, it also provides its own unique frame
images. Otherwise, you've seen all this code before in the <TT><FONT FACE="Courier">Spiderling</FONT></TT>
class, so I won't go over it again.
<P>
There is actually one other sprite-related class in Sim Tarantula
that you need to learn about before moving on to the applet class.
I'm referring to the <TT><FONT FACE="Courier">TarantulaVector</FONT></TT>
class, which is derived from <TT><FONT FACE="Courier">SpriteVector</FONT></TT>
and provides features specific to the Sim Tarantula sprite classes.
Listing 7.3 contains the source code for <TT><FONT FACE="Courier">TarantulaVector</FONT></TT>.
<HR>
<BLOCKQUOTE>
<B>Listing 7.3. The </B><TT><B><FONT FACE="Courier">TarantulaVector</FONT></B></TT><B>
class.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public class TarantulaVector extends
SpriteVector {<BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -