I am trying to create a stage where i am going to draw Textbuttons on.
I can launch the program fine without any errors. But there is no textbuttons that appear.
The issue might be that i cannot set the size of the stage i am using.
Here is the code for the initializing:
#Override
public void resize(int width, int height)
{
if(stage == null)
stage = new Stage();
stage.clear();
Gdx.input.setInputProcessor(stage);
TextButtonStyle style = new TextButtonStyle();
style.up = skin.getDrawable("Button");
style.down = skin.getDrawable("Button");
style.font = buttonFont;
startGameBtn = new TextButton("Start Game", style);
startGameBtn.setWidth(300);
startGameBtn.setHeight(150);
startGameBtn.setX(Gdx.graphics.getWidth() / 2 - startGameBtn.getWidth() / 2);
startGameBtn.setY((float) (Gdx.graphics.getHeight() / 1.5));
startGameBtn.addListener(new InputListener()
{
});
stage.addActor(startGameBtn);
}
And here is where i draw the button:
public void render(float delta)
{
Gdx.gl20.glClearColor(0, 0, 0, 1);
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(delta);
sb.begin();
stage.draw();
sb.end();
}
Thank you for any help! :)
Solved problem!
I accidently had a black background and a black button so it was actually drawing it, i just couldn't see it.
Cheers!
Related
I am using this stage that contains a dialog as a simple menu. It is working correctly, but when I try to make it bigger by increasing dialog size it just scales in a really bad way. What can i do?
public Menu()
{
skin = new Skin(Gdx.files.internal("rusty-robot/skin/rusty-robot-ui.json"));
stage=new Stage();
Dialog dialog=new Dialog("Choose the number of players",skin);
Button button= new Button(skin);
dialog.setSize(630, 450);
dialog.setPosition(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2, Align.center);
final SelectBox<String> selectBox=new SelectBox<String>(skin);
selectBox.setItems("Two Players","Three Players","Four Players","Five Players","Six Players");
Game.isMenu=true;
//dialog.getContentTable().defaults().pad(10);
dialog.getContentTable().add(selectBox);
dialog.getButtonTable().add(button);
stage.addActor(dialog);
Gdx.input.setInputProcessor(stage);
...button listeners..
public void draw()
{
stage.act();
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.draw();
}
I have a problem with size of ImageButton(s), buttons are not strectched/scaled because screen size of device its 1920x1080 and button picture is 342x129. (it is viewed smaller than original picture seems).
When I draw it through this game.batch.draw(playBtn, ...);
It works fine, but I need ImageButtons. What is wrong ?
Note: WIDTH = 480, HEIGHT = 800
picture: https://imgur.com/IJs4uPB
public MenuScreen(PlumberGame game) {
this.game = game;
camera = new OrthographicCamera();
viewport = new FitViewport(WIDTH,HEIGHT, camera);
stage =new Stage(viewport, spriteBatch);
background = new Texture("background.png");
title = new Texture("title.png");
camera.setToOrtho(false, WIDTH, HEIGHT);
}
#Override
public void show() {
stage = new Stage(); //Set up a stage for the ui
Gdx.input.setInputProcessor(stage); //Start taking input from the ui
atlas = new TextureAtlas("ui/buttons.pack");
skin = new Skin(atlas);
table = new Table(skin);
table.setBounds(0,0, WIDTH, HEIGHT);
ImageButton.ImageButtonStyle playBtnStyle = new ImageButton.ImageButtonStyle();
playBtnStyle.up = skin.getDrawable("playBtn");
playBtnStyle.down = skin.getDrawable("playBtnOn");
playBtn = new ImageButton(playBtnStyle);
playBtn.setSize(playBtn.getWidth(), playBtn.getHeight());
playBtn.getImage().setScaling(Scaling.fit);
playBtn.invalidateHierarchy();
playBtn.setPosition((float)(WIDTH * 0.15 ), (float) (HEIGHT * 0.5));
stage.addActor(playBtn);
}
#Override
public void render(float delta) {
stage.getBatch().setProjectionMatrix(camera.combined);
renderer.setProjectionMatrix(stage.getBatch().getProjectionMatrix());
renderer.setTransformMatrix(stage.getBatch().getTransformMatrix());
renderer.translate(WIDTH, HEIGHT, 0);
stage.act(Gdx.graphics.getDeltaTime()); //Perform ui logic
stage.getBatch().begin();
stage.getBatch().draw(background, 0, 0, WIDTH,HEIGHT);
stage.getBatch().draw(title, (float)(WIDTH * 0.12), (float) (HEIGHT * 0.75));
stage.getBatch().end();
stage.draw(); //Draw the ui
}
#Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
table.invalidateHierarchy();
table.setSize(width, height);
camera.update();
}
You are setting playBtn size wrong way.
This line doesn't make sense:
playBtn.setSize(playBtn.getWidth(), playBtn.getHeight());
I would recommend using Table which is really convinient when designing UIs. You specify the size of the actor when adding it to the table.
I can't try it out now since I'm not at home but it would look something like:
#Override
public void show() {
stage = new Stage(); //Set up a stage for the ui
Gdx.input.setInputProcessor(stage); //Start taking input from the ui
atlas = new TextureAtlas("ui/buttons.pack");
skin = new Skin(atlas);
table = new Table(skin);
table.setBounds(0,0, WIDTH, HEIGHT);
ImageButton.ImageButtonStyle playBtnStyle = new ImageButton.ImageButtonStyle();
playBtnStyle.up = skin.getDrawable("playBtn");
playBtnStyle.down = skin.getDrawable("playBtnOn");
playBtn = new ImageButton(playBtnStyle);
playBtn.setPosition((float)(WIDTH * 0.15 ), (float) (HEIGHT * 0.5));
Table table = new Table();
table.setFillParent(true);
table.add(playBtn).expand().fillX().height(yourHeight);
stage.addActor(table);
}
EDIT:
Another alternative is to set min size of the drawables you put in the image button style:
ImageButton.ImageButtonStyle playBtnStyle = new ImageButton.ImageButtonStyle();
playBtnStyle.up = skin.getDrawable("playBtn");
playBtnStyle.down = skin.getDrawable("playBtnOn");
playBtnStyle.up.setMinWidth(yourWidth);
playBtnStyle.up.setMinHeight(yourHeight);
playBtnStyle.down.setMinWidth(yourWidth);
playBtnStyle.down.setMinHeight(yourHeight);
I have a GameScreen with a SpriteBatch to draw all my textures on, but I want to add a pause button on the screen now. I've tried to use a stage on top of my SpriteBatch, but for some reason it won't show up.
Here's some of the code:
The constructor:
public GameScreen(MyGame game) {
stage = new Stage();
table = new Table();
pause_texture = new Texture("path_to_texture.png");
pause_image = new Image(pause_texture);
pause_image.setPosition(1920 - pause_image.getWidth() - 20, 20);
table.add(pause_image);
stage.addActor(table);
}
The render method:
public void render(float delta) {
Gdx.gl.glClearColor(1f, 1f, 1f, 1f);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
stage.act(delta);
stage.draw();
game.camera.update();
game.batch.setProjectionMatrix(game.camera.combined);
game.batch.begin();
//rendering stuff here
game.batch.end();
}
What am I doing wrong?
Don't use absolute positions on a Table, just do something like this:
public GameScreen(MyGame game){
stage = new Stage();
table = new Table();
pause_texture = new Texture("path_to_texture.png");
pause_image = new Image(pause_texture);
table.add(pause_image);
table.bottom().right();
stage.addActor(table);
}
For further reference look at Table on the Libgdx Wiki
Don't forget to move stage.act(delta); and stage.draw(); to after batch.end(), the GUI is the last thing that should be rendered so it can be in the front of everything.
I am using Screen-2D to build a button. I want give the button a function when it is click a sprite will be drawn how can i do this. This isn't all all my code but enough to show what am talking about.
public void create () {
buttonStyle = new TextButtonStyle();
buttonStyle.up = skin.getDrawable("button");
buttonStyle.over = skin.getDrawable("buttonpressed");
buttonStyle.down = skin.getDrawable("buttonpressed");
buttonStyle.font = font;
button = new TextButton("START", buttonStyle);
stage.addActor(button);
Gdx.input.setInputProcessor(stage);
button.addListener(new InputListener() {
#Override
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
drawTile(200,50);
return true;
}
});
}
// method used to draw a sprite when passing certain coordinates
public void drawTile(int x , int y) {
spriteBatch.draw(sprite, x , y );
}
public void render () {
Gdx.gl.glClearColor(1f, 0f, 0f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
spriteBatch.begin();
spriteBatch.draw(background, 0, 0);
drawGrid();
spriteBatch.draw(startButton, 0, 0);
stage.draw();
spriteBatch.end()
}
You got the right idea. See this example:
button.addListener(new ChangeListener() {
#Override
public void changed (ChangeEvent event, Actor actor) {
drawTile(200,50);
}
});
https://github.com/libgdx/libgdx/wiki/Scene2d.ui#changeevents
I think you need to read more tutorials about how LibGDX and Scene2D works : Event processing is done before your render method, so any drawing will be erased when you clear screen.
A right approach would be to add a sprite (as Drawable) to a widget group when click firing. Then stage rendering will renderer all your component including your sprites.
Comparaing to MVC pattern : The stage is your model, you modifiy your model when events occurs and the render method is the view of your model (draw your model).
I'm writing a new program in LibGDX handling Backgroundtextures and have just begun to implement the screens. But when I test it, it just shows me a black cleared screen with the given resolution.
I call the screen with the setScreen(screen)- Method in an implemented Game class.
So here is the code:
public class MenuScreen implements Screen{
Table table;
Stage stage;
TextButton button;
TextField textField;
Texture texture;
Pic2Box2d game;
public MenuScreen(Pic2Box2d gameH)
{
this.game = gameH;
stage = new Stage(0, 0, true);
table = new Table();
}
public void create()
{
final TextFieldStyle fieldStyle = new TextFieldStyle(new BitmapFont(), Color.WHITE, new BitmapFont(), Color.GRAY, null, null, null);
textField = new TextField("path", fieldStyle);
final TextButtonStyle buttonStyle = new TextButtonStyle();
buttonStyle.font = new BitmapFont();
buttonStyle.fontColor = Color.WHITE;
buttonStyle.pressedOffsetY = 1f;
buttonStyle.downFontColor = new Color(0.8f, 0.8f, 0.8f, 1f);
button = new TextButton("Übernehmen", buttonStyle);
button.setClickListener(new ClickListener() {
#Override
public void click(Actor actor, float x, float y) {
if(textField.getText() != "" && textField.getText() != "path")
{
texture = new Texture(textField.getText());
game.setScreen(new Workscreen(texture));
}
}
});
table.row();
table.add(textField);
table.add(button);
stage.addActor(table);
}
#Override
public void render(float delta) {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
Gdx.gl.glClearColor(0, 0, 0, 1);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
}
#idaNakav is correct about using show() and setting the Stage dimensions. However, that will still give you a black screen because your table doesn't have any size. Try changing your show() code to include table.setFillParent(true).
It should look something like this (code based on the example that you provided).
#Override
public void show() {
final TextFieldStyle fieldStyle = new TextFieldStyle(new BitmapFont(), Color.WHITE, null, null, null);
textField = new TextField("path", fieldStyle);
final TextButtonStyle buttonStyle = new TextButtonStyle();
buttonStyle.font = new BitmapFont();
buttonStyle.fontColor = Color.WHITE;
buttonStyle.pressedOffsetY = 1f;
buttonStyle.downFontColor = new Color(0.8f, 0.8f, 0.8f, 1f);
button = new TextButton("Übernehmen", buttonStyle);
button.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
if (textField.getText() != "" && textField.getText() != "path") {
texture = new Texture(textField.getText());
game.setScreen(new Workscreen(texture));
}
}
});
table.row();
table.add(textField);
table.add(button);
// Make the table fill the stage.
table.setFillParent(true);
stage.addActor(table);
}
When screen is becoming the current screen show method is called (not create like in your case), try changing your create method to show
also you are init the stage wrong , you should send it width and height , you sent 0,0
try something like
stage = new Stage(Gdx.graphics.getWidth(),Gdx.graphics.getHeight(),false);