我正在使用 AndEngine 创建一个应用程序。我有一个想要通过触摸移动的精灵(在这种情况下是绵羊)。我设法使用 Main Activity 类中的方法来做到这一点。我想更好地组织我的代码,所以我创建了一个 Sheep 类,它为我构建了一个带有身体和物理应用的精灵。
问题是,在我单击新创建的对象(羊)后,我的应用程序崩溃了。精灵在屏幕上显示并且物理正在工作。
我将复制一段我的代码,这样你就可以看到我做了什么:
我在主要活动中创建了我的绵羊对象,我为触摸事件注册了它,并将精灵附加到场景中:
public void onPopulateScene(Scene pScene,
OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
final Sheep sheep = new Sheep(CAMERA_WIDTH/2+200, CAMERA_HEIGHT/2, sheepTextureRegion, getVertexBufferObjectManager(), physicsWorld);
this.scene.registerTouchArea(sheep);
this.scene.attachChild(sheep);
pOnPopulateSceneCallback.onPopulateSceneFinished();
}
这些方法也在 MainActivity 中,它们用于触摸事件:
@Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
ITouchArea pTouchArea, float pTouchAreaLocalX,
float pTouchAreaLocalY) {
if (pSceneTouchEvent.isActionDown()) {
final IAreaShape sheep = (IAreaShape) pTouchArea;
/*
* If we have a active MouseJoint, we are just moving it around
* instead of creating a second one.
*/
if (this.mouseJoint == null) {
// this.mEngine.vibrate(100);
this.mouseJoint = this.createMouseJoint(sheep,
pTouchAreaLocalX, pTouchAreaLocalY);
}
return true;
}
return false;
}
@Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
if (this.physicsWorld != null) {
switch (pSceneTouchEvent.getAction()) {
case TouchEvent.ACTION_DOWN:
return true;
case TouchEvent.ACTION_MOVE:
if (this.mouseJoint != null) {
final Vector2 vec = Vector2Pool
.obtain(pSceneTouchEvent.getX()
/ PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT,
pSceneTouchEvent.getY()
/ PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT);
this.mouseJoint.setTarget(vec);
Vector2Pool.recycle(vec);
}
return true;
case TouchEvent.ACTION_UP:
if (this.mouseJoint != null) {
this.physicsWorld.destroyJoint(this.mouseJoint);
this.mouseJoint = null;
}
return true;
}
return false;
}
return false;
}
// ========================
// METHODS
// ========================
private MouseJoint createMouseJoint(IAreaShape sheep,
float pTouchAreaLocalX, float pTouchAreaLocalY) {
final Body body = (Body) sheep.getUserData();
final MouseJointDef mouseJointDef = new MouseJointDef();
final Vector2 localPoint = Vector2Pool.obtain(
(pTouchAreaLocalX - sheep.getWidth() * 0.5f)
/ PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT,
(pTouchAreaLocalY - sheep.getHeight() * 0.5f)
/ PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT);
this.surface.setTransform(localPoint, 0);
mouseJointDef.bodyA = this.surface;
mouseJointDef.bodyB = body;
mouseJointDef.dampingRatio = 0.95f;
mouseJointDef.frequencyHz = 30;
mouseJointDef.maxForce = (200.0f * body.getMass());
mouseJointDef.collideConnected = true;
mouseJointDef.target.set(body.getWorldPoint(localPoint));
Vector2Pool.recycle(localPoint);
return (MouseJoint) this.physicsWorld.createJoint(mouseJointDef);
}
这是绵羊类:
public class Sheep extends Sprite {
// CONSTANTS
private static final FixtureDef SHEEP_DEF = PhysicsFactory.createFixtureDef(1.0f, 0.2f, 0.1f);
private final static int CAMERA_WIDTH = 720;
private final static int CAMERA_HEIGHT = 480;
//FIELDS
public Sheep(float pX, float pY, ITextureRegion pTextureRegion,
VertexBufferObjectManager pVertexBufferObjectManager, PhysicsWorld pWorld)
{
super(pX, pY, pTextureRegion, pVertexBufferObjectManager);
final Sprite sheep = new Sprite(CAMERA_WIDTH / 2 + 200,
CAMERA_HEIGHT / 2, this.getTextureRegion(),
this.getVertexBufferObjectManager());
float width = sheep.getWidthScaled()/32;
float height = sheep.getWidthScaled()/32;
final Vector2[] vertices = {
new Vector2(-0.41797f * width, -0.44531f * height),
new Vector2(-0.19922f * width, -0.48828f * height),
new Vector2(+0.06641f * width, -0.52344f * height),
new Vector2(+0.39844f * width, -0.34375f * height),
new Vector2(+0.51172f * width, -0.00391f * height),
new Vector2(+0.35156f * width, +0.50000f * height),
new Vector2(-0.28516f * width, +0.50000f * height),
new Vector2(-0.43750f * width, +0.01172f * height)
};
final Body body = PhysicsFactory.createPolygonBody(pWorld, this, vertices, BodyType.DynamicBody, SHEEP_DEF);
body.setUserData(Sheep.this);
pWorld.registerPhysicsConnector(new PhysicsConnector(this, body, true, true));
}
}
我不知道是什么问题,所以也许你可以帮助我一点。这是我第一次使用 AndEngine,所以我错过了一些东西。
这是 LogCat 的副本:
10-02 14:24:13.779: E/AndroidRuntime(1968): FATAL EXCEPTION: UpdateThread
10-02 14:24:13.779: E/AndroidRuntime(1968): java.lang.NullPointerException
10-02 14:24:13.779: E/AndroidRuntime(1968): at com.nightingale.sheepgameandengine.MainActivity.createMouseJoint(MainActivity.java:256)
10-02 14:24:13.779: E/AndroidRuntime(1968): at com.nightingale.sheepgameandengine.MainActivity.onAreaTouched(MainActivity.java:199)
10-02 14:24:13.779: E/AndroidRuntime(1968): at org.andengine.entity.scene.Scene.onAreaTouchEvent(Scene.java:413)
10-02 14:24:13.779: E/AndroidRuntime(1968): at org.andengine.entity.scene.Scene.onSceneTouchEvent(Scene.java:357)
10-02 14:24:13.779: E/AndroidRuntime(1968): at org.andengine.engine.Engine.onTouchScene(Engine.java:452)
10-02 14:24:13.779: E/AndroidRuntime(1968): at org.andengine.engine.Engine.onTouchEvent(Engine.java:438)
10-02 14:24:13.779: E/AndroidRuntime(1968): at org.andengine.input.touch.controller.BaseTouchController$TouchEventRunnablePoolItem.run(BaseTouchController.java:102)
10-02 14:24:13.779: E/AndroidRuntime(1968): at org.andengine.util.adt.pool.RunnablePoolUpdateHandler.onHandlePoolItem(RunnablePoolUpdateHandler.java:54)
10-02 14:24:13.779: E/AndroidRuntime(1968): at org.andengine.util.adt.pool.RunnablePoolUpdateHandler.onHandlePoolItem(RunnablePoolUpdateHandler.java:1)
10-02 14:24:13.779: E/AndroidRuntime(1968): at org.andengine.util.adt.pool.PoolUpdateHandler.onUpdate(PoolUpdateHandler.java:88)
10-02 14:24:13.779: E/AndroidRuntime(1968): at org.andengine.input.touch.controller.BaseTouchController.onUpdate(BaseTouchController.java:62)
10-02 14:24:13.779: E/AndroidRuntime(1968): at org.andengine.engine.Engine.onUpdate(Engine.java:584)
10-02 14:24:13.779: E/AndroidRuntime(1968): at org.andengine.engine.Engine.onTickUpdate(Engine.java:548)
10-02 14:24:13.779: E/AndroidRuntime(1968): at org.andengine.engine.Engine$UpdateThread.run(Engine.java:820)