Adding sound to our game

A game with no sound is not complete. In this tutorial we will add background music, the noise of the bouncing of the ball and a "Game Over" with funny voice at the end of the game. To avoid copyright problems we are going to create the sounds ourselves.

Creating sounds

To create the sounds I looked up in Google to find a "free audio editor" and I found http://free-audio-editor.com/. I have to say that the free version of this product is powerful and easy to use.

With this editor I have created the archives: back.wav, gameover.wav y ball.wav. In the youtube video you can see how I did it and you can create them yourselves. You can also download those three and use them, which I now declare them copyright free. What you have to do is copy these archives to the com.edu4java.minitennis7 package.

Play sounds using AudioClip

To play these sound archives we will use the AudioClip class. We will create AudioClip objects, using the static method: Applet.newAudioClip(URL url) of the Applet class. This method needs un URL object which indicates where is the audio archive we are wanting to load and play. The following instruction creates a new URL object, using a location in Internet:

URL url = new URL("http://www.edu4java.com/es/game/sound/back.wav");

The next instruction uses a directory inside the local archive system:

URL url = new URL("file:/C:/Users/Eli/workspace/minitennis/src/com/edu4java/minitennis7/back.wav");

We will look for our archive using the classpath. This is the system which uses java to load the classes or more specifically the *.class archives which define the classes of the program. To obtain an URL from the classpath we use the getResource(String name) method of the Class class, where "name" is the name of the archive we want to obtain.

Below we can see two ways of how to obtain the URL of the "back.wav" archive, which is located in the same package as the SoundTest class or what is the same, in the same directory as the SoundTest.class archive.

URL url = SoundTest.class.getResource("back.wav");

URL url = new SoundTest().getClass().getResource("back.wav");

Both "SoundTest.class" and "new SoundTest().getClass()" gives us a class object which has the getResource method we want to use.

I have created the SoundTest class to show you how does AudioClip work but it isn´t necessary for our game. Below we can see the SoundTest source code complete:

package com.edu4java.minitennis7;

import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;

public class SoundTest {
	public static void main(String[] args) throws Exception {

//		System.out.println("1");
//		URL url = new URL("http://www.edu4java.com/sound/back.wav");
//		System.out.println("2");
//		AudioClip clip = Applet.newAudioClip(url);
//		System.out.println("3");
//		clip.play();
//		System.out.println("4");
//		Thread.sleep(1000);

//		URL url = new URL(
//			"file:/C:/Users/Eli/workspace/minitennis/src/com/edu4java/minitennis7/back.wav");

		URL url = SoundTest.class.getResource("back.wav");
		AudioClip clip = Applet.newAudioClip(url);
		AudioClip clip2 = Applet.newAudioClip(url);
		clip.play();
		Thread.sleep(1000);
		clip2.loop();
		Thread.sleep(20000);
		clip2.stop();
		
		System.out.println("end");
	}
}

This is the way to obtain the back.wav archive from the classpath. The classpath is the directories and archives *.jar collection from where our program can read the classes (*.class archives).

One advantage of this metodology is that we only have to indicate the position of the archive regarding the class which uses it. In our case as it is in the same package we only have to write "back.wav". Another advantage is that the sound archives can be included in the *.jar archive. We´ll see more about *.jar archives later on. Once we have the URL object we can create AudioClip objects using Applet.newAudioClip(url).

		AudioClip clip = Applet.newAudioClip(url);
		AudioClip clip2 = Applet.newAudioClip(url);

The AudioClip object has a play() method which starts an independent thread which plays the audio of the archive just once. To play the audio more than once we can use the loop() method of AudioClip which will play the sound repeatedly until the stop() method is called over the same AudioClip object.

Two audioClips can play at the same time. In the example I create two audioClips with the same audio: clip and clip2. I play "clip" with play, I wait a second Thread.sleep(1000) and play clip2 with loop. The result is a mixture of the two audios. Lastly, after 20 seconds Thread.sleep(20000) I call clip2.stop() and I stop the repetition of clip2.

<< Collision detection Creating a Sound class for our game >>