我正在使用Android Studio和LibGDX创建2D平台游戏。 现在,我正在实现一个屏幕控制器来移动角色,但是当我启动启动器时,它会自动关闭。
当我运行启动器时,这是控制台显示的内容:
Exception in thread "LWJGL Application" java.lang.IllegalArgumentException: batch cannot be null.
at com.badlogic.gdx.scenes.scene2d.Stage.<init>(Stage.java:108)
at com.globapps.supermarioclon.Tools.Controles.<init>(Controles.java:30)
at com.globapps.supermarioclon.Screens.PantallaJuego.<init>(PantallaJuego.java:57)
at com.globapps.supermarioclon.MarioBros.create(MarioBros.java:34)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:147)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:124)
这是控制器类的代码:
public class Controles {
Viewport viewport;
Stage stage;
boolean salto, izquierda, derecha;
OrthographicCamera cam;
public Controles() {
cam = new OrthographicCamera();
viewport = new FitViewport(800, 480, cam);
stage = new Stage(viewport, PantallaJuego.batch);
Gdx.input.setInputProcessor(stage);
Table table1 = new Table();
Table table2 = new Table();
table1.left().bottom();
table2.right().bottom();
Image flechaizquierda = new Image(new Texture("flechaIzquierda.png"));
flechaizquierda.setSize(50, 50);
flechaizquierda.addListener(new InputListener() {
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
izquierda = true;
return true;
}
@Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
izquierda = false;
}
});
final Image flechaderecha = new Image(new Texture("flechaDerecha.png"));
flechaderecha.setSize(50, 50);
flechaderecha.addListener(new InputListener() {
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
derecha = true;
return true;
}
@Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
derecha = false;
}
});
Image flechasalto = new Image(new Texture("flechaIzquierda.png"));
flechasalto.setSize(50, 50);
flechasalto.addListener(new InputListener() {
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
salto = true;
return true;
}
@Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
}
});
table1.add();
table1.add(flechaizquierda).size(flechaizquierda.getWidth(), flechaizquierda.getHeight());
table1.add();
table1.row().pad(0, 5, 0, 5);
table1.add();
table1.add(flechaderecha).size(flechaderecha.getWidth(), flechaderecha.getHeight());
table2.add();
table2.add(flechasalto).size(flechasalto.getWidth(), flechasalto.getHeight());
table2.row().padRight(5);
table2.add();
stage.addActor(table1);
stage.addActor(table2);
}
public void draw() {
stage.draw();
}
public boolean isDerecha() {
return derecha;
}
public boolean isIzquierda() {
return izquierda;
}
public boolean isSalto() {
return salto;
}
public void resize(int ancho, int alto) {
viewport.update(ancho, alto);
}
}
这是PlayScreen类:
public class PantallaJuego extends ApplicationAdapter implements Screen {
private MarioBros game;
public static SpriteBatch batch;
private TextureAtlas atlas;
private OrthographicCamera gamecam, cam;
private Viewport gamePort, viewport;
private HUD hud;
private TmxMapLoader maploader;
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private World world;
private Box2DDebugRenderer b2dr;
Controles controles;
private Mario player;
private Music musica;
public PantallaJuego(MarioBros game) {
atlas = new TextureAtlas("MarioyEnemigos.pack");
this.game = game;
gamecam = new OrthographicCamera();
gamePort = new FitViewport(MarioBros.V_WIDTH / MarioBros.PPM, MarioBros.V_HEIGHT / MarioBros.PPM, gamecam);
hud = new HUD(game.batch);
controles = new Controles();
batch = new SpriteBatch();
maploader = new TmxMapLoader();
map = maploader.load("nivel1mario.tmx");
renderer = new OrthogonalTiledMapRenderer(map, 1/MarioBros.PPM);
gamecam.position.set(gamePort.getWorldWidth()/2, gamePort.getWorldHeight()/2, 0);
world = new World(new Vector2(0,-10), true);
b2dr = new Box2DDebugRenderer();
player = new Mario(world, this);
new B2WorldCreator(world, map);
world.setContactListener(new WorldContactListener());
musica = MarioBros.manager.get("Audio/Música/Super Mario World - Overworld Theme Music (FULL VERSION).mp3", Music.class);
musica.setLooping(true);
musica.play();
}
public TextureAtlas getAtlas() {
return atlas;
}
@Override
public void show() {
}
public void handleInput(float dt) {
if(controles.isDerecha())
player.b2body.applyLinearImpulse(new Vector2(0.1f, 0), player.b2body.getWorldCenter(), true);
if(controles.isSalto())
MarioBros.manager.get("Audio/Sonidos/Super Mario Bros- Mario Jump Sound Effect.mp3", Sound.class).play();
player.b2body.applyLinearImpulse(new Vector2(0, 4f), player.b2body.getWorldCenter(), true);
if(controles.isIzquierda())
player.b2body.applyLinearImpulse(new Vector2(-0.1f, 0), player.b2body.getWorldCenter(), true);
}
public void update(float dt) {
handleInput(dt);
world.step(1 / 60f, 6, 2);
gamecam.position.x = player.b2body.getPosition().x;
cam.position.set(viewport.getWorldWidth() / 2, viewport.getWorldHeight() / 2, 0);
player.update(dt);
hud.update(dt);
if(Gdx.app.getType() == Application.ApplicationType.Android)
controles.draw();
gamecam.update();
cam.update();
renderer.setView(gamecam);
}
@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();
b2dr.render(world, cam.combined);
b2dr.render(world, gamecam.combined);
game.batch.setProjectionMatrix(gamecam.combined);
game.batch.begin();
player.draw(game.batch);
game.batch.end();
game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
hud.stage.draw();
}
如果有人可以帮助我,我会非常感激。谢谢。
答案 0 :(得分:1)
我认为你应该在实例化controles字段之前在PantallaJueago类中实例化你的批处理。
public PantallaJuego(MarioBros game) {
atlas = new TextureAtlas("MarioyEnemigos.pack");
this.game = game;
gamecam = new OrthographicCamera();
gamePort = new FitViewport(MarioBros.V_WIDTH / MarioBros.PPM, MarioBros.V_HEIGHT / MarioBros.PPM, gamecam);
hud = new HUD(game.batch);
batch = new SpriteBatch();
controles = new Controles();
因为在实例化“controles”时它为null。您的线路出现此错误
stage = new Stage(viewport, PantallaJuego.batch);
PantallaJuego.batch为空。
答案 1 :(得分:0)
在继续之前,你应该学习更多基础知识。这与NullPointerException有关,通常很容易修复。它告诉您,您尝试访问任何方法或变量,因为您没有初始化它。让我们拿你的筹码找错了。
Exception in thread "LWJGL Application" java.lang.IllegalArgumentException: batch cannot be null.
//Great! So let's fix this.
at com.badlogic.gdx.scenes.scene2d.Stage.<init>(Stage.java:108)
//This is a LibGDX class so there is probably nothing wrong with this
at com.globapps.supermarioclon.Tools.Controles.<init>(Controles.java:30)
//This is your class so let's go to this specific line, you can double click it.
stage = new Stage(viewport, PantallaJuego.batch);
//So either viewport or batch is null in this line.
//You can put a breakpoint here and run a debug,
//your program will stop on this line and you can hover
//to see what is in the variables. You will see that batch
// is null. Why, you may ask.
在主要类的构造函数中,首先设置new Controles()
controles = new Controles();
现在Controles的构造函数将运行并进入这一行:
stage = new Stage(viewport, PantallaJuego.batch);
由于您的代码未在batch = new SpriteBatch();
中到达PantallaJuego
,因此批处理仍然为空,因为stage不接受它将抛出NullPointer。快速解决方法是转换new SpriteBatch()
和new Controles()
。
我之所以说你应该首先开始学习基础知识是因为你的代码形成得很差。您应该以一种简洁的方式格式化代码并使用更小的方法,因为现在某些方法和构造函数会执行所有类型的操作并且很难阅读。除此之外,你正在养成非常糟糕的习惯,例如从SpriteBatch
(public static
)创建全局。实际上没有必要这样做,这是你在这里失败的部分原因。
看一下What is a NullPointerException, and how do I fix it?,虽然你的错误不是NullPointerException,但它非常相关。 Stage()
检查它自己是否为null并在它尝试访问它之前抛出另一个异常然后得到一个nullpointer。