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

アプリ作成基本に戻ってその3

あなたは

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

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

 

 

 

 

今回は

前回までやったロボの動きをアニメーション表示でやってみようと思います。そんなたいしたことではないのですが、画像の初期登録の仕方とクラスへの渡し方のメモみたいな感じでみてください。

使用画像 ロボ画像を5枚1組の画像に変更
 

ファイル名「Robo1Activity.java」 ここはそのまま

package and.roid.robo1;
import android.app.Activity;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.view.Display;
import android.view.Window;
import android.view.WindowManager;

public class Robo1Activity extends Activity {
	public float disp_w,disp_h;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        Window window = getWindow();
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        WindowManager manager = window.getWindowManager();
        Display disp = manager.getDefaultDisplay();
        disp_w = disp.getWidth();
        disp_h = disp.getHeight();

        setContentView(new MainLoop(this));
        //setContentView(R.layout.main);

    }
}
                           
 

Activityファイルは、一番下の段のコードがたまに変わるだけでいつもこのまま使っています。

完全フルスクリーン仕様&画面の幅、高さを取得しています。

 

ファイル名「MainLoop.java」 結構変更

package and.roid.robo1;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

public class MainLoop extends SurfaceView implements SurfaceHolder.Callback,Runnable{
	public static final int GAME_START = 0;//ゲーム状態固定値
	public static final int GAME_PLAY = 1;//ゲーム状態固定値
	private int game_state;//ゲーム状態決定変数
	private Thread thread;
	private SurfaceHolder holder;
	private float disp_w,disp_h;//画面の幅高さ
	private Robo1Activity robo1;//Activityクラス登録
	private int sleep;//遅延時間

	//変数設定

	private Drawable buckimg;
	private Object buck;
	private Drawable roboimg;
	private Object robo;
	private Drawable[] roboimgs;
	private Object line;

	private boolean robomovekeystate;//タップ長押し処理用

	//変数設定ここまで

	public MainLoop(Context context) {
		super(context);
		init(context);
	}
	public MainLoop(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	public void init(Context context){
		holder = getHolder();
		holder.addCallback(this);
		holder.setFixedSize(getWidth(), getHeight());
		robo1 = (Robo1Activity)context;
		disp_w = robo1.disp_w;//画面幅取得
		disp_h = robo1.disp_h;//画面高さ取得
		game_state = 1;//ゲーム状態

		//ここから初期化

		this.setSleep(50);//ループ中遅延時間
		robomovekeystate = false;

		Resources resources = context.getResources();//画像登録準備
		buckimg = resources.getDrawable(R.drawable.buck);//背景画像取り込み
		buck = new Object(disp_w,disp_h);//背景画像をオブジェクト登録
		buck.Drawableinit(buckimg,disp_w/2,disp_h/2,854,480);//背景画像初期設定

		//roboimg = resources.getDrawable(R.drawable.robo);//ロボ画像取り込み
		//robo = new Object(disp_w,disp_h);//ロボ画像をオブジェクト登録
		//robo.Drawableinit(roboimg,425,350,85,100);//ロボを初期設定

		roboimgs = new Drawable[5];
		Bitmap img= BitmapFactory.decodeResource(resources,R.drawable.android_ugoki);
		for(int i=0;i<roboimgs.length;i++){
		roboimgs[i] = new BitmapDrawable(
				Bitmap.createBitmap(img,i*(img.getWidth()/5),0,img.getWidth()/5,img.getHeight()));
		}
		robo = new Object(disp_w,disp_h);//ロボ画像をオブジェクト登録
		robo.Drawablesinit(roboimgs,425,300,85,100);//ロボを初期設定


		float[] lxy = {100,400,754,400};//ライン座標
		line = new Object(disp_w,disp_h);//ラインオブジェクト登録
		line.Lineinit(lxy,Color.CYAN,2,Paint.Style.FILL);//ラインオブジェクト初期設定


		//初期化ここまで

	}

	public void run() {
		Canvas c;
		Paint p = new Paint();
		p.setAntiAlias(true);

		while(thread != null){
			c = holder.lockCanvas();

			//ゲーム状態によってスイッチ処理
			switch(game_state){
			case GAME_START:
				StartDraw(c);
				break;
			case GAME_PLAY:
				PlayDraw(c,p);
				break;
			}
			holder.unlockCanvasAndPost(c);

			try {
				Thread.sleep(sleep);
			} catch (Exception e){}
		}
	}
	//タッチ処理
	public boolean onTouchEvent(MotionEvent event){
		int action = event.getAction();
		int x = (int)event.getX();
		int y = (int)event.getY();
		float time = event.getDownTime();
		switch(action){
		case MotionEvent.ACTION_DOWN:
			switch(game_state){
			case GAME_START:
				break;
			case GAME_PLAY:
				if(robomovekeystate==false){robomovekeystate=true;robo.setJetState(true,3);}
				break;
			}
			break;
		case MotionEvent.ACTION_UP:
			switch(game_state){
			case GAME_START:
				break;
			case GAME_PLAY:
				if(robomovekeystate==true) {robomovekeystate=false;robo.setJetState(false,0);}
				break;
			}
			break;
		case MotionEvent.ACTION_MOVE:
			switch(game_state){
			case GAME_START:
				break;
			case GAME_PLAY:
				break;
			}
			break;
		}
		return true;
	}

	public boolean RectTap(int x,int y,Drawable[] gazou,int keystate){
		return gazou[keystate].getBounds().left < x && gazou[keystate].getBounds().top < y &&
		gazou[keystate].getBounds().right > x && gazou[keystate].getBounds().bottom > y;
	}

	public void StartDraw(Canvas c){
	}
	public void PlayDraw(Canvas c,Paint p){
		//プレイ画面表示
		buck.Drawabledraw(c, p);
		robo.Drawablesdraw(c, p);
		float ac=0;
		if(robomovekeystate==true) {ac=-0.9f;}else{ac=-0;}
		robo.DrawableJump(ac);
		line.Linedraw(c, p);

		drawString("kye:"+robomovekeystate,50,100,20,Color.WHITE,c,p);
	}

	public void drawString(String str,int x,int y,int size,int col,Canvas c,Paint p){
		p.setColor(col);
		p.setTextSize(size);
		c.drawText(str, x, y, p);
	}

	public void setSleep(int s){sleep=s;}
	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {}

	public void surfaceCreated(SurfaceHolder arg0) {thread = new Thread(this);thread.start();}

	public void surfaceDestroyed(SurfaceHolder arg0) {thread = null;}
}


						                       
 

初期化の「//」のところは前回のです。その下roboimgsからが今回の画像登録です。

ビットマップで取り込み、Drawableの配列に5つに分けた画像を入れ込み、配列ごとObjectクラスに渡しています。

次はタップ処理の所です。タップしたらロボがジャンプしますのでその時にアニメーション用の引数を渡します。

画面から指を離したら、さっきと逆の引数を渡します。

 

ファイル名「Object.java」結構追加

package and.roid.robo1;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;

public class Object {
	private static final float GRAV = 0.45f;
	public float px,py;	//Rect,画像の中心座標
	private int w,h;		//Rect,画像の横幅縦幅
	private float wh,hh;	//Rect,画像の大きさ/2
	private Rect rect;		//Rect,画像ののRect

	private float[] linexy;	//Lineスタート座標エンド座標
	private int lw;			//Lineの太さ
	private Style style;	//Lineのスタイル

	private int col;		//オブジェクトカラー
	private int alpha;		//オブジェクト透過度

	private Drawable obj;	//Drawable型の画像
	private float speedx,speedy;//オブジェクトスピード

	private double disp_w,disp_h;

	private Drawable[] objs;
	private int objs_state;
	private boolean jet_state;


	//コンストラクタ
	public Object(double ww,double hh){
		disp_w = ww;disp_h=hh;
	}
	//円を作成したいときの初期設定
	public void Circleinit(float px,float py,int w, int col,int alpha,Style style){
		this.px = px;
		this.py = py;
		this.w = w;
		this.col = col;
		this.alpha = alpha;
		this.style = style;
		h=0;
		setgetDrawableSize();
	}
	//四角形を作成したいときの初期設定
	public void Rectinit(float px,float py,int w, int h,int col,int alpha){
		this.px = px;
		this.py = py;
		this.w = w;
		this.h = h;
		rect = setgetRectSize(new Rect((int)(px-w/2),(int)(py-h/2),(int)(px+w/2),(int)(py+h/2)));
		this.px = rect.left;
		this.py = rect.top;
		this.w = rect.right;
		this.h = rect.bottom;
		this.col = col;
		this.alpha = alpha;
	}
	//ラインを作成したいときの初期設定
	public void Lineinit(float[] lxy,int col,int w,Style style){
		linexy = new float[4];
		linexy = setgetLineSize(lxy);
		this.col = col;
		this.lw = w;
		this.style = style;
	}
	//Drawable型の画像を作成したいときの初期設定
	public void Drawableinit(Drawable img,float px,float py,int w, int h){
		this.obj = img;
		this.px = px;
		this.py = py;
		this.w = w;
		this.h = h;
		setgetDrawableSize();
		this.speedy = 0;

	}
	//円表示
	public void Circledraw(Canvas c,Paint p){
		p.setStyle(style);
		p.setAlpha(alpha);
		p.setColor(col);
		c.drawCircle(px, py, w, p);
	}
	public void Drawablesinit(Drawable[] img,float px,float py,int w, int h){
		objs = new Drawable[5];
		this.objs = img;
		this.px = px;
		this.py = py;
		this.w = w;
		this.h = h;
		setgetDrawableSize();
		this.speedy = 0;
		objs_state = 3;
		jet_state=true;

	}
	//四角形表示
	public void Rectdraw(Canvas c,Paint p){
		wh = w/2;hh=h/2;
		rect = new Rect((int)(px-wh), (int)(py-hh), (int)(px+wh), (int)(py+hh));
		p.setAlpha(alpha);
		p.setColor(col);
		c.drawRect(rect, p);
	}
	//ライン表示
	public void Linedraw(Canvas c,Paint p){
		p.setStrokeWidth(lw);
		p.setStyle(style);
		p.setColor(col);
		c.drawLines(linexy, p);
	}
	//Drawable型の画像表示
	public void Drawabledraw(Canvas c,Paint p){
		wh = w/2;hh=h/2;
		rect = new Rect((int)(px-wh), (int)(py-hh), (int)(px+wh), (int)(py+hh));
		obj.setBounds(rect);
		obj.draw(c);


		Stringdraw("sp:"+speedy,rect.left,rect.top,20,Color.RED,c,p);
	}
	public void Drawablesdraw(Canvas c,Paint p){
		wh = w/2;hh=h/2;
		rect = new Rect((int)(px-wh), (int)(py-hh), (int)(px+wh), (int)(py+hh));
		objs[objs_state].setBounds(rect);
		objs[objs_state].draw(c);

		if(jet_state == true){//85/2=42
			objs[4].setBounds(new Rect((int)(px-wh), (int)(py+hh), (int)(px+wh), (int)(py+hh*2)));
			objs[4].draw(c);
		}

		Stringdraw("sp:"+speedy,rect.left,rect.top,20,Color.RED,c,p);
	}
	//オブジェクトのジャンプ処理
	public void DrawableJump(float ac){
		speedy += ac + GRAV;
		//py += speedy;
	}
	//String型表示
	public void Stringdraw(String str,int x,int y,int size,int col,Canvas c,Paint p){
		p.setColor(col);
		p.setTextSize(size);
		c.drawText(str, x, y, p);
	}
	public void setJetState(boolean jet,int os){jet_state = jet;objs_state = os;}
	public void setPx(float x){px = x;}
	public void setPy(float y){py = y;}
	//このクラスのRect短形を取り出せるメソッド
	public Rect getRect(){return rect;}

	//このクラスのライン座標配列を取り出せるメソッド
	public float[] getLinexy(){return linexy;}

	//どのスマホの機種でもうまく表示出来るように、Rect短形座標変換
	public Rect setgetRectSize(Rect rect){
		this.rect = rect;
		double dw = disp_w / 854f;
		double dh = disp_h / 480f;

		int w;int h;
		w = this.rect.right;
		h = this.rect.bottom;
		this.rect.left *= dw;
		this.rect.top *= dh;
		w *= dw;
		h *= dh;
		this.rect.right = this.rect.left + w;
		this.rect.bottom = this.rect.top + h;

		return this.rect;
	}

	//どのスマホの機種でもうまく表示出来るように、ライン座標変換
	public float[] setgetLineSize(float[] lxy){
		linexy = new float[4];
		linexy = lxy;
		double dw = disp_w / 854f;
		double dh = disp_h / 480f;

		linexy[0] *= dw;
		linexy[1] *= dh;
		linexy[2] *= dw;
		linexy[3] *= dh;

		return linexy;
	}

	//どのスマホの機種でもうまく表示出来るように、座標変換
	public void setgetDrawableSize(){
		double dw = disp_w / 854f;
		double dh = disp_h / 480f;

		px *= dw;
		py *= dh;
		w *= dw;
		h *= dh;
	}

}



						              
 

今回はMainLoopクラスで5つに切り分けた画像をこちらで受け取るのと、アニメーション処理として表示の仕方も変更しました。

メンバ変数の追加をしました。5枚の画像を格納するobjs、どの画像を表示させるかのobjs_state、ホバリング中判定のjet_stateです。

init()も複数画像用を作成、配列ごとうけとります。便利です。obj_stateとjet_stateも初期化しています。

Drawもあまりかわりませんが、画像が配列に入っていますのでobjs_stateで指定してあげます。

ジェットアニメーション画像は配列の最後に入っています。jet_stateがtrueならそれを任意の場所に表示させます。

setJetState()メソッドでjet_state

 
実行結果
 

たったこれだけで全然違うものになってしまうんですね・・・

左右からせまりくる敵を、ふわふわと避けるゲームとか、タップした方向にふわふわと動いて何かを避けるゲームとか・・・・避けてばっかしですね;;

いや、避けるのではなく当たっていく!とか、想像力が全然足りていないデス。

今回思ったことは、たったこれだけの変化で全然違うものになった要因はやはり数学的な何かです。ふわふわアルゴリズムといいますか。ゲームのアイディアからこのアルゴリズムを考えるのか、こういうアルゴリズムならおもしろい動きをするなと考えてからアイディアを模索していくのか、難しい所です。

 

タップすると目が上を向き、ジェット的なナニカがでています。

 

今回はこれまでです。例えばこれを押す長さによって炎の大きさをかえたりとかで、もちょっとかっこよくなりそうです。

前回も今回もたいしたことはやってないのですが、グッっと動きがでてきました。

ここまででもわかる通り、わたくしの作成の仕方は、実行させながら作成していくやりかたでやっています。

色々考えて、ダーーッと書いて、エラーが出た日には書いた時間よりエラーを探す時間の方が長かったりするのがツライからです。

このやり方だとエラーが出れば、付け加えたコードだけ見ればいいのでラクチンです。ただそれだけの理由です。

フローチャートなど書ければいいのですが・・・・

 

骨組み作成、簡単な画像表示、タップ処理
その1をちょっとした変更で劇的に変化
アニメーション
タップ方向に動かし、画像も回転

 

 

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