I am using the libgdx scene2d.ui library to create a stage and a table as the Actor. I have created a FitViewport using final variables for the width and height. I am also using the FillViewports OrthographicCamera. when I run debug on my table the Widgets cells are mirrored to the rest of the cells.
I have read the documentation and the wiki on scene2d.ui and as much as I can find on widgets, tables, stages and nothing relating to my issue. I thought maybe it was a scaling thing like if the widgets were larger then the cell bounds but I've scaled the widgets down with minWidth and perfWidth nothing changes. I've tried different view ports, tried a separate Orthographic camera and tried different skins all resulting in the same thing and its like this on all my screens
[
]
everything seems to be working correctly but my OCD is driving me nuts over this. if anyone could give me some incite that would be awesome. or just tell me that its a glitch in the matrix and its not going to cause issues down the road and to move on with my coding.
This is my gameScreen Manager code
package com.armadillo.game.screens;
import com.armadillo.game.Arma;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
public class GameScreenManager {
private Arma game;
//viewport variables
protected Viewport screensViewport;
protected Viewport playViewport;
//screen variables
private LoadingScreen loadingScreen;
private MenuScreen menuScreen;
private PlayScreen playScreen;
private OptionsScreen optionsScreen;
private HighScoreScreen highScoreScreen;
private PauseScreen pauseScreen;
private GameOverScreen gameoverScreen;
//screen switch values
public final static int MENU = 0;
public final static int PLAY = 1;
public final static int OPTIONS = 2;
public final static int HIGH_SCORE = 3;
public final static int PAUSE = 4;
public final static int GAMEOVER = 5;
public GameScreenManager(Arma game) {
this.game = game;
//create and apply viewport with a OrthographicCamera centered to the viewport
screensViewport = new FitViewport(Arma.GAME_WORLD_WIDTH , Arma.GAME_WORLD_HEIGHT );
screensViewport.apply(true);
//create, set and initiate the screen to loadingScreen
loadingScreen = new LoadingScreen(this.game, this);
this.game.setScreen(loadingScreen);
}
//method used to switch states of screens
public void changeScreen(int screen) {
switch (screen) {
case MENU:
if (menuScreen == null)
menuScreen = new MenuScreen(this.game, this);
this.game.setScreen(menuScreen);
break;
case PLAY:
if (playScreen == null)
playScreen = new PlayScreen(this.game, this);
this.game.setScreen(playScreen);
break;
case OPTIONS:
if (optionsScreen == null)
optionsScreen = new OptionsScreen(this.game, this);
this.game.setScreen(optionsScreen);
break;
case HIGH_SCORE:
if (highScoreScreen == null)
highScoreScreen = new HighScoreScreen(this.game, this);
this.game.setScreen(highScoreScreen);
break;
case PAUSE:
if (pauseScreen == null)
pauseScreen = new PauseScreen(this.game, this);
this.game.setScreen(pauseScreen);
break;
case GAMEOVER:
if (gameoverScreen == null)
gameoverScreen = new GameOverScreen(this.game, this);
this.game.setScreen(gameoverScreen);
break;
}
}
}
this is my Options Screen code
package com.armadillo.game.screens;
import com.armadillo.game.Arma;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Event;
import com.badlogic.gdx.scenes.scene2d.EventListener;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.*;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
public class OptionsScreen implements Screen {
//passed through variables
private Arma game;
private GameScreenManager gsm;
//screen layout variables
private Stage stage;
private Table table;
private Skin skin;
private TextButton mainMenu;
//Label variables
private Label titleLabel;
private Label volumeMusicLabel;
private Label musicEnabledLabel;
private Label volumeSoundLabel;
private Label soundEnabledLabel;
//slider and CheckBox variables
private final Slider musicVolSlider;
private final Slider soundVolSlider;
private final CheckBox musicCheckBox;
private final CheckBox soundCheckBox;
public OptionsScreen(Arma game, GameScreenManager gsm) {
this.game = game;
this.gsm = gsm;
//create the stage using screenViewport parameters
stage = new Stage(gsm.screensViewport);
table = new Table();
table.top();
table.setDebug(true);
stage.addActor(table);
//create the skin that will used for layout design
skin = new Skin(Gdx.files.internal("skin/neon-ui2.json"));
//create labels
titleLabel = new Label("Options", skin);
volumeMusicLabel = new Label("Music Volume", skin);
musicEnabledLabel = new Label("Music", skin);
volumeSoundLabel = new Label("Sound Volume", skin);
soundEnabledLabel = new Label("Sound", skin);
mainMenu = new TextButton("Main Menu", skin);
//create and set Music and sound slider to adjust volume of the music
musicVolSlider = new Slider(0, 1, 0.1f, false, skin);
musicVolSlider.setValue(game.getOptions().getMusicVolume());
soundVolSlider = new Slider(0, 1, 0.1f, false, skin);
soundVolSlider.setValue(game.getOptions().getSoundVolume());
//create and set music and sound CheckBox to controll music on and off
musicCheckBox = new CheckBox("ON/OFF", skin);
musicCheckBox.setChecked(game.getOptions().isMusicEnabled());
soundCheckBox = new CheckBox("ON/OFF", skin);
soundCheckBox.setChecked(game.getOptions().isSoundEnabled());
//sets the table size to its parent which is the stage
table.setFillParent(true);
//add labels sliders and checkBox's to table
table.add(titleLabel);
table.row();
table.add(musicEnabledLabel);
table.add(musicCheckBox);
table.row();
table.add(volumeMusicLabel);
table.add(musicVolSlider);
table.row();
table.add(soundEnabledLabel);
table.add(soundCheckBox);
table.row();
table.add(volumeSoundLabel);
table.add(soundVolSlider);
table.row();
table.add(mainMenu).size(320, 60);
}
@Override
public void show() {
//set the stage to accept input
Gdx.input.setInputProcessor(stage);
//takes input from user and activates skin changes
mainMenu.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
gsm.changeScreen(gsm.MENU);
}
});
//an input from user to register sliders and checkboxes
musicVolSlider.addListener(new EventListener() {
@Override
public boolean handle(Event event) {
game.getOptions().setMusicVol(musicVolSlider.getValue());
return false;
}
});
soundVolSlider.addListener(new EventListener() {
@Override
public boolean handle(Event event) {
game.getOptions().setSoundVol(soundVolSlider.getValue());
return false;
}
});
musicCheckBox.addListener(new EventListener() {
@Override
public boolean handle(Event event) {
boolean enabled = musicCheckBox.isChecked();
game.getOptions().setMusicEnabled(enabled);
return false;
}
});
musicCheckBox.addListener(new EventListener() {
@Override
public boolean handle(Event event) {
boolean enabled = soundCheckBox.isChecked();
game.getOptions().setSoundEnabled(enabled);
return false;
}
});
}
@Override
public void render(float delta) {
//sets background color and clears screen
Gdx.gl.glClearColor(0, .1f, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//draws the stage and all its components
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
@Override
public void resize(int width, int height) {
//updates viewport and camera adjusting sizes locally
stage.getViewport().update(width, height, true);
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void hide() {
}
@Override
public void dispose() {
//dispose of the stage helps with memory leaks and garbage collection
stage.dispose();
}
}
and this is my main class Arma
package com.armadillo.game;
import com.armadillo.game.screens.*;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.audio.Music;
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;
public class Arma extends Game {
//the game world size
public static final int GAME_WORLD_WIDTH = 1600;
public static final int GAME_WORLD_HEIGHT = 900;
//assetmanger for music sound
public static AssetManager manager;
//Options object used to access option preferences
private GameOptions options;
//entity variables
public SpriteBatch batch;
public BitmapFont font;
public OrthographicCamera camera;
public Texture img;
private Music music;
@Override
public void create() {
//create entities
batch = new SpriteBatch();
font = new BitmapFont();
manager = new AssetManager();
options = new GameOptions();
manager.load("audio/music.wav", Music.class);
manager.finishLoading();
music = manager.get("audio/music.wav", Music.class);
//create and initiate the GameScreenManager
GameScreenManager gsm = new GameScreenManager(this);
}
public GameOptions getOptions() {
return this.options;
}
@Override
public void render() {
super.render();
//constantly check audio options
music.setVolume(options.getMusicVolume());
if (options.isMusicEnabled()) {
music.play();
} else if (!options.isMusicEnabled()){
music.stop();
}
}
@Override
public void dispose() {
//dispose of the stage, batch and manager. helps with memory leaks and garbage collection
batch.dispose();
music.dispose();
manager.dispose();
}
}
This has been fixed in LibGDX v1.10.0 (based on my testing). I don't see relevant information in the changelog; probably was too minor to bother mentioning? Or just incidentally cleaned up somehow.
https://libgdx.com/news/2021/04/gdx-1-10