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

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

シューティング作るぞ!> 第二回 自機の移動

あなたは

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

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

 

share
 

 

 

自機の移動

今回は自機の移動をします。スマホの場合、キャラを移動させる方法は制限されますよね。画面を犠牲にしてコントローラーを表示させる。タップで移動させる。傾きセンサーで移動。コントローラがない為に基本細かい動きはなかなかできません。でもそのなかで工夫したりするとおもしろいかもしれませんね。

このシューティングゲームはタップ方式でいきたいと思います。

シリーズものなので、前回と比べて変更した箇所のファイルのみ掲載しようと思います。

 

 

 

 

コード追記場所はMainLoop内onTouchEventメソッドです。

ACTION_MOVE値を取得すると、画面タップしたあとに移動したかどうかがわかります。なのでタップした指にキャラがついてくるような移動方法になります。タップした場所が自機クラスで定めた範囲であれば移動するようにしているため、ワープっぽく移動してしまうようなことを防いでいます。

Objectクラスの追記

OMoveメソッドで移動を実装しています。ただ単にタップしている場所に座標を置き換えているだけです。いまある座標を保存し、移動後に画面外にでるようなら保存している座標に戻しています。

OgetTapRectメソッドは、タップをちょっと早くするとどうしても処理の速さの関係上画像がタップ移動についてこれなくなりタップ位置から画像がはなれてついてこれなくなります。それを画像の範囲よりもちょっと幅広に設定してあげることにより余裕をもたせて、ある程度タップ位置が画像から離れても大丈夫なようにするための処理です。

 

ファイル名「MainLoop.java」

001/*
002 * SurfaceViewをextendsさせたクラス
003 * メインループなどはここにあります
004 * 基本的にSurfaceViewを使用した時には決まった変数の使用
005 * などがあるので、そういう変数やメソッドの末尾に
006 * ”お決まり”と書いておきます
007 */
008package and.roid.shooting2;
009 
010import android.content.Context;
011import android.content.res.Resources;
012import android.graphics.Bitmap;
013import android.graphics.BitmapFactory;
014import android.graphics.Canvas;
015import android.graphics.Color;
016import android.graphics.Paint;
017import android.graphics.drawable.Drawable;
018import android.util.AttributeSet;
019import android.view.MotionEvent;
020import android.view.SurfaceHolder;
021import android.view.SurfaceView;
022 
023public class MainLoop extends SurfaceView implements SurfaceHolder.Callback,Runnable{
024    private SurfaceHolder holder;//お決まり
025    private Thread thread;//お決まり
026 
027    //どのActivityを使用しているかのための変数
028    private Shooting2Activity s2a;
029    private Mesod ms;
030    private float disp_w,disp_h;
031    private Drawable jikiimg,tamaimg;
032 
033 
034    /*
035     * Objectクラスを使用する準備
036     * 今回だけではこれの意味はあまりありません
037     */
038    private Object jiki;
039 
040    //コンストラクタが二つあるけど気にしないように
041    //こちらのコンストラクタは、自前でViewを実装するときに
042    //呼ばれるコンストラクタっぽい
043    public MainLoop(Context context) {
044        super(context);
045        init(context);
046    }
047    //こちらはxml方式でViewを呼び出すときに呼ばれるぽい
048    public MainLoop(Context context, AttributeSet attrs) {
049        super(context, attrs);
050        init(context);
051    }
052 
053    public void init(Context context){
054        holder = getHolder();//お決まり
055        holder.addCallback(this);//お決まり
056        holder.setFixedSize(getWidth(), getHeight());//お決まり
057        /*
058         * s2a = (Shooting2Activity)context;
059         * よくわからないけども、私的には使用している(今現在
060         * 画面に表示させている)アプリの何か色々なものをcontext
061         * として受け取り、それがいまどのActivityのやつかとか
062         * そんな感じの雰囲気と思います。(キニシテナイ)
063         */
064        s2a = (Shooting2Activity)context;
065        ms = new Mesod();
066        disp_w = s2a.disp_w;
067        disp_h = s2a.disp_h;
068 
069        Resources resources = context.getResources();//画像登録準備
070        //ビットマップ方式で画像取り込み
071        //ビットマップで取り込む理由として、使用したい大きさなどに変換できるので
072        Bitmap img= BitmapFactory.decodeResource(resources,and.roid.shooting2.R.drawable.jiki);
073        //ここで画像分割
074        //わざわざ画像の大きさをgetWidthgetHeightを使用するのは
075        //確実に大きさを図って分割するため
076        Bitmap jikibit = Bitmap.createBitmap(img,0,0,img.getWidth()/2,img.getHeight());
077        Bitmap tamabit = Bitmap.createBitmap(img,img.getWidth()/2,0,img.getWidth()/2,img.getHeight());
078 
079        /*
080         * Onjectクラスではインスタンス(実装)できないので
081         * ObjectクラスをextendsさせたJikiクラスを実装
082         */
083        jiki = new Jiki(disp_w,disp_h);
084        jiki.Oint(jikibit, 240, 800, 0, 0, jikibit.getWidth(), jikibit.getHeight());
085 
086    }
087 
088    //implements Runnableを実装するとこのメソッドが自動追加
089    //ここがメインループとなります
090    public void run() {//お決まり
091        Canvas c;
092        Paint p = new Paint();
093        p.setAntiAlias(true);
094 
095        while(thread != null){
096            c = holder.lockCanvas();//お決まり
097 
098            c.drawColor(Color.BLACK);
099            jiki.ODraw(c);
100 
101 
102            holder.unlockCanvasAndPost(c);//お決まり
103 
104            try {
105                Thread.sleep(50);//お決まり
106            } catch (Exception e){}
107        }
108    }
109 
110    public boolean onTouchEvent(MotionEvent event){
111        int action = event.getAction();
112        int x = (int)event.getX();
113        int y = (int)event.getY();
114        switch(action){
115        case MotionEvent.ACTION_DOWN:
116            break;
117        case MotionEvent.ACTION_UP:
118            break;
119        case MotionEvent.ACTION_MOVE:
120            /*
121             * タップ範囲にオブジェクトがあると自機の移動処理をします
122             * これがないと、ワープのような動きになる場合があります。
123             */
124            if(ms.RectTap(x, y, jiki.OgetTapRect()) == true) jiki.OMove(x, y);
125            break;
126        }
127        return true;
128    }
129 
130 
131    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {}//お決まり
132 
133    public void surfaceCreated(SurfaceHolder arg0) {thread = new Thread(this);thread.start();}//お決まり
134 
135    public void surfaceDestroyed(SurfaceHolder arg0) {thread = null;}//お決まり
136 
137}
138 
139                        

前回書き忘れたのでちょっと細かく表記しています

ファイル名「Object.java」

01/*
02 * このクラスは画面に表示させるオブジェクト
03 * を作成させるためのクラスです
04 * このクラス単体ではインスタンス(オブジェクト化、実体化)
05 * はできず、このクラスをextendsさせて使うようにしています
06 * 理由としてはこのゲームを作成していくうちにわかってきますが
07 * コード表記がラクチンになります
08 */
09package and.roid.shooting2;
10 
11import android.graphics.Bitmap;
12import android.graphics.Canvas;
13import android.graphics.Rect;
14import android.graphics.drawable.BitmapDrawable;
15import android.graphics.drawable.Drawable;
16 
17public abstract class Object {
18    private Mesod ms = new Mesod();
19    private float disp_w,disp_h;
20    //オブジェクトの画像
21    private Drawable img;
22    //オブジェクトの中心座標
23    private float cx,cy;
24    //向かおうとしている座標
25    private float vx,vy;
26    //オブジェクトの移動スピード
27    private float spx,spy;
28    //オブジェクトの大きさ
29    private int imgw,imgh;
30 
31    public Object(){}
32    public Object(float dw,float dh){
33        disp_w = dw;
34        disp_h = dh;
35    }
36    //初期設定
37    public void Oint(Bitmap imgb,float x,float y, float sx,float sy,int w,int h){
38        img = new BitmapDrawable(imgb);
39        cx = ms.setSizeX(disp_w, x);
40        cy = ms.setSizeY(disp_h, y);
41        spx = sx;
42        spy = sy;
43        imgw = w;
44        imgh = h;
45    }
46    //画像表示
47    public void ODraw(Canvas c){
48        /*
49         * cx,cyは中心座標のため、画像の中心にちゃんとcx,cyがくるように調整
50         */
51        img.setBounds((int)(cx-imgw/2),(int)(cy-imgh/2),(int)(cx+imgw/2),(int)(cy+imgh/2));
52        img.draw(c);
53    }
54    /*
55     * タップしたまま指を動かすとオブジェクトを移動するようにします
56     * そのため動かした先の座標におきかえるだけにしています。
57     * しかし、弾などはそういう動きにしないため、のちのちはここは
58     * abstractになる予定です
59     * このままだと弾も敵もタップして動くような書き方になっています
60     * 今回は自機を動かすだけなのでとりあえずこれで
61     */
62    public void OMove(int x,int y){
63        float cxx = cx;
64        float cyy = cy;
65        cx = x;
66        cy = y;
67 
68        if(cx-imgw/2<0 || cx+imgw/2>disp_w) cx = cxx;
69        if(cy-imgh/2<0 || cy+imgh/2>disp_h) cy = cyy;
70    }
71    /*
72     * タップ範囲にオブジェクトがあると移動できるようにしてます。。
73     * しかしタップして動かしてみると、指の動きにオブジェクトが
74     * ついてこれない場合があります。そのためオブジェクトの大きさを
75     * タップ時のみ大きくしてある程度オブジェクトから離れても
76     * ついてこれるようにごまかしています。
77     */
78    public Rect OgetTapRect(){
79        Rect taprect = new Rect(
80                img.getBounds().left-50,img.getBounds().top-50,
81                img.getBounds().right+50,img.getBounds().bottom+50);
82        return taprect;
83        }
84}
85 
86 
87                        
 

無事成功しました!

 

自機の移動はこれで完了です。

こうやって自分で作成するとわかるのですが、既存のスマホゲームなどはちゃんと細かい気配りの工夫などがしてあるんだなと思います。

あーしたいこーしたいっていうのをコードにおこす為に思案するのがプログラミングの醍醐味ですよね!

 

<戻る   次へ>

 

 

 

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