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

📄 ch7.htm

📁 21天学会Java游戏编程
💻 HTM
📖 第 1 页 / 共 4 页
字号:
&nbsp;&nbsp;public TarantulaVector(Background back) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;super(back);<BR>
&nbsp;&nbsp;}<BR>
<BR>
&nbsp;&nbsp;public int add(Sprite s) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Only allow up to 10 sprites at once
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if (size() &lt;= 10)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return super.add(s);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;return -1;<BR>
&nbsp;&nbsp;}<BR>
<BR>
&nbsp;&nbsp;protected boolean collision(int i, int iHit) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Do nothing!<BR>
&nbsp;&nbsp;&nbsp;&nbsp;return false;<BR>
&nbsp;&nbsp;}<BR>
}</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The <TT><FONT FACE="Courier">TarantulaVector</FONT></TT> class
probably has a lot less code than you might have guessed, because
the majority of the derived functionality in Sim Tarantula is
carried out in the three sprite classes you just covered. You
really only need to have the <TT><FONT FACE="Courier">TarantulaVector</FONT></TT>
class for two reasons: limiting the maximum number of sprites
and eliminating collision actions.
<P>
Limiting the number of sprites that can be added to the sprite
list is necessary because the performance of the applet starts
dragging if you get too many tarantulas running around. Also,
it becomes very difficult to see what is happening if too many
sprites are on the screen at one time. The solution is an overridden
version of the <TT><FONT FACE="Courier">add</FONT></TT> method,
which simply checks to see how many sprites are currently in the
list and only adds new sprites if it is under the limit.
<P>
Getting rid of collision actions isn't absolutely necessary, but
it helps make the animation look a little more realistic. You
might recall that the default <TT><FONT FACE="Courier">collision</FONT></TT>
method in <TT><FONT FACE="Courier">Sprite</FONT></TT> causes two
sprites that collide to bounce off each other. In the case of
tarantulas, it actually looks better having them just walk over
each other, so you simply supply a <TT><FONT FACE="Courier">collision</FONT></TT>
method that returns false and all is well.
<P>
At this point, you have all the support classes necessary to move
on to the applet itself. You'll see that the applet has little
responsibility in regard to the specifics of Sim Tarantula, because
the derived sprite classes basically take care of themselves.
This is a direct benefit of using an object-oriented design approach.
<H3><A NAME="TheSimTarantulaClass"><B>The </B><TT><B><FONT SIZE=4 FACE="Courier">SimTarantula</FONT></B></TT><B><FONT SIZE=4>
Class</FONT></B></A></H3>
<P>
The <TT><FONT FACE="Courier">SimTarantula</FONT></TT> class models
the applet itself and takes care of all the dirty work related
to setting up the sprite classes. Because the overhead of managing
the sprite classes is very similar, much of the code in the <TT><FONT FACE="Courier">SimTarantula</FONT></TT>
class is the same as that in the <TT><FONT FACE="Courier">Atoms</FONT></TT>
class you developed yesterday. Knowing that, it makes more sense
to focus on the code in <TT><FONT FACE="Courier">SimTarantula</FONT></TT>
that is new, such as the <TT><FONT FACE="Courier">init</FONT></TT>
method:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public void init() {<BR>
&nbsp;&nbsp;// Load and track the images<BR>
&nbsp;&nbsp;tracker = new MediaTracker(this);<BR>
&nbsp;&nbsp;back = getImage(getCodeBase(), &quot;Res/Back.gif&quot;);
<BR>
&nbsp;&nbsp;tracker.addImage(back, 0);<BR>
&nbsp;&nbsp;Tarantula.initResources(this, tracker, 0);<BR>
&nbsp;&nbsp;Spiderling.initResources(this, tracker, 0);<BR>
&nbsp;&nbsp;Spidercide.initResources(this, tracker, 0);<BR>
}</FONT></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">init</FONT></TT> method takes care
of initializing all the resources for the different sprites. This
is done by calling the static <TT><FONT FACE="Courier">initResource</FONT></TT>
method for each. A <TT><FONT FACE="Courier">MediaTracker</FONT></TT>
class is passed in so that the image resources can be tracked.
<P>
The <TT><FONT FACE="Courier">run</FONT></TT> method is the workhorse
for <TT><FONT FACE="Courier">SimTarantula</FONT></TT> and is somewhat
similar to the <TT><FONT FACE="Courier">run</FONT></TT> method
implemented in the <TT><FONT FACE="Courier">Atoms</FONT></TT>
class. Listing 7.4 contains the source code for the <TT><FONT FACE="Courier">run</FONT></TT>
method in <TT><FONT FACE="Courier">SimTarantula</FONT></TT>.
<HR>
<BLOCKQUOTE>
<B>Listing 7.4. The </B><TT><B><FONT FACE="Courier">SimTarantula</FONT></B></TT><B>
class's </B><TT><B><FONT FACE="Courier">run</FONT></B></TT><B>
method.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public void run() {<BR>
&nbsp;&nbsp;try {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;tracker.waitForID(0);<BR>
&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;catch (InterruptedException e) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;return;<BR>
&nbsp;&nbsp;}<BR>
<BR>
&nbsp;&nbsp;// Create and add some spiderlings<BR>
&nbsp;&nbsp;tv = new TarantulaVector(new ImageBackground(this,
back));<BR>
&nbsp;&nbsp;for (int i = 0; i &lt; 5; i++) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;Point pos = tv.getEmptyPosition(new Dimension(
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Spiderling.image[0].getWidth(this),
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Spiderling.image[0].getHeight(this)));
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;tv.add(new Spiderling(this, pos));<BR>
&nbsp;&nbsp;}<BR>
<BR>
&nbsp;&nbsp;// Update everything<BR>
&nbsp;&nbsp;long t = System.currentTimeMillis();<BR>
&nbsp;&nbsp;while (Thread.currentThread() == animate) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;tv.update();<BR>
&nbsp;&nbsp;&nbsp;&nbsp;repaint();<BR>
&nbsp;&nbsp;&nbsp;&nbsp;try {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t += delay;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(Math.max(0, t
- System.currentTimeMillis()));<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;&nbsp;&nbsp;catch (InterruptedException e) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;}<BR>
}</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The <TT><FONT FACE="Courier">run</FONT></TT> method creates the
<TT><FONT FACE="Courier">TarantulaVector</FONT></TT> object and
passes an <TT><FONT FACE="Courier">ImageBackground</FONT></TT>
object into its constructor. This gives Sim Tarantula a desert
background image and makes the animation a lot more realistic.
Five <TT><FONT FACE="Courier">Spiderling</FONT></TT> objects are
then created and added to the tarantula vector. This is all it
takes to get the simulation underway.
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
If you recall, the <TT><FONT FACE="Courier">TarantulaVector</FONT></TT> class takes a <TT><FONT FACE="Courier">Background</FONT></TT> object as its only constructor parameter. However, in <TT><FONT FACE="Courier">SimTarantula</FONT></TT> the <TT><FONT 
FACE="Courier">TarantulaVector</FONT></TT> object is constructed using an object of type <TT><FONT FACE="Courier">ImageBackground</FONT></TT>. This is a very neat usage of the object-oriented design of the sprite and background classes. You can use a 
completely different type of background simply by passing a different type of <TT><FONT FACE="Courier">Background</FONT></TT> derived object into the <TT><FONT FACE="Courier">TarantulaVector</FONT></TT> constructor.
</BLOCKQUOTE>

</TD></TR>
</TABLE></CENTER>
<P>
<P>
The rest of the <TT><FONT FACE="Courier">SimTarantula</FONT></TT>
class is basically the same as <TT><FONT FACE="Courier">Atoms</FONT></TT>,
with the exception of different text in the applet title that
is displayed while the images are loading. With that, you have
a complete tarantula simulator applet with lots of cool derived
sprite objects that interact with each other.
<H2><A NAME="Summary"><B><FONT SIZE=5 COLOR=#FF0000>Summary</FONT></B></A>
</H2>
<P>
Although you didn't cover a lot of new territory in theory, you
made huge strides in this lesson in regard to practical sprite
usage. You started off by deriving a powerful new sprite class
that gives sprites a sense of direction. You followed up on this
by designing a simple tarantula simulator and putting it together
piece by piece. Although the tarantula simulator isn't technically
a game, it is about as close as you can get in terms of deriving
new sprites that interact with each other. With this knowledge,
you are empowered to create sophisticated applets with more complex
sprites that can work together to do more than just give the illusion
of movement.
<P>
You might be thinking at this point that it's time to jump into
writing a complete Java game. Although you are technically almost
ready, the next lesson changes the pace a little by introducing
you to handling user input in games. By learning how to handle
user input, you'll clear a major hurdle on your way to writing
full-blown Java games.
<H2><A NAME="QA"><B><FONT SIZE=5 COLOR=#FF0000>Q&amp;A</FONT></B></A>
<BR>
</H2>

<TABLE>
<TR VALIGN=TOP><TD WIDTH=50><B>Q</B></TD><TD><B>Why derive a directional sprite?</B>
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=50><B>A</B></TD><TD>A directional sprite is a sprite with a more specific purpose. In object-oriented programming, any time you have an object that extends another object, you should derive from the original object and add the new 
functionality. In this case, the <TT><FONT FACE="Courier">DirectionalSprite</FONT></TT> class inherits all the functionality of the original <TT><FONT FACE="Courier">Sprite</FONT></TT> class, while adding its own specific features.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=50><B>Q</B></TD><TD><B>Can the <TT><B><FONT FACE="Courier">DirectionalSprite</FONT></B></TT> class be used to model sprites with more than eight directions?</B>
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=50><B>A</B></TD><TD>Unfortunately, no. The <TT><FONT FACE="Courier">DirectionalSprite</FONT></TT> class is specifically designed to support exactly eight directions. It could be redesigned to be more general, in which case you 
would probably need to change the constructor to accept a parameter specifying the number of directions.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=50><B>Q</B></TD><TD><B>Why do I have to use sprite actions to do something as simple as adding a new sprite to the sprite list?</B>
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=50><B>A</B></TD><TD>Because you are trying to add a sprite from within another sprite. Sprites have no concept of the sprite list, so they don't know how to add sprites. The sprite actions define a communication protocol between 
the sprites and the sprite list that enables sprites to indirectly manipulate the list.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=50><B>Q</B></TD><TD><B>Why are the spiderlings and spidercides implemented as sprites?</B>
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=50><B>A</B></TD><TD>Because they are frame animations that need to be able to interact with the tarantula sprites. More generally, they are separate conceptual objects that are well suited for the sprite model provided by the <TT 
VALIGN=TOP><FONT FACE="Courier">Sprite</FONT></TT> class. Remember that just because an object isn't moving and bouncing around doesn't mean that it isn't a good candidate for a sprite.
</TD></TR>
</TABLE>
<P>
<H2><A NAME="Workshop"><B><FONT SIZE=5 COLOR=#FF0000>Workshop</FONT></B></A>
</H2>
<P>
The Workshop section provides questions and exercises to help
you get a handle on the material you learned today. Try to answer
the questions and at least briefly ponder the exercises before
moving on to tomorrow's lesson. You'll find the answers to the
questions in appendix A, &quot;Quiz Answers.&quot;
<H3><A NAME="Quiz"><B>Quiz</B></A></H3>
<OL>
<LI>How are directions modeled in the <TT><FONT FACE="Courier">DirectionalSprite</FONT></TT>
class?
<LI>How do the velocity multipliers in the <TT><FONT FACE="Courier">DirectionalSprite</FONT></TT>
class work?
<LI>How do the tarantulas determine when to give birth to new
spiderlings?
<LI>How do the tarantulas determine when to die?
<LI>Why do you need to derive the <TT><FONT FACE="Courier">TarantulaVector</FONT></TT>
class, as opposed to just using the <TT><FONT FACE="Courier">SpriteVector</FONT></TT>
class?
</OL>
<H3><A NAME="Exercises"><B>Exercises</B></A></H3>
<OL>
<LI>Modify <TT><FONT FACE="Courier">DirectionalSprite</FONT></TT>
so that it can be used to model sprites with any number of directions.
<LI>Modify Sim Tarantula to use the new <TT><FONT FACE="Courier">DirectionalSprite</FONT></TT>
class.
<LI>Think about how cool (and scared) I felt when I saw a real
tarantula in the wild while riding my mountain bike.
<LI>Write a <TT><FONT FACE="Courier">Food</FONT></TT> class to
model food that the tarantulas can eat.
<LI>Modify the <TT><FONT FACE="Courier">TarantulaVector</FONT></TT>
class to detect collisions between the tarantulas and the food.
<LI>Modify the <TT><FONT FACE="Courier">Tarantula</FONT></TT>
class to extend the life of the tarantulas when they eat food.
<LI>Design your own graphics for the sprites and background to
create a different type of simulation. SimSasquatch maybe?
</OL>
<P>
<HR WIDTH="100%"></P>

<CENTER><P><A HREF="ch6.htm"><IMG SRC="pc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="index.htm"><IMG SRC="hb.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="#CONTENTS"><IMG SRC="cc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="ch1rev.htm"><IMG 
SRC="nc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A></P></CENTER>

<P>
<HR WIDTH="100%"></P>

</BODY>
</HTML>

⌨️ 快捷键说明

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