LibGDX: ImageButton clicklistener not working - libgdx

This is my code:
Gdx.input.setInputProcessor(this);
bagImage = new Image(new Texture("bag.png"));
bagButton = new ImageButton(bagImage.getDrawable());
bagButton.setSize(125, 125);
bagButton.addListener(new ClickListener() {
public void clicked(InputEvent event, float x, float y) {
Gdx.app.debug("DEBUG", "clicked");
}
});
}
If I click on the button nothing happens. Why?

You should have stage and add ImageButton to this stage then setInputProcessor to this stage and you can use only Image instead of ImageButton since you don't use imageUp, imageDown.....
you code should be like this :
Stage stage = new Stage();
Gdx.input.setInputProcessor(stage);
bagImage = new Image(new Texture("bag.png"));
bagImage.setSize(125, 125);
stage.addActor(bagImage);
bagImage.addListener(new ClickListener() {
public void clicked(InputEvent event, float x, float y){
Gdx.app.debug("DEBUG", "clicked");
}
});
#Override
public void render(float delta) {
stage.act(delta);
stage.draw();
}

Related

libgdx isometric tiled map screen to world with viewport

I wanted to create a simple 30x30 isometric tiled map and add a listener to be able to click on the tiles. I looked up a lot of the articles and posts here but none of them helped me.
My issue is, i have a viewport, 30x17, a camera, a stage and a tiled map with tileWidth = 32 and tileHeight = 16 pixels.
Now when i render the tiled map it looks fine.
When i click on stage and try to get the world coordinates i see some really weird coordinates.
This is the code:
private static final float TILE_WIDTH = 32;
private static final float TILE_HEIGHT = 16;
private OrthographicCamera camera;
private Viewport viewport;
private Stage stage;
private IsometricTiledMapRenderer isometricTiledMapRenderer;
private Matrix4 isoTransform;
private Matrix4 invIsotransform;
public void load(AssetManagerLoaderV2 assetManagerLoader) {
assetManagerLoader.load();
init();
camera = new OrthographicCamera();
viewport = new FitViewport(30, 17, camera);
stage = new Stage(viewport);
TiledMap tiledMap = new TiledMapGenerator(assetManagerLoader).generate(30, 30);
isometricTiledMapRenderer = new IsometricTiledMapRenderer(tiledMap, 1/32f);
stage.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
System.out.println(screenToCell(x, y));
return true;
}
});
}
#Override
public void show() {
Gdx.input.setInputProcessor(stage);
}
#Override
public void render(float delta) {
DrawUtils.clearScreen();
viewport.apply();
isometricTiledMapRenderer.setView(camera);
isometricTiledMapRenderer.render();
}
#Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
isometricTiledMapRenderer.dispose();
stage.dispose();
}
public void init () {
//create the isometric transform
isoTransform = new Matrix4();
isoTransform.idt();
isoTransform.translate(0.0f, 0.25f, 0.0f);
isoTransform.scale((float)(Math.sqrt(2.0) / 2.0), (float)(Math.sqrt(2.0) / 4.0), 1.0f);
isoTransform.rotate(0.0f, 0.0f, 1.0f, -45.0f);
//... and the inverse matrix
invIsotransform = new Matrix4(isoTransform);
invIsotransform.inv();
}
public Vector2 worldToCell(float x, float y) {
float halfTileWidth = TILE_WIDTH * 0.5f;
float halfTileHeight = TILE_HEIGHT * 0.5f;
float row = (1.0f/2) * (x/halfTileWidth + y/halfTileHeight);
float col = (1.0f/2) * (x/halfTileWidth - y/halfTileHeight);
return new Vector2((int)col,(int)row);
}
public Vector2 screenToWorld(float x, float y){
Vector3 touch = new Vector3(x,y,0);
camera.unproject(touch);
touch.mul(invIsotransform);
touch.mul(isoTransform);
return new Vector2(touch.x,touch.y);
}
public Vector2 screenToCell(float x, float y) {
Vector2 world = screenToWorld(x,y);
world.y -= TILE_HEIGHT *0.5f;
return worldToCell(world.x,world.y);
}
Does anyone have an idea how to write worldToCell to get the proper coordinates?
I found the issue, i was missing one step.
This is what touchDown should look like:
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
Vector2 newCoords = stage.stageToScreenCoordinates(new Vector2(x, y));
System.out.println(screenToCell(newCoords.x, newCoords.y));
return true;
}
I need to convert stage coordinates to screen coordinates, now this code is working.

BitmapFont animation in Libgdx scene2d Actor

I am trying to animate an actor which contain a simple message written with bitmapfont using fadeIn action but it doesn't work.
Here is my code.
public class Message extends Actor{
BitmapFont font;
String message;
float x, y;
public Message(BitmapFont font, String message, float x, float y) {
this.font = font;
this.message = message;
this.x = x;
this.y = y;
}
#Override
public void draw(Batch batch, float parentAlpha) {
Color color = getColor();
batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
font.setColor(color.r, color.g, color.b, color.a * parentAlpha);
font.draw(batch, message, x, y);
}
}
Then when clicking a button the message should appear but it is only appear without animation.
button.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
BitmapFont font = new BitmapFont(Gdx.files.internal("myfont.font"));
Message message = new Message(font, "Tap Here", 100, 20);
stage.addActor(message);
message.addAction(Actions.fadeIn(5));
}});
Other actors animations on the same stage work fine as I'm calling:
stage.act(delta);
stage.draw();
You should set message actor's alpha to zero before adding the fadeIn action:
button.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
BitmapFont font = new
BitmapFont(Gdx.files.internal("myfont.font"));
Message message = new Message(font, "Tap Here", 100, 20);
message.getColor().a = 0f; // add this line
stage.addActor(message);
message.addAction(Actions.fadeIn(5));
}});

libGDX 1.4.1 button listener on a secondary screen

I have two screens, a MainActivity in my core folder, that has the render() method split into a few switch cases. On game-over, this part of the switch case gets triggered, which calls the render part of my game-over class:
case STOPPED:
// Exit and clean the game
gameOverScreen.render(Gdx.graphics.getDeltaTime());
break;
...
This is my GameOverScreen class:
public class GameOverScreen implements Screen {
private SpriteBatch gameOverBatch;
private FreeTypeFontGenerator gameOverFontGen;
private FreeTypeFontGenerator.FreeTypeFontParameter gameOverLogoParam;
private FreeTypeFontGenerator.FreeTypeFontParameter gameOverButtonParam;
private final MainActivity mainActivity;
private OrthographicCamera camera;
private BitmapFont bitmapLogoFont;
private BitmapFont bitmapButtonFont;
private Button exitGameButton;
private Button gameRestartButton;
private Sound buttonSound;
private Stage stage;
private float w;
private float h;
// Constructor
public GameOverScreen(MainActivity mainActivity) {
w = Gdx.graphics.getWidth();
h = Gdx.graphics.getHeight();
gameOverBatch = new SpriteBatch();
this.mainActivity = mainActivity;
camera = new OrthographicCamera();
camera.setToOrtho(false, 300, 300);
// Instantiate the font for this screen from file
gameOverFontGen = new FreeTypeFontGenerator(Gdx.files.internal("fonts/SF_Wonder_Comic.ttf"));
gameOverLogoParam = new FreeTypeFontGenerator.FreeTypeFontParameter();
gameOverLogoParam.size = 110;
gameOverButtonParam = new FreeTypeFontGenerator.FreeTypeFontParameter();
gameOverButtonParam.size = 40;
// Font for the logo
bitmapLogoFont = new BitmapFont();
bitmapLogoFont = gameOverFontGen.generateFont(gameOverLogoParam);
// Font for the buttons
bitmapButtonFont = new BitmapFont();
bitmapButtonFont = gameOverFontGen.generateFont(gameOverButtonParam);
// Instantiate the buttonSound
buttonSound = Gdx.audio.newSound(Gdx.files.internal("sounds/pauseBtn_sound.ogg"));
/*************************************** Create a Stage *******************************************/
stage = new Stage();
// Add some actors as the buttons
exitGameButton = new Button(new TextureRegionDrawable(
new TextureRegion(new Texture(Gdx.files.internal("images/off_red.png")))),
new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("images/off_white.png")))));
//exitGameButton.setX((w, 150));
//pauseButton.setY(flipCoordinates(h, 150));
exitGameButton.setOrigin(exitGameButton.getWidth() / 2, exitGameButton.getHeight() / 2);
exitGameButton.setBounds(w / 2 + 100, h / 2 - 60, exitGameButton.getWidth(), exitGameButton.getHeight());
exitGameButton.act(Gdx.graphics.getDeltaTime());
stage.addActor(exitGameButton);
exitGameButton.addListener(new ChangeListener() {
#Override
public void changed (ChangeEvent event, Actor actor) {
buttonSound.play();
}
});
// Add some actors as the buttons
TextButton.TextButtonStyle restartStyle = new TextButton.TextButtonStyle();
restartStyle.font = bitmapButtonFont;
restartStyle.up = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("images/back_red.png"))));
restartStyle.down = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("images/back_white.png"))));
gameRestartButton = new Button(new TextButton.TextButtonStyle(restartStyle));
gameRestartButton.setOrigin(gameRestartButton.getWidth() / 2, gameRestartButton.getHeight() / 2);
gameRestartButton.setBounds(w / 2 - 100, h / 2 - 60, gameRestartButton.getWidth(), gameRestartButton.getHeight());
gameRestartButton.act(Gdx.graphics.getDeltaTime());
stage.addActor(gameRestartButton);
// Capture the event listener for the return button
gameRestartButton.addListener(new ChangeListener() {
#Override
public void changed(ChangeEvent event, Actor actor) {
// Do something on restart
//MainActivity.state = MainActivity.State.RUN;
Gdx.app.log("GameRestartButton", " has been pressed");
}
});
gameRestartButton.act(Gdx.graphics.getDeltaTime());
//stage.addActor(exitGameButton);
//stage.addActor(gameRestartButton);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
gameOverBatch.begin();
bitmapLogoFont.setColor(Color.RED);
bitmapLogoFont.draw(gameOverBatch, "Game Over", w / 2 - 210, h / 2 + 150f);
gameOverBatch.end();
exitGameButton.act(Gdx.graphics.getDeltaTime());
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
#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() {
gameOverFontGen.dispose();
}
}
In GameOverScreen constructor I have two buttons (exitGameButton and gameReturnButton) I'd like to be able to trigger their event-listeners, but I can't seem to be able to do it. Neither of my buttons responds to the event listener. What am I doing wrong? Do I need to add something else on to my MainActivity class for these buttons to work ? Thanks much.
I figured it out, on the second screen I was missing from the constructor this: Gdx.input.setInputProcessor(stage); , of course, that only works if a stage has been previously created.
try this in your class GameOverScreen
.//
public Stage getStageGameOverScreen(){
return this.stage;
}
your Case:
case STOPPED:
// Exit and clean the game
Gdx.input.setInputProcessor(gameOverScreen.getStageGameOverScreen());
gameOverScreen.render(Gdx.graphics.getDeltaTime());
break;
...

LibGDX - how do I add a simple button?

I'm greatly confused on this. What is don't understand is how the stage and table layouts exactly work. All i want are 3 buttons that sends me to another screen. Could someone please write out an example for me to work with? Here is the code I have so far.
public class Menu implements Screen {
private SlingshotSteve game;
private Stage stage;
private TextButton button;
private TextButtonStyle textButtonStyle;
private BitmapFont font;
{
stage = new Stage(new ExtendViewport(800, 840));
Gdx.input.setInputProcessor(stage);
Table table = new Table();
table.setFillParent(true);
table.center().center();
stage.addActor(table);
font = new BitmapFont();
textButtonStyle = new TextButtonStyle();
textButtonStyle.font = font;
button = new TextButton("This is a button!!!", textButtonStyle);
stage.addActor(button);
}
// View Port Camera
private Viewport viewport;
PerspectiveCamera camera;
public Menu(SlingshotSteve gam) {
this.game = gam;
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
game.batch.end();
if (Gdx.input.isTouched()) {
game.setScreen((Screen) new GameScreen(game));
dispose();
}
}
#Override
public void resize(int width, int height) {
// View Port Camera
viewport.update(width, height);
stage.getViewport().update(width, height, true);
}
#Override
public void show() {
// Viewport Camera
camera = new PerspectiveCamera();
viewport = new FitViewport(800, 480, camera);
}
#Override
public void dispose() {
stage.dispose();
}
}
Don't add the button to the Stage. Instead add it to the Table you have created.
TextButton button1 = new TextButton("This is a button!!!", textButtonStyle);
TextButton button2 = new TextButton("This is a button!!!", textButtonStyle);
TextButton button3 = new TextButton("This is a button!!!", textButtonStyle);
table.add(button1);
table.row();
table.add(button2);
table.row();
table.add(button3);
table.row();

last point also rendering for actor in libgdx

I am new to lib gdx and facing problem of proper rendering. While I am moving Actor , it is moving fine but last position frame is not cleared from screen , so whole path is appearing while moving .
It is like if object 1 move then it appear like 11111111111111111111111111111 while it should be only at last point like 1.
My actor
public class SinglePipe extends Actor {
#Override
public void draw(SpriteBatch batch, float parentAlpha) {
batch.setColor(getColor().r, getColor().g, getColor().b, getColor().a);
batch.draw(Assets.car, this.getX(), this.getY());
}
#Override
public void act(float delta) {
// TODO Auto-generated method stub
super.act(delta);
}
}
Screen class
public class GameScreen implements Screen, GestureListener {
private Stage stage;
private SinglePipe singlePipe;
Logger logger = new Logger("");
public GameScreen() {
// Gdx.graphics.setContinuousRendering(false);
logger.setLevel(5);
stage = new Stage();
singlePipe = new SinglePipe();
stage.addActor(singlePipe);
}
#Override
public void render(float delta) {
// camera.update();
handleInput();
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL10.GL_GREEN_BITS);
stage.act();
// stage.draw();
}
private void handleInput() {
if (Gdx.input.isKeyPressed(Input.Keys.A)) {
// singlePipe.addAction(Actions.moveBy(5, 5));
// singlePipe.addAction(Actions.rotateBy(180));
singlePipe.setX(singlePipe.getX() + 5);
singlePipe.setY(singlePipe.getY() + 5);
}
}
}
In your render method use:
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);`