How can add a drawing function to a button in libgdx? - java

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).

Related

How to create a main menu using libgdx and java

Ive been playing around with libgdx for the past couple of days and I wanted to see if someone could give a simple example of how a main menu screen is created with a start button and exit button.
LibGDX suggests to use its "scene2d" component if you need to build a UI.
The simplest example can be found on LibGDX's Wiki right in the article about scene2d:
https://libgdx.com/wiki/graphics/2d/scene2d/scene2d
Actually, the first code example from the wiki will do - it is a bit modified by me and shoud be added to your implementation of Screen or Game:
private Stage stage;
#Override
public void create () {
stage = new Stage(new ScreenViewport());
Gdx.input.setInputProcessor(stage);
// Insert your UI elements here, for example:
Skin skin = new Skin(Gdx.files.internal("skin.json")); // https://libgdx.com/wiki/graphics/2d/scene2d/skin
Table menuContainer = new Table();
TextButton playButton = new TextButton("Play", skin);
playButton.addListener(new ClickListener() {
#Override
public void clicked (InputEvent event, float x, float y) {
// Called when player clicks on Play button
}
});
menuContainer.add(playButton);
TextButton exitButton = new TextButton("Exit", skin);
exitButton.addListener(new ClickListener() {
#Override
public void clicked (InputEvent event, float x, float y) {
// Called when player clicks on Exit button
}
});
menuContainer.add(exitButton);
}
#Override
public void resize (int width, int height) {
// See below for what true means.
stage.getViewport().update(width, height, true);
}
#Override
public void render () {
float delta = Gdx.graphics.getDeltaTime();
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(delta);
stage.draw();
}
#Override
public void dispose () {
stage.dispose();
}

LibGDX Button not responding on touch

My first problem is that the textfield is not showing up and the second is that the button is not responding. My idea is when image 'vault1' is touched the textfield should show 5.
This is what I have come up with and I can't figure out what I am doing wrong.
(I have only cut out neseccary code)
public void render(float delta) {
drawSprite("vault1", 600, 450);
}
public void show() {
Gdx.input.setInputProcessor(stage);
skin = new Skin(Gdx.files.internal("ui/menuSkin.json"), new TextureAtlas("ui/atlas.pack"));
vaultInput = new TextField("", skin);
vaultInput.setPosition(300, 250);
vaultInput.setSize(300, 40);
vaultInput.setText(text2);
vault1Button = new Image(vault1);
vault1Button.addListener(new ClickListener() {
public boolean touchDown(InputEvent e, float x, float y, int point, int button) {
System.out.println("133");
vaultInput.setText(score);
return false;
}});
}
private void drawSprite(String name, float x, float y) {
Sprite sprite = textureAtlas.createSprite(name);
sprite.setPosition(x, y);
sprite.draw(batch);
vault1 = sprite;
}
It's hard to tell when you've left out code but you are adding the stage to the input processor:
Gdx.input.setInputProcessor(stage);
The stage and actors added to the stage is now the only things that responds to input. But you are never adding anything to the stage and neither drawing the stage, you are drawing your sprites seperately in the drawSprite method.
If you instead add your button to the stage all you need to do is call stage.draw():
public void render(float delta) {
stage.draw();
stage.act(delta);
}
public void show() {
Gdx.input.setInputProcessor(stage);
skin = new Skin(Gdx.files.internal("ui/menuSkin.json"), new TextureAtlas("ui/atlas.pack"));
vaultInput = new TextField("", skin);
vaultInput.setPosition(300, 250);
vaultInput.setSize(300, 40);
vaultInput.setText(text2);
vault1Button = new Image(vault1);
vault1Button = new Image(vault1);
vault1Button.addListener(new ClickListener() {
public boolean touchDown(InputEvent e, float x, float y, int point, int button) {
System.out.println("133");
vaultInput.setText(score);
return false;
}});
vaultInput.setPosition(x1, y1);
vault1Button.setPosition(x2, y2);
stage.addActor(vaultInput);
stage.addActor(vault1Button);
}
Everything added to the stage will be drawn when calling stage.draw()
The value of the vault1 field is still null when show() is called. So your actual button that you added your listener to has zero size and nothing to draw.
Also, since render() is called continuously in the game loop, you are creating new sprites to draw on every frame and reassigning the vault1 variable every frame.
You need to create your image for the button in show() and add the button to the stage. Then you only need to draw the stage.

LibGDX stage fading to black color

I have multiple screens with stages in my game and I have been implementing a simple fade transition between them.
It works now, but I want that the screen fades out to black. The clear color of the game is white, though, so only the stage is obviously faded out, and the background keeps white. I have tried adding Actions.color(Color.BLACK, Interpolation.fade) to the stage but nothing really happens at all.
How could I implement the fade transition correctly?
Stage doesn't have drawable content only a group that contains all children.
So create full Screen black Image and add to stage as background. Then inside show() that make it white by action, as your required background.
#Override
public void show() {
final Image image=new Image(new TextureRegion(GdxTest.getTexture()));
image.setSize(stage.getWidth(),stage.getHeight());
image.setOrigin(stage.getWidth()/2,stage.getHeight()/2);
image.setColor(Color.BLACK);
stage.addActor(image);
stage.addListener(new ClickListener(){
#Override
public void clicked(InputEvent event, float x, float y) {
image.addAction(Actions.sequence(Actions.color(Color.BLACK,2),Actions.run(new Runnable() {
#Override
public void run() {
((GdxTest)Gdx.app.getApplicationListener()).setScreen(new SecondScreen());
}
})));
super.clicked(event, x, y);
}
});
image.addAction(Actions.color(Color.WHITE,2));
}
getTexture() method
public static Texture getTexture(){
Pixmap pixmap;
try {
pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
}catch (GdxRuntimeException e)
{
pixmap=new Pixmap(1,1, Pixmap.Format.RGB565);
}
pixmap.setColor(Color.WHITE);
pixmap.drawRectangle(0,0,1,1);
return new Texture(pixmap);
}

Two different textbutton are not responding on LibGDX

public class GameScreen implements Screen {
public void show()
{
buttonsAtlas = new TextureAtlas("Color.pack"); //button atlas image
buttonSkin = new Skin();
buttonSkin.addRegions(buttonsAtlas);
font = new BitmapFont(Gdx.files.internal("CustomFont.fnt"), false); //the font
stage = new Stage(); // window is stage
stage.clear();
TextButton.TextButtonStyle style = new TextButton.TextButtonStyle(); // button properties
style.up = buttonSkin.getDrawable("Red");
style.down = buttonSkin.getDrawable("Blue");
style.font = font;
gameButton = new TextButton("Game Screen", style); //button text and style
gameButton.setPosition(-250, 500); //button location
gameButton.setHeight(600); //button height
gameButton.setWidth(1200); //button width
shopButton = new TextButton("Shop Menuuuu", style); //button text and style
shopButton.setPosition(100, 500); //button location
shopButton.setHeight(600); //button height
shopButton.setWidth(1200); //button width
stage.addActor(shopButton);
stage.addActor(gameButton);
Gdx.input.setInputProcessor(stage);
gameButton.addListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
gameButton.setBounds(-250, 500, 100, 100);
Gdx.app.log("my app,", "pressed");
game.setScreen(new inGame(game));
return true;
}
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.log("my app", "released");
}
});
shopButton.addListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
shopButton.setBounds(100, 500, 100, 100);
Gdx.app.log("my app,", "pressed");
game.setScreen(new Shop(game));
return true;
}
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.log("my app", "released");
}
});
}
public void render(float x)
{
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
game.batch.begin();
stage.draw();
game.batch.end();
}
public void dispose()
{
batch.dispose();
buttonSkin.dispose();
buttonsAtlas.dispose();
stage.dispose();
}
I am trying to make two TextButtons to work at the same time. However there is always one button showing on the screen, which is the last button that was being added to the stage. In this case it is the gameButton because it is the last button that was added to the stage.
How do I make both button work?
There is no point in setting negative Coordinate, may be you need to understand Coordinate systems for game:
o,o is at bottom left corner of screen
so when you give negative value, that part is not being displayed.
so two images are overlapping in your case and stage gives z index to actors and object which is added last will have highest z index, that means last added object will be draws on top of others.
What you need to do:
gameButton.setPosition(0, 0); //x,y --absolute to bottom left corner
gameButton.setSize(200,200); //width, height
shopButton.setPosition(200, 0); //x,y --absolute to bottom left corner
shopButton.setSize(200,200); //width, height
also doing setbound inside actionlistner is not good idea

Libgdx adding a UI button separated from the gamescreen

I've got a GameScreen where I have 100 "dots" randomly bounce around the screen. I'm currently adding a UI button in order to rotate the screen; one on the left and one on the right. The button works, however, the button is "linked" to the camera because as the screen rotates (the playing field for the dots spins because the camera rotates), the button rotates with it. I want the button(s) to be fixed to the device screen, and not rotate with the underlying field of dots.
Do I have to unproject the button somehow, or create a separate stage for any UI elements (buttons, statusbar title alone the top, etc)? Many thanks.
Here's my code:
public class GameScreen implements Screen {
final jGdxDots game;
final MyGestureListener myGestureListener;
OrthographicCamera camera;
private Skin skin;
final int NUMBER_OF_DOTS = 100;
int dotTotal;
private Stage stage;
FPSLogger fpsLogger;
float cameraRotate = 0f;
public GameScreen(final jGdxDots gam) {
this.game = gam;
fpsLogger = new FPSLogger();
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480); //boolean = YDOWN or YUP axis.
//create stage
stage = new Stage(Gdx.graphics.getWidth(),Gdx.graphics.getHeight(),true);
//set stage to handle the inputs
//Gdx.input.setInputProcessor(stage);
stage.setCamera(camera);
//stage.setViewport(800, 480, true);
//multiplex the gesture listeners (both for stage and my listener)
myGestureListener = new MyGestureListener();
GestureDetector gd = new GestureDetector(myGestureListener);
InputMultiplexer im = new InputMultiplexer(gd, stage); // Order matters here!
Gdx.input.setInputProcessor(im);
//UI button
skin = new Skin(Gdx.files.internal("data/uiskin.json"));
final TextButton button = new TextButton("Rotate", skin, "default");
button.setWidth(100f); //200f
button.setHeight(100f); //20f
button.setPosition(10f, 10f);
button.addListener(new ClickListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
// TODO Auto-generated method stub
cameraRotate = 1f;
return super.touchDown(event, x, y, pointer, button);
}
#Override
public void touchUp(InputEvent event, float x, float y,
int pointer, int button) {
// TODO Auto-generated method stub
super.touchUp(event, x, y, pointer, button);
cameraRotate = 0f;
}
});
stage.addActor(button);
spawnDots(stage);
}
private void spawnDots(Stage theStage) {
//Rectangle raindrop = new Rectangle();
for (int i=0; i < NUMBER_OF_DOTS; i++) {
DotActor dot = new DotActor();
dot.setOrigin(8,8); //(dot.getWidth()/2, dot.getHeight()/2);
dot.vector.set(MathUtils.random(1,4), MathUtils.random(1,4));
dot.actorX = MathUtils.random(0, 800 - dot.getWidth());
dot.actorY = MathUtils.random(0, 480 - dot.getHeight());
stage.addActor(dot);
}
dotTotal = NUMBER_OF_DOTS;
}
#Override
public void dispose() {
stage.dispose();
}
#Override
public void render(float delta) {
//clear screen
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
//logger
fpsLogger.log();
//camera.zoom += 0.005f;
camera.rotate(cameraRotate); //(1.0f);
camera.update();
//run act() method of each actor
stage.act(Gdx.graphics.getDeltaTime());
//run each actor's draw() method who are members of this stage
stage.draw();
}
}
I had this problem too. Create a separate stage, or you might just want to draw directly with a sprite batch in a 'renderer' class
Mine looks something like this:
public OverlayRenderer()
{
this.spriteBatch = new SpriteBatch();
this.loadTextures();
}
public void render(String _message)
{
this.spriteBatch.begin();
this.spriteBatch.draw(TEXTURES.UI, 0, 0);
....
}
and directly after your
stage.draw();
line, I would add
overLayRenderer.render();

Categories

Resources