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

📄 679-683.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=679-683//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->

<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="676-679.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="683-686.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="CENTER"><A NAME="Heading36"></A><FONT COLOR="#000077">The init() Method</FONT></H4>
<P>Getting everything initialized is a pretty tough task, but let&#146;s get it done. Start by dividing the screen into three distinct regions for the status bar, the StarField (playing area), and the Terrain, respectively:
</P>
<!-- CODE SNIP //-->
<PRE>
public void init() &#123;
       d = size();
       statRect = new Rectangle(0, 0, d.width, 16);
       SFrect = new Rectangle( 0,statRect.height,&#8658;
d.width,(int)(d.height*.8));
Trect = new Rectangle( 0, statRect.height&#43;SFrect.height, d.width&#8658;
(int)(d.height-statRect.height-SFrect.height) );
</PRE>
<!-- END CODE SNIP //-->
<P>Next, give the Sprite class a copy of the applet&#146;s Graphics context:
</P>
<!-- CODE SNIP //-->
<PRE>
Sprite.theG = getGraphics().create();
</PRE>
<!-- END CODE SNIP //-->
<P>Define our ThreadGroups:
</P>
<!-- CODE SNIP //-->
<PRE>
everything = new ThreadGroup( "all");
group = new ThreadGroup( everything,"enemies");
bullets = new ThreadGroup(everything,"bullets");
</PRE>
<!-- END CODE SNIP //-->
<P>Create the status bar and prompt window:
</P>
<!-- CODE //-->
<PRE>
bar = new statusBar(everything, "statusbar");
bar.setBounds( statRect);
bar.im = createImage( statRect.width, statRect.height);
bar.setPriority(Thread.MIN_PRIORITY);
bar.start();

PF = new promptFrame();
PF.resize(d.width,d.height);
PF.show();
</PRE>
<!-- END CODE //-->
<P>And last, but not least, get the &#147;kicker&#148; started:
</P>
<!-- CODE SNIP //-->
<PRE>
       kicker = new Thread(this);
       kicker.setPriority(Thread.MAX_PRIORITY);
       kicker.start();
&#125;
</PRE>
<!-- END CODE SNIP //-->
<H4 ALIGN="LEFT"><A NAME="Heading37"></A><FONT COLOR="#000077">Using Double-Buffered Graphics</FONT></H4>
<P>Because we want to do the run() method next, we need to convert all of our Sprite classes to use double-buffered graphics. This isn&#146;t too hard, especially since we decided to have each Sprite create its own Image before it actually does any drawing. Here&#146;s the game plan: We have each Sprite work on creating its Image and then tracking its own location. Each time WordQuest wants to redraw, it simply queries each Sprite in the game, and draws that Sprite&#146;s Image at the proper location. Keep in mind that this means the StarField <I>must</I> be drawn first, or some Sprites may appear to vanish.</P>
<H4 ALIGN="CENTER"><A NAME="Heading38"></A><FONT COLOR="#000077">Double-Buffering the Sprite Class</FONT></H4>
<P>The only real change to the Sprite class that is required is that it no longer has to draw itself on the Graphics context. This means we can change run() to look like this:
</P>
<!-- CODE SNIP //-->
<PRE>
public void run() &#123;
       while(true) &#123;
              try&#123; sleep(DELAY); &#125; catch(Exception e);
              advance();
              &#125;
&#125;
</PRE>
<!-- END CODE SNIP //-->
<P>In addition, we want to add another method to make it easier to query the current Image:
</P>
<!-- CODE SNIP //-->
<PRE>
public Image currentImage() &#123;
if( anim== null)
       generateImage();
return anim[animIndex];
&#125;
</PRE>
<!-- END CODE SNIP //-->
<P>Other than that, Sprite remains the same. You could even remove the painting method, since it is no longer called. However, future games might still require such a method, so it&#146;s best to leave it in.
</P>
<H4 ALIGN="CENTER"><A NAME="Heading39"></A><FONT COLOR="#000077">Double-Buffering StarField</FONT></H4>
<P>The main changes that need to be made to StarField are in the run() method. Some minor changes also have to be made to handle the Image referenced herein, but you should be able to figure those out on your own:
</P>
<!-- CODE //-->
<PRE>
public void run() &#123;
Graphics bg = im.getGraphics();
       while(true) &#123;
              flag = true;
              paintSprite( bg);
              flag = false;
              anim[0]=im;
              im.flush();
              advance();
              try&#123; sleep(300); &#125; catch(Exception e);
       &#125;
&#125;
</PRE>
<!-- END CODE //-->
<P>StarField uses a boolean flag that is only <I>false</I> after it is done creating its Image. This is necessary because Java allows other classes to access the Image while it is still being generated, and this allows incomplete versions of it to be drawn onto the screen&#151;a very tacky effect.</P>
<H4 ALIGN="LEFT"><A NAME="Heading40"></A><FONT COLOR="#000077">See WordQuest Run</FONT></H4>
<P>The WordQuest run() method does the following: First, it checks to see if we are playing. If so, it runs the check method to handle any collisions, and so on. Then, it creates a new offscreen Image, and prepares it for drawing. It draws the StarField, and then all other Sprites on the Image, and then it draws the Image onto the current Graphics context.
</P>
<P>If the user is not playing, it checks to see if the promptFrame is &#147;ready&#148; (i.e., if the user has pressed the OK button). If so, it starts the game up again by calling all the game-starting methods. If the user is not ready to start playing, it just goes to sleep for a bit and checks again later.</P>
<P>That&#146;s how the run() method works, and we are going to code it before we code any of the methods to which it refers. This is so you can get a better handle on how the various methods interact as we write them.</P>
<P>Here&#146;s the run() code:</P>
<!-- CODE //-->
<PRE>
public void run() &#123;

while(true)
if( playing) &#123;
       try&#123;kicker.sleep(50); &#125;catch(Exception e);
       doCheck();

       im = createImage(d.width, d.height-Trect.height);
       offScreenG = im.getGraphics();
/* don&#146;t draw the StarField until it is ready (flag == false) */
try&#123;   while(SF.flag) kicker.sleep(100); &#125; catch(Exception e);
       offScreenG.drawImage(SF.currentImage(),SF.x,SF.y,null); //&#125;&#8658;
catch(Exception e);
try &#123;
       Sprite s[]=new Sprite[everything.activeCount()];
       everything.enumerate( s);
       for(int i=0;i&lt;everything.activeCount();i&#43;&#43;)
                   if( s[i] != SF)
                     try &#123;

offScreenG.drawImage(s[i].currentImage(),s[i].x,s[i].y,null);
                     &#125; catch(NullPointerException e);
&#125; catch(ArrayIndexOutOfBoundsException e);

       getGraphics().drawImage(im,0,0,null);

&#125; else &#123;
       if( PF.ready) &#123;
              PF.ready=false;
              name=PF.gotName;
              playing=true;
              PF.hide();
              initUser();
              nextQuestion();
              everything.resume();
              T.resume();
       &#125;
              try&#123;kicker.sleep(500);&#125;catch(Exception e);
       &#125;

&#125;
</PRE>
<!-- END CODE //-->
<P>To accompany the run() code we&#146;ll need those other crucial Thread methods, start() and stop():
</P>
<!-- CODE //-->
<PRE>
public void start() &#123;
questions = new Vector();
       try&#123;
              URL theURL = new URL(getCodeBase(), "data.txt");
              new dataThread( questions, theURL).start();
       &#125; catch (Exception e);
&#125;

public void stop() &#123;
       everything.stop();
&#125;
</PRE>
<!-- END CODE //-->
<P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="676-679.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="683-686.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>


</BODY>

⌨️ 快捷键说明

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