タッチイベントの処理と当たり判定の処理を追加。
タッチイベントの受け取りはActivityのonTouchEventをオーバーライド。EsGameRenderクラスにはタッチイベントの内容を受け取るメソッドを追加。
EsGameActivityクラスの修正部分。
//OpenGLESビュー private GLSurfaceView gLSurfaceView; private EsGameRender esGameRender; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //GLサーフェイスビューを作成して設定 gLSurfaceView = new GLSurfaceView(this); esGameRender = new EsGameRender(this); gLSurfaceView.setRenderer(esGameRender); setContentView(gLSurfaceView); } private int touchState; private float touchX, touchY; @Override public boolean onTouchEvent(MotionEvent event) { if(esGameRender == null){ return true; } touchX = event.getX(); touchY = event.getY(); touchState = event.getAction(); esGameRender.setTouchParam(touchX, touchY, touchState); return true; }
EsGameRenderクラスに、タッチした位置と標的の位置を元に当たり判定を行う処理を追加。
標的をタッチすると新たな標的を設定する。
package sample.game; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import sample.game.utils.TextureLoader; import android.content.Context; import android.opengl.GLSurfaceView; import android.util.Log; import static sample.game.utils.GraphicUtils.*; public class EsGameRender implements GLSurfaceView.Renderer { private final int one = 0x10000; private final static String TAG = "EsGame"; private Context context; public EsGameRender(Context context){ this.context = context; } @Override public void onDrawFrame(GL10 gl10) { makeWorld(gl10); drawTextureRectangle(gl10, context, 0.0f, 0.0f, 2.0f, 3.0f, background, 0, 0, 0, one);//背景 if( isTouchedTarget(glX,glY) ){ startNextTarget(); }else{ moveTarget(); } gl10.glPushMatrix(); gl10.glTranslatef(targetX, targetY, 0.0f); gl10.glRotatef(targetAngle, 0.0f, 0.0f, 1.0f); gl10.glScalef(targetSize, targetSize, 1.0f); drawTextureRectangle(gl10, context, 0.0f, 0.0f, 1.0f, 1.0f, target, 0, 0, 0, one);//標的 gl10.glPopMatrix(); } private boolean isTouchedTarget(float x, float y){ //標的とタッチ位置の距離を計算 float dx = x - targetX; float dy = y - targetY; float distance = (float) Math.sqrt(dx * dx + dy * dy); //距離が標的の当たり範囲(円で近似する)より小さければ当たり。 if(distance <= targetSize * 0.5f){ Log.d(TAG, "!!!!! Touch !!!!!!"); return true; }else{ return false; } } private void startNextTarget(){ //標的をランダムな位置に移動 final float dist = 2.0f;//直径2.0fの円周上。 float theta = (float) ((Math.random() * 10 % 360) / 180.0 * Math.PI); targetX = (float) (Math.cos(theta) * dist); targetY = (float) (Math.sin(theta) * dist); } private void moveTarget() { // Log.d(TAG, "state [x:y]="+ touchState + " [" + glX + ":" + glY +"]"); //100回に1度の割合で方向を転換する。 if((int)(Math.random() * (100+1)) % 100 == 0 ){ //旋回角度を-2.0〜2.0の範囲で変化させる。 targetTurnAngle = (float) (Math.random() * 4.0f - 2.0f ); Log.d(TAG, "方向転換! targetTurnAngle=" + targetTurnAngle); } targetAngle = targetAngle + targetTurnAngle; double theta = targetAngle / 180.0 * Math.PI; targetX = (float) (targetX + Math.cos(theta) * targetSpeed); targetY = (float) (targetY + Math.sin(theta) * targetSpeed); //画面外へ出たら反対の端へ移動させる if(targetX >= 2.0f){ targetX -= 4.0f; }else if(targetX <= -2.0f){ targetX += 4.0f; } if(targetY >= 2.5f){ targetY -= 5.0f; }else if(targetY <= -2.5f){ targetY += 5.0f; } } @Override public void onSurfaceChanged(GL10 gl10, int width, int height) { gl10.glViewport(0, 0, width, height); } @Override public void onSurfaceCreated(GL10 gl10, EGLConfig eglconfig) { background = TextureLoader.loadTexture(gl10, context, R.drawable.circuit);//リソース読み込み target = TextureLoader.loadTexture(gl10, context, R.drawable.fly); targetAngle = 30.0f;//初期の角度は30度 targetX = 0.5f; //右に0.5f targetY = -0.5f; //下に0.5f targetSize = 0.5f; //大きさ targetSpeed = 0.03f; //速度 targetTurnAngle = 1.0f; //旋回角度 } private int background ; private int target; private float targetAngle; private float targetX,targetY; private float targetSize; private float targetSpeed; private float targetTurnAngle; public void setTouchParam(float touchX, float touchY, int touchState) { //OpenGL上の座標に変換する。 glX = (touchX / 320.0f ) * 2.0f - 1.0f; glY = (touchY / 480.0f ) * -3.0f + 1.5f; this.touchState = touchState; } private int touchState; private float glX, glY; }