標的の処理を別クラスに分離し、ハエを複数表示するところまで。
新たにTargetクラスを作成し、標的の処理をTargetクラスのメソッドにする。
package sample.game; import static sample.game.utils.GraphicUtils.*; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.util.Log; public class Target { public float angle; public float x,y; public float size; public float speed; public float turnAngle; private final static String TAG = "EsGame"; public Target(float x, float y, float angle, float size, float speed, float turnAngle){ this.x = x; this.y = y; this.angle = angle; this.size = size; this.speed = speed; this.turnAngle = turnAngle; } public boolean isPointInside(float gx, float gy){ //標的とタッチ位置の距離を計算 float dx = gx - this.x; float dy = gy - this.y; float distance = (float) Math.sqrt(dx * dx + dy * dy); //距離が標的の当たり範囲(円で近似する)より小さければ当たり。 if(distance <= size * 0.5f){ Log.d(TAG, "!!!!! Touch !!!!!!"); return true; }else{ return false; } } public void move() { // Log.d(TAG, "state [x:y]="+ touchState + " [" + glX + ":" + glY +"]"); //100回に1度の割合で方向を転換する。 if((int)(Math.random() * (100+1)) % 100 == 0 ){ //旋回角度を-2.0〜2.0の範囲で変化させる。 turnAngle = (float) (Math.random() * 4.0f - 2.0f ); Log.d(TAG, "方向転換! turnAngle=" + turnAngle); } angle = angle + turnAngle; double theta = angle / 180.0 * Math.PI; x = (float) (x + Math.cos(theta) * speed); y = (float) (y + Math.sin(theta) * speed); //画面外へ出たら反対の端へ移動させる if(x >= 2.0f){ x -= 4.0f; }else if(x <= -2.0f){ x += 4.0f; } if(y >= 2.5f){ y -= 5.0f; }else if(y <= -2.5f){ y += 5.0f; } } public void moveNextPosition(){ //標的をランダムな位置に移動 final float dist = 2.0f;//直径2.0fの円周上。 float theta = (float) ((Math.random() * 10 % 360) / 180.0 * Math.PI); x = (float) (Math.cos(theta) * dist); y = (float) (Math.sin(theta) * dist); } public void draw(GL10 gl10, Context context, int targetTexture) { gl10.glPushMatrix(); gl10.glTranslatef(x, y, 0.0f); gl10.glRotatef(angle, 0.0f, 0.0f, 1.0f); gl10.glScalef(size, size, 1.0f); drawTextureRectangle(gl10, context, 0.0f, 0.0f, 1.0f, 1.0f, targetTexture, 0, 0, 0, 0x1000);//標的 gl10.glPopMatrix(); } }
それに伴い、EsGameRenderクラスを修正。また、複数の標的を表示するように初期化処理を修正。
標的を増やした結果、GCの滋孝による表示のガタツキが目立ってきた。
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.*; import static java.lang.Math.*; public class EsGameRender implements GLSurfaceView.Renderer { private static final int one = 0x10000; private static final String TAG = "EsGame"; private static final int TARGET_NUM = 20; private Target [] targets = new Target[TARGET_NUM]; private Context context; private double randf(){ return (random() * 10 % 1001) * 0.001f; } public EsGameRender(Context context){ this.context = context; for (int i = 0; i < TARGET_NUM; i++) { float x = (float) (randf() * 2.0f - 1.0f); float y = (float) (randf() * 2.0f - 1.0f); float angle = (float)(random() * 10.0 % 360 ); float size = (float) (randf() * 0.25f + 0.25f); float speed = (float)(randf() * 0.01f + 0.01f ) * 2; float turnAngle = (float) (randf() * 4.0f - 2.0f); targets[i] = new Target(x,y,angle,size,speed, turnAngle); } } @Override public void onDrawFrame(GL10 gl10) { makeWorld(gl10); drawTextureRectangle(gl10, context, 0.0f, 0.0f, 2.0f, 3.0f, background, 0, 0, 0, one);//背景 for(Target t : targets){ if( t.isPointInside(glX,glY) ){ t.moveNextPosition(); }else{ t.move(); } glX = -3.0f;//初期化 glY = -3.0f;//初期化 t.draw(gl10,context,targetTexture); } } @Override public void onSurfaceChanged(GL10 gl10, int width, int height) { gl10.glViewport(0, 0, width, height); } @Override public void onSurfaceCreated(GL10 gl10, EGLConfig eglconfig) { /* * ギザギザを目立たなくするGL_DITHERを無効にします。 */ gl10.glDisable(GL10.GL_DITHER); /* * カラーとテクスチャ座標の補間精度を最も効率的にします。 */ gl10.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); background = TextureLoader.loadTexture(gl10, context, R.drawable.circuit);//リソース読み込み targetTexture = TextureLoader.loadTexture(gl10, context, R.drawable.fly); } private int background ; private int targetTexture; 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; }