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.
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 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 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!
I'm trying to get a png file to be pasted onto the screen as a backdrop for my game, so far I can't seem to get this to work and I'm not too sure.
I have created a map class and have it create the Texture like so:
public static Texture backgroundTexture;
public static Sprite backgroundSprite;
public Maps(){
try{
backgroundTexture = new Texture(Gdx.files.internal("background.png"));
backgroundSprite = new Sprite(backgroundTexture);
}catch (Exception e){
e.printStackTrace();
}
}
public void renderBackground(SpriteBatch batch){
batch.draw(backgroundTexture, 1000, 800);
}
Then in my main class I have it called like so in the create method:
batch = new SpriteBatch();
map = new Maps();
batch.begin();
map.renderBackground(batch);
batch.end();
But this doesn't work? Should it be in render method cos it needs to refresh the background each turn? I've tried it in render but still didn't work. My screen size is WXH 1000x800
Try this:
OrthographicCamera cam = new OrthographicCamera(1000, 800);
SpriteBatch batch = new SpriteBatch();
Maps map = new Maps();
in your render/update method:
batch.setProjectionMatrix(cam.combined);
batch.begin();
map.renderBackground(batch);
batch.end();
in your Maps render method:
batch.draw(backgroundTexture, 0, 0, 1000, 800); //x, y, width, height
I'm trying to create a game with LibGDX. My problem comes when I put the background in the screen that I have. I created a Base Screen (abstract) in order to make easier. In Desktop, the screen fits good, but in Android, trying different devices, the screen doesn't scale to full screen. I solved this situation using the next easy code:
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(texture, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch.end();
}
That was enough to see my game in full screen on android devices. Now, I want to use Scene2D(which I don't know so much...) So I create a Stage, I'm dealing with the background like an actor. Here's my code.
public class MenuScreen extends BaseScreen {
private FitViewport viewport;
private Stage stage;
private Image imageFondo, imagePrueba;
//private float escala;
public MenuScreen(MissingWords missingwords) {
super(missingwords);
}
#Override
public void show() {
//viewport = new StretchViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
viewport = new FitViewport(800, 480);
stage = new Stage(viewport, missingwords.getSB());
//Gdx.input.setInputProcessor(stage);
/* Crear fondo */
imageFondo = new Image(missingwords.getAM().get("fondo.png", Texture.class));
stage.addActor(imageFondo);
imagePrueba = new Image(missingwords.getAM().get("prueba.png", Texture.class));
imagePrueba.setPosition(50, 50);
stage.addActor(imagePrueba);
}
#Override
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
stage.draw();
}
#Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
}
However, it doesn't work and I don't know if I'm using the Viewports in the correct way. How can I write this line in order to be compatible with Scene 2D and support android devices?
batch.draw(texture, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Thanks in advance.
Finally I "solved" it using a ScalingViewport. Like this:
viewport = new ScalingViewport(Scaling.stretch, 800, 480);
Scaling.stretch as javadoc says: the world is scaled to take the whole screen. So, it doesn't keep the aspect ratio but for me is good. Maybe it looks wrong using large screens, but I'm still learning and I don't know if this is the best solution. So, I hope this helps someone.