2012-03-30 4 views
0

Ich entwickle ein Sprite-Experiment, bei dem ein Satz Kugeln um den Bildschirm herum bewegt wird, der durch eine Änderung der Ausrichtung verursacht wird. Aber wenn ich die Partikel in meiner Klasse Renderer rendere (erstelle und positioniere), wie aktualisiere ich ihre Bewegungen, wobei SensorManager in meiner Klasse Activity implementiert ist. Folgendes ist der Code. Es mag lange dauern, aber ich habe so viele Redundanzen gekürzt, dass Sie es verstehen.OpenGL ES SensorManager Aktualisierung der Partikelposition

Da dies tendenziell lang ist, bitte mich bitten, das Bit zu klären, das Sie nicht verstehen können, und ich werde sie durch Bearbeiten ansprechen.

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); 


     }    
    } 

    }  
} 

Hier ist die Implementierung für 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

Fügen Sie bitte die Implementierung von 'MyGLBall' hinzu. Enthält es seine Position, Geschwindigkeit und Beschleunigung? –

+0

@StefanHanke hat meine Antwort aktualisiert. Und nein, ich nicht. Ist das ein Problem? – jmishra

+0

Das hängt davon ab, was Sie erreichen wollen;) Wenn der Benutzer das Gerät kippt, sollten sich die Bälle so bewegen, als ob sie sich auf dem Gerät befinden würden. –

Antwort

1

Nun, ist diese Art von Code-Review. Ich hoffe, das bringt dich in Schwung.

  1. Die Bälle sind physische Objekte (Art von) und haben ihre eigene Position, Geschwindigkeit und Beschleunigung. Dieser Zustand muss bei einem Sensorwechsel aktualisiert werden. Dies ist ein bisschen hantieren mit den Werten. Vergessen Sie nicht, die GLSurfaceView an redraw zu fragen. Die Zeichenlogik muss dann die Position verwenden, um den Ball in die richtige Position zu bringen.
  2. Ich habe die Sensorkalibrierung überhaupt nicht untersucht, eine einfache Kalibrierung implementiert, die die Sensorausgabe in den ersten fünf Sekunden misst und dann einen Basiswert einstellt. Der Orientierungssensor ist deprecated.
  3. Sie können einige zufällige Werte für den Anfangszustand der Bälle festlegen.
  4. Ziehen Sie in Betracht, Code wegzuwerfen, der nur Unordnung ist. Zum Beispiel hast du hier irgendwelche Texturen?