📄 814-821.html
字号:
<HTML>
<HEAD>
<META name=vsisbn content="1571690433"><META name=vstitle content="Black Art of Java Game Programming"><META name=vsauthor content="Joel Fan"><META name=vsimprint content="Sams"><META name=vspublisher content="Macmillan Computer Publishing"><META name=vspubdate content="11/01/96"><META name=vscategory content="Web and Software Development: Programming, Scripting, and Markup Languages: Java"><TITLE>Black Art of Java Game Programming:The Game of Worm</TITLE>
<!-- HEADER --><STYLE type="text/css"> <!-- A:hover { color : Red; } --></STYLE><META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW"><script><!--function displayWindow(url, width, height) { var Win = window.open(url,"displayWindow",'width=' + width +',height=' + height + ',resizable=1,scrollbars=yes'); if (Win) { Win.focus(); }}//--></script><SCRIPT><!--function popUp(url) { var Win = window.open(url,"displayWindow",'width=400,height=300,resizable=1,scrollbars=yes'); if (Win) { Win.focus(); }}//--></SCRIPT><script language="JavaScript1.2"><!--function checkForQuery(fm) { /* get the query value */ var i = escape(fm.query.value); if (i == "") { alert('Please enter a search word or phrase'); return false; } /* query is blank, dont run the .jsp file */ else return true; /* execute the .jsp file */}//--></script></HEAD><BODY>
<TABLE border=0 cellspacing=0 cellpadding=0>
<tr>
<td width=75 valign=top>
<img src="../1571690433.gif" width=60 height=73 alt="Black Art of Java Game Programming" border="1">
</td>
<td align="left">
<font face="arial, helvetica" size="-1" color="#336633"><b>Black Art of Java Game Programming</b></font>
<br>
<font face="arial, helvetica" size="-1"><i>by Joel Fan</i>
<br>
Sams, Macmillan Computer Publishing
<br>
<b>ISBN:</b> 1571690433<b> Pub Date:</b> 11/01/96</font>
</td>
</tr>
</table>
<P>
<!--ISBN=1571690433//-->
<!--TITLE=Black Art of Java Game Programming//-->
<!--AUTHOR=Joel Fan//-->
<!--AUTHOR=Eric Ries//-->
<!--AUTHOR=Calin Tenitchi//-->
<!--PUBLISHER=Macmillan Computer Publishing//-->
<!--IMPRINT=Sams//-->
<!--CHAPTER=20//-->
<!--PAGES=814-821//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="813-814.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="822-825.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="CENTER"><A NAME="Heading39"></A><FONT COLOR="#000077">Evaluating the Calculations</FONT></H4>
<P>After the above steps have completed, three conditions given below are evaluated, and <I>dpoint[1]</I> is set to the newly calculated value using the GetNewDirection() function given in Listing 20-14. The three conditions are</P>
<DL>
<DD><B>•</B> Is it time to change direction due to dirchange, or has a wall been reached? This is illustrated in Figure 20-10.
<P><A NAME="Fig10"></A><A HREF="javascript:displayWindow('images/20-10.jpg',317,250 )"><IMG SRC="images/20-10t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/20-10.jpg',317,250)"><FONT COLOR="#000077"><B>Figure 20-10</B></FONT></A> Worm selecting new direction dpoint[1] or dpoint[2] upon reaching a wall</P>
<DD><B>•</B> Has the worm reached one of its segments or that of another worm? This is illustrated in Figures 20-11(a) and 20-11(b).
<P><A NAME="Fig11"></A><A HREF="javascript:displayWindow('images/20-11.jpg',563,382 )"><IMG SRC="images/20-11t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/20-11.jpg',563,382)"><FONT COLOR="#000077"><B>Figure 20-11</B></FONT></A> Worm selecting new direction dpoint[1] in illustration (a) and dpoint[2] in illustration (b) due to all preferred paths blocked upon reaching another worm</P>
<DD><B>•</B> Is the new head location empty? This is illustrated in Figure 20-12.
<P><A NAME="Fig12"></A><A HREF="javascript:displayWindow('images/20-12.jpg',319,251 )"><IMG SRC="images/20-12t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/20-12.jpg',319,251)"><FONT COLOR="#000077"><B>Figure 20-12</B></FONT></A> Worm direction dpoint[0] is selected as first choice and is free</P>
</DL>
<P><B>Listing 20-14</B> Based on the old direction of motion, a new direction is returned by GetNewDirection() that is perpendicular to the current direction</P>
<!-- CODE //-->
<PRE>
private Dimension GetNewDirection(Dimension olddir,
int motion)
{
if (olddir.width == 1 || olddir.width == -1) {
dTemp.width = 0;
dTemp.height = motion;
}
else {
dTemp.width = motion;
dTemp.height = 0;
}
return dTemp;
}
</PRE>
<!-- END CODE //-->
<P>The segments are denoted with the symbols S, H, and T, which stand for (body) segment, head, and tail, respectively. Each segment has a subscript of either 1 or 2, where 1 is the target worm and 2 is the colliding worm.
</P>
<P>If the worm has reached a wall or <I>dirchange</I> has expired, then a new direction, <I>dpoint[1]</I>, is chosen at random to the left or to the right of the current head direction. If the worm reaches a worm segment, then the worm is forced to always turn left, and <I>dpoint[1]</I> is set appropriately.</P>
<H4 ALIGN="LEFT"><A NAME="Heading40"></A><FONT COLOR="#000077">Implications for Game Play</FONT></H4>
<P>This seemingly innocuous programming decision of always having the worm turn left has interesting game play ramifications. A player can block a partly coiled autonomous worm in such a way that the worm coils inward until it can no longer move. If this happens, then it will shrink one segment for each call to Next() until either it finds a new way out or it shrinks to the size of a single segment. If the next head location is free, then the head is set to the new position and the tail is dropped, which keeps the size of the autonomous worm constant. This effect is shown in the sequence of Figures 20-13(a) through 20-13(f).
</P>
<P><A NAME="Fig13"></A><A HREF="javascript:displayWindow('images/20-13.jpg',298,238 )"><IMG SRC="images/20-13t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/20-13.jpg',298,238)"><FONT COLOR="#000077"><B>Figure 20-13 (a-f) A</B></FONT></A> The sequence shows how a player can trap an autonomous worm and have it coil in on itself</P>
<P><A NAME="Fig14"></A><A HREF="javascript:displayWindow('images/20-14.jpg',297,238 )"><IMG SRC="images/20-14t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/20-14.jpg',297,238)"><FONT COLOR="#000077"><B>B</B></FONT></A> </P>
<P><A NAME="Fig15"></A><A HREF="javascript:displayWindow('images/20-15.jpg',299,239 )"><IMG SRC="images/20-15t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/20-15.jpg',299,239)"><FONT COLOR="#000077"><B>C</B></FONT></A> </P>
<P><A NAME="Fig16"></A><A HREF="javascript:displayWindow('images/20-16.jpg',299,239 )"><IMG SRC="images/20-16t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/20-16.jpg',299,239)"><FONT COLOR="#000077"><B>D</B></FONT></A> </P>
<P><A NAME="Fig17"></A><A HREF="javascript:displayWindow('images/20-17.jpg',298,239 )"><IMG SRC="images/20-17t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/20-17.jpg',298,239)"><FONT COLOR="#000077"><B>E</B></FONT></A> </P>
<P><A NAME="Fig18"></A><A HREF="javascript:displayWindow('images/20-18.jpg',298,238 )"><IMG SRC="images/20-18t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/20-18.jpg',298,238)"><FONT COLOR="#000077"><B>F</B></FONT></A> </P>
<P>The call to the current autonomous worm’s NotRegrowing() function, given in Listing 20-15, checks if the worm had recently shrunk due to a self-coiling condition and forces the worm to slowly regrow to its original size, which increases the challenge of the game.
</P>
<P><B>Listing 20-15</B> A counter in the Worm object NotRegrowing() function keeps track of autonomous worm regrowth after a self-coiling shrinking condition</P>
<!-- CODE //-->
<PRE>
public boolean NotRegrowing()
{
if (m_regrow > 0) {
m_regrow--;
if ((m_regrow < 100) && ((m_regrow & 7) == 0))
return false;
}
return true;
}
</PRE>
<!-- END CODE //-->
<P>Figure 20-14 shows three stages of motion when worm 1 collides with worm 2. Illustration (a) shows that the worm head can go either right or left. Rather than turning right, the worm will always turn left, as shown in illustration (b), even though only one free space remains in that direction. Illustration (c) shows the worm’s head segment stopped because no free space remains, and worm 1 shrinks by one segment.
</P>
<P><A NAME="Fig19"></A><A HREF="javascript:displayWindow('images/20-19.jpg',562,381 )"><IMG SRC="images/20-19t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/20-19.jpg',562,381)"><FONT COLOR="#000077"><B>Figure 20-14</B></FONT></A> Worm following predefined behavior and reaching a dead end</P>
<TABLE BORDER="2" BORDERCOLOR="#0000" ALIGN="CENTER">
<TR><TD>
<B>Coding Strategies Using <I>if-else</I> Statements</B>
<P>Filling out of the <I>dpoint[]</I> array in the DoAutoWorms() function is done using eight <I>if-else</I> statements. The same result could be arrived at using a more elegant algorithmic solution at the expense of more time and debugging effort. If you feel more comfortable using such simple constructs, don’t worry about using them. They may not look pretty, but if the constants are set up correctly from the start, this kind of code can be very robust and easy to decode. Use the algorithmic approach if a pattern appears that will allow use of looping constructs and if the <I>if-else</I> statements grow large in number.</TABLE>
</P>
<P>If the worm’s motion is blocked, additional processing must be performed to find a new direction of motion. The remaining two <I>dpoint[]</I> elements are filled out with the last two available directions. Two large <I>if-else</I> statements are used to calculate the missing directions. The <I>dpoint[]</I> array is evaluated in order by the <I>for</I> loop at the end of the DoAutoWorms() function so that the first new direction, <I>dpoint[1]</I>, is the direction of highest preference and <I>dpoint[3]</I> is the direction of least preference. If the preferred directions lead to a collision, then the other directions are evaluated in-order until a free direction is found. Figure 20-14, illustration (b), shows selection of the secondary choice <I>dpoint[2]</I> as the new direction because all other directions are blocked. <I>dpoint[0]</I> is by definition a collision, so it is not evaluated in the <I>for</I> loop but is used by the <I>if-else</I> statement only. If a collision is detected in all directions, then SetNextPoint() is not called and the tail of the worm is dropped, provided the worm will not shrink to a size less than one segment.</P><P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="813-814.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="822-825.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
</BODY>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -