Categories: Java | Java ME | Games | How To | Code Examples | MMAPI (JSR-135)
This page was last modified 13:38, 15 July 2008.
How to develop a game - Part 6
From Forum Nokia Wiki
In our last lesson we learned how to save our game settings, the Sound On/Off screen, but why we have this option, if we don't have any sound in our game? It's time to learn about Java Mobile Multimedia API (MMAPI) and add some sound to our game. Let's rock!
MMAPI offers a set of multimedia capabilities for mobile devices, including playback and recording of audio and video data from a variety of sources. Of course, not all mobile devices support all the options, but MMAPI is designed in such a way that it takes full advantage of the capabilities that are available, while ignoring those that it cannot support.
MMAPI Info
The MMAPI is built on a high-level abstraction of all the multimedia devices. This abstraction is implemented in three classes that form the core of operations that you do with this API. These classes are the Player and Control interfaces, and the Manager class. Another class, the DataSource abstract class, is used to locate resources, but unless you define a new way of reading data you will probably never need to use it directly.
In a nutshell, you use the Manager class to create Player instances for different media by specifying DataSource instances. The Player instances thus created are configurable by using Control instances. For example, almost all Player instances would theoretically support a VolumeControl to control the volume of the Player. Check the following diagram:
So let's start with the Manager class, basically its a factory of players supporting the following creation methods:
- createPlayer(DataSource source), creates a player based on a DataSource
- createPlayer(InputStream stream, String type), creates a player using the input stream as source and assuming the the media type provided. For a list of media types check at IANA web site.
- createPlayer(String locator), creates a player using a URL type parameter to identify the source data
This last method allows you to allocate different types of media depending of the URL protocol you choose. Here is a list of supported types:
- Midi Player - "device://midi", creates a midi Player.
- Tone Player - "device://tone", creates a tone Player.
- Capture Audio - "capture://audio", allows to capture audio from the device mic.
- Capture Video - "capture://video", allows to capture video from the device camera.
- Capture Radio - "capture://radio?f=105.1&st=stereo", allow to capture radio.
If you want to know what content types and protocols are supported for your device, use the following methods of Manager class:
- getSupportedContentTypes(), provides a list of available content types for all protocols or to a specific one.
- getSupportedProtocols(), provides a list of available protocols for all content types or to a specific one.
After you created a Player, you can start using it by simple calling the start() method, when it reach the end of media it will automatically stop. This is the more simplistic view of the Player class, actually it has five states:
- UNREALIZED, this is the initial state of Player when obtain from the Manager.
- REALIZED, when realized() is called the Player switch to this state obtaining the information required to acquire the media resources. Realizing a Player can be a resource and time consuming process. The Player may have to communicate with a server, read a file, or interact with a set of objects.
- PREFETCHED, after a player is realized, it may still need to acquire scarce or exclusive resources, fill buffers with media data, or perform other start-up processing. This is done by calling the prefetch() method that switch the player to this state.
- STARTED, when start() is called the Player starts to play the media resource until it reach the end of the media.
- CLOSED, when close() is called the Player switch to this state, releasing all the resources acquired. It can't be used again.
The following figure shows the various states and the transitions possible between them:
If your application needs information about the state changes you need to implement the PlayerListerner interface.
Play a Sound
Now that he have all the background information about MMAPI, let's start using it in our Arkanoid clone. The idea is to play a sound each time the ball hits a brick or the pad. To do this we are going to create a class called Multimedia with a playSound() method:
//multimedia libraries import javax.microedition.media.Manager; import javax.microedition.media.Player; import javax.microedition.media.MediaException; public class Multimedia { public void playSound(String file, String format) { try { InputStream is = getClass().getResourceAsStream(file); Player p = Manager.createPlayer(is, format); p.start(); } catch (IOException ioe) { } catch (MediaException me) { } }
Now he just need to use this method each time we detect a collision between the ball and the other entities. I created for this purpose a sound named "click.wav" that i added to our resource folder.
public void updateGameState(){ ... byte colision = ball.colided(pad); if (colision != Entity.COLLISION_NONE){ if (midlet.soundOn){ midlet.multimedia.playSound("click.wav", "audio/X-wav"); } } ... }
If you run your application, you will finally hear some sound on your game.
Capture video
Now that we have sound let's add another cool feature, let's capture the player photo each time he achieves a high score. For that we first need to access the camera video and show it to the player, the following method captures the camera video stream to an Item.
Player p; VideoControl vc; public Item showVideo(String url){ Item result = null; try { p = Manager.createPlayer(url); p.realize(); // Grab the video control . vc = (VideoControl)p.getControl("VideoControl"); if (vc != null) { // create the Item with the video image result =((Item)vc.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE, null)); // add a label result.setLabel("Photo"); } // start capture p.start(); } catch (IOException ioe) { } catch (MediaException me) { } return result; }
As you can see we are using a Control, the VideoControl, to create the Item to use in our Form.
public Displayable initNewHighScore(int score, int pos) { ... newHighScoreForm.append(multimedia.showVideo("capture://video")); ... }
Now we need to use our VideoControl to capture an image from the camera,
public Image captureVideo(){ Image result = null; try { // grab data byte[] imageData = vc.getSnapshot("encoding=png"); // create image; result = Image.createImage(imageData, 0, imageData.length); } catch (MediaException me) { me.printStackTrace(); } return result; }
and then call this method when we save a high score.
// we added an extra field to Score to store the image scores[pos].image = multimedia.captureVideo();
After this we just need to show our images in the high scores screen.
public Displayable initScoreForm() { ... if (scores[i].image != null){ highScoreForm.append(scores[i].image); } ... }
Just run the application to check our new feature! With this we end this lesson, next lesson we are going to see how to use the network capabilities of your phone. See you soon.
Downloads:
| Related Discussions | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Sending mastermind game "question pegs" to another player to play | hong1981 | Mobile Java Networking & Messaging & Security | 0 | 2004-07-22 19:00 |
| Making my game available for download | smb101 | Mobile Java General | 3 | 2004-06-24 14:00 |
| Developing a Game | Tina_Tibrewal | General Symbian C++ | 1 | 2006-12-01 10:39 |
| Sending mastermind game "question pegs" to another player to play | hong1981 | Mobile Java General | 0 | 2004-07-22 19:02 |
| audio weirdness... help please | KlaarMobileEntertainment | Symbian Media (Graphics & Sounds) | 0 | 2006-06-30 14:29 |


