📄 100-102.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:Animating Sprites</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=3//-->
<!--PAGES=100-102//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="097-100.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="102-107.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="LEFT"><A NAME="Heading16"></A><FONT COLOR="#000077">Java Interfaces</FONT></H4>
<P>Java provides a way of declaring an interface that is completely free of implementational detail. For example, the following declares an interface called myInterface:
</P>
<!-- CODE SNIP //-->
<PRE>
public interface myInterface {
void method1();
int method2(int i);
float method3(float i, int j);
}
</PRE>
<!-- END CODE SNIP //-->
<P>Each method declared in an interface is implicitly <I>public</I> and <I>abstract</I>. In other words, the above declaration is equivalent to</P>
<!-- CODE SNIP //-->
<PRE>
public interface myInterface {
public abstract void method1();
public abstract int method2(int i);
publc abstract float method3(float i, int j);
}
</PRE>
<!-- END CODE SNIP //-->
<P>No method bodies are permitted in an interface declaration, because all methods are abstract.
</P>
<P>Now, a class <I>implements</I> an interface by providing the definitions of the methods specified by the interface. To implement myInterface,for example, the implementing class needs to provide definitions of method1(), method(), and method3() that match the return types and the formal parameter lists. For example, the following class implements myInterface:</P>
<!-- CODE //-->
<PRE>
public class myClass implements myInterface {
public void method1() {
// do nothing
}
public int method2(int f) {
return f * 17 + 13;
}
public float method3(float s, int f) {
return s * f;
}
}
</PRE>
<!-- END CODE //-->
<P>As you see, the variable names in the parameter lists don’t need to match; only the types do. Another interface you’ve used several times is the Runnable interface, which is implemented by providing a run() method.
</P>
<P>Interfaces may also declare constants (i.e., static final variables). Then, a class that implements such an interface can use these constants directly, without having to prefix them with the class name, as is the case with static variables. Here’s an example:</P>
<!-- CODE //-->
<PRE>
interface FavoriteNumbers {
static final int IRA = 13;
static final int JO = 17;
}
class Us implements FavoriteNumbers {
int minus(int x) {
return JO - IRA * x;
}
}
</PRE>
<!-- END CODE //-->
<H4 ALIGN="CENTER"><A NAME="Heading17"></A><FONT COLOR="#000077">Multiple Interfaces</FONT></H4>
<P>A class can implement multiple interfaces, as in the following:
</P>
<!-- CODE SNIP //-->
<PRE>
public class MyLife extends HardLife
implements Birth,School,Work,Death {
...
}
</PRE>
<!-- END CODE SNIP //-->
<P>MyLife must provide the definitions of the methods specified in Birth, School, Work, and Death to compile without error. Some of these methods might be inherited from the superclass HardLife.
</P>
<P>An interface may inherit from other interfaces, as in the following example:</P>
<!-- CODE SNIP //-->
<PRE>
public interface Work extends WakeUp,Daydream,GoToSleep {
...
}
</PRE>
<!-- END CODE SNIP //-->
<P>Work inherits the abstract methods and constants declared in its parent interfaces. A class that implements Work must define the methods specified in WakeUp, Daydream, GoToSleep, and in Work itself.
</P>
<P>Be sure to distinguish inheritance from using an interface. A class can inherit elements of state and behavior from a superclass, but a class that implements an interface must supply the specified methods. Furthermore, a class inherits from only one class, while there is no restriction on the number of interfaces a class can implement.</P>
<H4 ALIGN="CENTER"><A NAME="Heading18"></A><FONT COLOR="#000077">Abstract Classes vs. Interfaces</FONT></H4>
<P>You might be wondering when it’s better to use an abstract class or an interface. An abstract class can provide instance variables, and nonabstract (i.e., implemented) methods, as well as abstract methods. If you have a purely abstract class that consists of only abstract methods, you will achieve greater flexibility by defining it as an interface. Neither an abstract class nor an interface can be instantiated; however, you can create variables that refer to objects that implement the interface or the abstract class. You will see examples of this below.
</P>
<P>Now let’s apply interfaces to Sprites.</P>
<H4 ALIGN="LEFT"><A NAME="Heading19"></A><FONT COLOR="#000077">Creating a Moveable Interface</FONT></H4>
<P>One of the most important things that sprites can do is <I>move</I>. For example, in the BoogieRectSprite class (your exercise), the update() method causes movement by modifying the values of <I>locx</I> and <I>locy</I>. This movement remains internal to the BoogieRectSprite object. Once the object is instantiated, the pattern of motion is fixed and unalterable by external objects.</P>
<P>However, some sprites need to be able to respond to external requests to move. Consider a video game where you control a ship that can move left or right. A sprite represents the ship, and this sprite must alter its motion based on your input. The sprite needs an interface to bridge the gap between its internal state and requests from the outside to move.</P>
<P>There are two solutions, and the one you’ll choose depends on the particular nature of the application.</P>
<DL>
<DD><B>•</B> One solution is to incorporate the movement methods into the Sprite class. In this case, all subclasses will respond to messages from the outside to move, unless these methods are overridden.
<DD><B>•</B> The other solution is to use a Moveable interface. This is the one we will adopt. This solution allows you to explicitly state which Sprite subclasses will obey requests to move. In addition, it allows you to address other classes that implement the Moveable interface in a uniform manner.
</DL>
<P>Here’s a short list of movement methods that we’ll use in the next few chapters:
</P>
<DL>
<DD><B>•</B> setPosition(int x, int y). This method moves the sprite to the screen location (x,y).
<DD><B>•</B> setVelocity(int x, int y). Velocity is the rate of change in the position, and it will be represented by two new instance variables, vx and vy. This method sets the values of vx and vy.
<DD><B>•</B> updatePosition(). This method updates the sprite’s location, based on its velocity.
</DL>
<P>Let’s translate this interface into Java. The definition of the Moveable interface is shown in Listing 3-4.
</P>
<P><B>Listing 3-4</B> Moveable interface</P>
<!-- CODE SNIP //-->
<PRE>
interface Moveable {
public abstract void setPosition(int x, int y);
public abstract void setVelocity(int x, int y);
public abstract void updatePosition();
}
</PRE>
<!-- END CODE SNIP //-->
<P>Next, let’s see how a Sprite subclass could implement this interface. We’re going to create an applet that bounces sprites off walls.
</P><P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="097-100.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="102-107.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
</BODY>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -