📄 673-675.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, Macmillan Computer Publishing
<br>
<b>ISBN:</b> 1571690433<b> Pub Date:</b> 11/01/96</font>
</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=673-675//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="669-673.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="676-679.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="LEFT"><A NAME="Heading28"></A><FONT COLOR="#000077">Writing the Prompt Frame</FONT></H4>
<P>Just like NetOthello in Chapter 15, WordQuest will use a Frame to get input from the user at the start of the game. However, this promptFrame will also track and display high scores using the HighScoreManager created in Chapter 8, Implementing a High Score Server on a Network. We aren’t doing anything new in this code, so it should look familiar. If not, you should refer back to Chapters 8 and 15. This code is only used to help out the main WordQuest class, so add it to the same file:
</P>
<!-- CODE //-->
<PRE>
class promptFrame extends Frame {
TextField TF;HighScoreManager HS = new HighScoreManager(10);Panel p;⇒
publicString gotName;boolean ready
promptFrame() { super("Ready for a new game?"); setLayout( new⇒
BorderLayout());p = new Panel(); p.setLayout( new FlowLayout());⇒
p.add( "West",new Label("Input your name: ")); p.add("West",TF = new⇒
TextField(20)); p.add("Center",new Button("OK")); add⇒
("South",p); gotName = null; ready=false;}
public void paint(Graphics g) {
Graphics offG;Dimension d = size();d.height-⇒
=p.preferredSize().height;Image im=createImage(d.width,d.height);
Rectangle r = new
Rectangle(0,0,d.width,d.height);offG=im.getGraphics();HS.paintScores⇒
(offG,r);g.drawImage(im,0,0,null);}
public boolean handleEvent(Event evt) {
if( (evt.target instanceof TextField && evt.id==Event.ACTION_EVENT) ||⇒
(evt.target instanceof Button && evt.arg.equals("OK"))) {
if( TF.getText() != "") gotName = TF.getText();⇒
ready = true; return true; }return super.handleEvent(evt);}
}
</PRE>
<!-- END CODE //-->
<H4 ALIGN="LEFT"><A NAME="Heading29"></A><FONT COLOR="#000077">Using ThreadGroups to Synchronize Enemy Sprites</FONT></H4>
<P>We want the enemy Sprites to come at the user in unison; that is, we want them to be <I>synchronized</I>. One excellent way of doing this is to make sure that they are all in the same ThreadGroup. This also makes them more manageable, and allows us to call certain methods (like suspend() and stop()) on the entire group at once. Furthermore, if we make the group containing the enemy Sprites part of a larger group that encompasses all Sprites, we can call these methods in all of the Sprites in the game at once. The hierarchy looks something like Figure 16-5.</P>
<P><A NAME="Fig5"></A><A HREF="javascript:displayWindow('images/16-05.jpg',561,381 )"><IMG SRC="images/16-05t.jpg"></A>
<BR><A HREF="javascript:displayWindow('images/16-05.jpg',561,381)"><FONT COLOR="#000077"><B>Figure 16-5</B></FONT></A> ThreadGroup hierarchy in WordQuest</P>
<P>In order to implement these ThreadGroups, we must declare each Sprite to be part of a ThreadGroup at the time it is instantiated. Once a Thread is in a group, it is there for good. This requires a few changes to the initialization method of Sprite:
</P>
<!-- CODE SNIP //-->
<PRE>
Sprite( ThreadGroup p, String d) {
super(p,d);
}
</PRE>
<!-- END CODE SNIP //-->
<P>When you create a Thread within a ThreadGroup, you must assign it a name. The name is not terribly important, unless you want to do some Thread operations on only specific Threads to which you do not have a pointer. Even though we have no need to do this, we still must provide a name, because that is one of Java’s quirky rules.
</P>
<H4 ALIGN="LEFT"><A NAME="Heading30"></A><FONT COLOR="#000077">Extending the Sprite Class</FONT></H4>
<P>There are a couple of changes to the Sprite class we should make next. The first thing we need to do is to add the capacity for each Sprite to have a certain data string associated with it. This will be used mainly for the enemy Sprites, each of which must display a potential answer to the question WordQuest poses. This mainly affects two methods, setXY() and generateImage() in Sprite.class. They need to be altered as follows:
</P>
<!-- CODE //-->
<PRE>
public String data;
...
public void setXY(int x, int y) {
this.x=x;
this.y=y;
if( data != null && !data.equals("user")) {
FontMetrics fm = theG.getFontMetrics();
WIDTH = fm.stringWidth( data) + 10;
}
if( bounds == null)
bounds = new Rectangle( x,y,WIDTH,HEIGHT);
else {
bounds.x=x;
bounds.y=y;
}
}
...
public synchronized void generateImage() {
...
case ENEMY: {
theColor = new Color(
(int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.⇒
random()*255));
blah.setColor( theColor);
blah.fillRect( 0,0,bounds.width,bounds.height);
blah.setColor(Color.black);
blah.fillRect( 5, (int)(bounds.height/2-⇒
theG.getFont().getSize()/2-1),WIDTH-10,theG.getFont().getSize()+2);
blah.setColor(Color.white);
blah.drawString( data, 5,⇒
(int)(bounds.height/2+theG.getFont().getSize()/2)
);
break;
}
...
</PRE>
<!-- END CODE //-->
<P>This will enable enemy Sprites to be resized to adequately display their data, and will draw it on top of their Image. Note that these Sprites will not draw any text if they are using a custom animation Image array. Any such array must either have the words imprinted on it (not very practical) or Sprite needs another method for adding the text to the Image (this is far easier and is left as an exercise for the user).
</P>
<P>Because most Sprites will be instantiated with their data as their name, we can change the initialization slightly:</P>
<!-- CODE SNIP //-->
<PRE>
Sprite( ThreadGroup p, String d) {
super(p,d);
data=d;
}
</PRE>
<!-- END CODE SNIP //-->
<P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="669-673.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="676-679.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
</BODY>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -