我正在使用Andengine和Box2D扩展组合2D平台游戏,使用PhysicsJumpExample(https://code.google.com/p/andengineexamples/source/browse/src/org/anddev/andengine/examples/PhysicsJumpExample.java)作为基础。我也使用TMX扩展进行级别加载。
我的水平,玩家控制等似乎工作正常,但我真的在重力方面与Box2D物理学挣扎。被控制的AnimatedSprite正在被重力作用,但是当使用“地球”引力(〜-9.8)时,下降速度太慢。如果我增加这个重力,那么下降速度会更快,但是Sprite会在坚固的“地板”上上下跳动,并且侧向移动会大大减少(由于我会假设的摩擦)。
最后,出于某种原因,我所看到的每一个例子在实例化PhysicsWorld时都使用了重力的正值,但是为了让重力“正常”,我不得不反转它。
显然我正在做一些非常错误的事情,并且非常欣赏这些问题的一些指示。
下面讨论的2个类的代码。
public class GameActivity extends SimpleBaseGameActivity {
private final static String TAG = "GameActivity";
private final int CAMERA_WIDTH = 800;
private final int CAMERA_HEIGHT = 480;
private HUD _hud;
private Text _score;
private Text _debug;
private PhysicsWorld mPhysicsWorld;
private PhysicsHandler _playerPhysics;
private TMXTiledMap _map;
private PlayerSprite _player;
private BitmapTextureAtlas mOnScreenControlTexture;
private TextureRegion mOnScreenControlBaseTextureRegion;
private TextureRegion mOnScreenControlKnobTextureRegion;
private Scene mScene;
private Font mFont;
private ITexture mPlayerTexture;
private TiledTextureRegion mPlayerTextureRegion;
@Override
public EngineOptions onCreateEngineOptions() {
final BoundCamera camera = new BoundCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
engineOptions.getAudioOptions().setNeedsMusic(true).setNeedsSound(true);
engineOptions.setWakeLockOptions(WakeLockOptions.SCREEN_ON);
return engineOptions;
}
@Override
public void onCreateResources() throws IOException {
}
@Override
public Scene onCreateScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
this.mPhysicsWorld = new PhysicsWorld(new Vector2(0, 0 - (SensorManager.GRAVITY_EARTH)), false);
this.mScene = new Scene();
this.mScene.getBackground().setColor(Color.BLACK);
try {
createFont();
createWorld();
createPlayer();
createControllers();
createHUD();
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
this.mScene.registerUpdateHandler(this.mPhysicsWorld);
return mScene;
}
private void createFont() {
FontFactory.setAssetBasePath("media/fonts/");
final ITexture mainFontTexture = new BitmapTextureAtlas(getTextureManager(), 256, 256, TextureOptions.NEAREST);
mFont = FontFactory.createStrokeFromAsset(getFontManager(), mainFontTexture, getAssets(), "game.otf", 40f, true, android.graphics.Color.WHITE, 2f,
android.graphics.Color.BLACK);
mFont.load();
}
private void createHUD() {
Log.d(TAG, "createHud");
_hud = new HUD();
_score = new Text(mEngine.getCamera().getCameraSceneWidth() - 80, mEngine.getCamera().getCameraSceneHeight() - 20, mFont, "0123456789", new TextOptions(
HorizontalAlign.RIGHT), getVertexBufferObjectManager());
_score.setText("0000");
_hud.attachChild(_score);
_debug = new Text(150, mEngine.getCamera().getCameraSceneHeight() - 20, mFont, "abcdefghijklmnopqrstuvwxyz0123456789.,()[] ", new TextOptions(HorizontalAlign.LEFT),
getVertexBufferObjectManager());
_debug.setText("");
_hud.attachChild(_debug);
mEngine.getCamera().setHUD(_hud);
}
private void createPlayer() throws Exception {
Log.d(TAG, "createPlayer");
this.mPlayerTexture = new AssetBitmapTexture(getTextureManager(), getAssets(), "media/sprites/p1.png");
this.mPlayerTextureRegion = TextureRegionFactory.extractTiledFromTexture(this.mPlayerTexture, 5, 2);
this.mPlayerTexture.load();
_player = new PlayerSprite(50, 320, this.mPlayerTextureRegion, mEngine.getCamera(), this.mPhysicsWorld, getVertexBufferObjectManager());
_player.setUserData(_player.getBody());
_playerPhysics = new PhysicsHandler(_player);
this.mPhysicsWorld.setContactListener(new ContactListener() {
@Override
public void preSolve(Contact contact, Manifold oldManifold) {
// TODO Auto-generated method stub
}
@Override
public void postSolve(Contact contact, ContactImpulse impulse) {
// TODO Auto-generated method stub
}
@Override
public void endContact(Contact contact) {
// TODO Auto-generated method stub
}
@Override
public void beginContact(Contact contact) {
if (contact == null || contact.getFixtureA() == null || contact.getFixtureB() == null)
return;
if (contact.getFixtureA().getBody().getUserData() == null || contact.getFixtureB().getBody().getUserData() == null)
return;
if (contact.getFixtureA().getBody().getUserData().toString().equals("player") || contact.getFixtureB().getBody().getUserData().toString().equals("player")) {
_player.setJumping(false);
}
}
});
_player.registerUpdateHandler(_playerPhysics);
this.mScene.attachChild(_player);
}
private void createControllers() {
Log.d(TAG, "createControllers");
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("media/");
mOnScreenControlTexture = new BitmapTextureAtlas(getTextureManager(), 256, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
mOnScreenControlBaseTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mOnScreenControlTexture, this, "images/controller.png", 0, 0);
mOnScreenControlKnobTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mOnScreenControlTexture, this, "images/controller_top.png", 128, 0);
getTextureManager().loadTexture(mOnScreenControlTexture);
final float x1 = mOnScreenControlBaseTextureRegion.getWidth();
final float y1 = (this.mEngine.getCamera().getCameraSceneHeight() - mOnScreenControlBaseTextureRegion.getHeight());
final DigitalOnScreenControl velocityOnScreenControl = new DigitalOnScreenControl(x1, y1, this.mEngine.getCamera(), this.mOnScreenControlBaseTextureRegion,
this.mOnScreenControlKnobTextureRegion, 0.1f, true, getVertexBufferObjectManager(), new IOnScreenControlListener() {
@Override
public void onControlChange(BaseOnScreenControl pBaseOnScreenControl, float pValueX, float pValueY) {
float x = 0, y = 0;
if (pValueX == -1 && pValueY == 0) {
if (_player.getDirection() != PlayerDirection.LEFT) {
_player.setRotation(-1);
_player.animate(75);
}
x = pValueX * 8;
y = pValueY * 8;
_player.setDirection(PlayerDirection.LEFT);
} else if (pValueX == -1 && pValueY == 1) {
if (!_player.isJumping()) {
if (_player.getDirection() != PlayerDirection.UP_LEFT) {
_player.animate(25);
}
x = SensorManager.GRAVITY_EARTH * -10;
y = SensorManager.GRAVITY_EARTH * -10;
_player.setDirection(PlayerDirection.UP_LEFT);
}
} else if (pValueX == 0 && pValueY == 1) {
if (!_player.isJumping()) {
if (_player.getDirection() != PlayerDirection.UP) {
_player.animate(75);
}
y = SensorManager.GRAVITY_EARTH * 2;
_player.setDirection(PlayerDirection.UP);
}
} else if (pValueX == 1 && pValueY == 1) {
if (!_player.isJumping()) {
if (_player.getDirection() != PlayerDirection.UP_RIGHT) {
_player.animate(25);
}
x = SensorManager.GRAVITY_EARTH * 10;
y = SensorManager.GRAVITY_EARTH * -10;
_player.setDirection(PlayerDirection.UP_RIGHT);
}
} else if (pValueX == 1 && pValueY == 0) {
if (_player.getDirection() != PlayerDirection.RIGHT) {
_player.animate(75);
}
x = pValueX * 8;
y = pValueY * 8;
_player.setDirection(PlayerDirection.RIGHT);
} else if (pValueX == 1 && pValueY == -1) {
_player.setDirection(PlayerDirection.DOWN_RIGHT);
} else if (pValueX == 0 && pValueY == 1) {
_player.setDirection(PlayerDirection.DOWN);
} else if (pValueX == -1 && pValueY == -1) {
_player.setDirection(PlayerDirection.DOWN_LEFT);
} else {
_player.setDirection(PlayerDirection.NONE);
if (!_player.isJumping()) {
_player.stopAnimation(0);
}
}
final Vector2 velocity = Vector2Pool.obtain(x, y);
_player.getBody().setLinearVelocity(velocity);
Vector2Pool.recycle(velocity);
_debug.setText(_player.getDirection().toString() + ": " + (pValueX * 60) + "," + (pValueY * 60));
}
});
velocityOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
velocityOnScreenControl.getControlBase().setAlpha(0.5f);
this.mScene.setChildScene(velocityOnScreenControl);
}
private void createWorld() {
Log.d(TAG, "createWorld");
try {
final TMXLoader tmxLoader = new TMXLoader(getAssets(), getTextureManager(), TextureOptions.NEAREST, getVertexBufferObjectManager());
_map = tmxLoader.loadFromAsset("media/levels/1/1.tmx");
final TMXLayer tmxLayer = _map.getTMXLayers().get(0);
tmxLayer.detachSelf();
this.mScene.attachChild(tmxLayer);
((BoundCamera) this.mEngine.getCamera()).setBounds(0, 0, tmxLayer.getHeight(), tmxLayer.getWidth());
((BoundCamera) this.mEngine.getCamera()).setBoundsEnabled(true);
float height = tmxLayer.getHeight();
float width = tmxLayer.getWidth();
final IShape bottom = new Rectangle(0, height - 2, width, 2, getVertexBufferObjectManager());
bottom.setVisible(false);
final IShape top = new Rectangle(0, 0, width, 2, getVertexBufferObjectManager());
top.setVisible(false);
final IShape left = new Rectangle(0, 0, 2, height, getVertexBufferObjectManager());
left.setVisible(false);
final IShape right = new Rectangle(width - 2, 0, 2, height, getVertexBufferObjectManager());
right.setVisible(false);
final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0, 0, 1f);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, bottom, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, top, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef);
this.mScene.attachChild(bottom);
this.mScene.attachChild(top);
this.mScene.attachChild(left);
this.mScene.attachChild(right);
float yOffset = _map.getTMXLayers().get(0).getHeight();
for (final TMXObjectGroup group : _map.getTMXObjectGroups()) {
if (group.getTMXObjectGroupProperties().containsTMXProperty("solid", "true")) {
for (final TMXObject object : group.getTMXObjects()) {
final Rectangle rect = new Rectangle(object.getX() + object.getWidth() / 2, yOffset - object.getY() - object.getHeight() / 2, object.getWidth(),
object.getHeight(), getVertexBufferObjectManager());
final FixtureDef boxFixtureDef = PhysicsFactory.createFixtureDef(0, 0, 1f);
Body b = PhysicsFactory.createBoxBody(this.mPhysicsWorld, rect, BodyType.StaticBody, boxFixtureDef);
b.setUserData("solid");
rect.setVisible(false);
rect.setZIndex(0);
this.mScene.attachChild(rect);
}
}
}
} catch (final TMXLoadException e) {
Log.e(TAG, e.getMessage());
}
}
@Override
public void onDestroyResources() throws IOException {
Log.d(TAG, "onDestroyResources: Cleanup scenes/resources");
super.onDestroyResources();
}
@Override
protected void onDestroy() {
super.onDestroy();
System.exit(0);
}
}
public class PlayerSprite extends AnimatedSprite {
public enum PlayerDirection {
NONE, LEFT, UP_LEFT, UP, UP_RIGHT, RIGHT, DOWN_RIGHT, DOWN, DOWN_LEFT
}
private Body _body;
private PlayerDirection _direction = PlayerDirection.NONE;
private boolean _jumping = false;
public PlayerSprite(float pX, float pY, ITiledTextureRegion region, Camera camera, PhysicsWorld physics, VertexBufferObjectManager vbo) {
super(pX, pY, region, vbo);
createPhysics(camera, physics);
camera.setChaseEntity(this);
}
public Body getBody() {
return _body;
}
public PlayerDirection getDirection() {
return _direction;
}
public void setDirection(PlayerDirection direction) {
_direction = direction;
}
public boolean isJumping() {
return _jumping;
}
public void setJumping(boolean jumping) {
_jumping = jumping;
}
private void createPhysics(final Camera camera, PhysicsWorld physics) {
_body = PhysicsFactory.createBoxBody(physics, this, BodyType.DynamicBody, PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f));
_body.setUserData("player");
physics.registerPhysicsConnector(new PhysicsConnector(this, _body, true, true));
}
}
答案 0 :(得分:2)
总是如此,只是张贴和寻求帮助奇迹般地导致自我解决。
对于遇到类似事情的其他人(虽然我怀疑任何人都可能如此愚蠢!)问题是“控制器”对玩家施加了力量(左,右,跳等)但是IOnScreenControlListener的OnControlChange事件得到了不断调用,我有“_player.getBody()。setLinearVelocity(velocity);” (速度是默认的0,0)反复调用,从而抵消了一些重力。
卫生署!