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

📄 636-639.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:NetOthello</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=15//-->
<!--PAGES=636-639//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->

<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="633-636.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="639-642.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="LEFT"><A NAME="Heading23"></A><FONT COLOR="#000077">Writing the Networking Code</FONT></H4>
<P>Time to get NetOthello to live up to the &#147;Net&#148; part of its name. Ideally, a game like this could simply open up a socket to a user-specified host and port and play with another person running the program on that machine. However, the current implementation of Java prohibits any applet from making arbitrary Socket connections. An applet is only permitted to make Socket connections to the host on which it originally resided. So, that is what NetOthello must do. It will connect to the server, which will be responsible for pairing it up with another client so that they can play together.
</P>
<H4 ALIGN="CENTER"><A NAME="Heading24"></A><FONT COLOR="#000077">Threading NetOthello</FONT></H4>
<P>To handle all of the network tasks, we are going to use a Thread. Here is how we&#146;ll get the Thread started in newGame():
</P>
<!-- CODE SNIP //-->
<PRE>
/* start the thread */
       kicker = new Thread(this);
       kicker.setPriority(Thread.MIN_PRIORITY);
       kicker.start();
</PRE>
<!-- END CODE SNIP //-->
<P>The run() method for this Thread is very complicated, and so we have to approach it in stages. Each stage consists of a loop that runs until that stage is complete. Always keep in mind that, in any loop, we must always be sure to &#147;sleep&#148; for a little so that we do not hog all available system resources.
</P>
<H4 ALIGN="CENTER"><A NAME="Heading25"></A><FONT COLOR="#000077">Getting the User Info</FONT></H4>
<P>The first stage is used to get the user&#146;s name from the promptFrame and then dispose of the Frame. It is pretty simple, so let&#146;s take a look:
</P>
<!-- CODE //-->
<PRE>
/* the main Thread loop */
public void run() &#123;

/* first, wait for pf to get a name from the user */
name = null;
while( name == null) &#123;
       name = pf.gotName;
       try &#123; kicker.sleep(500); &#125; catch(Exception e);
       &#125;

/* get rid of pf */
pf.dispose();
</PRE>
<!-- END CODE //-->
<H4 ALIGN="CENTER"><A NAME="Heading26"></A><FONT COLOR="#000077">Connecting to the Server</FONT></H4>
<P>Once we have the user&#146;s name (and the user has pressed the &#147;login&#148; button on the promptFrame), we can proceed to connect to the server. Since we cannot connect to anyone except the server, we can always use getCodeBase() to find out the server&#146;s DNS name. However, we can still allow the port to be defined in the HTML tag. To do this, add the following to init():
</P>
<!-- CODE SNIP //-->
<PRE>
/* check applet parameters */
try&#123;
        thePort = Integer.valueOf( getParameter("port") ).intValue();
&#125; catch(Exception e) &#123;
        thePort = 8314;
&#125;
</PRE>
<!-- END CODE SNIP //-->
<P>Notice that we default to 8314 (after the chemistry constant, R, which is 8.314) if the port is not defined by the &lt;APPLET&gt; tag. Now, here is the next stage of run():
</P>
<!-- CODE //-->
<PRE>
s = null;

/* ok, now make the socket connection */
while( s == null )
try&#123;
       theHost = getCodeBase().getHost();
       display("Attempting to make connection");
       s = new Socket(theHost,thePort);
      dis = new DataInputStream( s.getInputStream() );
      ps = new PrintStream( s.getOutputStream() );
&#125; catch( Exception e) &#123;
       try &#123; kicker.sleep(7500); &#125; catch(Exception ex);
&#125;

display("Connection established");
display("Waiting for another player...");
</PRE>
<!-- END CODE //-->
<P>This repeatedly tries to connect to the server, and once it does, we can proceed to the main part of the run() loop.
</P>
<H4 ALIGN="CENTER"><A NAME="Heading27"></A><FONT COLOR="#000077">Handling Server Input</FONT></H4>
<P>This stage handles input from the server and processes it, taking any appropriate action. First, we loop and wait for input:
</P>
<!-- CODE //-->
<PRE>
/* here is the main event loop */
while( kicker != null) &#123;
String input=null;
StringTokenizer st = null;

while( input == null)
try &#123;
       kicker.sleep(100);
       input = dis.readLine();
&#125; catch (Exception e) &#123;
       input = null;
&#125;
System.out.println("Got: "&#43;input); //used for debugging purposes
</PRE>
<!-- END CODE //-->
<P>Now that we have some input from the server, we can try to process it. There are several commands that the client understands, so let&#146;s walk through each one separately. The first is the <I>bye</I> command, which will be generated in the NetOthello stop() method. It is used to signal that the client has disconnected, and if we receive this message, it is safe to assume that our opponent has logged off and abandoned our game. In this case, we display a message and restart:</P>
<!-- CODE SNIP //-->
<PRE>
/* if the other person disconnected for any reason... start over */
if( input.equals("bye" ) ) &#123;
       display("Your partner has left the game... Restarting");
       newGame();
       repaint();
       return;
       &#125;
</PRE>
<!-- END CODE SNIP //-->
<P>The remainder  of the command is  assumed to be in the format &#147;command|value1|value2|value3|&#133;&#148; (look familiar?). We will use a StringTokenizer to parse the input into commands and values. The first command we check for is the <I>start</I> command. This signals the beginning of the game, and it also tells the client whether it will be playing white or black. The <I>local</I> variable is then set accordingly:</P>
<!-- CODE //-->
<PRE>
st = new StringTokenizer(input,"|");
String cmd = st.nextToken();
String val = st.nextToken();
/* if we are ready to start a game */
if( cmd.equals("start") ) &#123;
       display("Got another player.");
       if( val.equals("black") ) local = BLACK;
       else local = WHITE;
       display("You will play "&#43;val);
       repaint();
       &#125;
</PRE>
<!-- END CODE //-->
<P>Next, check for the <I>move</I> command, which lets us know that the person whose turn it is currently (as defined by the <I>turn</I> variable) has made a move. We must then pass the two integer parameters to the doMove() method, which will do the actual move-making. Here&#146;s how it works:</P>
<!-- CODE SNIP //-->
<PRE>
else /* if we got a move, make it */
if(  cmd.equals("move"))
       doMove( Integer.valueOf(val).intValue(), &#8656;
Integer.valueOf(st.nextToken()).intValue(), turn);
</PRE>
<!-- END CODE SNIP //-->
<P>The last command we might get is the <I>say</I> command, which, just as it did in ChatRoom, signals that our opponent has something to say to us. In this case, we just display the message:</P>
<!-- CODE SNIP //-->
<PRE>
else /* if this is a message from a player */
if(cmd.equals("say"))
       display( val );
&#125;
&#125;
</PRE>
<!-- END CODE SNIP //-->
<P>That&#146;s all there is to it! All we have left to do is stop() to ensure that NetOthello tidies up before it quits. Here&#146;s what that looks like:
</P>
<!-- CODE //-->
<PRE>
/* if the Thread stops, be sure to clean up! */
public void stop() &#123;
try &#123;
       ps.println("bye");
       dis.close();
       ps.close();
       s.close();

&#125; catch (Exception e);
&#125;
</PRE>
<!-- END CODE //-->
<P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="633-636.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="639-642.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>


</BODY>

⌨️ 快捷键说明

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