FC2ブログ
BS blog Ranking

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

アプリ開発 ブログランキングへ
にほんブログ村 IT技術ブログ Androidアプリ開発へ
にほんブログ村
BS blog Ranking

BGMや効果音を再生するManagerクラスを作るぜ!

今回から2回に渡って、BGMを再生したり効果音を鳴らすManagerクラスの実装と、Managerを使用するためのBaseActivityの実装を行います。

構想としては、ManagerクラスをBaseActivityでスタティッククラスとしてインスタンス生成を行い、例えば、画面を遷移してもBGMが途切れることのないロジックを考えています。
各画面のActivityでは、BaseActivityを継承して使用することになります。

では、Managerクラスから取り掛かります。

AndroidではMediaPlayerというクラスが用意されています。このクラスを使ってBGMや効果音を再生することができます。

まずコンストラクタで使用する音楽をMapに取り込みましょう。ちなみにMapはプライベート変数です。

/**
* コンストラクタ
*
* @param context コンテキスト
*/
public SoundManager(Context context) {

  mSoundMap = new HashMap();

  // BGM
  mSoundMap.put("bgm_top", MediaPlayer.create(context, R.raw.bgm_top));
  mSoundMap.put("bgm_game", MediaPlayer.create(context, R.raw.bgm_game));

  // 効果音
  mSoundMap.put("se_touch", MediaPlayer.create(context, R.raw.se_touch));
  mSoundMap.put("se_card", MediaPlayer.create(context, R.raw.se_card));
  mSoundMap.put("se_win", MediaPlayer.create(context, R.raw.se_win));
  mSoundMap.put("se_lose", MediaPlayer.create(context, R.raw.se_lose));
}

次にBGMを再生するメソッドです。こちらは引数にBGMの名前を指定して再生する仕組みです。
setLooping(boolean)によりループさせるか、start()で再生、setVolume(float, float)でボリュームを調整しています。
最後のsoundNameを代入しているmPlayBgmはプライベート変数で、画面遷移時に再生しているBGMの名前を保持するためのものです。

/**
* BGMを再生する
*
* @param soundName サウンド名
*/
public void startSoundBgm(String soundName) {

  stopAllSoundExceptOne(soundName);
  for (String key : mSoundMap.keySet()) {
    if (key.equals(soundName)) {
      mSoundMap.get(key).setLooping(true);
      mSoundMap.get(key).start();
      mSoundMap.get(key).setVolume(0.7F, 0.7F);
      mPlayBgm = soundName;
    }
  }
}

効果音も同様です。

/**
* 効果音を鳴らす
*
* @param soundName サウンド名
*/
public void startSoundEffect(String soundName) {

  for (String key : mSoundMap.keySet()) {
    if (key.equals(soundName)) {
      mSoundMap.get(key).setLooping(false);
      mSoundMap.get(key).start();
    }
  }
}

次にインスタンス解放のメソッドも用意しておきます。
Androidアプリではメモリリーク防止のためにも、使わなくなったインスタンスを解放する必要があります。
引数でサウンド名を指定することもできますし、nullを引数で渡してやると、全てのサウンドのインスタンスを解放する仕組みです。

/**
* MediaPlayerのインスタンスを解放する
*
* @param soundName サウンド名
*/
public void releaseInstance(String soundName) {

  for (String key : mSoundMap.keySet()) {
    if (soundName != null) {
      if (key.equals(soundName)) {
        MediaPlayer mediaPlayer = mSoundMap.get(key);
        mediaPlayer.reset();
        mediaPlayer.release();
        mediaPlayer = null;
      }
    } else {
      MediaPlayer mediaPlayer = mSoundMap.get(key);
      mediaPlayer.reset();
      mediaPlayer.release();
      mediaPlayer = null;
    }
  }
}

どんどんいきましょう。BGMの一時停止メソッドです。

/**
* BGMを一時停止する
*
* @param soundName サウンド名
*/
public void pauseSoundBgm(String soundName) {

  for (String key : mSoundMap.keySet()) {
    if (key.equals(soundName)) {
      mSoundMap.get(key).pause();
    }
  }
}

startSoundBgm(String)でセットしたプライベート変数mPlayBgmのGetterです。

/**
* 再生中のBGM名を取得する
*
* @return
*/
public String getPlayBgm() {
  return mPlayBgm;
}

画面遷移した際のフラグもプライベート変数として定義しておきます。
そのGetter/Setterです。

/**
* 画面遷移フラグを取得する
*
* @return
*/
public boolean isChangeScreenFlag() {
  return mChangeScreenFlag;
}

/**
* 画面遷移フラグを設定する
*
* @param changeScreenFlag
*/
public void setChangeScreenFlag(boolean changeScreenFlag) {
  mChangeScreenFlag = changeScreenFlag;
}

最後に、startSoundBgm(String)で呼び出しているプライベートメソッドです。
今回のアプリでは、どの画面でもBGMが再生される仕様となりますので、全サウンド停止処理の実装は行いません・・・現時点では。

/**
* 指定されたサウンドを除いた全てのサウンドを停止する
*
* @param soundName サウンド名
*/
private void stopAllSoundExceptOne(String soundName) {

  for (String key : mSoundMap.keySet()) {
    if (!key.equals(soundName)) {
      mSoundMap.get(key).stop();
    }
  }
}

SoundManagerは以上です。
次回はSoundManagerのインスタンスを生成するBaseActivityクラスの実装を行います。
スポンサーサイト

アプリ開発 ブログランキングへ
にほんブログ村 IT技術ブログ Androidアプリ開発へ
にほんブログ村
BS blog Ranking

Bitmapを端末の画面サイズに合わせてリサイズするぜ!

今回よりガシガシ、コーディングを行っていきます。
まずは共通処理から。

Androidでは端末ごとに画面サイズと解像度が異なります。
そのため、画像の表示は一つのバイナリで対応させる必要があります。

画面レイアウトを定義するXMLファイルにdip指定でサイズを指定することもできますが、今回はプログラムで動的に画像の大きさを変更することにします。
ちなみにdipという単位は〝端末に依存しないピクセル〟です。具体的には160dpi(解像度)の1ピクセルの物理的な大きさを1dipと定義しています。つまり、320dpiのディスプレイを持つ端末では、1dip=2ピクセルという計算になります。

ではまず、端末のディスプレイ情報を格納しておくコンテナであるDTOを用意します。
ここではDisplayDtoとしました。定義する変数は以下となります。

/** density */
private float density;

/** densityDpi */
private int densityDpi;

/** scaledDensity 1pxに対する1dpの倍率 */
private float scaledDensity;

/** widthPixels 幅 */
private int widthPixels;

/** heightPixels 高さ */
private int heightPixels;

/** xdpi */
private float xdpi;

/** ydpi */
private float ydpi;

もちろんGetter/Setterの用意もお願いします。

次にUtilityクラスに端末のディスプレイ情報を取得するメソッドを用意します。

/**
* ディスプレイDTOを取得する
*
* @param displayMetrics
* @return displayDto ディスプレイDTO
*/

public static final DisplayDto getDisplayDto(DisplayMetrics displayMetrics) {

  DisplayDto displayDto = new DisplayDto();
  displayDto.setDensity(displayMetrics.density);
  displayDto.setDensityDpi(displayMetrics.densityDpi);
  displayDto.setScaledDensity(displayMetrics.scaledDensity);
  displayDto.setWidthPixels(displayMetrics.widthPixels);
  displayDto.setHeightPixels(displayMetrics.heightPixels);
  displayDto.setXdpi(displayMetrics.xdpi);
  displayDto.setYdpi(displayMetrics.ydpi);
  return displayDto;
}

最後にディスプレイ情報を格納したDTOを引数に持つ、動的に画像の大きさを変更するメソッドを用意します。
こちらもUtilityクラスです。

/**
* Bitmapを端末の画面サイズに合わせてリサイズする
*
* @param src 元画像
* @param displayDto
* @return dst リサイズした画像
*/

public static final Bitmap resizeBitmap(Bitmap src, DisplayDto displayDto) {

  // 画面サイズを取得
  float displayWidth = displayDto.getWidthPixels();
  float displayHeight = displayDto.getHeightPixels();

  // 拡大比率
  float widthScale = displayWidth / Const.DISPLAY_WIDTH;
  float heightScale = displayHeight / Const.DISPLAY_HEIGHT;
  // 比率をMatrixに設定
  Matrix matrix = new Matrix();
  matrix.postScale(widthScale, heightScale);

  int srcWidth = src.getWidth();   // 元画像の幅
  int srcHeight = src.getHeight();  // 元画像の高さ

  // リサイズ
  Bitmap dst = Bitmap.createBitmap(
      src, 0, 0, srcWidth, srcHeight, matrix, true);
  src = null;
  return dst;
}

DISPLAY_WIDTHとDISPLAY_HEIGHTですが、こちらはConstクラスに定義している定数となります。
画像はすべて480×854をベースとしますので、DISPLAY_WIDTH=480、DISPLAY_HEIGHT=854となります。

コメントに書いてある通りですが、処理の流れとしては、端末の画面サイズをベースとなる画面サイズで割り、拡大比率を出しています。そこから元画像のリサイズ処理をMatrixクラスを用いて行っています。
最終的に書き出されたBitmapであるdstを返し、元画像のBitmapであるsrcはメモリリーク防止のため、nullを代入しておきます。

以上で、元画像であるBitmapとディスプレイDTOを渡してやれば、リサイズされたBitmapが返ってくるメソッドの完成です!

アプリ開発 ブログランキングへ
にほんブログ村 IT技術ブログ Androidアプリ開発へ
にほんブログ村
プロフィール

samahiko

Author:samahiko
Androidアプリ開発の備忘録へようこそ!
開発環境→仕様→コーディング→ローンチという流れをリアルタイムで記録していきますので応援よろしくです!

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。