JavaとJavaEEプログラマのブログ

JavaEEを中心にしたをソフトウェア開発についてのブログ

標的の処理を別クラスに分離し、ハエを複数表示するところまで。

新たに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;
}