【发布时间】:2020-11-21 15:41:50
【问题描述】:
我也是 stackoverflow、Kryonet 和 libgdx 的新手。在这里,在学习libgdx的过程中,我想制作一个在线剪刀石头布游戏来体验libgdx kryonet。起初我想在我的游戏中实现一个聊天系统来试用 Kryonet。 The idea is很简单的一个;聊天框(文本区域)、发送和加入按钮、用户名和消息文本字段。当有人点击发送按钮时,消息将被发送到连接到服务器的每个客户端。但是当我向发送按钮发送垃圾邮件时,它会给出一些错误类型(有时是 1,有时是 2,有时是另一种)并关闭游戏:
错误类型 1
线程“LWJGL 应用程序”中的异常 java.lang.NullPointerException 在 com.badlogic.gdx.graphics.g2d.GlyphLayout.setText(GlyphLayout.java:144) 在 com.badlogic.gdx.graphics.g2d.GlyphLayout.setText(GlyphLayout.java:63) 在 com.badlogic.gdx.scenes.scene2d.ui.TextArea.calculateOffsets(TextArea.java:288) 在 com.badlogic.gdx.scenes.scene2d.ui.TextField.draw(TextField.java:330) 在 com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:123) 在 com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) 在 com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup.draw(WidgetGroup.java:170) 在 com.badlogic.gdx.scenes.scene2d.ui.Table.draw(Table.java:119) 在 com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:123) 在 com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) 在 com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup.draw(WidgetGroup.java:170) 在 com.badlogic.gdx.scenes.scene2d.ui.Table.draw(Table.java:119) 在 com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:110) 在 com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) 在 com.badlogic.gdx.scenes.scene2d.Stage.draw(Stage.java:128) 在 com.mygdx.game.screens.PlayScreen.render(PlayScreen.java:118) 在 com.badlogic.gdx.Game.render(Game.java:46) 在 com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:233) 在 com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:128)
错误类型 2
线程“LWJGL 应用程序”java.lang.ArrayIndexOutOfBoundsException 中的异常:2980 在 com.badlogic.gdx.graphics.g2d.BitmapFontCache.addGlyph(BitmapFontCache.java:408) 在 com.badlogic.gdx.graphics.g2d.BitmapFontCache.addToCache(BitmapFontCache.java:379) 在 com.badlogic.gdx.graphics.g2d.BitmapFontCache.addText(BitmapFontCache.java:511) 在 com.badlogic.gdx.graphics.g2d.BitmapFontCache.addText(BitmapFontCache.java:505) 在 com.badlogic.gdx.graphics.g2d.BitmapFontCache.addText(BitmapFontCache.java:486) 在 com.badlogic.gdx.graphics.g2d.BitmapFont.draw(BitmapFont.java:214) 在 com.badlogic.gdx.scenes.scene2d.ui.TextField.drawText(TextField.java:376) 在 com.badlogic.gdx.scenes.scene2d.ui.TextField.draw(TextField.java:349) 在 com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:123) 在 com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) 在 com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup.draw(WidgetGroup.java:170) 在 com.badlogic.gdx.scenes.scene2d.ui.Table.draw(Table.java:119) 在 com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:123) 在 com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) 在 com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup.draw(WidgetGroup.java:170) 在 com.badlogic.gdx.scenes.scene2d.ui.Table.draw(Table.java:119) 在 com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:110) 在 com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) 在 com.badlogic.gdx.scenes.scene2d.Stage.draw(Stage.java:128) 在 com.mygdx.game.screens.PlayScreen.render(PlayScreen.java:118) 在 com.badlogic.gdx.Game.render(Game.java:46) 在 com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:233) 在 com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:128)
错误类型 3
线程“LWJGL 应用程序”中的异常 java.lang.NullPointerException 在 com.badlogic.gdx.graphics.g2d.GlyphLayout.setText(GlyphLayout.java:144) 在 com.badlogic.gdx.graphics.g2d.GlyphLayout.setText(GlyphLayout.java:63) 在 com.badlogic.gdx.scenes.scene2d.ui.TextArea.calculateOffsets(TextArea.java:288) 在 com.badlogic.gdx.scenes.scene2d.ui.TextField.draw(TextField.java:330) 在 com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:123) 在 com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) 在 com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup.draw(WidgetGroup.java:170) 在 com.badlogic.gdx.scenes.scene2d.ui.Table.draw(Table.java:119) 在 com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:123) 在 com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) 在 com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup.draw(WidgetGroup.java:170) 在 com.badlogic.gdx.scenes.scene2d.ui.Table.draw(Table.java:119) 在 com.badlogic.gdx.scenes.scene2d.Group.drawChildren(Group.java:110) 在 com.badlogic.gdx.scenes.scene2d.Group.draw(Group.java:57) 在 com.badlogic.gdx.scenes.scene2d.Stage.draw(Stage.java:128) 在 com.mygdx.game.screens.PlayScreen.render(PlayScreen.java:118) 在 com.badlogic.gdx.Game.render(Game.java:46) 在 com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:233) 在 com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:128)
错误中提到的at com.mygdx.game.screens.PlayScreen.render(PlayScreen.java:118) 行是:我当前屏幕的render() 方法中的stage.draw(); 行。我不知道问题出在哪里,但我的猜测是客户端收到垃圾邮件包时丢失了一些东西。
下面是我的代码,以获得一些帮助和线索,我们将不胜感激。
render() 方法
public void render(float delta) {
//inputHandler();
Gdx.gl20.glClearColor(0, 0, 0, 1);
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
app.camera.update();
app.viewport.apply();
app.batch.setProjectionMatrix(app.camera.combined);
app.batch.begin();
//app.batch.setColor(0.85f, 0.85f, 0.85f, 1);
app.batch.draw(wallpaper,0,0);
app.batch.end();
//stage.getCamera().update();
//stage.getViewport().apply();
stage.act(delta);
stage.draw();
}
startServer() 方法
private void startServer() {
server = new Server(25565,25565);
server.getKryo().register(LoginRequest.class);
server.getKryo().register(LoginResponse.class);
server.getKryo().register(MessageRequest.class);
server.getKryo().register(MessageResponse.class);
server.getKryo().register(String.class);
server.start();
try {
server.bind(25565,25565);
server.addListener(new Listener(){
@Override
public void received(Connection connection, Object o) {
super.received(connection, o);
if(o instanceof LoginRequest) {
LoginRequest req = (LoginRequest) o;
LoginResponse response = new LoginResponse();
response.setResponseMessage("\n -> " + req.getUsername() + " has joined the server!");
server.sendToAllTCP(response);
}
if(o instanceof MessageRequest) {
MessageRequest req = (MessageRequest) o;
MessageResponse response = new MessageResponse();
response.setMessage("\n -> " + req.getUsername() + " : " + req.getMessage());
server.sendToAllTCP(response);
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
//btn_server.setDisabled(true);
//btn_server.clearListeners();
}
createButton() 方法(btn_server => 发送消息按钮,我忘了改变量名,别介意)
private void createButton() {
btn_style = new TextButton.TextButtonStyle();
btn_style.font = font;
btn_style.up = new TextureRegionDrawable(texUp);
btn_style.down = new TextureRegionDrawable(texDown);
btn_style.over = new TextureRegionDrawable(texOver);
btn_style.disabled = new TextureRegionDrawable(texLock);
btn_join = new TextButton("Join Server", btn_style);
btn_server = new TextButton("Send Message", btn_style);
btn_server.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
if(client.isConnected()) {
MessageRequest req = new MessageRequest();
req.setUsername(name.getText());
req.setMessage(message.getText());
client.sendTCP(req);
}
//btn_server.setDisabled(true);
//btn_server.clearListeners();
}
});
btn_join.addListener(new InputListener() {
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
client = new Client(25565,25565);
client.getKryo().register(LoginRequest.class);
client.getKryo().register(LoginResponse.class);
client.getKryo().register(MessageRequest.class);
client.getKryo().register(MessageResponse.class);
client.getKryo().register(String.class);
try {
client.start();
client.connect(5000, myIP, 25565, 25565);
} catch (IOException e) {
e.printStackTrace();
}
if(client.isConnected()) {
btn_join.setDisabled(true);
name.setDisabled(true);
btn_join.clearListeners();
LoginRequest req = new LoginRequest();
req.setUsername(name.getText());
client.sendTCP(req);
client.addListener(new Listener(){
@Override
public void received(Connection connection, Object o) {
super.received(connection, o);
if(o instanceof LoginResponse) {
LoginResponse response = (LoginResponse) o;
textArea.appendText(response.getResponseMessage());
}
if(o instanceof MessageResponse) {
MessageResponse response = (MessageResponse) o;
textArea.appendText(response.getMessage());
}
}
});
}
return true;
}
});
}
【问题讨论】:
-
这对我来说太多了,无法为您调试和调试,但我建议您阅读这两本书以了解如何自己调试 NullPointerException 等常见错误。 stackoverflow.com/questions/218384/…stackoverflow.com/questions/3988788/…
-
感谢您的关注。我试图摆脱使用 if... != null 的问题。如果有任何进展,我都会进行更新。
-
所有错误都是相关的,告诉你textarea的文本有问题。在
textArea.appendText设置断点并检查 -
我做了,但找不到任何好的曲目。之后,我尝试使用 List/ScrollPane 而不是 TextArea 向客户端显示所有消息。我仍然收到一个错误,如我的新答案所示。