Android AndEngine Physics - 图像问题

时间:2011-12-10 11:49:19

标签: android andengine

我正在开发一个小游戏/项目,我决定使用AndEngine,因为基本上该引擎中的添加/删除物理功能就是我所需要的。但似乎我有一点问题。我必须在场景中添加36个不同的图片,并能够在选择时删除它们。问题是我的图像被损坏而且没有显示所有图像,只有前两个。我错过了什么或者我做错了吗?以下是我在设备上的内容:

Broken images

这是我的代码:

public class Game extends BaseExample implements IAccelerometerListener, IOnSceneTouchListener, IOnAreaTouchListener {

// ===========================================================
// Constants
// ===========================================================
private static final int CAMERA_WIDTH = 980;
private static final int CAMERA_HEIGHT = 560;

// ===========================================================
// Fields
// ===========================================================


private BitmapTextureAtlas mBitmapTextureAtlas;

private TextureRegion firstSprite;
private TextureRegion secondSprite;
private TextureRegion thirdSprite;
private TextureRegion fourthSprite;
private TextureRegion fifthSprite;
private TextureRegion sixSprite;
private TextureRegion sevenSprite;
private TextureRegion eightSprite;
private TextureRegion nineSprite;
private TextureRegion tenSprite;

private Scene mScene;

private PhysicsWorld mPhysicsWorld;
private int mFaceCount = 0;

@Override
public Engine onLoadEngine() {
    Toast.makeText(this, "Touch the screen to add objects. Touch an object to remove it.", Toast.LENGTH_LONG).show();
    final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

    final EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
    engineOptions.getTouchOptions().setRunOnUpdateThread(true);
    return new Engine(engineOptions);
}

@Override
public void onLoadResources() {
    this.mBitmapTextureAtlas = new BitmapTextureAtlas(128, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
    this.firstSprite = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "1.png", 0, 0); // 64x32
    this.firstSprite.setTextureRegionBufferManaged(false);
    this.secondSprite = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "2.png", 0, 32); // 64x32
    this.secondSprite.setTextureRegionBufferManaged(false);
    this.thirdSprite = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "3.png", 0, 32); // 64x32
    this.thirdSprite.setTextureRegionBufferManaged(false);
    this.fourthSprite = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "4.png", 0, 32); // 64x32
    this.fourthSprite.setTextureRegionBufferManaged(false);
    this.fifthSprite = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "5.png", 0, 32); // 64x32
    this.fifthSprite.setTextureRegionBufferManaged(false);
    this.sixSprite = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "6.png", 0, 32); // 64x32
    this.sixSprite.setTextureRegionBufferManaged(false);
    this.sevenSprite = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "7.png", 0, 32); // 64x32
    this.sevenSprite.setTextureRegionBufferManaged(false);
    this.eightSprite = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "8.png", 0, 32); // 64x32
    this.eightSprite.setTextureRegionBufferManaged(false);
    this.nineSprite = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "9.png", 0, 32); // 64x32
    this.nineSprite.setTextureRegionBufferManaged(false);
    this.tenSprite = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "10.png", 0, 32); // 64x32
    this.tenSprite.setTextureRegionBufferManaged(false);
    this.mEngine.getTextureManager().loadTexture(this.mBitmapTextureAtlas);

}

@Override
public Scene onLoadScene() {
    this.mEngine.registerUpdateHandler(new FPSLogger());

    this.mScene = new Scene();
    this.mScene.setBackground(new ColorBackground(204f, 204f, 204f));
    this.mScene.setOnSceneTouchListener(this);

    this.mPhysicsWorld = new PhysicsWorld(new Vector2(0, SensorManager.GRAVITY_EARTH), false);

    final Shape ground = new Rectangle(0, CAMERA_HEIGHT - 2, CAMERA_WIDTH, 2);
    final Shape roof = new Rectangle(0, 0, CAMERA_WIDTH, 2);
    final Shape left = new Rectangle(0, 0, 2, CAMERA_HEIGHT);
    final Shape right = new Rectangle(CAMERA_WIDTH - 2, 0, 2, CAMERA_HEIGHT);

    final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0, 0.5f, 0.5f);
    PhysicsFactory.createBoxBody(this.mPhysicsWorld, ground, BodyType.StaticBody, wallFixtureDef);
    PhysicsFactory.createBoxBody(this.mPhysicsWorld, roof, BodyType.StaticBody, wallFixtureDef);
    PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef);
    PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef);

    this.mScene.attachChild(ground);
    this.mScene.attachChild(roof);
    this.mScene.attachChild(left);
    this.mScene.attachChild(right);

    this.mScene.registerUpdateHandler(this.mPhysicsWorld);

    this.mScene.setOnAreaTouchListener(this);

    return this.mScene;
}

@Override
public void onLoadComplete() {

}

@Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
        ITouchArea pTouchArea, float pTouchAreaLocalX,
        float pTouchAreaLocalY) {

    if(pSceneTouchEvent.isActionDown()) {
        this.removeFace((Sprite)pTouchArea);
        return true;
    }

    return false;
}

@Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
    if(this.mPhysicsWorld != null) {
        if(pSceneTouchEvent.isActionDown()) {
            this.addFace(pSceneTouchEvent.getX(), pSceneTouchEvent.getY());
            return true;
        }
    }
    return false;
}

@Override
public void onAccelerometerChanged(AccelerometerData pAccelerometerData) {
    final Vector2 gravity = Vector2Pool.obtain(pAccelerometerData.getX(), pAccelerometerData.getY());
    this.mPhysicsWorld.setGravity(gravity);
    Vector2Pool.recycle(gravity);
}

private void addFace(final float pX, final float pY) {
    this.mFaceCount++;

    Sprite face = null;
    Body body = null;

    final FixtureDef objectFixtureDef = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);

    /*if(this.mFaceCount % 2 == 0) {
        face = new Sprite(pX, pY, this.firstSprite);
        body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
    } else {
        face = new Sprite(pX, pY, this.secondSprite);
        body = PhysicsFactory.createCircleBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
    }*/

    switch(this.mFaceCount){
    case 1:
            face = new Sprite(pX, pY, this.firstSprite);
            body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
        break;
    case 2:
            face = new Sprite(pX, pY, this.secondSprite);
            body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
        break;
    case 3:
            face = new Sprite(pX, pY, this.thirdSprite);
            body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
        break;
    case 4:
            face = new Sprite(pX, pY, this.fourthSprite);
            body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
        break;
    case 5:
            face = new Sprite(pX, pY, this.fifthSprite);
            body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
        break;
    case 6:
            face = new Sprite(pX, pY, this.sixSprite);
            body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
        break;
    case 7:
            face = new Sprite(pX, pY, this.sevenSprite);
            body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
        break;
    case 8:
            face = new Sprite(pX, pY, this.eightSprite);
            body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
        break;
    case 9:
            face = new Sprite(pX, pY, this.nineSprite);
            body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
        break;
    case 10:
            face = new Sprite(pX, pY, this.tenSprite);
            body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
        break;

    }

    if(this.mFaceCount<=9){
        this.mScene.registerTouchArea(face);
        this.mScene.attachChild(face);
        this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face, body, true, true));
    }
}

@Override
public void onResumeGame() {
    super.onResumeGame();

    this.enableAccelerometerSensor(this);
}


private void removeFace(final Sprite face) {
    final PhysicsConnector facePhysicsConnector = this.mPhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape(face);

    this.mPhysicsWorld.unregisterPhysicsConnector(facePhysicsConnector);
    this.mPhysicsWorld.destroyBody(facePhysicsConnector.getBody());

    this.mScene.unregisterTouchArea(face);
    this.mScene.detachChild(face);

    System.gc();
    }

}

任何想法都是我的错误?

2 个答案:

答案 0 :(得分:2)

主要问题在于onLoadResources方法。

纹理(在你的例子中是BitmapTextureAtlas)只是一个包含所有小图像的大画布。

现在,方法BitmapTextureAtlasTextureRegionFactory.createFromAsset(..)接收2个数字参数(最后2个参数)。这些用于纹理上的图像位置。

现在,看看你在做什么:将所有图像加载到同一位置!所以一些图像(最后一个图像加载 - 10.png)覆盖其他图像...

有关详细信息,请参阅纹理&amp; TextureRegions here

您的代码中存在的另一个问题 - 在您的addFace方法中,当您致电PhysicsFactory.createBoxBody(...)时,正在创建并且它会自动加入你的物理世界,即使你没有在它之间和精灵之间注册一个物理连接器,即使你没有将精灵附加到场景中。

只有当您确定时才需要创建一个正文。否则,请确保将其销毁。

答案 1 :(得分:0)

this.tenSprite = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas,this,“10.png”,0,32);

这是ur图像的分离现在看看结尾0,32对于你只需要改变它的所有图像是相同的64,64