[PR] この広告は3ヶ月以上更新がないため表示されています。
ホームページを更新後24時間以内に表示されなくなります。

Androidプログラミング日記 (仮)  

シューティング作るぞ!> 第七回 爆発アニメーション

あなたは

人目のプログラマーだよ。

Androidプログラミング日記 (仮).

 

share
 

 

 

爆発アニメーション

ちょっとMainLoopクラス内がごちゃついてきたので整理しつつついでに爆発アニメーションも追加しました。これも結構考えました。爆発するのはミサイルなのか敵機なのか、、、もうメンドイのでとにかくオブジェクト消失したらその座標に爆発アニメーションオブジェクト作成でいいや。となりました。なので追加ファイルに爆発用クラスを作成しました。

しかしまた違う性質のオブジェクトなのでObjectクラスもどんどん大きくなってきました・・こんなものなのかな;;

ちょろちょろ整理した結果、またもやほとんど変更するはめになりましたので掲載します;;たった1行の変更とか、ここのメソッドをあっちに持っていったとかですけどね。

ファイル名「MainLoop.java」

001/*
002 * SurfaceViewをextendsさせたクラス
003 * メインループなどはここにあります
004 * 基本的にSurfaceViewを使用した時には決まった変数の使用
005 * などがあるので、そういう変数やメソッドの末尾に
006 * ”お決まり”と書いておきます
007 */
008package and.roid.shooting2;
009 
010import java.util.ArrayList;
011import java.util.Date;
012import java.util.Random;
013 
014import android.content.Context;
015import android.content.res.Resources;
016import android.graphics.Bitmap;
017import android.graphics.BitmapFactory;
018import android.graphics.Canvas;
019import android.graphics.Color;
020import android.graphics.Paint;
021import android.graphics.Rect;
022import android.graphics.drawable.Drawable;
023import android.media.MediaPlayer;
024import android.util.AttributeSet;
025import android.view.MotionEvent;
026import android.view.SurfaceHolder;
027import android.view.SurfaceView;
028 
029public class MainLoop extends SurfaceView implements SurfaceHolder.Callback,Runnable{
030    private SurfaceHolder holder;//お決まり
031    private Thread thread;//お決まり
032 
033    //どのActivityを使用しているかのための変数
034    private Shooting2Activity s2a;
035    private Mesod ms;
036    private float disp_w,disp_h;
037    private Bitmap jikibit,tamabit;
038    //弾用、連続で重ならないようにの変数
039    private boolean tamaflg;
040    private int tamatime;
041    //弾変化ボタン用
042    private Rect tamabtn;
043    //音源用3種
044    private MediaPlayer jitama1s,jitama2s,jitama3s;
045 
046    //敵機画像用
047    private Drawable tekiimg;
048    private Bitmap tekibit;
049 
050    //爆発画像用
051    private Bitmap[] bombit = new Bitmap[4];
052    private boolean bomflg=false;
053 
054    //写真撮影用ポーズボタン
055    private Rect pose;
056    private boolean poseflg;
057 
058 
059    /*
060     * 今回画面に表示させるオブジェクトは自機と弾です
061     * 全然違うオブジェクトですがObjectクラスをextends
062     * することで同じような変数として扱うことができます。
063     * 自機は一つのオブジェクトだけですが、弾はたくさん
064     * 表示します。しかし数は決まっていません。なので
065     * ArrayListを使用することにしました。
066     * 普通の配列変数では、いくつ配列を使用するかを決めないと
067     * いけませんが、ArrayListの場合は使用したいときに配列的な
068     * ものをいくつでも作成することができます。
069     */
070    private ArrayList<Object> object = new ArrayList();
071 
072    //コンストラクタが二つあるけど気にしないように
073    //こちらのコンストラクタは、自前でViewを実装するときに
074    //呼ばれるコンストラクタっぽい
075    public MainLoop(Context context) {
076        super(context);
077        init(context);
078    }
079    //こちらはxml方式でViewを呼び出すときに呼ばれるぽい
080    public MainLoop(Context context, AttributeSet attrs) {
081        super(context, attrs);
082        init(context);
083    }
084 
085    public void init(Context context){
086        holder = getHolder();//お決まり
087        holder.addCallback(this);//お決まり
088        holder.setFixedSize(getWidth(), getHeight());//お決まり
089        /*
090         * s2a = (Shooting2Activity)context;
091         * よくわからないけども、私的には使用している(今現在
092         * 画面に表示させている)アプリの何か色々なものをcontext
093         * として受け取り、それがいまどのActivityのやつかとか
094         * そんな感じの雰囲気と思います。(キニシテナイ)
095         */
096        s2a = (Shooting2Activity)context;
097        ms = new Mesod();
098        disp_w = s2a.disp_w;
099        disp_h = s2a.disp_h;
100 
101        Resources resources = context.getResources();//画像登録準備
102        //ビットマップ方式で画像取り込み
103        //ビットマップで取り込む理由として、使用したい大きさなどに変換できるので
104        Bitmap img= BitmapFactory.decodeResource(resources,and.roid.shooting2.R.drawable.jiki);
105        //ここで画像分割
106        //わざわざ画像の大きさをgetWidthgetHeightを使用するのは
107        //確実に大きさを図って分割するため
108        jikibit = Bitmap.createBitmap(img,0,0,img.getWidth()/4,img.getHeight());
109        tamabit = Bitmap.createBitmap(img,img.getWidth()/4,0,img.getWidth()/4,img.getHeight());
110 
111        /*
112         * Onjectクラスではインスタンス(実装)できないので
113         * ObjectクラスをextendsさせたJikiクラスを実装
114         * ArrayListを使用しているため、addでインスタンスしています
115         * メソッドなどを使用する場合はget(インデックス).でメソッドなど
116         * 色々呼び出したりします。
117         * 今回はArrayListの0番目の要素に自機が入っています
118         */
119        object.add(new Jiki(disp_w,disp_h));
120        object.get(0).Oint(jikibit, 240, 800, 0, 0, jikibit.getWidth(), jikibit.getHeight(),0);
121 
122        tamaflg = true;
123        tamatime = 5;
124 
125        //弾ボタン用座標
126        tamabtn = new Rect(0,0,50,50);
127 
128        //3種類の音源を取り込み使用準備
129        jitama1s = MediaPlayer.create(context,R.raw.jitama1);
130        jitama2s = MediaPlayer.create(context,R.raw.jitama2);
131        jitama3s = MediaPlayer.create(context,R.raw.jitama3);
132        try{
133            jitama1s.prepare();
134            jitama2s.prepare();
135            jitama3s.prepare();
136        }catch (Exception e){}
137 
138        //敵機画像登録&作成
139        tekibit = Bitmap.createBitmap(img,img.getWidth()/4*2,0,img.getWidth()/4,img.getHeight());
140 
141        //ついでなのでランダムで敵機10機作成
142        Random r = new Random(new Date().getTime());
143        for(int i=0;i<10;i++){
144        int x = r.nextInt((int) (disp_w-50));
145        int y = r.nextInt((int) (disp_h/2));
146        object.add(new Tekiki(disp_w,disp_h));
147        object.get(object.size()-1).
148            Oint(tekibit, x, y, 0, 0, tekibit.getWidth(), tekibit.getHeight(),0);
149        }
150 
151        img= BitmapFactory.decodeResource(resources,and.roid.shooting2.R.drawable.bom);
152        //ここで画像分割
153        //わざわざ画像の大きさをgetWidthgetHeightを使用するのは
154        //確実に大きさを図って分割するため
155        for(int i=0;i<2;i++){
156            for(int j=0;j<2;j++){
157        bombit[j+i*2] = Bitmap.createBitmap(
158                img,
159                j*(img.getWidth()/2),i*(img.getHeight()/2),
160                img.getWidth()/2,img.getHeight()/2);
161        }
162        }
163 
164        //ポースボタン
165        pose = new Rect((int)disp_w-50,0,(int)disp_w,50);
166        poseflg=false;
167 
168    }
169 
170    //implements Runnableを実装するとこのメソッドが自動追加
171    //ここがメインループとなります
172    public void run() {//お決まり
173        Canvas c;
174        Paint p = new Paint();
175        p.setAntiAlias(true);
176 
177        while(thread != null){
178            c = holder.lockCanvas();//お決まり
179 
180            //ポース用
181            if(poseflg==false){
182            c.drawColor(Color.BLACK);
183 
184 
185 
186            //弾変化ボタン
187            p.setColor(Color.BLUE);
188            c.drawRect(tamabtn, p);
189            p.setTextSize(30);
190            c.drawText("tama:"+object.get(0).tamajoutai, 50, 50, p);
191 
192            p.setColor(Color.RED);
193            c.drawRect(pose, p);
194 
195            /*
196             * 自機も弾も同じObjectの要素を持っているので
197             * インスタンス(実装)時に作成したいクラスを
198             * 指定しておけば、同じObjectクラスとして使用
199             * することができます。わざわざ各オブジェクトの
200             * メソッドを呼ぶのではなく、共通しているObjectの
201             * メソッドを呼ぶことで解決しています
202             */
203 
204            for(int i=0;i<object.size();i++){
205                object.get(i).ODraw(c);
206                object.get(i).OMove();
207                //当たり判定
208                ms.Atarihantei(object,i);
209                if(object.get(i).bomsflg==true){
210                    object.add(new Bom(disp_w,disp_h));
211                    object.get(object.size()-1).Oint(
212                            bombit, object.get(i).cx, object.get(i).cy,
213                            0, 0, bombit[0].getWidth(), bombit[0].getHeight(),0);
214                }
215                /*
216                 * 弾が画面外に出たらオブジェクト要素を消去します
217                 */
218                if(object.get(i).Ogetdead()==true) object.remove(i);
219            }
220            /*
221             * 弾を1發打ったら連続で打てないようになり、タイマー
222             * が0になったら打てるようにしています。
223             */
224            if(tamaflg == false){
225                --tamatime;
226                if(tamatime < 0){
227                    tamatime = 5;
228                    tamaflg = true;
229                }
230            }
231 
232 
233            }
234            holder.unlockCanvasAndPost(c);//お決まり
235 
236 
237            try {
238                Thread.sleep(50);//お決まり
239            } catch (Exception e){}
240        }
241    }
242 
243    public boolean onTouchEvent(MotionEvent event){
244        int action = event.getAction();
245        int x = (int)event.getX();
246        int y = (int)event.getY();
247        switch(action){
248        case MotionEvent.ACTION_DOWN:
249            /*
250             * 弾を打っていいよ状態であり自機画像範囲にタップしていれば
251             * Jitama(弾クラス)を作成する
252             */
253            if(tamaflg == true && ms.RectTap(
254                    x, y, object.get(0).OgetTapRect()) == true){
255                /*
256                 * 弾を出すような操作をすると
257                 * どんな弾を作成するかのメソッドを
258                 * 呼び出します
259                 */
260                Tamajoutai();
261                tamaflg = false;
262            }
263            /*
264             * 弾状態を変化させるボタン
265             * 本来ならアイテムなどで弾の飛び方などの
266             * 変化をさせるものでしょうけども、今回は
267             * テストということで青短形タップで変化します
268             */
269            if(ms.RectTap(x, y, tamabtn)==true){
270                ++object.get(0).tamajoutai;
271                object.get(0).tamajoutai = (object.get(0).tamajoutai+3)%3;
272            }
273 
274            //ポーズボタン用
275            if(ms.RectTap(x, y, pose)==true){
276                if(poseflg==true){poseflg=false;}else{poseflg=true;}
277            }
278            break;
279        case MotionEvent.ACTION_UP:
280            break;
281        case MotionEvent.ACTION_MOVE:
282            if(ms.RectTap(x, y, object.get(0).OgetTapRect()) == true) object.get(0).OMove(x, y);
283 
284            break;
285        }
286        return true;
287    }
288 
289 
290    /*
291     * このメソッドも他のファイルに移したい所ですが
292     * MainLoopで使用している変数を多く使用しているため
293     * 渡す変数が多いならここでもいいんじゃないかな・・・とか
294     * 思っちゃってます。どうしたものか
295     *
296     * Objectクラスに弾の状態を表す変数を用意しています
297     * それを外部から操作して変化させることでここのif文
298     * の分岐に割り当てられます
299     */
300    public void Tamajoutai(){
301        //通常の1発だけ
302        if(object.get(0).tamajoutai == 0){
303            object.add(new JiTama(disp_w,disp_h));
304            object.get(object.size()-1).Oint(
305                    tamabit, object.get(0).cx, object.get(0).cy-jikibit.getHeight(),
306                    0, 30, tamabit.getWidth(), tamabit.getHeight(),0);
307            //音源再生
308            ms.playSound(jitama1s);
309        }
310        //2発並んで
311        if(object.get(0).tamajoutai == 1){
312 
313            object.add(new JiTama(disp_w,disp_h));
314            object.get(object.size()-1).Oint(
315                    tamabit, object.get(0).cx-20, object.get(0).cy-jikibit.getHeight(),
316                    0, 30, tamabit.getWidth(), tamabit.getHeight(),0);
317            object.add(new JiTama(disp_w,disp_h));
318            object.get(object.size()-1).Oint(
319                    tamabit, object.get(0).cx+20, object.get(0).cy-jikibit.getHeight(),
320                    0, 30, tamabit.getWidth(), tamabit.getHeight(),0);
321            //音源再生
322            ms.playSound(jitama3s);
323        }
324        /*
325         * 36度づつ自機の周りに10発一気に出ます
326         *
327         * ちょっと改造しました。自機を中心にちょっと離れた場所
328         * から弾が発射されるようにするために、弾の初期位置の角度
329         * (360/10)からその角度にsinでx座標cosでy座標に進む座標
330         * の最小値が出るので、一定の数値を掛ける(55)、そして
331         * 自機の中心座標にそれぞれ足したりすることで自機の中心から
332         * 少し離れた場所から発射されるようになりました。
333         */
334        if(object.get(0).tamajoutai == 2){
335            for(int i=0;i<10;i++){
336            int r = i*(360/10);
337            float rx = (float) (Math.sin(ms.toRadian(r))*55);
338            float ry = (float) (Math.cos(ms.toRadian(r))*55);
339            object.add(new JiTama(disp_w,disp_h));
340            object.get(object.size()-1).Oint(
341                    tamabit, object.get(0).cx+rx, object.get(0).cy-ry,
342                    30, 30, tamabit.getWidth(), tamabit.getHeight(),r);
343            }
344            //音源再生
345            ms.playSound(jitama2s);
346        }
347    }
348 
349    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {}//お決まり
350 
351    public void surfaceCreated(SurfaceHolder arg0) {thread = new Thread(this);thread.start();}//お決まり
352 
353    public void surfaceDestroyed(SurfaceHolder arg0) {thread = null;}//お決まり
354 
355}
356 
357 
358 
359                        

ファイル名「Object.java」

01/*
02 * ほとんどのメソッドをabstractにしました
03 * これによって自機クラス弾クラスと違うオブジェクト
04 * によってメソッド名は同じでそれぞれ違う固有の命令
05 * を書くことができます
06 *
07 * このクラスは画面に表示させるオブジェクト
08 * を作成させるためのクラスです
09 * このクラス単体ではインスタンス(オブジェクト化、実体化)
10 * はできず、このクラスをextendsさせて使うようにしています
11 * 理由としてはこのゲームを作成していくうちにわかってきますが
12 * コード表記がラクチンになります
13 */
14package and.roid.shooting2;
15 
16import android.graphics.Bitmap;
17import android.graphics.Canvas;
18import android.graphics.Color;
19import android.graphics.Paint;
20import android.graphics.Rect;
21import android.graphics.drawable.BitmapDrawable;
22import android.graphics.drawable.Drawable;
23 
24public abstract class Object {
25    public Mesod ms = new Mesod();
26    public float disp_w,disp_h;
27    //オブジェクトの画像
28    public Drawable img;
29    //オブジェクトの中心座標
30    public float cx,cy;
31    //向かおうとしている座標
32    public float vx,vy;
33    //オブジェクトの移動スピード
34    public float spx,spy;
35    //オブジェクトの大きさ
36    public int imgw,imgh;
37    //オブジェクトを消去させるための変数
38    public boolean dead;
39    //弾の状態
40    public int tamajoutai;
41    //弾画像の角度
42    public int tamar;
43    //オブジェクト当たり範囲
44    public Rect atarir;
45    //オブジェクトの種類
46    public int obsyurui;
47    //爆発用
48    public Drawable[] boms = new Drawable[4];
49    public boolean bomsflg=false;
50    public int bomindex=0;
51 
52    public Object(){}
53    public Object(float dw,float dh){
54        disp_w = dw;
55        disp_h = dh;
56    }
57    /*
58     * このクラスに各オブジェクトに必要なメソッドを書いても
59     * いいのですが、どのオブジェクトにどのメソッドを使用して
60     * いるかなどの管理も大変なので、こういうメソッドを持って
61     * いますよ的なことだけかいておきます(abstract)
62     * 作ろうとしている弾クラスには、タップ座標はいらないので
63     * メソッドのオーバーライドで登録
64     */
65    //画像表示
66    public abstract void ODraw(Canvas c);
67    //初期設定
68    public abstract void Oint(Bitmap imgb,float x,float y, float sx,float sy,int w,int h);
69    public abstract void Oint(Bitmap[] imgb,float x,float y, float sx,float sy,int w,int h,int tj);
70    public abstract void Oint(Bitmap imgb,float x,float y, float sx,float sy,int w,int h,int tj);
71    public abstract void OMove();
72    public abstract void OMove(int x,int y);
73    public abstract Rect OgetTapRect();
74    /*
75     * オブジェクトによって調べたい範囲が違うので引数で指定して調べるように変更
76     */
77    public boolean OsotoX(int ww){return (cx-ww<0 || cx+ww>disp_w);}
78    public boolean OsotoY(int hh){return (cy-hh<0 || cy+hh>disp_h);}
79    public boolean Ogetdead(){return dead;}//表示していいかどうかを返す
80 
81}
82 
83                        

ファイル名「Jiki.java」

01/*
02 * 自機クラス
03 * Objectクラスをextendsしています
04 */
05package and.roid.shooting2;
06 
07import android.graphics.Bitmap;
08import android.graphics.Canvas;
09import android.graphics.Paint;
10import android.graphics.Rect;
11import android.graphics.drawable.BitmapDrawable;
12 
13public class Jiki extends Object{
14 
15    public Jiki(){}
16    public Jiki(float dw,float dh){
17        super(dw,dh);
18    }
19    //初期設定
20    public void Oint(Bitmap imgb,float x,float y, float sx,float sy,int w,int h,int tj){
21        img = new BitmapDrawable(imgb);
22        cx = ms.setSizeX(disp_w, x);
23        cy = ms.setSizeY(disp_h, y);
24        spx = sx;
25        spy = sy;
26        imgw = w;
27        imgh = h;
28        dead = false;
29        //弾の初期状態を受け取ります
30        tamajoutai = tj;
31        atarir = new Rect((int)cx-30,(int)cy-30,(int)cx+30,(int)cy+30);
32        obsyurui = 0;
33    }
34    public void ODraw(Canvas c){
35        /*
36         * 画像を表示させていいかどうかdead状態を調べて表示
37         * cx,cyは中心座標のため、画像の中心にちゃんとcx,cyがくるように調整
38         */
39        if(dead == false){
40            img.setBounds((int)(cx-imgw/2),(int)(cy-imgh/2),
41                    (int)(cx+imgw/2),(int)(cy+imgh/2));
42            img.draw(c);
43            ms.OdrawRect(atarir,c);
44        }
45    }
46    /*
47     * 今回はここは使用していません
48     */
49    public void OMove(int x, int y) {
50        float cxx = cx;
51        float cyy = cy;
52        cx = x;
53        cy = y;
54        //当たり判定更新
55        atarir = new Rect((int)cx-30,(int)cy-30,(int)cx+30,(int)cy+30);
56 
57        if(OsotoX(imgw/2)==true) cx = cxx;
58        if(OsotoY(imgh/2)==true) cy = cyy;
59    }
60    public void OMove() {}
61 
62    /*
63     * タップ範囲にオブジェクトがあると移動できるようにしてます。。
64     * しかしタップして動かしてみると、指の動きにオブジェクトが
65     * ついてこれない場合があります。そのためオブジェクトの大きさを
66     * タップ時のみ大きくしてある程度オブジェクトから離れても
67     * ついてこれるようにごまかしています。
68     */
69    public Rect OgetTapRect(){
70        Rect taprect = new Rect(
71                img.getBounds().left-50,img.getBounds().top-50,
72                img.getBounds().right+50,img.getBounds().bottom+50);
73        return taprect;
74        }
75    @Override
76    public void Oint(Bitmap imgb, float x, float y, float sx, float sy, int w,int h) {}
77    @Override
78    public void Oint(Bitmap[] imgb, float x, float y, float sx, float sy,
79            int w, int h, int tj) {}
80}
81 
82                        

ファイル名「JiTama.java」

01/*
02 * 弾の種類で後方や横など飛び方が異なる
03 * 飛び方もさせたいので、飛ぶ方向を角度
04 * で設定。それに合わせて画像の角度も変化
05 * させるようにしました
06 */
07package and.roid.shooting2;
08 
09import android.graphics.Bitmap;
10import android.graphics.Canvas;
11import android.graphics.Rect;
12import android.graphics.drawable.BitmapDrawable;
13 
14public class JiTama extends Object{
15    /*
16     * 弾と画像の角度
17     */
18    public int tamakakudo;
19 
20    public JiTama(){}
21    public JiTama(float dw,float dh){
22        super(dw,dh);
23    }
24    public void ODraw(Canvas c){
25        /*
26         * 画像を回転させるにあたり、rotateのみでやろうとすると
27         * 別の画像も一緒に回転してしまいおかしくなります。
28         * そこでsave()でいったん以前の画像を保存しておき、表示
29         * し終わったらrestore()で開放すると手法で、ちゃんと表示
30         * するようになります
31         *
32         * 画像を表示させていいかどうかdead状態を調べて表示
33         * cx,cyは中心座標のため、画像の中心にちゃんとcx,cyがくるように調整
34         */
35        if(dead == false){
36            c.save();
37            img.setBounds((int)(cx-imgw/2),(int)(cy-imgh/2),
38                    (int)(cx+imgw/2),(int)(cy+imgh/2));
39            c.rotate(tamar, cx, cy);
40            img.draw(c);
41            ms.OdrawRect(atarir,c);
42            c.restore();
43        }
44    }
45    /*
46     * 角度で弾を飛ばすようにしています
47     * 画像角度と移動角度は-90度ほどの誤差があるので
48     * 調整
49     * 例えば角度0度でここもそのままの角度0度にすると
50     * 画像表示は正常だが飛ぶ方向が右方向に・・・
51     */
52    public void OMove() {
53        cx += (float) Math.cos(ms.toRadian(tamar-90)) * spx;
54        cy += (float) Math.sin(ms.toRadian(tamar-90)) * spy;
55        //当たり判定更新
56        atarir = new Rect((int)cx-10,(int)cy-10,(int)cx+10,(int)cy+10);
57        /*
58         * 範囲外にでたら弾消してくださいの合図
59         */
60        if(OsotoX(-imgw/2)==true) dead = true;
61        if(OsotoY(-imgh/2)==true) dead = true;
62    }
63 
64    public void OMove(int x, int y) {}
65    public Rect OgetTapRect() {return null;}
66    //初期設定
67    @Override
68    public void Oint(Bitmap imgb, float x, float y, float sx, float sy, int w,int h, int r) {
69        img = new BitmapDrawable(imgb);
70        cx = ms.setSizeX(disp_w, x);
71        cy = ms.setSizeY(disp_h, y);
72        spx = sx;
73        spy = sy;
74        imgw = w;
75        imgh = h;
76        dead = false;
77        tamar = r;
78        atarir = new Rect((int)cx-10,(int)cy-10,(int)cx+10,(int)cy+10);
79        obsyurui = 0;
80    }
81    @Override
82    public void Oint(Bitmap imgb, float x, float y, float sx, float sy, int w,int h) {}
83    @Override
84    public void Oint(Bitmap[] imgb, float x, float y, float sx, float sy,int w, int h, int tj) {}
85 
86}
87 
88 
89                        

 ファイル名「Tekiki.java」

01package and.roid.shooting2;
02 
03import android.graphics.Bitmap;
04import android.graphics.Canvas;
05import android.graphics.Rect;
06import android.graphics.drawable.BitmapDrawable;
07 
08public class Tekiki extends Object{
09 
10    public Tekiki(){}
11    public Tekiki(float dw,float dh){
12        super(dw,dh);
13    }
14 
15    @Override
16    public void ODraw(Canvas c) {
17        /*
18         * 画像を表示させていいかどうかdead状態を調べて表示
19         * cx,cyは中心座標のため、画像の中心にちゃんとcx,cyがくるように調整
20         */
21        if(dead == false){
22            img.setBounds((int)(cx-imgw/2),(int)(cy-imgh/2),
23                    (int)(cx+imgw/2),(int)(cy+imgh/2));
24            img.draw(c);
25            ms.OdrawRect(atarir,c);
26        }
27    }
28 
29 
30 
31    @Override
32    public void Oint(Bitmap imgb, float x, float y, float sx, float sy, int w,
33            int h, int tj) {
34        img = new BitmapDrawable(imgb);
35        cx = ms.setSizeX(disp_w, x);
36        cy = ms.setSizeY(disp_h, y);
37        spx = sx;
38        spy = sy;
39        imgw = w;
40        imgh = h;
41        dead = false;
42        tamajoutai = tj;
43        atarir = new Rect((int)cx-30,(int)cy-30,(int)cx+30,(int)cy+30);
44        obsyurui = 1;
45    }
46 
47    @Override
48    public void OMove() {}
49 
50    @Override
51    public void OMove(int x, int y) {}
52 
53    @Override
54    public Rect OgetTapRect() {return null;}
55    @Override
56    public void Oint(Bitmap imgb, float x, float y, float sx, float sy, int w,
57            int h) {}
58    @Override
59    public void Oint(Bitmap[] imgb, float x, float y, float sx, float sy,
60            int w, int h, int tj) {}
61 
62}
63 
64 
65                        

今回の追加ファイル ファイル名「Bom.java」

01package and.roid.shooting2;
02 
03import android.graphics.Bitmap;
04import android.graphics.Canvas;
05import android.graphics.Rect;
06import android.graphics.drawable.BitmapDrawable;
07 
08public class Bom extends Object{
09 
10    public Bom(){}
11    public Bom(float dw,float dh){
12        super(dw,dh);
13    }
14    @Override
15    public void ODraw(Canvas c) {
16            boms[bomindex].setBounds((int)(cx-40),(int)(cy-40),
17                    (int)(cx+40),(int)(cy+40));
18            boms[bomindex].draw(c);
19            ++bomindex;
20            if(bomindex>3)dead=true;
21    }
22 
23    @Override
24    public void Oint(Bitmap[] imgb, float x, float y, float sx, float sy,
25            int w, int h, int tj) {
26        for(int i=0;i<4;i++){
27            boms[i] = new BitmapDrawable(imgb[i]);
28        }
29        cx = ms.setSizeX(disp_w, x);
30        cy = ms.setSizeY(disp_h, y);
31        spx = sx;
32        spy = sy;
33        imgw = w;
34        imgh = h;
35        dead = false;
36        //爆発の初期状態を受け取ります
37        tamajoutai = tj;
38        atarir = new Rect((int)cx-30,(int)cy-30,(int)cx+30,(int)cy+30);
39        obsyurui = 1;
40    }
41    @Override
42    public void Oint(Bitmap imgb, float x, float y, float sx, float sy, int w,int h, int tj) {}
43    public void OMove() {}
44    public void OMove(int x, int y) {}
45    public Rect OgetTapRect() {return null;}
46    @Override
47    public void Oint(Bitmap imgb, float x, float y, float sx, float sy, int w,int h) {}
48}
49 
50                        

ファイル名「Mesod.java」

01/*
02 * 無理やり作った汎用メソッド群
03 * なんども使用するようなメソッドをかためて置いて
04 * おきたかったので無理やりつくったクラス
05 */
06 
07package and.roid.shooting2;
08 
09import java.util.ArrayList;
10 
11import android.graphics.Canvas;
12import android.graphics.Color;
13import android.graphics.Paint;
14import android.graphics.Rect;
15import android.media.MediaPlayer;
16 
17public class Mesod {
18    /*
19     * わたくしの環境がXPERIAでその画面幅でアプリを作成
20     * しているのでそれから各アプリの画面幅に合うように調整
21     * させるための変数
22     */
23 
24    static public final float XPERIA_W = 480f;
25    static public final float XPERIA_H = 854f;
26    //せっかくなので0も固定値に
27    static public final float ZERO = 0f;
28    private static final double PIE = 3.1415926;
29 
30 
31    /*
32     * Objectクラスから移動してきた当たり範囲表示メソッド
33     *
34     * オブジェクトすべてに、オブジェクトごとの当たり判定
35     * を作成しました。それはゲーム中は見えないもののため
36     * わかりやすくするために可視化しています。
37     */
38    public void OdrawRect(Rect rec,Canvas c){
39        Paint p=new Paint();
40        p.setColor(Color.RED);
41        //c.drawRect(rec, p);
42    }
43    /*
44     * MainLoopクラスに表記していたメソッドをコチラニ移動してみました
45     *
46     * メインループで表示移動メソッドが呼び出されているオブジェクト
47     * をArrayList型のObjectとナンバー(i)を受け取り、その他と総当りで判定
48     * 同じオブジェクト以外と同じ種類のオブジェクト以外なら判定
49     * この場合自機と自機弾は同じ種類としています
50     * Mesodクラスの短形同士の当たり判定がtrueなら比べたオブジェクト
51     * 両方共に消す
52     */
53    public void Atarihantei(ArrayList<Object> object,int i){
54        for(int j=0;j<object.size()-1;j++){
55            if(i!=j && object.get(i).obsyurui != object.get(j).obsyurui){
56                if(RectRect(object.get(i).atarir, object.get(j).atarir)==true){
57                object.get(i).dead=true;
58                object.get(i).bomsflg=true;
59                object.get(j).dead=true;
60                }
61            }
62 
63        }
64    }
65    //渡された短形と短形の当たり判定。重なっていればtrue
66    public boolean RectRect(Rect oa,Rect ob){
67        return oa.left < ob.right && ob.left < oa.right && oa.top < ob.bottom && ob.top < oa.bottom;
68    }
69    //サウンド再生用
70    public void playSound( MediaPlayer mp){
71           mp.seekTo(0);
72           mp.start();
73    }
74    /*
75     * sin,cosなどを使用するときに入れ込む数値は
76     * 3.14を半周とした数値を180で割ったラジアン値
77     * というものを使用しなければなりません。
78     * (1周3.14×2=6.28を360で割った数値)
79     * 角度設定などは度数で出したほうが簡単なので設定は
80     * 度数でして、使用するときにここのメソッドでラジアン値
81     * に変換しています
82     */
83    public double toRadian(double deg){return (deg * PIE / 180);}
84    /*
85     * 受け取ったxy座標と調べたい短形範囲が重なっているかいないか
86     */
87    public boolean RectTap(int x,int y,Rect gazou){
88        return gazou.left < x && gazou.top < y && gazou.right > x && gazou.bottom > y;
89    }
90    /*
91     * この2行で各座標を実装機種の画面比に合わせます
92     */
93    public int setSizeX(float disp_w,float zahyou){return (int) (zahyou * (disp_w / XPERIA_W));}
94    public int setSizeY(float disp_h,float zahyou){return (int) (zahyou * (disp_h / XPERIA_H));}
95}
96 
97                        

 

 

無事成功しました!

 

一瞬だけの動きとかが多いので、ポーズボタンを作成しました。チカチカしますがキャプチャはできるようになったのでちょっとだけ楽チンです。

今回爆発アニメーションを作成にするにあたってサイト様から画像をお借りしました

アズールコントレイル様からお借りしました。ありがとうございます。

 

<戻る   次へ>

 

 

 

Androidプログラミング日記 (仮) | サイトマップ | 個人情報保護方針 | 応援メールテヘペロ | ©2012 Japan  相互リンク大募集中です