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

📄 ch12.htm

📁 有关于游戏开发的教程我阅读后感觉不错所以就拿出来与大家共享。
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<HTML>

<HEAD>
   <TITLE>Chapter 12 -- Playing Sound with Java</TITLE>
   <META>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">
<H1><FONT COLOR=#FF0000>Chapter 12</FONT></H1>
<H1><B><FONT SIZE=5 COLOR=#FF0000>Playing Sound with Java</FONT></B>
</H1>
<P>
<HR WIDTH="100%"></P>
<P>
<H3 ALIGN=CENTER><FONT COLOR="#000000"><FONT SIZE=+2>CONTENTS<A NAME="CONTENTS"></A>
</FONT></FONT></H3>


<UL>
<LI><A HREF="#JavaSoundSupport" >Java Sound Support</A>
<UL>
<LI><A HREF="#TheAudioClipClass" >The AudioClip Class</A>
<LI><A HREF="#AlternativestoUsingAudioClip" >Alternatives to Using AudioClip</A>
</UL>
<LI><A HREF="#SampleAppletWildAnimals" >Sample Applet: WildAnimals</A>
<LI><A HREF="#Summary" >Summary</A>
<LI><A HREF="#QA" >Q&amp;A</A>
<LI><A HREF="#Workshop" >Workshop</A>
<UL>
<LI><A HREF="#Quiz" >Quiz</A>
<LI><A HREF="#Exercises" >Exercises</A>
</UL>
</UL>
<HR>
<P>
On <A HREF="ch11.htm" >Day 11</A>, you learned all about sound
and how it is used in computer games, as well as how to find and
record your own sounds. However, you didn't learn anything about
how to actually implement sound in Java. Sure, you might have
sampled a bunch of neat sounds, but they aren't of much use until
you under-stand how to play them in a real applet.
<P>
Today you learn all about sound and how it works in Java. You
find out all the not-so-gory details about how sound is represented
in Java, along with the classes and methods used to load and play
sounds. It turns out that the current release of Java has pretty
limited support for sound. Nevertheless, more than enough audio
support is there to liven up Java games. You finish up today's
lesson by using the sound support in Java 1.0 to build a pretty
neat applet that plays multiple sound effects.
<P>
The following topics are covered in today's lesson:
<UL>
<LI>Java sound support
<LI>Sample applet: WildAnimals
</UL>
<H2><A NAME="JavaSoundSupport"><B><FONT SIZE=5 COLOR=#FF0000>Java
Sound Support</FONT></B></A></H2>
<P>
The current sound support in Java comes in the form of a class
and a few methods in the <TT><FONT FACE="Courier">Applet</FONT></TT>
class. The <TT><FONT FACE="Courier">AudioClip</FONT></TT> class,
which is part of the applet package, models a digital audio sound
clip in the AU file format. You learn about this class next. You
learn about the methods supporting sound in the <TT><FONT FACE="Courier">Applet</FONT></TT>
class later in today's lesson.
<P>
The AU file format, which you learned about in yesterday's lesson,
is currently the only sound format supported by Java. If you recall,
it is designed around 8,000 Hz mono 8-bit ULAW encoded audio clips.
This is a fairly low-quality sound format, and it severely limits
Java in providing professional audio capabilities. However, in
the current context of the Web, just being able to play AU audio
clips in Java is plenty for many applets.
<P>
As far as games go, the quality of the sound isn't always as crucial
as you might think. Many sound effects (animal noises, for example)
don't require very high-quality audio. You find this out firsthand
in this lesson when you implement an applet using various animal
sound effects.
<H3><A NAME="TheAudioClipClass"><B>The </B><TT><B><FONT SIZE=4 FACE="Courier">AudioClip</FONT></B></TT><B><FONT SIZE=4>
Class</FONT></B></A></H3>
<P>
The <TT><FONT FACE="Courier">AudioClip</FONT></TT> class models
a sound clip in Java. It is an abstract class, so you can't directly
create instances of it. The only way to create <TT><FONT FACE="Courier">AudioClip</FONT></TT>
objects is by calling one of the <TT><FONT FACE="Courier">getAudioClip</FONT></TT>
methods of the <TT><FONT FACE="Courier">Applet</FONT></TT> class.
You'll learn more about that in a moment. But first, take a look
at the methods in the <TT><FONT FACE="Courier">AudioClip</FONT></TT>
class.
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public abstract void play()<BR>
public abstract void loop()<BR>
public abstract void stop()</FONT></TT>
</BLOCKQUOTE>
<P>
As you can see, these methods are very high-level and quite simplistic.
You can't ask for a much easier interface than just calling <TT><FONT FACE="Courier">play</FONT></TT>
to play an audio clip and <TT><FONT FACE="Courier">stop</FONT></TT>
to stop an audio clip. The only twist is the <TT><FONT FACE="Courier">loop</FONT></TT>
method, which plays an audio clip repeatedly in a loop until you
explicitly call <TT><FONT FACE="Courier">stop</FONT></TT> to stop
it. The <TT><FONT FACE="Courier">loop</FONT></TT> method is useful
when you have an audio clip that needs to be repeated, such as
a music clip or a footstep sound.
<P>
None of the methods in <TT><FONT FACE="Courier">AudioClip</FONT></TT>
require parameters; the <TT><FONT FACE="Courier">AudioClip</FONT></TT>
object is entirely self-contained. For this reason, there isn't
a lot to learn about using the <TT><FONT FACE="Courier">AudioClip</FONT></TT>
class. By simply understanding the three methods implemented by
the <TT><FONT FACE="Courier">AudioClip</FONT></TT> class (<TT><FONT FACE="Courier">play</FONT></TT>,
<TT><FONT FACE="Courier">loop</FONT></TT>, <TT><FONT FACE="Courier">stop</FONT></TT>),
you are practically already a Java sound expert!
<P>
Before your ego gets too inflated, remember that you still haven't
learned the details of how to create an <TT><FONT FACE="Courier">AudioClip</FONT></TT>
object. As I mentioned a little earlier, you use one of the <TT><FONT FACE="Courier">Applet</FONT></TT>
class's <TT><FONT FACE="Courier">getAudioClip</FONT></TT> methods
to create and initialize an <TT><FONT FACE="Courier">AudioClip</FONT></TT>
object. The two versions of <TT><FONT FACE="Courier">getAudioClip</FONT></TT>
are as follows:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public AudioClip getAudioClip(URL url)
<BR>
public AudioClip getAudioClip(URL url, String name)<BR>
</FONT></TT>
</BLOCKQUOTE>
<P>
<CENTER> <TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Note</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
I mentioned earlier that you can't create an <TT><FONT FACE="Courier">AudioClip</FONT></TT> object directly because <TT><FONT FACE="Courier">AudioClip</FONT></TT> is an abstract class. Because the class is abstract, you might be wondering how an <TT><FONT 
FACE="Courier">AudioClip</FONT></TT> object can be created at all. Technically, it is impossible to ever create an object based on an abstract class. However, in the case of <TT><FONT FACE="Courier">AudioClip</FONT></TT>, you use the <TT><FONT 
FACE="Courier">getAudioClip</FONT></TT> method to get a platform-specific <TT><FONT FACE="Courier">AudioClip</FONT></TT> derived object. In other words, <TT><FONT FACE="Courier">getAudioClip</FONT></TT> acts as a native method that returns a native class 
derived from <TT><FONT FACE="Courier">AudioClip</FONT></TT>. The method and class are native because sound support varies so widely on different platforms. The purpose of the <TT><FONT FACE="Courier">AudioClip</FONT></TT>, therefore, is to standardize the 
interface for the native audio clip classes, which results in a general, platform-independent programming solution.
</BLOCKQUOTE>

</TD></TR>
</TABLE></CENTER>
<P>
<P>
The only difference between these two <TT><FONT FACE="Courier">getAudioClip</FONT></TT>
methods is whether or not the URL parameter contains a complete
reference to the name of the audio clip. In the first version,
it is assumed that the URL contains the complete name; the second
version uses the name in a separate <TT><FONT FACE="Courier">name</FONT></TT>
parameter. You will typically use the second version, because
you can easily retrieve the base URL of the applet or the HTML
document in which the applet is embedded. You do this by using
either the <TT><FONT FACE="Courier">getCodeBase</FONT></TT> or
the <TT><FONT FACE="Courier">getDocumentBase</FONT></TT> method
of <TT><FONT FACE="Courier">Applet</FONT></TT>, like this:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">AudioClip clip1 = getAudioClip(getCodeBase(),
&quot;sound1.au&quot;);<BR>
AudioClip clip2 = getAudioClip(getDocumentBase(), &quot;sound2.au&quot;);</FONT></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">getCodeBase</FONT></TT> method returns
the base URL of the applet itself, whereas <TT><FONT FACE="Courier">getDocumentBase</FONT></TT>
returns the base URL of the HTML document containing the applet.
It is usually smarter to use <TT><FONT FACE="Courier">getCodeBase</FONT></TT>
to specify the base URL for loading resources used by a Java applet.
The reason for this is that it is often useful to organize Java
applets into a directory structure beneath the HTML documents
in which they appear. Furthermore, you usually reference images
and sounds either from the same directory where the applet is
located or from a subdirectory beneath it.
<P>
<CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR><TD><B>Tip</B></TD></TR>
<TR><TD>
<BLOCKQUOTE>
I like to organize images and sounds used by an applet in a directory called <TT><FONT FACE="Courier">Res</FONT></TT>, beneath the directory containing the actual Java classes. This isolates the executable part of an applet from the resource content used 
by the applet, resulting in a more organized file structure.
</BLOCKQUOTE>

</TD></TR>
</TABLE></CENTER>
<P>
<H3><A NAME="AlternativestoUsingAudioClip"><B>Alternatives to
Using </B><TT><B><FONT SIZE=4 FACE="Courier">AudioClip</FONT></B></TT></A>
</H3>
<P>
In the audio discussion thus far, I might have led you to believe
that you must use an <TT><FONT FACE="Courier">AudioClip</FONT></TT>
object to play sounds in Java. This isn't entirely true! The truth
is that you are only required to create an <TT><FONT FACE="Courier">AudioClip</FONT></TT>
object if you want to play looped sounds. For normal (nonlooped)
sounds, you have the option of using one of the <TT><FONT FACE="Courier">play</FONT></TT>
methods in the <TT><FONT FACE="Courier">Applet</FONT></TT> class
instead of using an <TT><FONT FACE="Courier">AudioClip</FONT></TT>
object. The definitions for the <TT><FONT FACE="Courier">play</FONT></TT>
methods implemented in <TT><FONT FACE="Courier">Applet</FONT></TT>
are as follows:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public void play(URL url)<BR>
public void play(URL url, String name)</FONT></TT>
</BLOCKQUOTE>
<P>
These <TT><FONT FACE="Courier">play</FONT></TT> methods take exactly
the same parameters taken by the <TT><FONT FACE="Courier">getAudioClip</FONT></TT>
methods. In fact, the <TT><FONT FACE="Courier">play</FONT></TT>
methods in <TT><FONT FACE="Courier">Applet</FONT></TT> actually
call <TT><FONT FACE="Courier">getAudioClip</FONT></TT> to get
an <TT><FONT FACE="Courier">AudioClip</FONT></TT> object and then
use the <TT><FONT FACE="Courier">AudioClip</FONT></TT> object's
<TT><FONT FACE="Courier">play</FONT></TT> method to play the sound.
In this way, the <TT><FONT FACE="Courier">Applet</FONT></TT> <TT><FONT FACE="Courier">play</FONT></TT>
methods basically provide a higher level method of playing audio.
This is evident in Listing 12.1, which shows the Java 1.0 source
code for the <TT><FONT FACE="Courier">Applet</FONT></TT> <TT><FONT FACE="Courier">play</FONT></TT>
methods.
<HR>
<BLOCKQUOTE>
<B>Listing 12.1. The Java 1.0 </B><TT><B><FONT FACE="Courier">Applet</FONT></B></TT><B>
class's </B><TT><B><FONT FACE="Courier">play</FONT></B></TT><B>
methods.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier">public void play(URL url) {<BR>
&nbsp;&nbsp;AudioClip clip = getAudioClip(url);<BR>
&nbsp;&nbsp;if (clip != null) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;clip.play();<BR>
&nbsp;&nbsp;}<BR>
}<BR>
<BR>
public void play(URL url, String name) {<BR>
&nbsp;&nbsp;AudioClip clip = getAudioClip(url, name);<BR>
&nbsp;&nbsp;if (clip != null) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;clip.play();<BR>
&nbsp;&nbsp;}<BR>
}</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The <TT><FONT FACE="Courier">Applet</FONT></TT> <TT><FONT FACE="Courier">play</FONT></TT>
methods both create a temporary <TT><FONT FACE="Courier">AudioClip</FONT></TT>
object and then use it to play the sound by calling its <TT><FONT FACE="Courier">play</FONT></TT>
method. This provides an even higher level of interface to playing
nonlooped sounds than the <TT><FONT FACE="Courier">AudioClip</FONT></TT>
class provides.
<H2><A NAME="SampleAppletWildAnimals"><B><FONT SIZE=5 COLOR=#FF0000>Sample
Applet: WildAnimals</FONT></B></A></H2>
<P>
Now that you are a Java sound expert (at least in theory), it's
time to put your newfound knowledge to work in a sample applet.
Because this book is ultimately about writing games, it's important
for you to never compromise in making your applets as entertaining
as possible. For this reason, the applet you're going to develop
to demonstrate sound is a little more than a simple sound player.
As a matter of fact, it's quite wild! Figure 12.1 shows a screen
of the WildAnimals applet, which uses the Java <TT><FONT FACE="Courier">AudioClip</FONT></TT>
class to generate some entertaining results. The source code,
executable, images, and sounds for WildAnimals are located on
the accompanying CD-ROM.
<P>
<A HREF="f12-1.gif" ><B>Figure 12.1 : </B><I>The WildAnimals sample applet.</I></A>
<P>
The screen shot of WildAnimals doesn't quite convey the real purpose
of the applet. So, at this point, I encourage you to run it for
yourself from the CD-ROM to get the real effect. Just in case
you're the impatient type and choose to skip the wild animal experience,
I'll fill you in on what's happening. WildAnimals randomly plays
a variety of wild animal sounds to go with the eyes that are staring
at you from the darkness.
<P>
Now that you know what it does, let's take a look at the implementation
of WildAnimals. The <TT><FONT FACE="Courier">WildAnimals</FONT></TT>
class really only defines one member variable beyond the variables
required for animation that you've already seen in prior applets:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">private AudioClip[] clip = new AudioClip[5];</FONT></TT>
</BLOCKQUOTE>
<P>
This array of <TT><FONT FACE="Courier">AudioClip</FONT></TT> objects
is used to store the wild animal sounds.
<P>
The <TT><FONT FACE="Courier">init</FONT></TT> method in <TT><FONT FACE="Courier">WildAnimals</FONT></TT>
initializes the audio clips by calling the <TT><FONT FACE="Courier">getAudioClip</FONT></TT>
method:

⌨️ 快捷键说明

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