我正在开发一个精灵实验,其中涉及由于方向变化而在屏幕周围移动一组球。但是当我在Renderer
课程中渲染(创建和定位)粒子时,如何在我的SensorManager
课程中实现Activity
更新他们的动作。以下是代码。这可能很长,但我已经减少了多少冗余以使你理解它。
由于这种情况往往很长,请让我澄清一下您理解的问题,我会通过编辑解决这些问题。
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 :(得分:1)
嗯,这是一种代码审查。我希望这能让你开始。
GLSurfaceView
询问redraw。然后绘制逻辑需要使用该位置将球移动到正确的位置。