box2d碰撞无法按预期的方式运行libGDX And​​roid

时间:2017-05-02 16:50:42

标签: android libgdx box2d

<base target="_blank">

所以这个交易是每当Kubo_BIT跳到Enemy_BIT时,上面反转对象碰撞的类会抛出一个错误。当这个物体在水平面上碰撞时,它会完全没问题。 下面是渲染两个对象的PlayScreen

public class WorldContactListener implements ContactListener {
    @Override
    public void beginContact(Contact contact) {
    //fixtures that participate in the collision
    Fixture fixA = contact.getFixtureA();
    Fixture fixB = contact.getFixtureB();

    //collision definition
    int cDef = fixA.getFilterData().categoryBits | fixB.getFilterData().categoryBits;

    //figure out what kind of the collision occures
    switch (cDef){
        //if the player jumps on the enemy
        case KuboGame.KUBO_BIT | KuboGame.ENEMY_HEAD_BIT:
            if(fixA.getFilterData().categoryBits == KuboGame.ENEMY_HEAD_BIT)
                ((Spider)fixA.getUserData()).hitOnHead();
            else ((Spider)fixB.getUserData()).hitOnHead();
            break;
        //if the character collides with the wall or the ground
        case KuboGame.ENEMY_BIT | KuboGame.DEFAULT_BIT:
            if(fixA.getFilterData().categoryBits == KuboGame.ENEMY_BIT)
                ((Enemy)fixA.getUserData()).reverseVelocity(true, false);
            else ((Enemy)fixB.getUserData()).reverseVelocity(true, false);
            break;
        //enemy collides with another enemy
        case KuboGame.ENEMY_BIT | KuboGame.ENEMY_BIT:
            ((Enemy)fixA.getUserData()).reverseVelocity(true, false);
            ((Enemy)fixB.getUserData()).reverseVelocity(true, false);
        break;
        //player collides with an enemy
        case KuboGame.KUBO_BIT | KuboGame.ENEMY_BIT:
            if(fixA.getFilterData().categoryBits == KuboGame.KUBO_BIT) {
                ((Kubo)fixA.getUserData()).hit();
                ((Enemy)fixB.getUserData()).reverseVelocity(true, false);
                } else{
                ((Kubo)fixA.getUserData()).hit();
                ((Enemy)fixA.getUserData()).reverseVelocity(true, false);
                }
            break;
        //player collides with an item
        case KuboGame.KUBO_BIT | KuboGame.COINS_BIT:
           if(fixA.getFilterData().categoryBits == KuboGame.COINS_BIT) {
               ((Coin)fixA.getUserData()).use();
            } else ((Coin)fixB.getUserData()).use();
            break;
    }
}

@Override
public void endContact(Contact contact) {

}

@Override
public void preSolve(Contact contact, Manifold oldManifold) {

}

@Override
public void postSolve(Contact contact, ContactImpulse impulse) {

}
}

此处是Android Studio的错误日志:

public class PlayScreen implements Screen {

private KuboGame game;
private TextureAtlas atlas;
private Hud hud;
private OrthographicCamera gamecam;
private Viewport gamePort;
//here added 3
private TmxMapLoader maploader;
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;

private World world;
private Box2DDebugRenderer b2dr;
private B2WorldCreator creator;

private Kubo player;
private MapProperties prop;
private int[] data;

int mapWidth;
int mapHeight;
int tilePixelWidth;
int tilePixelHeight;


int mapPixelWidth;
int mapPixelHeight;



String mapName;


private Controller controller;

public PlayScreen(KuboGame game, String mapName, int[] prevData){
    atlas = new TextureAtlas("kuboRunSmaller.pack");
    this.game = game;
    this.mapName = mapName;
    this.data = prevData;
    gamecam = new OrthographicCamera();
    gamePort = new FitViewport(KuboGame.V_WIDTH / KuboGame.PPM, 
KuboGame.V_HEIGHT / KuboGame.PPM , gamecam);

    hud = new Hud(game.batch);
    hud.addScore(prevData[0]);
    hud.addLife(prevData[1]);
    hud.addLevel(prevData[2]);

    //added here 3
    maploader = new TmxMapLoader();
    //map = maploader.load("l1.tmx");
    map = maploader.load(mapName);

    prop = map.getProperties();

    mapWidth = prop.get("width", Integer.class);
    mapHeight = prop.get("height", Integer.class);
    tilePixelWidth = prop.get("tilewidth", Integer.class);
    tilePixelHeight = prop.get("tileheight", Integer.class);

    mapPixelWidth = mapWidth * tilePixelWidth;
    mapPixelHeight = mapHeight * tilePixelHeight;

    renderer = new OrthogonalTiledMapRenderer(map, 1 / KuboGame.PPM);
    gamecam.position.set(gamePort.getWorldWidth()/ 2, 
    gamePort.getWorldHeight()/ 2, 0);

    world = new World(new Vector2(0,-10), true); //bodies are at rest

    b2dr = new Box2DDebugRenderer();

    creator = new B2WorldCreator(this);
    player = new Kubo(this);
    controller = new Controller(game.batch);


    world.setContactListener(new WorldContactListener());

}

public TextureAtlas getAtlas(){
    return atlas;
}

@Override
public void show() {
   // world.setContactListener(new WorldContactListener());
}

public boolean gameOver(){
    if(player.currentState == Kubo.State.DEAD){
        return true;
    }else if(player.b2body.getPosition().y <= 0){
        return true;
    }
    return false;
}

public void levelComplete(){
    Gdx.app.log("GAME STATE", " LEVEL COMPLETE!");
    game.updateMaxScore(Hud.getScore());
    data[0] = hud.getScore();
    data[1] = hud.getLives();
    data[2] = hud.getLevel();
    game.setScreen(new LevelCompleteScreen(game, data));
    dispose();

}

public void handleInput(float dt){

    if(player.currentState != Kubo.State.DEAD) {
        if (Gdx.input.isKeyJustPressed(Input.Keys.UP))
            player.b2body.applyLinearImpulse(new Vector2(0, 2.6f), 
player.b2body.getWorldCenter(), true);
        if (Gdx.input.isKeyPressed(Input.Keys.RIGHT) && 
player.b2body.getLinearVelocity().x <= 2)
            player.b2body.applyLinearImpulse(new Vector2(0.1f, 0), 
player.b2body.getWorldCenter(), true);
        if (Gdx.input.isKeyPressed(Input.Keys.LEFT) && 
player.b2body.getLinearVelocity().x >= -2)
            player.b2body.applyLinearImpulse(new Vector2(-0.1f, 0), 
player.b2body.getWorldCenter(), true);

    }

    if(player.currentState != Kubo.State.DEAD){
        if(controller.isUpPressed() && player.b2body.getLinearVelocity().y 
== 0)
            player.b2body.applyLinearImpulse(new Vector2(0, 2.6f), 
player.b2body.getWorldCenter(), true); //was 0.4
        if(controller.isRightPressed() && 
player.b2body.getLinearVelocity().x <= 2)
            player.b2body.applyLinearImpulse(new Vector2(0.1f, 0), 
player.b2body.getWorldCenter(), true);
        if(controller.isLeftPressed() && player.b2body.getLinearVelocity().x 
>= -2)
            player.b2body.applyLinearImpulse(new Vector2(-0.1f, 0), 
player.b2body.getWorldCenter(), true);

    }

}

public void update(float dt){


    handleInput(dt);

    world.step(1/80f, 6, 2);

    player.update(dt);
    hud.update(dt);


    for(Enemy enemy :creator.getSpiders()) {
        enemy.update(dt);
        if(enemy.getX() < player.getX() + 180/ KuboGame.PPM)
            enemy.b2body.setActive(true);
    }

    for(Item item :creator.getCoins()){
        item.update(dt);


    }

    if(player.currentState != Kubo.State.DEAD) {
        if (player.b2body.getPosition().x >= KuboGame.V_WIDTH / 2 / 
KuboGame.PPM &&
                (mapPixelWidth/ KuboGame.PPM - 
player.b2body.getPosition().x)>= KuboGame.V_WIDTH / 2 / KuboGame.PPM )  {
            gamecam.position.x = player.b2body.getPosition().x;
        }else if(player.b2body.getPosition().x < 0.1){
            player.b2body.setAwake(false);
        }else if(mapPixelWidth/ KuboGame.PPM - player.b2body.getPosition().x 
<= 0.1)
        {levelComplete();}

    }
    gamecam.update();

    renderer.setView(gamecam);
}

public TiledMap getMap(){
    return map;
}

public World getWorld(){
    return world;
}
@Override
public void render(float delta) {


    update(delta);
    Gdx.gl.glClearColor(0,0,0,1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    renderer.render();

    //Next statement draws box2Dbodies to the screen
    //b2dr.render(world, gamecam.combined);
    game.batch.setProjectionMatrix(gamecam.combined);
    game.batch.begin();
    player.draw(game.batch);

   //draw all spiders
    for(Enemy enemy :creator.getSpiders())
        enemy.draw(game.batch);
    //draw all coins
    for(Item item :creator.getCoins())
        item.draw(game.batch);

    game.batch.end();

    game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
    hud.stage.draw();

    controller.draw();

    if(gameOver()){
        game.updateMaxScore(Hud.getScore());
        game.setScreen(new GameOverScreen(game, mapName));
        dispose();
    }
}

@Override
public void resize(int width, int height) {

    gamePort.update(width, height);
    controller.resize(width,height);
}

@Override
public void pause() {

}

@Override
public void resume() {

}

@Override
public void hide() {

}

@Override
public void dispose() {
    map.dispose();
    renderer.dispose();
    world.dispose();
    b2dr.dispose();
    hud.dispose();
}
}

1 个答案:

答案 0 :(得分:0)

在你的代码中,你将fixA userdata投射到敌人和kubo。你需要改变它,所以一个是fixA而另一个是fixB。

    case KuboGame.KUBO_BIT | KuboGame.ENEMY_BIT:
        if(fixA.getFilterData().categoryBits == KuboGame.KUBO_BIT) {
            ((Kubo)fixA.getUserData()).hit();
            ((Enemy)fixB.getUserData()).reverseVelocity(true, false);
            } else{
            ((Kubo)fixB.getUserData()).hit(); // here
            ((Enemy)fixA.getUserData()).reverseVelocity(true, false);
            }
        break;