I'm kinda new to LibGDX.
I'm just learning the ropes.
Trying to get a basic TextButton to display at a reasonable size on screen.
Working exclusively on Android IDE (AIDE).
Using only default skins and what-not, I've tried to set width and height as well as setScale() but only the text size seems to increase on the command.
What am I doing wrong?
https://oi1161.photobucket.com/albums/q501/StudioGilliam/Screenshot_20190423-184819_LibGDXButtonsTest.jpg
public class MyGdxGame implements ApplicationListener
{
private Stage stage;
private Table table;
private TextButton btn;
#Override
public void create()
{
stage = new Stage(new ScreenViewport());
Gdx.input.setInputProcessor(stage);
table = new Table();
table.setBounds(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
TextButton.TextButtonStyle style = new TextButton.TextButtonStyle();
style.font = new BitmapFont();
btn = new TextButton("Button", style);
btn.pad(20);
btn.setTransform(true);
btn.setScale(5.0f);
btn.setTouchable(Touchable.enabled);
table.add(btn);
table.debug();
stage.addActor(table);
}
#Override
public void render()
{
Gdx.gl.glClearColor(0, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
stage.draw();
}
#Override
public void dispose()
{
stage.dispose();
}
#Override
public void resize(int width, int height){}
#Override
public void pause(){}
#Override
public void resume(){}
}
EDIT:
I realised that parent objects like stages and tables control the properties of their children, so I added:
table.add(btn).width(300).height(100);
And now it looks better but the text is way off centre...
https://oi1161.photobucket.com/albums/q501/StudioGilliam/Screenshot_20190423-191104_LibGDXButtonsTest.jpg
On a Textbutton, you should use setFontScale() and pack() to resize the button to the font size.
However, for supporting different screen sizes without any own coding, consider using FitViewport/ExtendViewport
Related
At the moment desktop version of application is fine, the buttons are scaled quite nice but when I deploy to android they're tiny and barely usable.
DesktopLauncher ..
public class DesktopLauncher {
public static void main (String[] arg) {
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
config.title = "Color Catchin";
config.width = 800;
config.height = 480;
new LwjglApplication(new ColorCatch(), config);
}
}
AndroidLauncher ..
public class AndroidLauncher extends AndroidApplication {
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
config.useAccelerometer = false;
config.useCompass = false;
initialize(new ColorCatch(), config);
}
}
Core code ..
public class MainMenu implements Screen {
Skin skin = new Skin(Gdx.files.internal("ui/uiskin.json"));
Stage stage = new Stage();
final private ColorCatch game;
public MainMenu(final ColorCatch gam) {
game = gam;
Gdx.input.setInputProcessor(stage);
Table table = new Table();
table.setFillParent(true);
stage.addActor(table);
final TextButton play = new TextButton("Play", skin);
final TextButton quit = new TextButton("Quit", skin);
table.add(play).pad(10);
table.row();
table.add(quit).pad(10);
play.addListener(new ChangeListener() {
public void changed(ChangeEvent event, Actor actor) {
game.setScreen(new GameScreen(game));
dispose();
}
});
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(delta);
stage.draw();
}
#Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
}
}
desktop ..
android ..
By default Stage will have a ScalingViewport set to Scaling.stretch with a virtual viewport size of Gdx.graphics.getWidth() x Gdx.graphics.getHeight (see here).
On Desktop you will start with a size of 800x480, because that's what you told your launcher. On Android, this is dynamic and depends on the device. On your device it might be 1920x1080.
Since you do not change your button sizes, they will have the same size on both devices in terms of pixels. because of the totally different screen density though, on Android the buttons will appear to be much smaller.
The easiest solution to get both to the same level would be to use a Viewport with a fixed virtual size. For example a new FitViewport(800, 480). You can supply that viewport to the stage via new Stage(viewport).
However, scaling up or down depending on the screens size to keep the aspect ratio and the virtual resolution is usually not a good idea for UIs. It might be better to use a ScreenViewport instead and set your actors' sizes relative to each other. You can use Value.percentWidth(0.5f, rootTable) for example, to set the width of a widget to 50% of the root table, that takes the whole screen (via setFillParent(true)).
i have the following class that is suppose to reference a font and then draw a string to the screen once an event has occured. the class is called like this .
if (grumpface.whiteballoon.getBoundingRectangle().overlaps(spriterect)) {
((Game) Gdx.app.getApplicationListener()).setScreen(new GameOverScreen());
}
;
the class it references it this but i still cant get the font to appear any suggestiosns?
class GameOverScreen implements Screen{
private Stage stage;
// Called automatically once for init objects
#Override
public void show() {
stage = new Stage();
stage.setDebugAll(true); // Set outlines for Stage elements for easy debug
BitmapFont white = new BitmapFont(Gdx.files.internal("hazey.fnt"), false);
LabelStyle headingStyle = new LabelStyle(white, Color.BLACK);
Label gameoverstring = new Label("game ovaaaa!", headingStyle);
gameoverstring.setPosition(100, 100);
stage.addActor(gameoverstring);
}
// Called every frame so try to put no object creation in it
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(delta);
stage.draw();
}
The font color of your label is getting set to "black", which is the same as your background color.
I'm trying to get a screenshot to display on the background of a pause menu.
My screenshot method uses ScreenUtils.getFrameBufferPixmap() to get the screenshot; I got it from here.
My code for the pause screen is as follows:
public class CEscapeScreen implements CScreen {
private final Stage stage;
private class BGActor extends Actor {
Pixmap pixmap = CUtil.getScreenshot(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false);
Texture t = new Texture(pixmap);
#Override
public void draw(Batch batch, float alpha) {
batch.draw(t, 0, 0);
}
}
public CEscapeScreen(CGame g) {
Actor bgActor = new BGActor();
stage = new Stage();
final TextButton quitButton = new TextButton("Quit to Main Menu", CUi.getUISkin(), "default");
...
table.add(quitButton);
stage.addActor(bgActor);
stage.addActor(table);
}
#Override
public void display() {
stage.draw();
}
}
The display method is called every frame by the current Screen the program is on.
What I'm trying to accomplish is to get a screenshot of the screen before the pause screen stage is drawn, and then draw that screenshot behind the quitButton.
Every other Screen clears and makes a new Stage like this one.
The problem I'm having, is that only the quitButton appears on the Escape Menu. Why does this happen?
I'm new to LibGDX and I am taking it slowly. I'm still trying to understand most things which is why typically google searches don't help due to the fact that their too complicated. I have a main menu that has text that I want centered no matter what the screen size is. Here is the code that I have for that menu.
public class Menu implements Screen {
SlingshotSteve game;
OrthographicCamera camera;
public Menu(final SlingshotSteve gam) {
this.game = gam;
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
game.font.draw(game.batch, "Welcome to Slingshot Steve!!! ", 100, 150);
game.font.draw(game.batch, "Tap anywhere to begin!", 100, 100);
game.batch.end();
if (Gdx.input.isTouched()) {
game.setScreen((Screen) new GameScreen(game));
dispose();
}
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
}
}
I'm here to save you!
To get width / height from a String drawn with your BitmapFont you can utilize this super nice method:
game.font.getBounds(String string)
And to use it in your case, it would be something like this:
game.font.getBounds("Tap anywhere to begin!").width / 2;
Cheers!
It is possible to do it the way Nine Magics suggested, however one would usually do it via a Stage, which is part of scene2d.
More specifically one would use scene2d.ui which is a bunch of Actors like Button, Image, Label etc. You can attach a ClickListener to a Button for example and react on this event.
Furthermore, for layouting there is one very powerful Actor, namely Table which you can very easily use to center things on the screen.
Some very minimalistic code:
// do this once, in create() or show()
Skin skin = new Skin("uiskin.json"); // get the demo skin from the libgdx test resources
Stage stage = new Stage();
Table table = new Table(skin);
table.add("Welcome to Slingshot Steve!!!");
table.row();
table.add("Tap anywhere to begin!");
stage.addActor(table);
// do this in your render loop
stage.act();
stage.draw();
You can find the "default" skin resources here. You need to get all the uiskin.* files.
So i want to create a mainmenu for my game and i'm stuck on what to do next i have all the art done and it's all in layers and packed in a .pack
public class MainMenu implements Screen {
CrazyZombies game;
Stage stage;
BitmapFont font;
TextureAtlas MainMenu;
Texture road;
Skin skin;
SpriteBatch batch;
public MainMenu(CrazyZombies game){
this.game = game;
}
#Override
public void render(float delta) {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
Gdx.gl.glClearColor(0.09f, 0.28f, 0.2f, 1);
stage.act(delta);
batch.begin();
stage.draw();
batch.end();
}
#Override
public void resize(int width, int height) {
if(stage == null)
stage = new Stage(width, height, true);
stage.clear();
Gdx.input.setInputProcessor(stage);
}
#Override
public void show() {
batch = new SpriteBatch();
skin = new Skin();
MainMenu = new TextureAtlas("data/mainmenu/MainMenu.pack");
}
#Override
public void hide() {
dispose();
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
batch.dispose();
skin.dispose();
MainMenu.dispose();
stage.dispose();
}
}
If anyone could give me some guidelines or tutorials on what to do now it would be great i've looked in a lot of places but they have not given me the required answers.
Have a look at this tutorial which sums up what you want exactly:
LibGDX: Using a Splash Screen or Menu
i think it will be easy if u use scene2D that will handle all the complexity and help you to create a nice looking UI with a little bit of code .
you may need to check this link
https://github.com/libgdx/libgdx/wiki/Scene2d.ui
Basically, you need to
create a skin, and
we need to add buttionTextureStyle to it.
Don't forget to add fonts, it took me a hour to figure out that fonts are not set by default like other parameters of buttonTextureStyle
and then you create a button with created skin
and then add that button to the stage.