Tracerbullit90x90_small Carsten Schw... 4 posts

Hi I've made a little game where you can remove stuff that appears on the screen of your phone. I haved added sound by creating four mediaplayers.

    
  public MyView(Context context)
  {
    super(context);
    getHolder().addCallback(this);
    _screenDice = new Dice();

    _mpDrop  = MediaPlayer.create(this.getContext(), R.raw.drop);
    _mpPurge = MediaPlayer.create(this.getContext(), R.raw.purge);
    _mpTouch = MediaPlayer.create(this.getContext(), R.raw.touch);
    _mpMusic = MediaPlayer.create(this.getContext(), R.raw.shortmusic);

    _gameThread = new GameThread(getHolder(), this);
    setFocusable(true);
  }
    
  

I started using the sounds in the game and it worked fine, then i added the option of playing music in the background, I enable/disable music based on the settings in the surfaceCreated method of my view:

  
  @Override
  public void surfaceCreated(SurfaceHolder holder)
  {
    if (Prefs.getMusic(this.getContext()))
    {
      playMusic(true);
    }
    else
    {
      playMusic(false);
    }

    if (_gameThread.getState() == Thread.State.TERMINATED)
    {
      _gameThread = new GameThread(getHolder(), this);
      _gameThread.setRunning(true);
      _gameThread.start();
    }
    else
    {
      _gameThread.setRunning(true);
      _gameThread.start();
    }    
  }
  

The methods for playing sounds and music looks like this:


  
  //--------------------------------------------------------------------------
  //
  // Sound functions
  //
  //--------------------------------------------------------------------------

  private void playDropSound()
  {
    if (null != _mpDrop && Prefs.getSound(getContext()))
    {
      _mpDrop.seekTo(0);
      _mpDrop.start();
    }      
  }

  private void playPurgeSound()
  {
    if (null != _mpPurge && Prefs.getSound(getContext()))
    {
      _mpPurge.seekTo(0);
      _mpPurge.start();
    }      
  }

  private void playTouchSound()
  {
    if (null != _mpTouch && Prefs.getSound(getContext()))
    {
      _mpTouch.seekTo(0);
      _mpTouch.start();
    }      
  }

  private void playMusic(boolean bStart)
  {
    if (null != _mpMusic)
    {
      if (bStart)
      {
        _mpMusic.seekTo(0);
        _mpMusic.setLooping(true);
        _mpMusic.start();
      }
      else
      {
        _mpMusic.setLooping(false);
      }
    }
  }
  

 

There are some issues with this:

  • When I play the game with music disabled through the settings, the music sometimes mixes in together with the sounds at random
  • When i turn the phone in landscape mode I get a Null pointer exception, this happens in the first line that calls playMusic in surfaceCreated. It seems that I have fixed this by checking on null in the play functions
  • I'm not quite sure on the number of players you can have running in parallel

Any comments on these?

 
Burnette_ed_small Ed Burnette 357 posts

You can’t have very many of them. Android doesn’t tell you what the limit is but it seems to be around 4. You’re probably getting a null returned from the MediaPlayer.create sometimes.

I recommend the following best practices:

- Don’t create your media players in the constructor. If you do it there, then there’s no place for you to call player.release, which is very important or you’ll run out of resources. You could create them in onSurfaceCreated and release them in onSurfaceDestroyed, but as a best practice I think it’s better if you do anything not related to the graphics in your Activity instead of your View. So, do it in onResume and onPause in your Activity.

- Likewise, start your thread in on(Something)Created or onResume and stop it in on(Something)Destroyed or onPause. Do everything that you create or initialize in matched bookend pairs like this.

- If you want overlapping sounds, and sounds that happen instantly because of some event like a button press or a ball hitting a wall, then use SoundPool instead of MediaPlayer. Also use .ogg format because it’s quicker to decode and play without pauses.

Hope this helps, and good luck.

2 posts, 2 voices