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

📄 642-646.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=642-646//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->

<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="639-642.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="647-650.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="LEFT"><A NAME="Heading32"></A><FONT COLOR="#000077">Step 3: Coding GameGroup.class</FONT></H4>
<P>GameGroup is designed to be an all-purpose multigame server handler. It receives a Socket from GameServerThread and spins it off into a GameClientThread, which it adds to an array. GameGroup does not need a Vector, because it is used for games where there is a known, predetermined number of players. In the case of Othello, this is two players, but we want to be as general as possible. The basic setup is quite simple. Remember that GameGroups are created with a specific number of players in mind:
</P>
<!-- CODE //-->
<PRE>
import java.lang.*;
import java.net.*;
import java.io.*;
import java.util.*;
import GameClientThread;

public class GameGroup extends Thread &#123;

GameClientThread arr[];
final int SIZE=2;

GameGroup ( Socket s ) &#123;
       arr = new GameClientThread[SIZE];
       addClient( s );
&#125;

&#125;
</PRE>
<!-- END CODE //-->
<P>Notice that all that is required to change the number of players in a GameGroup is to change the constant SIZE. Next, let&#146;s write the method that adds a Socket to the array:
</P>
<!-- CODE //-->
<PRE>
public void addClient( Socket s ) &#123;
int x;

for( x=0; x&lt;SIZE; x&#43;&#43;)
       if( arr[x] == null || !arr[x].isAlive() ) &#123;
              arr[x] = new GameClientThread(s,this);
              arr[x].start();
              return ;
              &#125;

&#125;
</PRE>
<!-- END CODE //-->
<P>As soon as we create a GameClientThread, we have to start() it so that it will immediately start processing input. GameGroup&#146;s Thread is not started until the GameGroup is full. This signals the start of the game, so GameGroup must assign colors to each of the players and let them know to start playing. This is the only really proactive thing that GameGroup does. This is done in the run() method along with some garbage collection that makes sure all of the clients are still alive. If anyone leaves, everyone is sent the <I>bye</I> command, and the GameGroup stops itself (so it can be garbage collected):</P>
<!-- CODE //-->
<PRE>
public void run() &#123;
int x;

arr[0].message("start|white");
arr[1].message("start|black");

while( true ) &#123;
       for(x=0;x&lt;SIZE;x&#43;&#43;)
              if( arr[x] == null || !arr[x].isAlive() ) &#123;
                     output("bye");
                     stop();
                     &#125;
try&#123; sleep( 10000 ); &#125; catch(Exception e);
&#125;
&#125;
</PRE>
<!-- END CODE //-->
<P>Like any good object, GameGroup cleans up after itself, in the finalize() method:
</P>
<!-- CODE //-->
<PRE>
public void finalize() &#123;
int x;

output("bye");

try &#123;
for(x=0; x&lt;SIZE; x&#43;&#43;)
       if( arr[x] != null ) &#123;
              arr[x].stop();
              &#125;
&#125; catch(Exception e);

&#125;
</PRE>
<!-- END CODE //-->
<P>The GameGroup also has a method that is eventually called by GameClientThread to output a message to all currently connected clients. It is quite simple:
</P>
<!-- CODE SNIP //-->
<PRE>
public void output(String str) &#123;
int x;

for(x=0;x&lt;SIZE;x&#43;&#43;)
       if(arr[x] != null)
             arr[x].message(str);

&#125;
</PRE>
<!-- END CODE SNIP //-->
<P>GameGroup does one last thing. GameServerThread needs a way of determining if GameGroup is &#147;full,&#148; which means that all of its slots are full and no more clients may be added. This is done with the full() method:
</P>
<!-- CODE SNIP //-->
<PRE>
public boolean full() &#123;
int x;

for(x=0;x&lt;SIZE;x&#43;&#43;)
       if( arr[x] == null )
              return false;
return true;
&#125;
</PRE>
<!-- END CODE SNIP //-->
<P>Even though we&#146;ve now written all of GameGroup&#146;s methods, you still can&#146;t compile it, because GameGroup requires a compiled version of GameClientThread. However, GameClientThread needs a compiled version of GameGroup in order to compile. Hopefully, you remember the trick we learned in Chapter 9 for dealing with this dilemma: Compile a dumbed-down version of one class, compile its partner, and then change and recompile the first one. Or you could just use the precompiled binaries that come with the CD-ROM. Either way, you&#146;re almost done!
</P>
<H4 ALIGN="LEFT"><A NAME="Heading33"></A><FONT COLOR="#000077">Step 4: Building GameClientThread.class</FONT></H4>
<P>This is a puny little class that just watches a Socket and passes any input it receives to its parent GameGroup. It also has a little method for sending a message to its client, if needed. Here&#146;s what it looks like:
</P>
<!-- CODE //-->
<PRE>
import java.net.*;
import java.lang.*;
import java.io.*;
import java.util.*;
import GameGroup;

public class GameClientThread extends Thread &#123;
GameGroup parent;
Socket theSock;
DataInputStream dis;
PrintStream ps;
String alias;

GameClientThread(Socket s, GameGroup p) &#123;
theSock = s;
parent = p;
&#125;
&#125;
</PRE>
<!-- END CODE //-->
<P>Setting that up was pretty easy. Here is what the run() method looks like:
</P>
<!-- CODE //-->
<PRE>
public void run() &#123;

       try &#123;
              dis = new DataInputStream( new BufferedInputStream(
              theSock.getInputStream()));
            ps = new PrintStream( theSock.getOutputStream());
      &#125; catch (Exception e) &#123;
           stop();
/* notice that, if there is any problem, we stop immediately */
       &#125;

while (theSock !=null) &#123;
String input = null;
try &#123;
input = dis.readLine().trim();
if(input != null) &#123;
       parent.output(input);
       if(input.equals("bye"))
              stop();
       &#125;
&#125; catch (Exception e) &#123;
       stop();
       theSock = null;
&#125;
try&#123; sleep(100); &#125; catch(Exception e);
&#125;
&#125;
</PRE>
<!-- END CODE //-->
<P>And top it off with a little method for receiving messages:
</P>
<!-- CODE //-->
<PRE>
public boolean message(String str) &#123;
boolean flag = false;
while (!flag)
try &#123;
       ps.println(str);
       flag = true;
&#125; catch (Exception e) &#123;
       flag = false;
&#125;
return true;
&#125;
</PRE>
<!-- END CODE //-->
<P>Now, don&#146;t forget to clean up!
</P>
<!-- CODE //-->
<PRE>
public void finalize() &#123;
       try &#123;
               ps.close();
               dis.close();
               theSock.close();
       &#125; catch(Exception e);
theSock = null;

&#125;
</PRE>
<!-- END CODE //-->
<P>Ta dah! NetOthello is now fully functional, and you and a friend can play if you have a Web server. If you don&#146;t, that&#146;s OK; run the server (from a command line) and two clients (in appletviewer) and you can play against yourself! Enjoy, have some fun, and, when you&#146;re ready, we&#146;ll start making some improvements.
</P>
<H3><A NAME="Heading34"></A><FONT COLOR="#000077">Adding Some Features</FONT></H3>
<P>NetOthello is a pretty cool applet already, but let&#146;s see if we can make it even cooler.
</P><P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="639-642.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="647-650.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>


</BODY>

⌨️ 快捷键说明

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