[Android game development 8] add audio in the game-Details mediaplayer and soundpoo! And explains the difference between the two and the purpose of the game!

Source: Internet
Author: User
Tags drawtext

Li huaming himiOriginal, reprinted must be explicitly noted:
Reprinted from[Heimi gamedev block]Link: http://www.himigame.com/android-game/312.html


Many kids shoes say that after my code is run, clicking home or back will cause a program exception. If you have encountered this, you certainly haven't carefully read the himi blog, in article 19th, himi specifically wrote about the causes and solutions of these errors. I have added my remarks on this blog, and my provincial children's shoes are always confused. Please click here to contact us for further reading:

[Android game development 19th] (required) surfaceview Running Mechanism explanation-analyze back and home buttons and switch to the background to handle exceptions!

In game development, I learned from materials and books that two formats of playing audio can be used in our game development: mediaplayer and soundpool!

PS: Of course, there is another jetplayer, but the format of the file to be played is quite troublesome, so I will not explain it here. If you are interested, you can study it on your own;




Mediaplayer and: soundpool class! What are their advantages and disadvantages? Or, which one is better for game development?

The answer is: both are required !!! After analyzing the pros and cons and their respective purposes, I will give you a detailed explanation when you are familiar with each playing mode!


The following is the code first: (first look at the code and then I will explain the pros and cons of the two playback forms, their respective uses, and several notes in the Code !)


Package COM. himi; <br/> Import Java. util. hashmap; <br/> Import android. content. context; <br/> Import android. graphics. canvas; <br/> Import android. graphics. color; <br/> Import android. graphics. paint; <br/> Import android. media. audiomanager; <br/> Import android. media. mediaplayer; <br/> Import android. media. soundpool; <br/> Import android. view. keyevent; <br/> Import android. view. motionevent; <br/> Import Andro Id. view. surfaceholder; <br/> Import android. view. surfaceview; <br/> Import android. view. surfaceholder. callback; <br/> public class mysurfaceview extends surfaceview implements callback, runnable {<br/> private thread th; <br/> private surfaceholder SFH; <br/> private canvas; <br/> private mediaplayer player; <br/> private paint; <br/> private Boolean on = true; <br/> private int currentvol, Ma Xvol; <br/> private audiomanager am; <br/> private hashmap <integer, integer> soundpoolmap; // Note 1 <br/> private int loadid; <br/> private soundpool; <br/> Public mysurfaceview (context) {<br/> super (context ); <br/> // obtain the audio service and convert it to an audio manager, which is used to control the volume. <br/> AM = (audiomanager) mainactivity. instance <br/>. getsystemservice (context. audio_service); <br/> maxvol = aM. getstreammaxvolume (audiomanag Er. stream_music); <br/> // obtain the maximum volume (15 Max!. Not 100 !) <Br/> SFH = This. getholder (); <br/> SFH. addcallback (this); <br/> TH = new thread (this); <br/> This. setkeepscreenon (true); <br/> setfocusable (true); <br/> paint = new paint (); <br/> paint. setantialias (true); <br/> // initialize mediaplayer <br/> player = mediaplayer. create (context, R. raw. himi); <br/> player. setlooping (true); // set loop playback <br/> // initialization of soundpool <br/> soundpool = new soundpool (4, audiomanager. stream_music, 10 0); <br/> soundpoolmap = new hashmap <integer, integer> (); <br/> soundpoolmap. put (1, soundpool. load (mainactivity. content, <br/> r. raw. himi_ogg, 1); <br/> loadid = soundpool. load (context, R. raw. himi_ogg, 1); <br/> // The last parameter of the load () method, which identifies the sound with priority. Currently, there is no effect. It is only a value for future compatibility. <Br/>}< br/> Public void surfacecreated (surfaceholder holder) {<br/>/* <br/> * in Android OS, if you press the button on your phone to adjust the volume, there are two situations: <br/> * One is to adjust the volume of the phone's own ringtones, and the other is to adjust the game, software, music playback volume <br/> * when we are in the game, we always want to adjust the game volume rather than the phone volume, <br/> * The problem is annoying again. I found in development that you can adjust the game volume only when the game has sound to play <br/>, otherwise, it is the volume of the mobile phone. Is there a way for the mobile phone to adjust the volume of the game as long as it is <br/> * in the running game status? Try the following code! <Br/> */<br/> mainactivity. instance. setvolumecontrolstream (audiomanager. stream_music); <br/> // set the volume to the media volume. When the playback is paused, the volume will not be adjusted by default, wahaha </P> <p> player. start (); <br/> th. start (); <br/>}< br/> Public void draw () {<br/> canvas = SFH. lockcanvas (); <br/> canvas. drawcolor (color. white); <br/> paint. setcolor (color. red); <br/> canvas. drawtext ("current volume:" + currentvol, 100, 40, paint); <br/> canvas. drawtext ("Current playback time" + Player. getcurrentposition () + "milliseconds", 100, <br/> 70, paint); <br/> canvas. drawtext (" 中 button switching pause/start", 100,100, paint); <br/> canvas. drawtext (" ← (5 seconds), 100,130, paint); <br/> canvas. drawtext ("arrow keys → keys to 5 seconds", 100,160, paint); <br/> canvas. drawtext (" ↑ ", 100,190, paint); <br/> canvas. drawtext (" ↓ ", 100,220, paint); <br/> SFH. unlockcanvasandpost (canvas); <br/>}< br/> private void logic () {<Br/> currentvol = aM. getstreamvolume (audiomanager. stream_music); // continuously obtain the current volume value <br/>}< br/> @ override <br/> Public Boolean onkeydown (INT key, keyevent event) {<br/> If (Key = keyevent. keycode_dpad_center) {<br/> On =! On; <br/> If (on = false) <br/> player. pause (); <br/> else <br/> player. start (); <br/>}else if (Key = keyevent. keycode_dpad_up) {// press the key here. The current screen mode is normal. <br/> player. seekto (player. getcurrentposition () + 5000); <br/>} else if (Key = keyevent. keycode_dpad_down) {<br/> If (player. getcurrentposition () <5000) {<br/> player. seekto (0); <br/>}else {<br/> player. seekto (player. getcurrentposition ()-5000); <br/>}< br/>} else if (Key = keyevent. keycode_dpad_left) {<br/> currentvol + = 1; <br/> If (currentvol> maxvol) {<br/> currentvol = 100; <br/>}< br/> AM. setstreamvolume (audiomanager. stream_music, currentvol, // Note 2 <br/> audiomanager. flag_play_sound); <br/>} else if (Key = keyevent. keycode_dpad_right) {<br/> currentvol-= 1; <br/> If (currentvol <= 0) {<br/> currentvol = 0; <br/>}< br/> AM. setstreamvolume (audiomanager. stream_music, currentvol, <br/> audiomanager. flag_play_sound); <br/>}< br/> soundpool. play (loadid, currentvol, currentvol, 1, 0, 1f); // Note 3 <br/> // soundpool. play (soundpoolmap. get (1), currentvol, currentvol, 1, 0, 1f); // Note 4 <br/> // soundpool. pause (1); // pause the soundpool sound <br/> return Super. onkeydown (Key, event); <br/>}< br/> @ override <br/> Public Boolean ontouchevent (motionevent event) {<br/> return true; <br/>}< br/> Public void run () {<br/> // todo auto-generated method stub <br/> while (true) {<br/> draw (); <br/> logic (); <br/> try {<br/> thread. sleep (100); <br/>} catch (exception ex) {<br/>}< br/> Public void surfacechanged (surfaceholder holder, int format, int width, <br/> int height) {<br/>}< br/> Public void surfacedestroyed (surfaceholder holder) {<br/>}< br/>


1. Steps for playing audio using mediaplayer:

1. Call mediaplayer. Create (context, R. Raw. himi). Call the create method using the mediaplayer class and pass in the resource audio file indexed by ID to obtain the instance;

2. The obtained instance can call mediaplayer. Star ();

Simple. In fact, there are several constructor methods for mediaplayer. If you are interested, you can try and implement them. Here we will introduce you to the basics in a simple and practical way!


Ii. Steps for playing audio in soundplayer:

1. new generates an instance; new soundpool (4, audiomanager. stream_music, 100); the first parameter is the number of sound streams that can be played simultaneously. The second parameter is the sound type, and the third parameter is the sound quality;

2. loadid = soundpool. Load (context, R. Raw. himi_ogg, 1 );

3. Use an instance to call the play method to input the corresponding audio file ID!


The following describes the advantages and disadvantages of two Playback modes:


Using mediaplayer to play audio files has some shortcomings:

For example, high resource usage, long latency, and simultaneous playback of multiple audios are not supported.

These disadvantages determine that mediaplayer is not ideal in some scenarios, for example, in game development with relatively high time precision.

At first, I used a common mediaplayer method, but this method is not suitable for game development because it is common to play multiple sound effects simultaneously in the game, anyone who has used mediaplayer should know that it does not support real-time playback of multiple sounds, and there may be more or less latency, which is intolerable, especially when the sound (such as the continuous click button) is played in a fast and continuous manner, it will be very obvious, and 3 ~ Latency of 5 seconds: [Use mediaplayer. seekto () to solve this problem ];


Some problems with using soundpool:

1. soundpool can only apply for a maximum of 1 MB of memory space, which means we can only use some very short sound fragments, instead of playing songs or game background music (you can use jetplayer to play background music ).

2. soundpool provides pause and stop methods, but it is recommended that you do not use these methods easily, because sometimes they may cause your program to terminate inexplicably. Some friends report that they do not stop the playing sound immediately. Instead, they stop playing the data in the buffer zone. They may play for another second.
3. We recommend that you use Ogg for audio format. Audio files in WAV format are used to store game sound effects. After repeated tests, when the playback interval of a sound effect is short, an exception will occur (soundpool currently only supports 16-bit wav files ). The problem was solved by converting the file to the Ogg format.

4. When playing audio using soundpool, if you call the playing function during initialization to play music, there is no sound at all, not because it is not executed, but soundpool requires a preparation time! . Of course, this preparation time is also very short, it will not affect the use of, but the program will play without sound, so I wrote the soundpool play in the key to deal,Remarks 4


After reading the pros and cons, let's take a look at my code remarks:

Note 1:

Here I have defined a hashmap. This is a hash table. If you are not familiar with this class, we recommend that you use it frequently with hashtable, the main differences between them are: hashmap is not synchronized, empty key values, high efficiency; hashtable synchronization, non-empty key values, low efficiency; but hashmap is not supported in j2s, because me does not support null key values, you can only use hashtable, Keke, and verbose in me. Here I use hashmap to store multiple audio IDs, multiple audios can be played simultaneously during playback.

As mentioned above, soundpool supports simultaneous playing of multiple audios, and this method is called during Playing (Note 3) Soundpool. Play (loadid, currentvol, currentvol, 1, 0, 1f); the first parameter indicates the previous loadid! Obtained Through soundpool. Load (context, R. Raw. himi_ogg, 1,

Note that hashmap must be defined as hashmap <integer, integer> Hm = new hash <integer, integer>, declare that this hash table is a hash table where both the key and Volue values are integer! Why do you want to do this, because if you simply define it as hashmap Hm = new hashmap (), then when you play it, that isNote 4When hashmap. Get () is used as the first ID parameter in the method, an error message is displayed!


Soundpool can only apply for a maximum of 1 MB of memory space, which means we can only use some very short sound clips. Why can only use some very short sound?

Let's take a look.Note 4The first parameter of the method. The input ID must be an int value, so the int actually corresponds to the audio ID returned by the load () method, in addition, this ID will become smaller because of the audio file size. Once our audio file exceeds the maximum int value, a memory error will be reported. That's why soundpool can only play some brief audio. Of course, I cannot verify and explain why such a definition is defined in the OS.


Note 4: Interpretation of parameters in this method

The first parameter is through soundpool. the ID of the audio returned by the load () method. The second and third parameters indicate the size of the left and right channels, the fourth parameter indicates the priority, and the fifth parameter indicates the number of loops, the last one is the playback speed (1.0 = normal playback, range: 0.5 to 2.0)



The Media Service obtains an audio manager to adjust the volume. It should be emphasized that the adjustment of the audio is to use the audio manager to call setstreamvolume (), instead of mediaplayer. setvolue (INT leftvolume, int rightvolume); the two parameters of this method are to adjust the Left and Right audio channels rather than adjust the sound size.


Well, we have analyzed what needs to be used in game development. The conclusion is that soundpool is suitable for special effects. In fact, it is better to play background music with mediaplayer. Of course, let's take a look at everyone's preferences and choices! The following is a project attached: (Project 10 + MB includes res audio files)


If someone asks how to know that a song has been played, let's talk about it here:


Playbackcompleted status:After the file is normally played and loop playback is not set, it enters this state and triggers the oncompletion () method of oncompletionlistener. In this case, you can call the START () method to play the file from scratch again, stop () to stop the mediaplayer, or seekto () to locate the playback position again.

Note: 1. Do not forget the binding operation! MP. setoncompletionlistener (this );

2. If you have set Loop Playing MP. setlooping (true);, it will never be monitored until the playback is complete !!!! Be sure to pay attention here!



Source code: original link: http://www.himigame.com/android-game/312.html


(We recommend that you subscribe to this blog, because our update speed is very fast ~ Wahaha)



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.