I am developing a sprite experiment that involves moving set of balls around the screen caused by change in orientation. But when I render (create and position) the particles in my Renderer class, how do I update their movements considering SensorManager is implemented in my Activity class. Following is the code. It may be long but I have curtailed as much redundancies to make you understand it.
Since this tends to be long, please ask me to clarify the bit you have trouble understanding and I’ll address them through edit.
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);
}
}
}
}
Here’s the implementation for 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);
}
}
Well, this is kind of a code review. I hope this gets you started.
GLSurfaceViewto redraw. The draw logic then needs to use the position to move the ball to the correct position.