无法在Libgdx中显示文本
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法在Libgdx中显示文本相关的知识,希望对你有一定的参考价值。
我正在使用Libgdx制作一款安卓游戏。我是新手,我无法找到,为什么我的命令font.draw()中的文本没有显示。一直在努力,直到我为这个游戏添加一个舞台。我在代码顺序中也有上层sb.begin();
我在谷歌上搜索了很多,我发誓我花了至少4个小时谷歌搜索,但都没有成功。
如果有人能帮助我,我将非常感激。
非常感谢您的回复!
sb.draw(gameoverImg, cam.position.x - gameoverImg.getWidth() / 2, cam.position.y + 95);
sb.draw(table, cam.position.x - table.getWidth() / 2 + 33, cam.position.y - 180);
font.getData().setScale(0.25f);
font.draw(sb, "" + currentHighScore, cam.position.x + 30, FlappyDemo2.HEIGHT / 2 - 200);
font.draw(sb, "" + score, cam.position.x + 30, FlappyDemo2.HEIGHT / 2 - 159);
myTextureRegion = new TextureRegion(playBtn2);
myTexRegionDrawable = new TextureRegionDrawable(myTextureRegion);
button = new ImageButton(myTexRegionDrawable); //Set the button up
button.setPosition(253/2, 112);
stage = new Stage(new ScreenViewport()); //Set up a stage for the ui
stage.addActor(button); //Add the button to the stage to perform rendering and take input.
myTextureRegion2 = new TextureRegion(scoreBtn);
myTexRegionDrawable2 = new TextureRegionDrawable(myTextureRegion2);
button2 = new ImageButton(myTexRegionDrawable2); //Set the button up
button2.setPosition(345, 185);
stage.addActor(button2);
如果你认真对待编程从基础开始。如果这是你的更新方法,那么你正在创建一个new Stage
和2 new ImageButton
并在每帧加载纹理。如果你想到这一秒,你会发现这是错误的做法。使用new关键字是“昂贵的”,因为它创建了一个新对象。在我们的快速计算机上,这并不重要但最终会产生延迟。另外,如果你每一帧都创建一个新的舞台,你就不能用它来做很多事情......旧的每一帧都会被处理掉。您可以在更新循环之外执行此操作。
如果这不是您的更新方法,则将您绘制的行移动到更新方法。还要确保更新方法每帧都清除屏幕。这就是图形通常的工作方式,屏幕被清除的每一帧都被重新绘制。
我强烈建议你离开游戏编程并从基础java教程开始。这将使你的生活变得更加容易,因为你淹死的那一刻,如果你不采取这一步,将会有一段时间。我确实想指出你正确的方向,希望下面的代码是一个大开眼界。编程中最重要的部分是整洁地构建代码。一个超过10行的方法可以分成多个方法,并且更具可读性。
我总是使用Screen功能构建到LibGDX中来开始。
test screen.Java
/**
* Extending from screen adapter to gain it's functionality and implement the Gesture Listener to use input.
*/
public class TestScreen extends ScreenAdapter implements GestureDetector.GestureListener {
// Declare fields, here we reserve memory to put the objects in.
// There is almost never a reason to make your fields public.
// Expose them with getters and setters if you need too.
private SpriteBatch spriteBatch;
private Viewport viewport;
private Stage stage;
private BitmapFont font;
/**
* The constructor gets run whenever you use the new keyword.
* This is a good place to initialize the fields.
*/
public TestScreen() {
spriteBatch = new SpriteBatch();
// There are many viewports, this just sets the viewport to the size of the window width and
// height. Note that most, if not all other viewports ask for worldWidth and worldHeight not
// screenWidth and screenHeight.
// It is also important to note that at this point when the code runs the window is not opened
// yet so the viewport does not get any width. That is why we need to update it in the resize
// method below, this will also make sure it does it's job when stretching the window.
viewport = new ScreenViewport();
viewport.apply();
// Never load assets and textures in the game loop. Unless of course you let the player load
// a image but then just load it once and not every frame.
// I used a random font in my library with the size of 20 pixels.
font = new BitmapFont(Gdx.files.internal("fonts/sarpanch_20.fnt"));
// I put the stage setup in it's own method.
stage = new Stage();
setupStage();
// Input multiplexer allows for multiple input sources. In this case we made this screen
// a GestureListener and the stage also needs input if you want to press buttons.
Gdx.input.setInputProcessor(new InputMultiplexer(
new GestureDetector(this),
stage
));
}
/**
* This is already a fairly long method. I could have put the click listener in it's own method
* so we could reuse it on other actors and the code will be more readable.
*/
private void setupStage() {
// Use clear instead of the new keyword whenever you can.
stage.clear();
// I advice to use the Skin functionality for actor elements. It works great when you know
// what you are doing. For now, just a style object.
Label.LabelStyle style = new Label.LabelStyle(font, Color.RED);
// final makes sure you won't put a new object in the field. It is needed because I use it
// in the listener/observer pattern below and that only runs when it observers a specific
// event. Thus it needs to still be the same object.
final Label label = new Label("Hello World", style);
label.setPosition(100, 100);
// Add awesome effect to label.
label.addListener(new ClickListener() {
@Override
public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) {
label.getStyle().fontColor = Color.BLUE;
}
@Override
public void exit(InputEvent event, float x, float y, int pointer, Actor fromActor) {
label.getStyle().fontColor = Color.RED;
}
});
// Instead I could have moved this click listener to addHoverColor(Actor actor)...
// sure, the above code would remain similar but in here it would read.
// addHoverColor(label);
// Which is much more readable.
// add the Label actor to stage.
stage.addActor(label);
}
/**
* render is the game loop. delta is the time since previous frame.
* @param delta
*/
@Override
public void render(float delta) {
super.render(delta);
// Unfortunately LibgDX couples logic and drawing in this method.
// Always remember to do the logic first and then render
// Let's make 2 methods for that to keep the code neat and decoupled.
update(delta);
draw();
//I use Stage to draw my GUI, the logic goes in update but the gui is always drawn on top
drawGui();
}
private void update(float delta) {
stage.act();
}
private void draw() {
//Clear screen and fill it with color.
Gdx.gl.glClearColor(.05f, .05f, .05f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// I want to be able to move the camera around so the sprite batch needs to know it projection
spriteBatch.setProjectionMatrix(viewport.getCamera().combined);
spriteBatch.setColor(Color.RED);
spriteBatch.begin();
//Use the SpriteBatch to draw the font.
font.draw(spriteBatch, "Hello World", 100, 100);
spriteBatch.end();
//System.out.println(viewport.getCamera().viewportWidth);
}
private void drawGui() {
stage.draw();
}
/**
* resize is called whenever the window changes size. So also at the start when the window is
* being set to your or default config size.
* @param width
* @param height
*/
@Override
public void resize(int width, int height) {
super.resize(width, height);
viewport.update(width, height);
}
// Screen adapter also has pause(), resume() and dispose(). But I leave those for now.
// Following the mandatory methods from the GestureListener. I just use pan to move the camera around
@Override
public boolean touchDown(float x, float y, int pointer, int button) {
return false;
}
@Override
public boolean tap(float x, float y, int count, int button) {
return false;
}
@Override
public boolean longPress(float x, float y) {
return false;
}
@Override
public boolean fling(float velocityX, float velocityY, int button) {
return false;
}
@Override
public boolean pan(float x, float y, float deltaX, float deltaY) {
viewport.getCamera().translate(-deltaX, deltaY, 0);
viewport.getCamera().update();
return false;
}
@Override
public boolean panStop(float x, float y, int pointer, int button) {
return false;
}
@Override
public boolean zoom(float initialDistance, float distance) {
return false;
}
@Override
public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2) {
return false;
}
@Override
public void pinchStop() {
}
}
现在我们只需要对主要核心类进行一些小改动。
// Extend from game instead of application listener
public class MyGame extends Game {
@Override
public void create () {
// Now you have access to setScreen.
setScreen(new TestScreen());
}
}
我希望这是有道理的。它简短而简单,我确信在阅读你的代码时你可以阅读我的代码。所以让我再次按下,编写简洁的代码是编程的最重要方面。不仅对我们而且对你自己也是如此。显然,对语言有扎实的基础知识有助于此。
以上是关于无法在Libgdx中显示文本的主要内容,如果未能解决你的问题,请参考以下文章