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

📄 301-303.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:Implementing a High Score Server on a Network</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=8//-->
<!--PAGES=301-303//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->

<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="299-301.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="304-306.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="CENTER"><A NAME="Heading37"></A><FONT COLOR="#000077">Converting HighScoreManager to a Thread</FONT></H4>
<P>Once the HighScoreManager implements Runnable, you will not be able to compile it. This is because an Object that implements the Runnable interface is aspiring to become a Thread object. Every thread must have a run() method. Unless the HighScoreManager class contains these methods, it can never become a thread, so the compiler will not compile it.
</P>
<P>Normally, a Thread object must be started by another object before it can run. This is why we chose to use the Runnable interface rather than just extending the Thread class; Runnable lets HighScoreManager start itself. This is useful because, if you remember, we do not want the applet that makes use of HighScoreManager to have to do very much interacting with it. We want HighScoreManager to do all the work.</P>
<P>So how do we make HighScoreManager into a thread? First, we should implement Runnable in our declaration of HighScoreManager, like this:</P>
<!-- CODE SNIP //-->
<PRE>
public class HighScoreManager extends Object implements Runnable &#123;
</PRE>
<!-- END CODE SNIP //-->
<P>Now, we need to declare a thread object. We are going to call it <I>kicker</I> because I like to think of threads being &#147;kicked&#148; into action when they start. This metaphor may work for you, or it may not. Nevertheless, we are going to use <I>kicker</I>. Once we declare <I>kicker</I>, we are going to need to instantiate it with the new() method, like this:</P>
<!-- CODE SNIP //-->
<PRE>
Thread kicker;
kicker = new Thread(this);
</PRE>
<!-- END CODE SNIP //-->
<P>The variable <I>this</I> always points to the current object, in this case to HighScoreManager. The above commands tell the compiler to create a thread, called <I>kicker</I>, based on HighScoreManager. When we tell <I>kicker</I> to start, it will call HighScoreManager&#146;s start() method. Let&#146;s put that code we just wrote into HighScoreManager. The thread must be declared as a global variable in HighScoreManager, but it should not be instantiated until HighScoreManager is created with its initialization routine. Also, when HighScoreManager is created, it should start <I>kicker</I>, since we don&#146;t have any reason to wait. Here&#146;s the code:</P>
<!-- CODE //-->
<PRE>
Thread kicker = null;
...
HighScoreManager(int max) &#123;
       NUM_SCORES=max;
       L= new HighScoreList(NUM_SCORES);
       kicker = new Thread(this);
       kicker.start();
       newColors();
&#125;
</PRE>
<!-- END CODE //-->
<P>We still haven&#146;t created the Thread methods in HighScoreManager, so let&#146;s do that now. The first is start(). This is called as soon as Thread is activated, and it returns immediately. The only thing we need to do here is to make sure that <I>kicker</I> is active (not set to <I>null</I>).</P>
<!-- CODE SNIP //-->
<PRE>
public void start() &#123;

if (kicker == null)
       kicker = new Thread(this);

&#125;
</PRE>
<!-- END CODE SNIP //-->
<P>Now we have to do the actual work of the thread. This is the run() method, which is called right after start(). If run() ever finishes (if it returns), the thread is finished and will be killed. Therefore, we need to make a loop that will run as long as HighScoreManager is alive. We do this by checking to see if <I>kicker</I> is equal to <I>null</I> (remember that <I>kicker</I> is a reference to HighScoreManager, so if HighScoreManager ever dies, so does <I>kicker</I>). If it is, we exit; otherwise, we continue. We are also going to make use of the sleep() method, which is how a thread puts itself to sleep for a certain amount of time. To make it easy to change this value later, create a constant (in Java, a <I>final variable</I>) with the delay (in milliseconds) you would like between each time the client checks for new scores from the server. To begin with, choose a relatively small value, like 10000 (10 seconds), for easy debugging. Declare it like this:</P>
<!-- CODE SNIP //-->
<PRE>
final int DELAY = 10000;
</PRE>
<!-- END CODE SNIP //-->
<P>Next, write the run() code. All it does is call getScores(), which does the real work anyway, so it, too, is short:
</P>
<!-- CODE SNIP //-->
<PRE>
public void run() &#123;

while (kicker != null) &#123;
getScores();

try&#123; kicker.sleep(DELAY); &#125; catch(Exception e);
&#125;
&#125;
</PRE>
<!-- END CODE SNIP //-->
<P>Here we have another potential exception that we caught, but we don&#146;t really care what it has to say, so we just ignore it. However, even though we don&#146;t care about it, Java still requires us to catch it.
</P>
<P>One last Thread method and then we&#146;re finished. Sometimes, someone may want to tell HighScoreManager to stop looking for scores. We know for sure this will happen when HighScoreManager is finished (i.e., when the applet quits), so we&#146;d better be prepared. The stop() method must cause the run() method to finish executing or it must cause the Thread object to be garbage-collected. This stop() method does both, just for good measure:</P>
<!-- CODE SNIP //-->
<PRE>
public void stop() &#123;

kicker = null;
&#125;
</PRE>
<!-- END CODE SNIP //-->
<P>If you compile HighScoreManager again and run testApp, everything should appear normal. However, if you wait a few seconds (however long you set your <I>DELAY</I> to) and press the Change Colors button, you will notice that each entry in the list has been repeated. Why? Because each time we call getScores(), it adds the same list of names to the HighScoreList. If you let the program run long enough, it will eventually fill up with the first-place score. The problem lies in the inadequacies of our data-acquisition code, which doesn&#146;t do very much, so we just have to be sure we correct this glitch at the same time we add some functionality.</P>
<H3><A NAME="Heading38"></A><FONT COLOR="#000077">Writing the Networking Code</FONT></H3>
<P>It is now time to start the second half of our discussion. Up until now, we have been using simulated data, but the time has come to replace this with some actual networking code. The code will create a new socket, try to connect to the server, and, if successful, submit to the server any new scores it has accumulated. Once they have been sent, it will clear our list of new scores so that they do not get sent more than once. In addition, the method will request any new scores that may have been acquired by the server since the last time it checked. If the score list has changed, the client will request that the entire list be re-sent and will replace its current list with the new one.
</P><P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="299-301.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="304-306.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>


</BODY>

⌨️ 快捷键说明

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