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

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

あなたは

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

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

 

 

 

 

これだけじゃぁ

さすがにこれだけではゲームも何もありません。しかしこれをちょちょっと変化させるだけでゲームっぽく、そしてアイディアが生まれそうな動きをさせることができます。

使用画像 前回と変わらず
 

ファイル名「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」 ちょっと変化。Objectクラスの変更に合わせて変化させています。

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.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 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);//ロボを初期設定


		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;
				break;
			}
			break;
		case MotionEvent.ACTION_UP:
			switch(game_state){
			case GAME_START:
				break;
			case GAME_PLAY:
				if(robomovekeystate==true) robomovekeystate=false;
				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.Drawabledraw(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;}
}


						                       
 

前回との変更点は PlayDraw()メソッド内の float ac=0; から3行ですね。

タップしているなら引数に「-0.9f」を渡し、タップしていなければ引数に「0」を渡しています。

前回と大きく違う所は、タップしていようがいまいがDrawableJump()メソッドを呼び出しています。

 

ファイル名「Object.java」DrawabeJump()メソッドを変更

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;
	private 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;

	//コンストラクタ
	public Object(double ww,double hh){
		disp_w = ww;disp_h=hh;
	}
	//四角形を作成したいときの初期設定
	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 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 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);
	}
	//このクラスの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;
	}

}



						
 

Objectクラスです。

前回と違う所は、まず定数 GRAV=0.45f の追加とDrawableJump()の変更です。

DrawableJump(float ac)とfloat型の数値acを受け取りapeedyに定数GRAVと一緒に足します。それを画像y座標にさらに足します。

引数acはMainLoopの所で出ましたが、タップしていると-0.9f、していないと0を渡してくれます。タップしていないと0ということはGRAVも足すわけですからy座標+0.45fずつ足されていくわけです。

逆にタップしていれば -0.9f+0.45f=-0.45f になりy座標-0.45fずつ足されることになります。

実行結果写真は、見た目変わらないのでそのままにしていますが、タップしたりしなかったりするとふわふわとロボが浮いている感じになります。

 
実行結果

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

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

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

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

 

 
 

 

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

 

 

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