Gday 伙计们,我对大学的作业有疑问。这个想法是在触摸屏幕的时间和地点创建粒子。当程序尝试创建粒子时,我得到一个未捕获的异常。
弹出的错误是:
05-22 17:39:18.597: I/System.out(1196): screen touched
05-22 17:39:18.597: I/System.out(1196): about to add point
05-22 17:39:18.597: I/System.out(1196): addpoint called
05-22 17:39:18.606: I/System.out(1196): particle details created
05-22 17:39:18.616: I/System.out(1196): particle created
05-22 17:39:18.616: I/System.out(1196): x:295.61588y:293.3667
05-22 17:39:18.616: D/AndroidRuntime(1196): Shutting down VM
05-22 17:39:18.636: W/dalvikvm(1196): threadid=1: thread exiting with uncaught exception (group=0x40015560)
05-22 17:39:18.646: I/System.out(1196): about to draw particles
05-22 17:39:18.687: E/AndroidRuntime(1196): FATAL EXCEPTION: main
05-22 17:39:18.687: E/AndroidRuntime(1196): java.lang.NullPointerException
05-22 17:39:18.687: E/AndroidRuntime(1196): at au.edu.ballarat.drawing_30103645.DrawingRenderer.addPoint(DrawingRenderer.java:71)
主要代码:绘图活动是
package au.edu.ballarat.drawing_30103645;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;
import android.app.Activity;
import android.content.Context;
public class DrawingActivity extends Activity {
private GLSurfaceView glSurface;
private DrawingRenderer myRenderer;
public static Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
// Call the superclass onCreate
super.onCreate(savedInstanceState);
// Instantiate our GLSurfaceView passing it this context
glSurface = new GLSurfaceView(this);
// Instantiate our renderer instance so we can use it to draw things
myRenderer = new DrawingRenderer();
// Specify we'll use our myRenderer instance to draw things
glSurface.setRenderer(myRenderer);
// Display the surface!
setContentView(glSurface);
context = getApplicationContext();
}
@Override
protected void onPause() {
// When the application is paused, we should call both Activity's
// and GLSurfaceView's onPause() methods in that order!
super.onPause(); // Always call the superclass method first!
glSurface.onPause();
}
@Override
protected void onResume() {
// When the application is resumed after pausing, we should call
// both Activity's and GLSurfaceViews onResume() methods.
super.onResume();// Always call the superclass method first!
glSurface.onResume();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
System.out.println("screen touched ");
int action = event.getAction();
if(action == MotionEvent.ACTION_DOWN){
DrawingRenderer dr = new DrawingRenderer();
System.out.println("about to add point");
dr.addPoint((float)event.getX(), (float)event.getY() );
System.out.println("action down");
}
else if (action == MotionEvent.ACTION_POINTER_DOWN){
System.out.println("action pointer down");
}
else if (action == MotionEvent.ACTION_MOVE){
System.out.println("action move");
}
return true;
}}
渲染器的代码:DrawingRenderer 是
package au.edu.ballarat.drawing_30103645;
import java.util.ArrayList;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.egl.EGLConfig;
import android.opengl.GLSurfaceView.Renderer;
public class DrawingRenderer implements Renderer {
// Define our array of Particle objects
private ArrayList<DrawingParticle> particleList;
DrawingParticle p;
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
System.out.println("no error yet");
particleList = new ArrayList<DrawingParticle>();
}
// Method to reset the surface if it flips vertical to horizontal etc.
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// Reset the width and height of our viewport
gl.glViewport(0, 0, width, height);
// Reset the Projection matrix
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
// Set up an orthographic projection
gl.glOrthof(0, width, 0, height, 1, -1);
// Reset the ModelView matrix
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
// Specify a "chunky" point size (default is 1.0f)
gl.glPointSize(3.0f);
}
// Method to draw the frame
@Override
public synchronized void onDrawFrame(GL10 gl) {
// Set the clear colour to red and clear the screen
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// Enable the vertex array client state
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// Draw then update the position of all particles
System.out.println("about to draw particles");
for (DrawingParticle p : particleList) {
System.out.println("about to draw particles");
p.draw(gl);
p.update();
}
// Disable the vertex array client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
public synchronized void addPoint(float xLocation, float yLocation){
System.out.println("addpoint called");
DrawingParticle particle = new DrawingParticle(xLocation, yLocation);
System.out.println("particle created");
System.out.println("x:"+ xLocation + "y:" + yLocation);
particleList.add(particle);
System.out.println(particleList);
}
}
粒子的代码是 DrawingParticle:
package au.edu.ballarat.drawing_30103645;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import au.edu.ballarat.xylophone_30103645.Utils;
import java.util.Random;
public class DrawingParticle {
public static final int VERTEX_COUNT = 1; // Each point is 1 vertex
public static final int COORDS_PER_VERTEX = 2; // X and Y co-ords for 2D!
// Float.SIZE gives us the size of a float in bits (32 bits), divide by 8 //
// to get size in bytes (4 bytes)!
public static final int BYTES_PER_FLOAT = 4;
public static final int BUFFER_SIZE = VERTEX_COUNT * COORDS_PER_VERTEX
* BYTES_PER_FLOAT;
private static float vertices[] = { 0.0f, 0.0f }; // Point is at the origin
private static FloatBuffer vertexBuffer;
private static Random random = new Random();
private float x;
private float y;
private float ySpeed;
private float GRAVITY = 1.0f;
private float size;
private float red, green, blue, alpha;
private float rotation;
private int framesToLive;
// Particle constructor
public DrawingParticle(float INITIAL_X_LOCATION, float INITIAL_Y_LOCATION) {
// Allocate memory for our ByteBuffer (1 * 2 * 4 = 8 Bytes)
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
// Specify byte order in use (little-endian or big-endian)
byteBuffer.order(ByteOrder.nativeOrder());
// Specify our vertexBuffer as a FloatBuffer version
// of our byteBuffer object
vertexBuffer = byteBuffer.asFloatBuffer();
// Put our vertex data in the vertex buffer
vertexBuffer.put(vertices);
// Reset our buffer ready for use
vertexBuffer.flip();
// Specify a random position for our point
// Specify random horizontal and vertical speeds for our point
red = Utils.randRange(0.0f, 1.0f);
green = Utils.randRange(0.0f, 1.0f);
blue = Utils.randRange(0.0f, 1.0f);
alpha = Utils.randRange(0.0f, 1.0f);
ySpeed = Utils.randRange(1.0f, 6.0f);
x = INITIAL_X_LOCATION;
y = INITIAL_Y_LOCATION;
size = Utils.randRange(1.0f, 6.0f);
rotation = 0.0f;
System.out.println("particle details created");
}
synchronized void draw(GL10 gl) {
System.out.println("Draw called");
// Reset the ModelView matrix
gl.glLoadIdentity();
// Specify our vertexes
gl.glColor4f(green, red, blue, alpha);
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, DrawingParticle.vertexBuffer);
gl.glPointSize(size);
// Translate (i.e. move horizontally and vertically) to the
// position of the particle
gl.glTranslatef(x,y, 0.0f);
// And finally draw the particle as a point!
// Params: Primitive type, start location of vertexBuffer, end
// location of vertexBuffe
gl.glDrawArrays(GL10.GL_POINTS, 0, DrawingParticle.VERTEX_COUNT);
}
public synchronized void update() {
// Move the particle by its component speeds
y += ySpeed;
ySpeed -= GRAVITY;
// reduce the alpha
if (alpha > 0.1f){
alpha = alpha - 0.1f;
}
framesToLive = framesToLive - 1;
size = size + 0.3f;
rotation = rotation + 1;
}
}
我知道它可以用像 try/catch 块这样简单的东西来修复,但我不确定它应该放在哪里。它是学校作业,所以我别无选择,只能尝试完成它。
感谢这里的用户可以提供的任何帮助。