Step3 OpenGLのタップ処理とスコア表示
敵が視界に入り(画面に写っている)状態でそのオブジェクトをタップすると敵を倒せるという処理を追加します。加えて、ゲーム開始前/プレイ中/ゲームオーバーとなる状態遷移を実装し、ゲームとして完成させましょう。
1.敵を倒す処理の追加
処理の流れとしては、タップされた座標の取得、OpenGLで使われる3次元座標から、画面上の2次元座標に変換し、タップされた座標と照らし合わせるというものになります。
タップされた座標の取得はARGame.javaで行います。
// 画面に触れたときに呼び出される関数 @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mGLRenderer.onTouch((int) event.getX(), displayY - (int) event.getY()); break; case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_CANCEL: break; } return super.onTouchEvent(event); } |
取得した座標は画面左下を原点とした座標になっています。OpenGLでは、画面左上を原点とした座標になるため、その変換を行なって座標の受け渡しを行います。
GLRendererに以下のようなメソッドを追加します。座標の取得と共に、画面にタッチされたかを判定するフラグも作成します。
public void onTouch(int x, int y) { isTouched = true; touchX = x; touchY = y; } |
作成したフラグを利用してonDrawFrame中の処理で当たり判定を行う処理を呼びします。
・・・(中略)・・・ if (isTouched) { isTouched = false; slap(gl); } ・・・(中略)・・・ |
当たり判定を行う処理は以下のようになります。
private void slap(GL10 gl) { int color[] = new int[1]; ByteBuffer buf = ByteBuffer.allocateDirect(4); buf.order(ByteOrder.nativeOrder()); gl.glReadPixels(touchX, touchY, 1, 1, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, buf); buf.asIntBuffer().get(color); if (color[0] != 0) { vibrator.vibrate(100); enemy.initPosition(); score += 1; } } |
当たり判定は、画面中に描画されるOpenGLの画素を取得し、その色を判別することで行います。ここでは、タップされた座標の画素を取得し、背景でなければ撃墜処理を起こっています。撃墜処理は、端末を振動させる、敵を初期値(ランダム)に移動する、スコアを増やすといったものになっています。
2.状態遷移の作成
ゲームの状態遷移を行う処理を追加します。onDrawFrame内の処理をstateの値によって変化させることで実現します。
switch (state) { case STATE_START: if (isTouched) { isTouched = false; state = STATE_PLAY; } break; case STATE_PLAY: ・・・(中略)・・・ さきほど記述したonDrawFrameの内容 ・・・(中略)・・・ break; case STATE_GAMEOVER: if (isTouched) { isTouched = false; initialize(); } break; } |
STATE_STARTでは画面がタップされたらゲームを開始するようにします。STATE_GAMEOVERでは、内容の初期化を行います。初期化の内容は以下のようになります。
private void initialize() { enemy = new Enemy(); state = STATE_START; score = 0; } |
ゲームの処理はひと通り完成しました。最後に、スコアの表示などを行う部分を作成しましょう。
3.スコアの表示
スコアの表示は3Dではないため、ARView.java内でCanvasクラスを使用して行います。ARViewの内容は以下のようになります。
public class ARView extends View { private int displayX; private int displayY; private int mScore; private int mState; privat ARView(Context context) { super(context); // 画面サイズの取得 Display disp = ((WindowManager) context .getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); displayX = disp.getWidth(); displayY = disp.getHeight(); mState = GLRenderer.STATE_START; } // (1)描画処理 @Override protected void onDraw(Canvas canvas) { Paint paint = new Paint(); paint.setAntiAlias(true); // スコアの描画 paint.setTextSize(16); paint.setColor(Color.WHITE); canvas.drawText("SCORE:" + Integer.toString(mScore), 10, 20, paint); if(mState == GLRenderer.STATE_START){ String str = new String("TAP TO START!"); paint.setTextSize(32); paint.setColor(Color.WHITE); float textWidth = paint.measureText(str) / 2; canvas.drawText(str, displayX/2-textWidth, displayY/2, paint); }else if (mState == GLRenderer.STATE_GAMEOVER){ String str = new String("GAME OVER"); paint.setTextSize(32); paint.setColor(Color.WHITE); float textWidth = paint.measureText(str) / 2; canvas.drawText(str, displayX/2-textWidth, displayY/2, paint); } } // (2)更新処理の呼び出し public void drawScreen(int state, int score) { // 状態の更新 mState = state; mScore = score; /// onDrawを呼び出して再描画 invalidate(); } |
(1)描画処理
ゲームの状態によって描画内容を変化させます。スコアの描画に加えて、STATE_STARTでは、画面に触れるとゲームが開始される旨を、STATE_GAMEOVERではGAME OVERと表示します。
(2)更新処理の呼び出し
各パラメータを引渡、画面の再描画を行います。
ARView.javaの処理を行うために、GLRendererに情報を取得するメソッドを加えます。
public int getState() { return state; } public int getScore() { return score; } |
これらの処理を利用して、ARGame.javaのonSensorChangedメソッド内で、画面の更新処理を行うようにします。
・・・(中略)・・・ mGLRenderer.setState(actual_orientation[0], actual_orientation[2]); arView.drawScreen(mGLRenderer.getState(), mGLRenderer.getScore()); } |
これでARGame.javaは完成です。実際にプレイすると、以下のような画面が現れます。 実際には背景にカメラ画像が映るので、自分の周りにいる見えない敵がこちらに近づいてくるような形になります。
以上でARアプリの作成は終了です。ここまで3回にわたってARを取り上げてきましたが、いかがだったでしょうか。ARといってもマーカー検出、位置情報、センサー利用やOpenGLの利用など、様々なアプローチがあることがお分かり頂けたと思います。工夫次第で面白いアプリが作成できると思いますので、是非皆さんも考えてみて下さい。
次回は作成したアプリをAndroid マーケット™ に登録するという内容を取り挙げます。 12回に渡る連載も、次回で最終回となります。最後までよろしくお願いします。
今回コラムで使用したプログラムはこちらとからダウンロード出来ます。
第11回 ARゲームを作ってみよう(3)
Step1 Android OpenGLの導入とセンサーによる紐付け
Step2 敵の動作と終了判定
Step3 OpenGLのタップ処理とスコア表示
(文責:株式会社ベストクリエイト)
■免責事項