我们如何在andengine中创建一种方式的墙壁,即当一个身体从上到下落在墙上时,身体应该与墙壁发生碰撞,而当从下到上时,它会忽略碰撞并允许身体穿过墙壁?我研究了以下教程http://www.iforce2d.net/b2dtut/one-way-walls并尝试在 android 中实现此功能但无法正常工作。这是我到目前为止所做的:
public class JumpingBallActivity extends SimpleBaseGameActivity implements IOnSceneTouchListener, IAccelerationListener, ContactListener {
private int CAMERA_WIDTH = 480;
private int CAMERA_HEIGHT = 800;
private BitmapTextureAtlas mBitmapTextureAtlas;
private ITextureRegion smileyRegion;
private Scene mScene;
private Camera camera;
private Sprite smileySprite;
private Body smileyBody;
private PhysicsWorld mPhysicsWorld;
private Body slabWallBody;
private FixtureDef FIXTURE_DEF = PhysicsFactory.createFixtureDef(0.6f, 0.0f, 0.0f);
final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(1, 0.0f, 0.0f);
@Override
public EngineOptions onCreateEngineOptions() {
// TODO Auto-generated method stub
camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
return new EngineOptions(true, ScreenOrientation.PORTRAIT_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
}
@Override
protected void onCreateResources() {
// TODO Auto-generated method stub
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 84, 84, TextureOptions.BILINEAR);
smileyRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mBitmapTextureAtlas, getAssets(), "smiley.png", 0, 0);
mBitmapTextureAtlas.load();
enableAccelerationSensor(this);
}
@Override
protected Scene onCreateScene() {
// TODO Auto-generated method stub
this.mScene = new Scene();
this.mScene.setBackground(new Background(0, 0, 0));
this.mScene.setOnSceneTouchListener(this);
this.mPhysicsWorld = new PhysicsWorld(new Vector2(0, 15), false);
final VertexBufferObjectManager vertexBufferObjectManager = this.getVertexBufferObjectManager();
Rectangle rect1 = new Rectangle((CAMERA_WIDTH/2) - 100, (CAMERA_HEIGHT/2) + 50, 200, 10, vertexBufferObjectManager);
slabWallBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld, rect1, BodyType.StaticBody, wallFixtureDef);
slabWallBody.setUserData("slab");
mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(rect1, slabWallBody, false, false));
smileySprite = new Sprite(smileyRegion.getWidth(), smileyRegion.getHeight(), smileyRegion, vertexBufferObjectManager);
smileyBody = PhysicsFactory.createCircleBody(mPhysicsWorld, smileySprite, BodyType.DynamicBody, FIXTURE_DEF);
smileyBody.setUserData("smiley");
mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(smileySprite, smileyBody, true, false));
final Rectangle ground = new Rectangle(0, CAMERA_HEIGHT - 2, CAMERA_WIDTH, 2, vertexBufferObjectManager);
final Rectangle roof = new Rectangle(0, 0, CAMERA_WIDTH, 2, vertexBufferObjectManager);
final Rectangle left = new Rectangle(0, 0, 2, CAMERA_HEIGHT, vertexBufferObjectManager);
final Rectangle right = new Rectangle(CAMERA_WIDTH - 2, 0, 2, CAMERA_HEIGHT, vertexBufferObjectManager);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, ground, BodyType.StaticBody, wallFixtureDef).setUserData("wall");
PhysicsFactory.createBoxBody(this.mPhysicsWorld, roof, BodyType.StaticBody, wallFixtureDef).setUserData("wall");
PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef).setUserData("wall");
PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef).setUserData("wall");
mScene.attachChild(smileySprite);
mScene.attachChild(rect1);
mScene.attachChild(right);
mScene.attachChild(left);
mScene.attachChild(roof);
mScene.attachChild(ground);
this.mScene.registerUpdateHandler(this.mPhysicsWorld);
mPhysicsWorld.setContactListener(this);
mScene.setOnSceneTouchListener(this);
return mScene;
}
@Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
// TODO Auto-generated method stub
smileyBody.setLinearVelocity(0, -15);
return false;
}
@Override
public void onAccelerationAccuracyChanged(AccelerationData pAccelerationData) {
// TODO Auto-generated method stub
}
@Override
public void onAccelerationChanged(AccelerationData pAccelerationData) {
// TODO Auto-generated method stub
final Vector2 gravity = Vector2Pool.obtain(0, 15);
this.mPhysicsWorld.setGravity(gravity);
Vector2Pool.recycle(gravity);
smileyBody.setLinearVelocity(pAccelerationData.getX() * 2, smileyBody.getLinearVelocity().y);
}
@Override
public void beginContact(Contact contact) {
// TODO Auto-generated method stub
// Log.d("begin contact", "begin contact");
// Log.d("begin contact", smileyBody.getLinearVelocity().toString() + "");
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
Fixture platFormFixture = null;
Fixture ballFixture = null;
// also could not understand whats going on here in the code coming forward
if(fixtureA.getBody().getUserData().equals("slab") && fixtureB.getBody().getUserData().equals("smiley")) {
platFormFixture = fixtureA;
ballFixture = fixtureB;
}
if(fixtureA.getBody().getUserData().equals("smiley") && fixtureB.getBody().getUserData().equals("slab")) {
platFormFixture = fixtureB;
ballFixture = fixtureA;
}
if(platFormFixture == null) {
return;
}
Body platFormBody = platFormFixture.getBody();
Body ballBody = ballFixture.getBody();
int numPoints = contact.getWorldManifold().getNumberOfContactPoints();
WorldManifold worldManiFold = contact.getWorldManifold();
for(int i = 0; i < numPoints; i++) {
Vector2 vector2 = ballBody.getLinearVelocityFromWorldPoint(worldManiFold.getPoints()[i]);
Vector2 vector3 = platFormBody.getLinearVelocityFromWorldPoint(worldManiFold.getPoints()[i]);
Vector2 vector4 = platFormBody.getLocalVector(vector2.sub(vector3));
if(vector4.y < -1) {
// Log.d("collision ignored", "collision ignored");
return;
}
else if(vector4.y < 1) {
Vector2 localPoint = platFormBody.getLocalPoint(worldManiFold.getPoints()[i]);
Log.d("local y", localPoint.y + "");
float f = 1.1f;
if(localPoint.y > f - 0.05f) {
return;
}
}
}
contact.setEnabled(false);
}
@Override
public void endContact(Contact contact) {
// TODO Auto-generated method stub
contact.setEnabled(true);
// Log.d("end contact", "end contact");
// Log.d("end contact", smileyBody.getLinearVelocity().toString());
}
Vector2 v;
@Override
public void preSolve(Contact contact, Manifold oldManifold) {
// TODO Auto-generated method stub
// Log.d("presolve", "presolve");
// Log.d("presolve", smileyBody.getLinearVelocity().toString());
}
@Override
public void postSolve(Contact contact, ContactImpulse impulse) {
// TODO Auto-generated method stub
// Log.d("postsolve", "postsolve");
// Log.d("postsolve", smileyBody.getLinearVelocity().toString());
}
}