さっそく
このプログラムに4ファイルほど使用しました、オプションメニュー用にString.xmlファイルを変更追加しました。String.xmlファイルの変更は「オプションメニュー」をご覧ください。
あなたは
人目のプログラマーだよ。
Androidプログラミング日記 (仮).
初心者脱出バウンディングボックスを以前作成しました。今回もバウンディングボックスを作成しました。しかしただ同じものは作りません。手に入れたコードを総動員して色々なものを詰め込みました。タッチでボックスが増えていくのは前のままなのですが、無限に増やせます。メモリ注意です!オプションメニューから(メニューボタンから)作成したBOXのクリアと背景色を白黒黄青グレーから選べます。このコードをちょいと変更するだけで色々遊べると思います。たぶん・・
このプログラムに4ファイルほど使用しました、オプションメニュー用にString.xmlファイルを変更追加しました。String.xmlファイルの変更は「オプションメニュー」をご覧ください。
ファイル名「Box.java」 package and.roid.box; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.graphics.Color; import android.graphics.PixelFormat; import android.os.Bundle; import android.view.Display; import android.view.Menu; import android.view.MenuItem; import android.view.Window; import android.view.WindowManager; public class Box extends Activity { //登録するオプションメニューの種類3種 private static final int MENU_ITEM0=0, MENU_ITEM1=1, MENU_ITEM2=2, MENU_ITEM3=3, MENU_ITEM4=4, MENU_ITEM5=5; public float disp_w,disp_h;//端末の画面の大きさを取得するための変数 private int col = Color.WHITE; private boolean reset = false; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFormat(PixelFormat.TRANSLUCENT); //端末の画面の大きさを取得するための処理 Window window = getWindow(); WindowManager manager = window.getWindowManager(); Display disp = manager.getDefaultDisplay(); disp_w = disp.getWidth();//端末の画面の横幅取得 disp_h = disp.getHeight();//端末の画面の縦幅取得 setContentView(new BoxView(this)); } //メニューボタンを押すと、セットされたメニューを表示 public boolean onCreateOptionsMenu(Menu menu){ super.onCreateOptionsMenu(menu); //add(0,MENU_ITEM0,0,R.string.menu_item0) //引数はグループID、アイテムID、優先順位、アイテムタイトルです MenuItem item0 = menu.add(0,MENU_ITEM0,0,R.string.menu_item0); //アイコン設定 item0.setIcon(R.drawable.ic_reset); MenuItem item1 = menu.add(0,MENU_ITEM1,0,R.string.menu_item1); item1.setIcon(R.drawable.ic_white); MenuItem item2 = menu.add(0,MENU_ITEM2,0,R.string.menu_item2); item2.setIcon(R.drawable.ic_brack); MenuItem item3 = menu.add(0,MENU_ITEM3,0,R.string.menu_item3); item3.setIcon(R.drawable.ic_yellow); MenuItem item4 = menu.add(0,MENU_ITEM4,0,R.string.menu_item4); item4.setIcon(R.drawable.ic_blue); MenuItem item5 = menu.add(0,MENU_ITEM5,0,R.string.menu_item5); item5.setIcon(R.drawable.ic_gray); return true; } //オプションメニューを選択した時の処理 public boolean onOptionsItemSelected(MenuItem item){ switch (item.getItemId()){ case MENU_ITEM0: reset = true; showDialog(this,"","BOXをすべて消しました"); return true; case MENU_ITEM1: col = Color.WHITE; showDialog(this,"","背景を白にしました"); return true; case MENU_ITEM2: col = Color.BLACK; showDialog(this,"","背景を黒にしました"); return true; case MENU_ITEM3: col = Color.YELLOW; showDialog(this,"","背景を黄色にしました"); return true; case MENU_ITEM4: col = Color.BLUE; showDialog(this,"","背景を青にしました"); return true; case MENU_ITEM5: col = Color.GRAY; showDialog(this,"","背景をグレーにしました"); return true; } return true; } //ダイアログを表示させる処理 private void showDialog(final Activity activity, String title, String text) { AlertDialog.Builder ad = new AlertDialog.Builder(activity); ad.setTitle(title); ad.setMessage(text); ad.setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { activity.setResult(Activity.RESULT_OK); } }); ad.create(); ad.show(); } public int getcolor(){return col;} public boolean getreset(){return reset;} public void setreset(){reset = false;} } |
||
ファイル名「BoxView」 package and.roid.box; import android.R.color; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; public class BoxView extends SurfaceView implements SurfaceHolder.Callback,Runnable{ private SurfaceHolder holder; private Thread thread; private float disp_w,disp_h; private Box box; private BoxGamen gamen; private int back_col; private static final int gamen_x = 5, gamen_y = 5, gamen_col = Color.BLACK; private boolean start; public BoxView(Context context) { super(context); holder = getHolder(); holder.addCallback(this); holder.setFixedSize(getWidth(), getHeight()); start = false; init(context); } public void init(Context context){ box = (Box)context; disp_w = box.disp_w; disp_h = box.disp_h; gamen = new BoxGamen(gamen_x,gamen_y,(int)disp_w-5,(int)disp_h-35,gamen_col); } public void run() { Canvas c; Paint p = new Paint(); p.setAntiAlias(true); while(thread != null){ if(box.getreset() == true) { box.setreset(); start = box.getreset(); gamen.Reset(); } c = holder.lockCanvas(); c.drawColor(box.getcolor()); gamen.draw(c, p, start); p.setTextSize(30); p.setColor(color.black); c.drawText("reset:"+box.getreset(), 10, 50, p); holder.unlockCanvasAndPost(c); try { Thread.sleep(50); } catch (Exception e){} } } public boolean onTouchEvent(MotionEvent event){ int action = event.getAction(); int x = (int)event.getX(); int y = (int)event.getY(); switch(action){ case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_UP: if(x < disp_w-95 && y < disp_h-95){ start = true; gamen.init(x, y); } break; } return true; } 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;} } |
||
ファイル名「BoxGamen.java」 package and.roid.box; import java.util.ArrayList; import java.util.Date; import java.util.Random; import android.R.color; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; public class BoxGamen { private int gamen_x,gamen_y,gamen_w,gamen_h,gamen_col; private static final int box_wh = 100, box_d = 360; private ArrayList |
||
ファイル名「BoxOb.java」 package and.roid.box; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; public class BoxOb { private static final double PIE = 3.1415926; private double obj_x,obj_y;//オブジェクト座標 private int obj_wh; private int obj_d;//オブジェクトが進む角度 private int obj_xspeed;//移動量 private int obj_yspeed;//移動量 private int obj_col;//オブジェクトの色 private int obj_vxy; BoxOb(double x,double y, int wh, int d, int vxy,int col){ obj_x = x; obj_y = y; obj_wh = wh; obj_d = d; obj_vxy = vxy; obj_col = col; obj_d = (obj_d+360)%360; obj_xspeed = (int) (Math.cos(toRadian(obj_d))*obj_vxy); obj_yspeed = (int)-(Math.sin(toRadian(obj_d))*obj_vxy); } public void init(){} public void draw(Canvas c, Paint p){ p.setStyle(Paint.Style.FILL); p.setColor(obj_col); c.drawRect(new Rect( (int)obj_x, (int)obj_y, (int)obj_x + obj_wh, (int)obj_y + obj_wh), p); } public void move(int x1,int y1,int x2,int y2){ obj_x += obj_xspeed; obj_y += obj_yspeed; if(obj_x < x1 || obj_x > x2-obj_wh ) obj_xspeed *= -1; if(obj_y < y1 || obj_y > y2-obj_wh ) obj_yspeed *= -1; } public float toRadian(float deg){return (float) (deg * PIE / 180);} } |
||
|
||
|
||
始まると白い背景でなにもありません。タップするとランダムな大きさ、色、角度、速さで移動します。作成できるBOXの数は、このプログラムでは指定させてなく、ArrayListでどんどん作成してしまうので、各々で作成できる数は決めてください。起動時はメモリと電池残量に注意です。メニューボタンを押すと作成したBOXクリアと背景を5色どれかに変更ができます。なにがおもしろいかとかはありません。綺麗なのは綺麗ですけどね・・
今回はオプションメニューの使用、これは書いてある場所コード自体などそのまま使ってもいいかもしれません。あとソースコード的なことは、配列は配列ですが、ArrayListを使用しています。配列は最初に使う数を指定しないといけませんが、これは追加していく形で使用できるのでものすごく便利です。あと今回BOXの移動方向は角度で行い、移動量も角度計算にておこなっています。これにより、ちょっとした改造で色々なお試し遊びができます。相手を作りそれに近づくコードにすると、直線的な動きではなくなり誘導弾のような動きになったり、へんな動きをしたりします。BoxOb.javaは表示するBOXをオブジェクトとして扱っているので、これに円や画像などの表示をくわえたりも簡単にできます。弾幕作成の練習とかもできますね。BOX同士に当たり判定をつけてみたり、バウンディングボックスは単純ながら色々なゲームに役に立つアルゴリズムを勉強できるのでわたしは大好きです。
以前のバウンディングボックスよりもだいぶ発展できました。これはAndroidプログラミングがちょっとだけ染み付いてきたということでいいかもしれません。しかしながら、どの言語プログラミングにも言えることなのですが、作成するプログラムの大半を占めるものはアルゴリズムです。シューティングゲームが作りたいなら弾幕の移動方法や当たり判定、背景の移動方法など言語ごとの勉強はいりませんよね。そのアルゴリズムを勉強できる簡単なプログラミングコードを作成して、やりたいアルゴリズムを試す、そんなコードがわたしは大好きです。バウンディングボックスはその一つですね。
何か簡単なプログラムを組んで、あとあとそれを改造していくと自分がどのくらいできるようになったかわかるのでおもしろいですね。