作成中のゲームアプリから
効果音の再生で再利用できそうなモジュールを取り出してみたよ。
HashMapにキーと効果音を登録して、キーを使って再生できる。
play(String[] keys)を作ったのは、
ゲームでエサを取ったときの効果音が鳴らないことがあるため。
連続でエサを取ると1つ目のエサを取った時は再生されても、
2つ目を取った時はすでにエサ取得音が再生中のため再生されない。
それを回避するため、同じ効果音を複数登録しておき、
1つ目が再生中であれば、2つ目を再生。
2つ目が再生中であれば、3つ目を再生とする。
使用例
private String[] FOODKEYS={"food1","food2","food3","food4"};
//効果音登録
SoundMap.put(FOODKEYS[0],context, R.raw.food);
SoundMap.put(FOODKEYS[1],context, R.raw.food);
SoundMap.put(FOODKEYS[2],context, R.raw.food);
SoundMap.put(FOODKEYS[3],context, R.raw.food);
//効果音再生
SoundMap.play(FOODKEYS);
import java.util.HashMap;
import android.content.Context;
import android.media.MediaPlayer;
/**
* 効果音の登録と再生
* @author inoue
*
*/
public class SoundMap {
static private HashMap _soundMap=new HashMap();
static private boolean _soundOn=true;
/**
* 効果音登録
* @param key
* @param context
* @param resid
*/
static public void put(String key,Context context,int resid){
MediaPlayer mp=MediaPlayer.create(context, resid);
put(key,mp);
}
/**
* 効果音登録
* @param key
* @param mp 効果音
*/
static public void put(String key, MediaPlayer mp){
_soundMap.put(key, mp);
}
/**
* 指定されたキーに登録されている効果音の再生
* 再生に失敗した場合、後に続くキーを使う。
* @param keys
* @return 再生の成否
*/
static public boolean play(String[] keys){
if(!isSoundOn())return false;
for(String key:keys){
if(play(key))return true;
}
return false;
}
/**
* 指定されたキーに登録されている効果音の再生
* @param key
* @return 再生の成否
*/
static public boolean play(String key){
if(!isSoundOn())return false;
MediaPlayer mp=_soundMap.get(key);
if(mp!=null){
if(!mp.isPlaying()){
mp.start();
return true;
}
}
return false;
}
static public void soundOn(){
_soundOn=true;
}
static public void soundOff(){
_soundOn=false;
}
static public boolean isSoundOn(){
return _soundOn;
}
}
派遣SEとして採用されました。
こっちのandroidアプリ開発はあまり時間が割けなくなります。
設計書なんて今まで書いたことない。
ガリガリとコーディングしてるのが楽しいんだけどな。
ひまを見つけてゲーム完成させるよ。
ViewからActivityの呼び出しで何故か強制終了された。
下の呼び出しなんだけど。これのせいで何日も悩まされる。
XXXXActivity activity = (XXXXActivity)this.getContext();
新規プロジェクトにソースをコピーしたら何故か動くようになった。
わけがわからない。
androidアプリ
開発中の画面です。
走ったりジャンプしたりします。
どんなゲームを作るのか全く考えずに、なんとなく進めてきましたが、
ようやく見えてきました。
壁に衝突したときが良い感じにできた。
あと一息か。実機を入手しないと。
プリンの画像は
ここから盗んだ。
複数画像を一つのオブジェクトに持たせてアニメーションさせます。
ImageAnimation.java
package jp.inoue.image;
import java.util.ArrayList;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
//複数の画像を表示する
public class ImageAnimation {
private int DEFAULT_ANIMATION_PAUSE=3;//指定が無い場合のpause時間
private Loc _loc;//表示位置
private ArrayList<Bitmap> _imgList;
private ArrayList<Loc> _hoseiList;//各画像の位置補正
private ArrayList<Integer> _animationList;//表示パターン
private int _animationCount;
public ImageAnimation(){
_loc=new Loc(0,0);
_imgList=new ArrayList<Bitmap>();
_hoseiList=new ArrayList<Loc>();
_animationList=new ArrayList<Integer>();
_animationCount=0;
}
public void setLoc(int x,int y){
_loc._x=x;
_loc._y=y;
}
public Loc getLoc(){
return _loc;
}
public void setAnimationList(ArrayList<Integer>animationList){
_animationList=animationList;
}
public void resetAnimationCount(){
_animationCount=0;
}
public void addImage(Resources r,int imageNum){
addImage(r,imageNum,0,0,DEFAULT_ANIMATION_PAUSE);
}
public void addImage(
Resources r,int imageNum,int hoseiX,int hoseiY,int pause){
Bitmap bmp = BitmapFactory.decodeResource(r, imageNum);
_imgList.add(bmp);
_hoseiList.add(new Loc(hoseiX,hoseiY));
for(int i=0;i<pause;i++)
_animationList.add(_imgList.size()-1);
}
public void draw(Canvas canvas){
int imgNum=_animationList.get(_animationCount);
Loc hoseiLoc=_hoseiList.get(imgNum);
canvas.drawBitmap(
_imgList.get(imgNum),_loc._x+hoseiLoc._x,
_loc._y+hoseiLoc._y,null);
_animationCount++;
if(_animationCount>=_animationList.size())
_animationCount=0;
}
class Loc{
int _x;
int _y;
Loc(int x,int y){
_x=x;
_y=y;
}
}
}
AnimationTestView.java
package jp.inoue.image;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.view.View;
public class AnimationTestView extends View {
private ImageAnimation _imageAnimation1;
private ImageAnimation _imageAnimation2;
public AnimationTestView(Context context){
super(context);
Resources resources=getResources();
_imageAnimation1=new ImageAnimation();
_imageAnimation1.addImage(resources, R.drawable.cara1_1);
_imageAnimation1.addImage(resources, R.drawable.cara1_2);
_imageAnimation1.addImage(resources, R.drawable.cara1_3);
_imageAnimation1.setLoc(10, 20);
_imageAnimation2=new ImageAnimation();
_imageAnimation2.addImage(resources, R.drawable.cara1_1,0,0,1);
_imageAnimation2.addImage(resources, R.drawable.cara1_2,10,0,1);
_imageAnimation2.addImage(resources, R.drawable.cara1_3,15,0,2);
_imageAnimation2.setLoc(30, 120);
}
protected void onDraw(Canvas canvas) {
_imageAnimation1.draw(canvas);
_imageAnimation2.draw(canvas);
}
}
AnimationTestActivity.java
package jp.inoue.image;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Handler;
import android.app.Activity;
import android.os.Bundle;
public class AnimationTestActivity extends Activity {
private AnimationTestView _view;
Handler handler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// View の設定
_view = new AnimationTestView(getApplication());
setContentView(_view);
// Timer の設定
handler=new Handler();
Timer timer = new Timer(false);
timer.schedule(new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
_view.invalidate();
}
});
}
},0, 100);
}
}
実行結果
二体の生き物が表示されます。
上はゆっくりとその場でアニメーション
下は座標補正の設定で右に飛んでいるように見える。pauseを少なく設定で素早くアニメーションする。
AnimationTestActivityのTimerの呼び出しを変えると全体の速度が変わる。