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

📄 794-798.html

📁 java game programming e-book
💻 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,&nbsp;Macmillan Computer Publishing
    <br>
    <b>ISBN:</b>&nbsp;1571690433<b>&nbsp;&nbsp;&nbsp;Pub Date:</b>&nbsp;11/01/96</font>&nbsp;&nbsp;
</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=794-798//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->

<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="790-794.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="798-801.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="LEFT"><A NAME="Heading20"></A><FONT COLOR="#000077">Reinitializing After Each Game</FONT></H4>
<P>The construction of the queue is done once for the life of the game. Each time the player restarts the game, the worm&#146;s queue is refilled with the correct x and y segment positions in tail-to-head order in the <I>for</I> loop in Listing 20-2. In this example we always set the worm moving from left to right. Two variables, <I>m_startidx</I> and <I>m_endidx</I>, point to the head and tail of the worm, respectively. Each time we restart the game, we need only reset these variables to their original values and the game can begin again. This is a handy way of avoiding needless reallocation of the worm objects. Note that we also reset the starting direction of the worm in the <I>dDir</I> object.</P>
<P><B>Listing 20-2</B> Reinitializing a worm after each game using the function ReviveWorm()</P>
<!-- CODE //-->
<PRE>
public void ReviveWorm()
&#123;
    int count, i;

    for (i = 0, count = 0; i &lt; m_wormlen; i&#43;&#43;, count&#43;&#43;)  &#123;
        m_points[count].width = i &#43; m_startx;
        m_points[count].height = m_starty;
    &#125;
    // set the buffer's start and end points
    // which are the head and tail of the worm

    m_startidx = count - 1;
    m_endidx = 0;
    m_regrow = 0;

    // set the current traveling direction

    dDir.width = m_startxdir;
    dDir.height = m_startydir;
&#125;
</PRE>
<!-- END CODE //-->
<H4 ALIGN="LEFT"><A NAME="Heading21"></A><FONT COLOR="#000077">Adding Worker Functions</FONT></H4>
<P>Since the worm cannot show its implementation to the SessionManager, several useful worker functions are added to the worm object.
</P>
<H4 ALIGN="CENTER"><A NAME="Heading22"></A><FONT COLOR="#000077">The DoYouHaveSegmentAt() Function</FONT></H4>
<P>The function DoYouHaveSegmentAt(), shown in Listing 20-3, is passed an x and y location on the playing surface. It must reply <I>true</I> or <I>false</I> if it has a segment at those coordinates. This function demonstrates some interesting aspects of the ring buffer implementation.</P>
<P><B>Listing 20-3</B> The ability to ask if a worm has a segment at a given point</P>
<!-- CODE //-->
<PRE>
public boolean DoYouHaveSegmentAt(Dimension newpoint)
&#123;
    int curridx = m_endidx;

    while (true) &#123;
        // if matches, return true
        if (newpoint.width == m_points[curridx].width &#38;&#38;
             newpoint.height == m_points[curridx].height)
            return true;
        if (curridx == m_startidx)
            break;
        curridx&#43;&#43;;
        if (curridx &gt;= m_wormsize)
            curridx = 0;
    &#125;
    // no match return false
    return false;
&#125;
</PRE>
<!-- END CODE //-->
<P>First, we assume a worm is never less than one segment in size for the entire worm object. Here we check the worm segments beginning with the tail. You will notice that we don&#146;t compare the objects to each other, such as <I>newpoint == m_points[curridx]</I>. Some C&#43;&#43; class libraries would override the == operator to allow implicit comparison of the coordinates; under Java this behavior is different and we must compare the variables explicitly. Once we have reached the head, we are done, and no match was found. Notice the comparison <I>curridx &gt;= m_wormsize</I>; this comparison correctly wraps around our index when we reach the end of the array to simulate an abstract ring buffer.</P>
<H4 ALIGN="CENTER"><A NAME="Heading23"></A><FONT COLOR="#000077">The GetNextPoint() and SetNextPoint() Functions</FONT></H4>
<P>The worm is always moving in a direction specified by the <I>dDir</I> object that it maintains. This direction changes under the player&#146;s control. The SessionManager needs to call GetNextPoint() to identify which point would be the next head location for the worm. This function does not change the worm&#146;s head position, because the SessionManager must decide from this information if a collision is imminent. If no collision is detected, the SessionManager will call SetNextPoint() to set this worm&#146;s new head position.</P>
<H4 ALIGN="CENTER"><A NAME="Heading24"></A><FONT COLOR="#000077">The DropLastPoint() Function</FONT></H4>
<P>The last two functions discussed above are not adequate to control the worm&#146;s motion. A means to drop the tail of the worm is also required for each head addition; otherwise, the worm will grow continuously! Code to drop the point could be placed in SetNextPoint(), but we will put it in a function called DropLastPoint() to allow occasional retention of the tail point, allowing for a slower growth of the worm. Thus, DropLastPoint() is selectively called by the SessionManager depending on various factors. The three head and tail manipulation functions are given in Listing 20-4.
</P>
<P><B>Listing 20-4</B> Three helper functions that control the head and tail segments of the worm</P>
<!-- CODE //-->
<PRE>
public Dimension GetNextPoint()
&#123;
    dNext.width = m_points[m_startidx].width;
    dNext.height = m_points[m_startidx].height;

    dNext.width &#43;= dDir.width;
    dNext.height &#43;= dDir.height;

    m_nextadded = false;

    return dNext;
&#125;

public boolean SetNextPoint(Dimension newpoint)
&#123;
    int tempidx;

    m_startidx&#43;&#43;;
    if (m_startidx &gt;= m_wormsize)
        m_startidx = 0;

    m_points[m_startidx].width = dNewpoint.width
                     = newpoint.width;
    m_points[m_startidx].height = dNewpoint.height
                     = newpoint.height;

    // don't grown beyond max, force a drop by calling
    // routine
    tempidx = m_startidx &#43; 1;
    if (tempidx &gt;= m_wormsize)
        tempidx = 0;

    m_nextadded = true;

    return tempidx == m_endidx;
&#125;

public boolean DropLastPoint()
&#123;
    dOldpoint.width = m_points[m_endidx].width;
    dOldpoint.height = m_points[m_endidx].height;

    if (m_regrow == 0)
            if (CountSegments() &lt;= m_wormlen / 2)
                m_regrow = 150;

        if (m_endidx == m_startidx) &#123;
            m_lastdropped = false;
            return m_lastdropped;
        &#125;

        m_endidx&#43;&#43;;
        if (m_endidx &gt;= m_wormsize)
            m_endidx = 0;

        m_lastdropped = true;
        return m_lastdropped;
    &#125;
</PRE>
<!-- END CODE //-->
<P>To prevent overflow of the <I>m_points</I> array and contain the size of the worm to the maximum array size, SetNextPoint() returns <I>true</I> if the maximum worm size has been reached, which will force SessionManager to drop the tail segment regardless of other circumstances. In a similar manner, under special circumstances which will be clarified in a later section, an autonomous worm can shrink to zero length. DropLastPoint() will not drop the tail segment if that would cause the worm size to fall to zero. You will notice a variable called <I>m_regrow</I> in this function. This variable is used to slowly restore the size of shrunken autonomous worms to their original length.</P>
<P>The variables <I>m_nextadded</I> and <I>m_lastdropped</I> are used as placeholders for a subsequent call about the worm&#146;s growth status from the SessionManager.</P><P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="790-794.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="798-801.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>


</BODY>

⌨️ 快捷键说明

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