2012-03-30 9 views
0

私は、向きの変化によって生じる画面の周りのボールの集合を動かすスプライト実験を開発しています。しかし、私がRendererクラスのパーティクルをレンダリング(作成および配置)するとき、SensorManagerが私のActivityクラスに実装されていると考えて、その動きを更新するにはどうすればいいですか?以下はコードです。それは長いかもしれませんが、私はあなたにそれを理解させるために多くの冗長性を減らしました。OpenGL ES SensorManagerパーティクル位置の更新

これは長くなる傾向があるので、わかりにくい部分を明確にするように私に依頼してください。

public class MyGLCubeTouchActivity extends Activity implements SensorEventListener { 

    private GLSurfaceView myTouchSurface; 
    private SensorManager sm; 
    public float xPosition, xAcceleration,xVelocity = 0.0f; 
    public float yPosition, yAcceleration,yVelocity = 0.0f; 
    public float xmax,ymax; 
    public float frameTime = 0.666f; 
    private List<MyGLBall> ball; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
// TODO Auto-generated method stub 
    super.onCreate(savedInstanceState); 
     myTouchSurface=new TouchSurfaceView(this); 
     setContentView(myTouchSurface); 
     sm=(SensorManager) getSystemService(Context.SENSOR_SERVICE); 

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
    sm=(SensorManager) getSystemService(Context.SENSOR_SERVICE); 
    if(sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size()!=0){ 

     Sensor s=sm.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0); 
     sm.registerListener(this, s, SensorManager.SENSOR_DELAY_GAME); 
     } 

    if(sm.getSensorList(Sensor.TYPE_ORIENTATION).size()!=0){ 

    Sensor s=sm.getSensorList(Sensor.TYPE_ORIENTATION).get(0); 
    sm.registerListener(this, s, SensorManager.SENSOR_DELAY_GAME); 

     } 

    myTouchSurface.requestFocus(); 
    myTouchSurface.setFocusableInTouchMode(true); 
    Display display = getWindowManager().getDefaultDisplay(); 
    xmax = (float)display.getWidth() - 50; 
    ymax = (float)display.getHeight() - 50; 

    ball=new ArrayList<MyGLBall>(36); 
    for(int i=0;i<=35;i++){ 
    ball.add(new MyGLBall()); 
     } 
    } 

    @Override 
    protected void onPause() { 
    // TODO Auto-generated method stub 
    super.onPause(); 
    myTouchSurface.onPause(); 
    //sm.unregisterListener(this); 

    } 

    @Override 
    protected void onResume() { 
    // TODO Auto-generated method stub 
    super.onResume(); 
    myTouchSurface.onResume(); 
    // Register this class as a listener for the accelerometer sensor 
    sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 
      SensorManager.SENSOR_DELAY_GAME); 
    // ...and the orientation sensor 
    sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ORIENTATION), 
      SensorManager.SENSOR_DELAY_NORMAL); 
    } 

    @Override 
    public void onAccuracyChanged(Sensor arg0, int arg1) { 
    // TODO Auto-generated method stub 

    } 

    @Override 
    public void onSensorChanged(SensorEvent arg0) { 
    // TODO Auto-generated method stub 
     if (arg0.sensor.getType() == Sensor.TYPE_ORIENTATION) { 
     //Set sensor values as acceleration 

     yAcceleration = arg0.values[1]; 
     xAcceleration = arg0.values[2]; 
     updateBall(); 
     Toast.makeText(getApplicationContext(), "onsSensorChanged executed", Toast.LENGTH_SHORT); 
    } 


} 


    private void updateBall() { 
    //Calculate new speed 
    float xSpeed = xVelocity + (xAcceleration * frameTime); 
    float ySpeed = yVelocity + (yAcceleration * frameTime); 

    //Calc distance travelled in that time 
    float xS = ((xVelocity + xSpeed)/2)*frameTime; 
    float yS = ((yVelocity + ySpeed)/2)*frameTime; 

    //Add to position negative due to sensor 
    //readings being opposite to what we want! 
    xPosition -= xS; 
    yPosition -= yS; 

    if (xPosition > xmax) { 
     xPosition = xmax; 
    } else if (xPosition < 0) { 
     xPosition = 0; 
    } 
    if (yPosition > ymax) { 
     yPosition = ymax; 
    } else if (yPosition < 0) { 
     yPosition = 0; 
    } 
    } 

    public class TouchSurfaceView extends GLSurfaceView { 

    private MyGLRenderer mRenderer; 

    public TouchSurfaceView(Context context) { 
     super(context); 
     // TODO Auto-generated constructor stub 

      mRenderer=new MyGLRenderer(); 
      setRenderer(mRenderer); 
      setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); 

    } 

    class MyGLRenderer implements GLSurfaceView.Renderer{ 

     private Random r; 
     private MyGLCube mCube; 
     public float mAngleX; 
     public float mAngleY; 

     public MyGLRenderer(){ 
      r=new Random(); 
     } 

     @Override 
     public void onDrawFrame(GL10 gl) { 
      // TODO Auto-generated method stub 


      gl.glDisable(GL10.GL_DITHER); 
      gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 

      gl.glMatrixMode(GL10.GL_MODELVIEW); 
      gl.glLoadIdentity(); 
      gl.glClientActiveTexture(DRAWING_CACHE_QUALITY_HIGH); 


      for(int i=0;i<=35;i++){ 

      float randX=(float)((r.nextFloat()) *(1.0f - (-1.0f)) + (-1.0f)); 
      float randY=(float)((r.nextFloat()) *(1.0f - (-1.0f)) + (-1.0f)); 
       gl.glPushMatrix(); 
        gl.glTranslatef(randX, randY, -3.0f); 
        gl.glScalef(0.3f, 0.3f, 0.3f); 
        gl.glColor4f(r.nextFloat(), r.nextFloat(), r.nextFloat(), 1); 
        gl.glEnable(GL10.GL_TEXTURE_2D); 


        ball.get(i).draw(gl); 
       gl.glPopMatrix(); 
      } 
     } 

     @Override 
     public void onSurfaceChanged(GL10 gl, int width, int height) { 
      // TODO Auto-generated method stub 
      gl.glViewport(0, 0, width, height); 
      float ratio=(float) width/height; 
      gl.glMatrixMode(GL10.GL_PROJECTION); 
      //gl.glOrthof(-2, 2, -2, 2, -1, 1); 
      gl.glLoadIdentity(); 
      gl.glFrustumf(-ratio, ratio, -1, 1, 1, 25); 

     } 

     @Override 
     public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
      // TODO Auto-generated method stub 
      gl.glDisable(GL10.GL_DITHER); 
      gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); 
      gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 


     }    
    } 

    }  
} 

ここMyGLBall

の実装
 public class MyGLBall { 

private final float degToRad=(float) (3.14159265358979323846/180.0); 
private int points=360; 
private float vertices[]={0.0f,0.0f,0.0f}, colorVals[]={0.2f,0.6f,0.3f,1.0f}; 
private FloatBuffer vertBuff, colorBuff, alBuff, dlBuff, slBuff, lPosBuff, lDirecBuff; 
private float[] al = {0.03f, 0.07f, 0.03f, 1.0f}, dl={0.3f, 0.8f, 0.2f, 1.0f}, sl={0.6f, 0.4f, 0.8f, 1.0f}; 
float shineness = 0.4f; 
float[] lPosition = {0.5f, 0.8f, 0.3f, 0.4f}; 
float[] lDirection = {0.0f, 0.0f, -1.0f}; 

//centre of circle 

public MyGLBall(){ 

    vertices=new float[(points+1)*3]; 
    colorVals=new float[(points+1)*4]; 
    for(int i=3;i<(points+1)*3;i+=3){ 
     double rad=(i*360/points*3)*(3.14/180); 
     vertices[i]=(float)Math.cos(rad); 
     vertices[i+1]=(float) Math.sin(rad); 
     vertices[i+2]=0;  
    } 

    for(int i=4;i<(points+1)*4;i+=4){ 
     float colorVal=r.nextFloat(); 
     colorVals[i]=colorVal; 
     colorVals[i+1]=colorVal; 
     colorVals[i+2]=colorVal; 
     colorVals[i+3]=1; 
    } 

     ByteBuffer bBuff=ByteBuffer.allocateDirect(vertices.length*4);  
     bBuff.order(ByteOrder.nativeOrder()); 
     vertBuff=bBuff.asFloatBuffer(); 
     vertBuff.put(vertices); 
     vertBuff.position(0); 

     ByteBuffer bColorBuff=ByteBuffer.allocateDirect(colorVals.length*4); 
     bColorBuff.order(ByteOrder.nativeOrder()); 
     colorBuff=bColorBuff.asFloatBuffer(); 
     colorBuff.put(colorVals); 
     colorBuff.position(0); 

     ByteBuffer bAlBuff=ByteBuffer.allocateDirect(al.length*4); 
     bAlBuff.order(ByteOrder.nativeOrder()); 
     alBuff=bAlBuff.asFloatBuffer(); 
     alBuff.put(al); 
     alBuff.position(0); 

     ByteBuffer bDlBuff=ByteBuffer.allocateDirect(dl.length*4); 
     bDlBuff.order(ByteOrder.nativeOrder()); 
     dlBuff=bDlBuff.asFloatBuffer(); 
     dlBuff.put(dl); 
     dlBuff.position(0); 

     ByteBuffer bSlBuff=ByteBuffer.allocateDirect(sl.length*4); 
     bSlBuff.order(ByteOrder.nativeOrder()); 
     slBuff=bSlBuff.asFloatBuffer(); 
     slBuff.put(sl); 
     slBuff.position(0); 

     ByteBuffer bLPosBuff=ByteBuffer.allocateDirect(lPosition.length*4); 
     bLPosBuff.order(ByteOrder.nativeOrder()); 
     lPosBuff=bLPosBuff.asFloatBuffer(); 
     lPosBuff.put(lPosition); 
     lPosBuff.position(0); 

} 

public void draw(GL10 gl){ 

    gl.glEnable(GL10.GL_CULL_FACE); 
    gl.glEnable(GL10.GL_SMOOTH); 
    gl.glEnable(GL10.GL_DEPTH_TEST);  
    gl.glTranslatef(0, 0, 0); 
// gl.glScalef(size, size, 1.0f); 
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertBuff); 
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
    gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, points/2); 
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 

} 

    } 
+0

「MyGLBall」の実装を追加してください。位置、速度、加速度を含んでいますか? –

+0

@StefanHankeが私の答えを更新しました。そして、いいえ、私はしません。それは問題ですか? – jmishra

+0

これはあなたが達成したいことにかかっています;)ユーザーがデバイスを傾けると、ボールはデバイスの上にあるかのように動きますか? –

答えて

1

まあ、これはコードレビューのようなものであるのです。私はこれがあなたを始めることを望む。

  1. ボールは物理的なオブジェクト(並べ替え)であり、独自の位置、速度、および加速度を持ちます。この状態は、センサーの変更時に更新する必要があります。これは値でちょっとしたことです。 GLSurfaceViewredrawと忘れずにお問い合わせください。ドローロジックは、ボールを正しい位置に動かすためにその位置を使用する必要があります。
  2. 私はセンサーの校正を全く見ていないので、センサーの出力を最初の5秒間測定してベース値を設定する簡単な校正を実装しました。方位センサーはdeprecatedです。
  3. ボールの初期状態のランダムな値を設定することを検討してください。
  4. ちょうど混乱しているコードをスローすることを検討してください。たとえば、ここにテクスチャがありますか?