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

📄 664-667.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:WordQuest</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=16//-->
<!--PAGES=664-667//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->

<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="659-664.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="667-669.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="CENTER"><A NAME="Heading17"></A><FONT COLOR="#000077">Initializing</FONT></H4>
<P>Now we initialize the Terrain. To do this, we require that the creating class pass along three things: the width of each Polygon, the Terrain&#146;s bounding Rectangle, and the Graphics context to be used. Then, we calculate the size of the Vector needed to store the Polygons (the number of Polygons of the requested width that would fit within the bounding Rectangle). Then we actually create the first set of Polygons needed to draw the Terrain:
</P>
<!-- CODE //-->
<PRE>
Terrain( int w, Rectangle r, Graphics g) &#123;
WIDTH = w;
bounds = r;
theG = g.create();

int num = (int) (r.width/WIDTH);
v = new Vector(num);
while( num-- &gt;= 0)
        v.addElement(nextPoly());
&#125;
</PRE>
<!-- END CODE //-->
<H4 ALIGN="CENTER"><A NAME="Heading18"></A><FONT COLOR="#000077">Creating the nextPoly() Method</FONT></H4>
<P>Of course, we haven&#146;t written the nextPoly() method, so let&#146;s do that next. It creates a Polygon of random height starting with the Y coordinate of the last Polygon created:
</P>
<!-- CODE //-->
<PRE>
Polygon nextPoly() &#123;
Polygon p = new Polygon();
        p.addPoint( (int)(WIDTH/2), (int)(bounds.height * Math.random()));
        p.addPoint( 0, lasty);
        p.addPoint( 0, bounds.height);
        p.addPoint( WIDTH, bounds.height);
        p.addPoint( WIDTH, lasty = (int)(bounds.height * Math.random()));
return p;
&#125;
</PRE>
<!-- END CODE //-->
<P>Notice that we create the Polygon using x and y coordinates that are relative to an X coordinate of zero. When we draw the actual Polygon onto the screen, we are going to need to shift it over before it is drawn, and for that we need a new method:
</P>
<!-- CODE SNIP //-->
<PRE>
void paintPolyXY(Graphics g, Polygon p, int x, int y) &#123;
       for(int i=0;i&lt;p.npoints;i&#43;&#43;) &#123;
              p.xpoints[i]&#43;=x;
              p.ypoints[i]&#43;=y;
              &#125;
       g.fillPolygon(p);
&#125;
</PRE>
<!-- END CODE SNIP //-->
<H4 ALIGN="CENTER"><A NAME="Heading19"></A><FONT COLOR="#000077">Drawing Terrain onto the Screen</FONT></H4>
<P>Next, let&#146;s write the method that actually draws the entire Terrain onto the screen. For this, we must take each Polygon out of the Vector and make a copy of it, because the method we just wrote for painting the Polygon actually changes its X and Y coordinates. We then send the copy to be painted, and leave the original alone:
</P>
<!-- CODE //-->
<PRE>
public void paintAll( Graphics g, Rectangle r) &#123;

g.setColor(Color.black);
g.fillRect(bounds.x,bounds.y,bounds.width,bounds.height);

g.setColor( Color.yellow);
for(int x=0;x&lt;v.size();x&#43;&#43;) &#123;
       Polygon p2 = (Polygon) v.elementAt(x);
       Polygon p = new Polygon(p2.xpoints,p2.ypoints,p2.npoints);
       paintPolyXY(g,p,r.x&#43;x*WIDTH,r.y);
        &#125;
&#125;
</PRE>
<!-- END CODE //-->
<H4 ALIGN="CENTER"><A NAME="Heading20"></A><FONT COLOR="#000077">Using copyArea() to Enhance Performance</FONT></H4>
<P>Although we could go ahead now and write the Thread code that makes the Terrain go, the result would be horrendously slow. Even if we used double-buffered graphics to draw each successive frame of the Terrain, the method is simply not fast enough, especially when there are many Threads running simultaneously (as there will be in the final product). The key to solving this problem is to recognize that 90 percent of the Terrain (all but one Polygon) doesn&#146;t change each time. Therefore, it is wasteful and inefficient (not to mention slow) to have to redraw the entire Terrain for each frame. Rather, we can take advantage of a Graphics method called copyArea(), which actually copies a rectangular set of bits from one location on a Graphics context to another. Using this method, we can easily copy the majority of the Terrain to the left, and then only draw the one remaining Polygon right next to it. Here&#146;s the code:
</P>
<!-- CODE SNIP //-->
<PRE>
public void paintChange( Graphics g, Rectangle r) &#123;
       g.copyArea( r.x,r.y,r.width,r.height,-WIDTH,0);
       g.setColor(Color.black);
       g.fillRect( r.x&#43;r.width-WIDTH,r.y,WIDTH,r.height);
       g.setColor(Color.yellow);
       paintPolyXY(g, (Polygon)v.lastElement(), r.x&#43;r.width-WIDTH,r.y);
&#125;
</PRE>
<!-- END CODE SNIP //-->
<H4 ALIGN="CENTER"><A NAME="Heading21"></A><FONT COLOR="#000077">Finishing the Thread Methods</FONT></H4>
<P>Now it&#146;s time to finish up the Thread-related methods of Terrain.class. First, there is a method that will be called each frame to dispose of the oldest Polygon and to add a new one:
</P>
<!-- CODE SNIP //-->
<PRE>
public void advance() &#123;

v.removeElementAt(0);
v.addElement( nextPoly());

&#125;
</PRE>
<!-- END CODE SNIP //-->
<P>Next, we add a new variable and method that will allow the applet to request that the entire Terrain (and not just the new Polygon) be redrawn at the next available instant. This method also makes reference to the Sprite class &#147;warp&#148; factor that is used to increase the drawing frequency of the Terrain when necessary. This, of course, assumes that the applet using Terrain is also using Sprite. If this is not the case, you can always give Terrain a separate &#147;warp&#148; variable (or just leave this feature out altogether).
</P>
<!-- CODE SNIP //-->
<PRE>
boolean repaint=true;
&#133;
public void repaint() &#123;
       repaint=true;
&#125;
</PRE>
<!-- END CODE SNIP //-->
<H4 ALIGN="CENTER"><A NAME="Heading22"></A><FONT COLOR="#000077">Adding Functionality</FONT></H4>
<P>And last but not least, we create the run() method in order to actually give this class some functionality!
</P>
<!-- CODE //-->
<PRE>
public void run() &#123;
    while(true) &#123;
               if( repaint) &#123;
                     paintAll(theG,bounds);
                     repaint = false;
                     &#125;
               else
                     paintChange(theG,bounds);
               advance();
               try&#123; sleep(200/Sprite.warp); &#125; catch(Exception e);
       &#125;
&#125;
</PRE>
<!-- END CODE //-->
<P>Terrain is finished! I would recommend writing up a simple applet to prove this to yourself, or if you wish, you can proceed straight to the rest of our background drawing.
</P><P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="659-664.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="667-669.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>


</BODY>

⌨️ 快捷键说明

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