LIBGDX - Table's textButtons are not filling the respective rows - java

I was recently working on a game which utilises Scene2D until I ran into this problem as shown in this picture:
The bounds in which I'm able to click the button exceed the actual TextButton's area
I've read the documentation for TableLayouts in the GitHub page here and have read different articles about Scene2D in general, and I tried fiddling around with the different functions (eg padding, colSpan) to try to come to a solution but I can't seem to find a work around for this.
Here is the code responsible for the setup and drawing of the table:
table = new Table();
table.setDebug(true);
table.add(graphicsButton).width(200f).height(200f);
table.row();
table.add(audioButton).width(200f).height(200f);
table.row();
table.add(backToTitleButton).width(200f).height(200f);
table.setBounds(0, 0, stage.getWidth(), stage.getHeight());
stage.addActor(table);
And here is the rest of the code (note that I haven't centred the text within the buttons yet, I've only added filler values, also - I've removed the empty functions from the Screen class for convenience)
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextField;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
import com.thesameritan.game.GUI.UI;
public class OptionsScreen extends ScreenProperties implements Screen {
private Stage stage;
private Table table;
OptionsScreen (final Game game) {
super();
stage = new Stage(new ScreenViewport());
Gdx.input.setInputProcessor(stage);
TextButton backToTitleButton = UI.createNewButton("BACK", buttonStyle, 0.8f, 25f, 0.9f); //creates button from another class with text, style, padBottom, padLeft and fontScale
TextButton graphicsButton = UI.createNewButton("GRAPHICS", buttonStyle, 0.9f, 20f, 0.9f);
TextButton audioButton = UI.createNewButton("AUDIO", buttonStyle, 0.9f, 20f, 0.9f);
backToTitleButton.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
//branch to title
}
});
graphicsButton.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
//branch to graphics
}
});
audioButton.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
//branch to options
}
});
table = new Table();
table.setDebug(true);
table.add(graphicsButton).width(200f).height(200f);
table.row();
table.add(audioButton).width(200f).height(200f);
table.row();
table.add(backToTitleButton).width(200f).height(200f);
table.setBounds(0, 0, stage.getWidth(), stage.getHeight());
stage.addActor(table);
}
#Override
public void render (float delta) {
clearScreen(); //from ScreenProperties
stage.draw();
}
#Override
public void dispose() {
disposeObjects(); //from ScreenProperties
stage.dispose();
}
}
What I would like is either minimising the gaps between the buttons without affecting the button's size - which again, I've tried by changing the .width() and .height() values or actually reduce the size of the interactive area (shown in the red lines)
Thank you so much!

The interesting and missing part here is UI.createNewButton.
Instead of setting debug to the outer table, you can debug the button itself: backToTitleButton.setDebug(true). You'll see that the click bounds doesn't exceed the buttons area, but the graphical representation is not correct. I suspect you aren't using a Ninepatch for the Rectangle.

Related

Event handling in libgdx not working as expected

I've been learning about libgdx recently. In the process of following the instructions on their libgdx wiki I ran into some problems.
Specifically in the GameScreen class at the 99th line I changed the code inside so that it goes back to the previous screen (MainMenuScreen class) and yes you see when the mouse is pressed it worked (I mean go back to the screen before ) but a very very short time after, the screen AUTOMATICALLY switches to the GameScreen class (like I click the mouse once but it makes me 1 more redundant task). I guess when I click on the GameScreen screen it did the code in the if statement on line 99 to go to MainMenuScreen screen. In that screen at line 32 I guess it was true after I got to this screen because when I change the key is listened then it works fine (only converts once). I was intending to try implementing InputProcessor on each screen class but now I'm avoiding it for some reason. Can someone give me some advice recommend.Thank you
Here is the source code for the MainMenuScreen class.
package com.mygdx.game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.utils.ScreenUtils;
//import com.mygdx.game.Drop;
public class MainMenuScreen implements Screen {
final Drop game;
OrthographicCamera camera;
public MainMenuScreen(final Drop gam) {
game = gam;
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
}
#Override
public void render(float delta) {
ScreenUtils.clear(0, 0, 0.2f, 1);
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
game.font.draw(game.batch, "Welcome to Drop!!! ", 100, 150);
game.font.draw(game.batch, "Tap anywhere to begin!", 100, 100);
game.batch.end();
if (Gdx.input.isTouched()) { //I guess right after switching to this screen this conditional sentence was true before
game.setScreen(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() {
}
}
Here is source code for the GameScreen class
package com.mygdx.game;
import java.util.Iterator;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ScreenUtils;
import com.badlogic.gdx.utils.TimeUtils;
public class GameScreen implements Screen {
final Drop game;
Texture dropImage;
Texture bucketImage;
//Sound dropSound;
//Music rainMusic;
OrthographicCamera camera;
Rectangle bucket;
Array<Rectangle> raindrops;
long lastDropTime;
int dropsGathered;
public GameScreen(final Drop gam) {
this.game = gam;
// load the images for the droplet and the bucket, 64x64 pixels each
dropImage = new Texture(Gdx.files.internal("drop.png"));
bucketImage = new Texture(Gdx.files.internal("bucket.png"));
// load the drop sound effect and the rain background "music"
//dropSound = Gdx.audio.newSound(Gdx.files.internal("drop.wav"));
//rainMusic = Gdx.audio.newMusic(Gdx.files.internal("rain.mp3"));
//rainMusic.setLooping(true);
// create the camera and the SpriteBatch
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
// create a Rectangle to logically represent the bucket
bucket = new Rectangle();
bucket.x = 800 / 2 - 64 / 2; // center the bucket horizontally
bucket.y = 20; // bottom left corner of the bucket is 20 pixels above
// the bottom screen edge
bucket.width = 64;
bucket.height = 64;
// create the raindrops array and spawn the first raindrop
raindrops = new Array<Rectangle>();
spawnRaindrop();
}
private void spawnRaindrop() {
Rectangle raindrop = new Rectangle();
raindrop.x = MathUtils.random(0, 800 - 64);
raindrop.y = 480;
raindrop.width = 64;
raindrop.height = 64;
raindrops.add(raindrop);
lastDropTime = TimeUtils.nanoTime();
}
#Override
public void render(float delta) {
// clear the screen with a dark blue color. The
// arguments to clear are the red, green
// blue and alpha component in the range [0,1]
// of the color to be used to clear the screen.
ScreenUtils.clear(0, 0, 0.2f, 1);
// tell the camera to update its matrices.
camera.update();
// tell the SpriteBatch to render in the
// coordinate system specified by the camera.
game.batch.setProjectionMatrix(camera.combined);
// begin a new batch and draw the bucket and
// all drops
game.batch.begin();
game.font.draw(game.batch, "Drops Collected: " + dropsGathered, 0, 480);
game.batch.draw(bucketImage, bucket.x, bucket.y);
for (Rectangle raindrop : raindrops) {
game.batch.draw(dropImage, raindrop.x, raindrop.y);
}
game.batch.end();
// process user input
if (Gdx.input.justTouched()) { //This conditional works fine
/* Vector3 touchPos = new Vector3();
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
bucket.x = touchPos.x - 64 / 2;
*/
game.setScreen(new MainMenuSceen(game)); //Screen switch
}
if (Gdx.input.isKeyPressed(Keys.LEFT))
bucket.x -= 200 * Gdx.graphics.getDeltaTime();
if (Gdx.input.isKeyPressed(Keys.RIGHT))
bucket.x += 200 * Gdx.graphics.getDeltaTime();
// make sure the bucket stays within the screen bounds
if (bucket.x < 0)
bucket.x = 0;
if (bucket.x > 800 - 64)
bucket.x = 800 - 64;
// check if we need to create a new raindrop
if (TimeUtils.nanoTime() - lastDropTime > 1000000000)
spawnRaindrop();
// move the raindrops, remove any that are beneath the bottom edge of
// the screen or that hit the bucket. In the later case we play back
// a sound effect as well.
Iterator<Rectangle> iter = raindrops.iterator();
while (iter.hasNext()) {
Rectangle raindrop = iter.next();
raindrop.y -= 200 * Gdx.graphics.getDeltaTime();
if (raindrop.y + 64 < 0)
iter.remove();
if (raindrop.overlaps(bucket)) {
dropsGathered++;
//dropSound.play();
iter.remove();
}
}
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
// start the playback of the background music
// when the screen is shown
//rainMusic.play();
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
dropImage.dispose();
bucketImage.dispose();
//dropSound.dispose();
//rainMusic.dispose();
}
}
Here is source for Drop class
package com.mygdx.game;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class Drop extends Game {
SpriteBatch batch;
BitmapFont font;
public void create() {
batch = new SpriteBatch();
// Use LibGDX's default Arial font.
font = new BitmapFont();
this.setScreen(new MainMenuScreen(this));
}
public void render() {
super.render(); // important!
}
public void dispose() {
batch.dispose();
font.dispose();
}
}
Your analysis of the problem seems correct to me. The method Gdx.input.isTouched() will immediately return true, if the screen is still being touched after you changed to the main menu.
Also you the solution that you already tried seems correct:
I was intending to try implementing InputProcessor on each screen class
When using an InputProcessor you will get one event (the method call to touchDown or touchUp) when the screen is touched, and don't need to pull the touch event using the isTouched method.
A problem when implementing InputProcessor with both classes probably is, that you can only set one to be the input processor of the game using the method Gdx.input.setInputProcessor. (When setting the second input processor, the first one is removed).
A solution to this problem is the InputMultiplexer. You can add this multiplexer as the input processor of the game (using Gdx.input.setInputProcessor(multiplexer)) and then add your input processors (the main menu and game objects) to this multiplexer: multiplexer.addProcessor(mainMenu) or ((InputMultiplexer) Gdx.input.getInputProcessor()).addProcessor(game).
This way you can handle touch events instead of pulling the touched state in both of your classes.

My LibGDX slider won't slide

As goes without saying, I'm a complete novice and I'm not too sure what to do.
When I run my application, the slider simply won't slide. I've looked everywhere, and the closest I got was thinking it may be something to do with a knob but I have no idea what specifically. It may be worth noting that I'm using the default LibGDX UI files.
package com.angus;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Slider;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
public class Audio extends ApplicationAdapter {
Slider slider;
Skin skin;
Stage stage;
#Override
public void create () {
skin = new Skin(Gdx.files.internal("uiskin.json"));
stage = new Stage(new ScreenViewport());
slider = new Slider(0.00f, 10.00f, 1.00f, false, skin);
stage.addActor(slider);
System.out.println(slider.getStyle());
}
#Override
public void render () {
stage.draw();
}
#Override
public void dispose () {
}
}
Any help would be greatly appreciated! Thank you in advance.
I think this should help:
Gdx.input.setInputProcessor(stage);
This tells LibGDX to handle inputs from stage.
Extending icarumbas' answer, at the beginning of the render() method, you need to clear the screen.
Gdx.gl.glClearColor(red, blue, green, alpha);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
red, blue, green, alpha are all floats of 0-1. If you wanted to make the background color white, you would use: Gdx.gl.glClearColor(1f, 1f, 1f, 1f);
So render clears the screen then draws the slider.

libGDX font being drawn out of the viewport

I'm having problems to draw some text in the screen, and I found out that depending on the viewport size, the text may get out of the display despite being calculating the coordinates as the center of the screen. Here's the code, it is a just slightly modified project as created by libgdxgenerator by default:
package net.iberdroid.libgdxtestfonts;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
public class LibGdxTestFonts extends ApplicationAdapter {
SpriteBatch batch;
Texture img;
BitmapFont defaultFont;
private OrthographicCamera camera;
private Viewport viewport;
private float textY;
private float textX;
#Override
public void create() {
camera = new OrthographicCamera();
viewport = new FitViewport(
640,
480,
camera);
camera.setToOrtho(false);
batch = new SpriteBatch();
img = new Texture("badlogic.jpg");
defaultFont = new BitmapFont();
textX = viewport.getWorldWidth() / 2;
textY = viewport.getWorldHeight() / 2;
}
#Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.setProjectionMatrix(camera.combined);
defaultFont.setColor(Color.WHITE);
Gdx.app.log("render", String.format("TextX: %f TextY: %f", textX, textY));
defaultFont.draw(batch, "HELLO WORLD!", textX, textY);
batch.end();
}
#Override
public void dispose() {
batch.dispose();
img.dispose();
}
}
As far as I understand, that should draw a HELLO WORLD! text starting around the center of the screen. And it actually does it with that viewport size. Now, if you try with a bigger viewport, let's say 800x600, the text will move to the right and top, if try even with higher values, it will become a point in which the text will get out the boundaries of the screen by the top-right corner.
The same happens in the opposite direction. The smaller viewport you try, the further from the center and closer to the bottom-left corner the text will appear, until it eventually get out the boundaries too.
So either I am failing to grasp something here, or the BitMap.draw method seems to be ignoring the viewport size and using others that I cannot figure out.
If someone else does it, please, make me know.
Thanks a lot in advance!
P.S. I've tried also with a Hiero generated font and had the same issue.
Adding this seems to solve the problem with the position, though I still have a problem with the scale, but that's a different issue.
#Override public void resize (int width, int height) {
viewport.update(width, height, true);
}

Why isn't my clicklistener working?

Here is my code
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.viewport.FitViewport;
public class MainMenuScreen extends SpaceInvaderScreen {
SpriteBatch batch;
TextureRegion background;
Stage stage;
TextButton playbutton;
float time = 0;
public MainMenuScreen(Game game){
super(game);
}
#Override
public void show(){
batch = new SpriteBatch();
batch.getProjectionMatrix().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
background = new TextureRegion(new Texture("data/cool.jpg"), 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
stage = new Stage(new FitViewport(1280, 1080));
Skin uiskin = new Skin(Gdx.files.internal("data/skin/uiskin.json"));
playbutton = new TextButton("Play", uiskin);
playbutton.setWidth(200);
playbutton.setHeight(100);
playbutton.setPosition(980, 620);
playbutton.setBounds(playbutton.getX(), playbutton.getY(), playbutton.getWidth(), playbutton.getHeight());
playbutton.addListener( new ClickListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
game.setScreen( new GameScreen(game));
return true;
};
});
stage.addActor(playbutton);
Gdx.input.setInputProcessor(stage);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0.15f, 0.15f, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(background, 0, 0);
batch.end();
stage.act();
stage.draw();
time += delta;
}
#Override
public void hide(){
batch.dispose();
background.getTexture().dispose();
}
}
i'm not sure whats going on with the clicklistener as to why it doesn't work. I also tried using the touchDown method but it doesn't work either. Sorry if this sounds like a stupid question, im fairly new to the library
Just two things to try: I can see that you're building the button in the show method. Why? It makes much more sense to have a setup method and build the whole layout of the application / game / whatever in that setup method before showing anything. But this is just a shot in the dark, I don't know this framework you are using and I might be very well wrong.
Also another thing that might cause problems when you keep multiple instances of the same game! Watch out to build the game once and only once, and pass that single instance around. Why is that important? Because there might be a case that you are calling game.setScreen( new GameScreen(game)); but on the wrong instance!
Please post your SpaceInvaderScreen as well so it might be easier to debug it.
And anyway, have you tried debugging the touchDown method? Is it called at all?
Also two more things: ClickListener is a class. Not an interface. So when you are overriding the touchDown method, then you are basically bypassing the parent code in the superclass.
Try calling as the first line in the touchdown method:
super.touchDown(event, x, y, pointer, button);
Also the ClickListener documentation says:
when true is returned, the event is handled (...) This does not affect
event propagation inside scene2d, but causes the Stage event methods
to return true, which will eat the event so it is not passed on to the
application under the stage.
So you should try returning false;

Stage not being drawn

I'm pulling out my hair trying to figure out why this isn't working.
I'm just trying to put together a basic Options menu and for some reason the Stage doesn't seem to be drawing the actors.
I've tried putting the same actor creation code into another project with a working stage and it draws fine, and I've gone over both this and the working project with a fine tooth comb looking for anything I'm missing and as far as I can tell everything stage-related in the working code is in this one too, yet all I get with this OptionsScreen.java is a blank black screen.
Here's the java file in question, OptionsScreen.java
package com.kittykazoo.screens;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox;
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox.CheckBoxStyle;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.viewport.StretchViewport;
import com.kittykazoo.gamehelpers.ScreenHandler;
public class OptionsScreen implements Screen {
private ScreenHandler sh;
private Stage stage;
private Skin skin;
private OrthographicCamera cam;
private ShapeRenderer shapeRenderer;
private SpriteBatch batch;
private Label sfxVolValue;
private Label musicVolValue;
public OptionsScreen(ScreenHandler sh) {
Gdx.app.log("OptionsScreen", "Attached");
this.sh = sh;
cam = new OrthographicCamera();
cam.setToOrtho(true, 960, 600);
shapeRenderer = new ShapeRenderer();
shapeRenderer.setProjectionMatrix(cam.combined);
batch = new SpriteBatch();
batch.setProjectionMatrix(cam.combined);
stage = new Stage();
Gdx.input.setInputProcessor(stage);
createOptions();
}
private void createOptions() {
skin = new Skin();
Pixmap pixmap = new Pixmap(100, 100, Format.RGBA8888);
pixmap.setColor(Color.GREEN);
pixmap.fill();
skin.add("white", new Texture(pixmap));
BitmapFont bfont = new BitmapFont();
bfont.scale(1);
skin.add("default", bfont);
CheckBoxStyle checkBoxStyle = new CheckBoxStyle();
checkBoxStyle.checkboxOff = skin.newDrawable("white", Color.WHITE);
checkBoxStyle.checkboxOffDisabled = skin.newDrawable("white",
Color.DARK_GRAY);
checkBoxStyle.checkboxOn = skin.newDrawable("white", Color.WHITE);
checkBoxStyle.checkboxOnDisabled = skin.newDrawable("white",
Color.DARK_GRAY);
checkBoxStyle.checked = skin.newDrawable("white", Color.WHITE);
checkBoxStyle.font = skin.getFont("default");
skin.add("default", checkBoxStyle);
TextButtonStyle textButtonStyle = new TextButtonStyle();
textButtonStyle.up = skin.newDrawable("white", Color.DARK_GRAY);
textButtonStyle.down = skin.newDrawable("white", Color.DARK_GRAY);
textButtonStyle.checked = skin.newDrawable("white", Color.BLUE);
textButtonStyle.over = skin.newDrawable("white", Color.LIGHT_GRAY);
textButtonStyle.font = skin.getFont("default");
skin.add("default", textButtonStyle);
final CheckBox checkBox = new CheckBox("Checkbox here", checkBoxStyle);
checkBox.setPosition(100, 100);
stage.addActor(checkBox);
final TextButton textButton = new TextButton("UPDATE", textButtonStyle);
textButton.setPosition(200, 200);
stage.addActor(textButton);
textButton.addListener(new ChangeListener() {
public void changed(ChangeEvent event, Actor actor) {
textButton.setText("Submitting...");
sh.hideOptions();
}
});
}
#Override
public void render(float delta) {
// Black background
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
#Override
public void resize(int width, int height) {
Gdx.app.log("OptionsScreen", "resizing");
stage.setViewport(new StretchViewport(width, height));
}
#Override
public void show() {
Gdx.app.log("OptionsScreen", "show called");
}
#Override
public void hide() {
Gdx.app.log("OptionsScreen", "hide called");
}
#Override
public void pause() {
Gdx.app.log("OptionsScreen", "pause called");
}
#Override
public void resume() {
Gdx.app.log("OptionsScreen", "resume called");
}
#Override
public void dispose() {
stage.dispose();
skin.dispose();
}
}
I assume I must be missing something super obvious. If anyone can tell me where I'm going wrong I would be very grateful!
public void resize(int width, int height) {
stage.setViewport(new StretchViewport(width, height));
}
This is completely wrong in many ways. First of all, you do not want to create a new viewport on every resize, because of the Garbage Collector.
Furthermore creating a StretchViewport with the new screen width and height renders the StretchViewport useless, because it will basically behave like a ScreenViewport instead. Make sure to read the Viewports wiki article to understand how the different viewports work.
And last but not least, the reason why your stage is not drawn is also hidden within that. A UI Stage needs to have the camera centered, otherwise it won't be rendered correctly.
So what you want to do instead is the following:
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
}

Categories

Resources