<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();
}
}
答案 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;