ImageButton doesn't seem to detect clicks (Scene2d.ui) - java

When trying to put a simple ImageButton on stage, It didn't seem to detect clicks.
ImageButton btnStart = new ImageButton(ButtonArt.UP, ButtonArt.DOWN));
// btnStart.setClickListener(new ClickListener() {
// #Override
// public void click(Actor a, float arg1, float arg2) {
// a.visible = false;
// }
// });
stage.addActor(btnStart);
ButtonArt.UP and ButtonArt.DOWN are TextureRegions, of each state.
Now when I click on the button, it doesn't change state! I also tried the above ClickListener (for testing), but it seemed that didn't work either.
In my render method I just call stage.act() and stage.render().
I also tried drawing the TextureRegions with SpriteBatch in my render method, and they are in fact different textures.
Am I doing something wrong?

You will need to set the stage as your inputprocessor:
Gdx.input.setInputProcessor(stage);
If you need to have multiple inputprocessors (e.g., you need clicks registered outside your scene), you will need to use an InputMultiplexer, like this:
InputMultiplexer plex = new InputMultiplexer();
plex.addProcessor(myOtherProcessor);
plex.addProcessor(stage);
Gdx.input.setInputProcessor(plex);

Related

Why is my LibGDX ImageButton only being detected once?

I am making a game in Android Studio using LibGDX, and I am attempting to add a pause button to the top corner of the main game screen. My game has been pausing fine thus far, but I have only been pausing when a key was pressed. Now I want to add a button, and I got the button to render in the top right corner, but when I press it it only works once. The first time I press it, my game pauses fine. But every time I try and pause it after that, it doesn't work. I have used extensive log statements and debugging and have found out that after pressing it once, the Listener doesn't even detect the button being pressed at all, so I am lead to believe that is where my issue is.
This is how I create my button in my HUD class, which is the class that prints the score onscreen at all times:
TextureAtlas buttonAtlas = new TextureAtlas(Gdx.files.internal("Buttons.pack"));
Skin skin = new Skin();
skin.addRegions(buttonAtlas);
ImageButton.ImageButtonStyle style = new ImageButton.ImageButtonStyle();
style.imageUp = skin.getDrawable("PauseButton");
style.imageDown = skin.getDrawable("PauseButton");
style.imageChecked = skin.getDrawable("PauseButton");
button = new ImageButton(style);
I then added a Listener to check if the button is clicked:
button.addListener(new ClickListener()
{
#Override
public void clicked(InputEvent event, float x, float y)
{
Gdx.app.log("","Button was pressed");
pauseGame();
}
});
The method pauseGame() that is called after the Listener detects the button being clicked:
public void pauseGame()
{
Gdx.app.log("","Game should be pausing");
screen.pauseGame();
}
screen is a class called PlayScreen that is the main game screen for my game, and its pauseGame() method works perfectly. The game before you press the pause button is as follows(You can see the pause button in the top right corner, please excuse the graphics, they are simply placeholders until I make and add my own graphics):
Game before pause
In my main PlayScreen class, this is my pauseGame method:
public void pauseGame()
{
gamePaused = true;
if(music.isPlaying())
{
musicType = type.NORMAL;
music.pause();
}
else if(barrageMusic.isPlaying())
{
musicType = type.BARRAGE;
barrageMusic.pause();
}
createPauseWindow();
}
And then in my render method, I call another method called update. In this method, I update my viewport, my HUD, and create new enemies. This is the only method that stops being called when gamePaused is true. The rest of my rendering and other necessary updates still take place. I have been trying to fix this problem for a long time but no matter how many different ways I rewrite the code to pause the game or make different listeners, the pause button only works one time and then never again.
Have you ever tried with touchDown method?
It might works.
button.addListener(new ClickListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
pause();
event.handle();
return true;
}
});
And try to change to a global variable base, a variable that is checked inside your render method and if it is true call the pause method. That to avoid call complex actions like pause from a listener, something like this:
button.addListener(new ClickListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
pause = true;
event.handle();
return true;
}
});
...
public void render(){
if (pause == true){
pauseGame();
}
...
}
It simplifies your listener and let you find easily your error.

How to Make a button that directly Extends Actor? Libgdx

I want to make a button that directly extends Actor. The reason I want to do this is because I don't want to go through the trouble of making a text button that has skins and such. I just want to be able to load my png file on the screen and make it clickable. Anyone have ideas or should I just stick to the Textbutton?
How about an ImageTextButton?
Or you use a Button, and add a Stack (which holds multiple items, that you can place on them self)
I don't recommend you, to do your own button. You'll reinvent the wheel.
I suggest: try ImageTextButton.
If that does not help --> Button + Stack
public class TextureActor extends Actor {
private Texture texture;
public TextureActor(Texture texture) {
this.texture = texture;
}
#Override
public void draw(Batch batch, float parentAlpha) {
batch.draw(texture, getX(), getY(), getWidth(), getHeight());
}
}
You can certainly replace Texture with anything else which can be drawn by the batch. Or use another draw method with more detailed parameters.
Buttons don't actually need a skin, so it would be far easier to just make a factory method to simplify it, rather than code all the logic of a proper button:
public static Button makeButton (TextureRegion upImage, TextureRegion downImage, Actor contentActor) {
Button.ButtonStyle style = new Button.ButtonStyle();
style.up = new TextureRegionDrawable(upImage);
style.down = new TextureRegionDrawable(downImage);
return contentActor == null ? new Button(style) : new Button(contentActor, style);
}

Making "toggle buttons" with LibGDX

I'm trying to make sort of toggle buttons with LibGDX, so I searched how I could do them, and I found the ToggleButton class, but I suppose it's old since I don't have it in the last build...
So I'm trying to do them this way:
final TextButton button = new TextButton(weapon.getName(), skin2, "buy");
button.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
if(button.isChecked()){
button.setChecked(false);
System.out.println("unchecked");
} else {
button.setChecked(true);
System.out.println("checked");
}
}
});
Actually, it keeps telling me unchecked, as if my button was always unchecked, so the setChecked method doesn't seems to word ...
I tried the toggle method, and it doesn't help at all, and I didn't found any other solution ...
So i was wondering if you had any idea of how I should do this !
Thanks for your help ! :)
The button is toggled automatically when clicked, you don't have to add another listener to do it manually.
So the reason it only prints "unchecked" is because the Button checks itself when clicked, and then your listener is called, which just unchecks it immediately.

libgdx clickable image not working

I have a menu screen in libgdx and I had a text button that started a new game like this.
textButton.addListener(new ChangeListener() {
public void changed (ChangeEvent event, Actor actor) {
g.setScreen( new level1(g));
}
});
It looked like crap so I changed it to an image.
playbuttontexture = new Texture(Gdx.files.internal("data/playbutton.png"));
playbuttontexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
TextureRegion playbuttonregion = new TextureRegion(playbuttontexture, 0, 0, 512, 256);//powers of 2
playbutton = new Image(playbuttonregion);
playbutton.setSize(512,256);
playbutton.setBounds(width/2-playbutton.getWidth()/2, height/2-playbutton.getHeight()/2, 512, 256);
//playbutton.setOrigin(playbutton.getWidth()/2, playbutton.getHeight()/2);
playbutton.setPosition(width/2-playbutton.getWidth()/2, height/2-playbutton.getHeight()/2);
and
playbutton.addListener(new ChangeListener() {
public void changed (ChangeEvent event, Actor actor) {
g.setScreen( new level1(g));
}
});
Now when I click it nothing happens? What am I doing wrong?
The problem here is that Image does not fire a changed(...) event anymore. This event is only fired by the TextButton you've used before when the status changes from clicked to not-clicked and the other way around. It can also be fired in other cases, since it is kind of a "generic" event, as the JavaDoc states, but that varies from actor to actor.
Change it to a ClickListener and use the clicked(...) method instead. This event should be fired by all actors in the scene2d.ui package.
for me this is what it looks like when I implemented the code ( I was having a similar issue. noone did a great job at pointing me to the right places to look. )
playbutton.addListener( new ClickListener(){
#Override
public void clicked (InputEvent event, float x, float y) {
//your code to do stuff when the button is clicked
}
});

Why does Activity not have a onClick event handler?

I'm trying to have my activity respond to a single click but I cannot find a way to implement this.
I can use onTouchEvent override that method and have my logic run there but onClick is not possible?
What is the reason behind this and what could I do to get the desired effect that I want?
As requested: what I currently have
#Override
public void onClick(View event) {
// TODO Auto-generated method stub
x = event.getX();
y = event.getY();
pixelColor = Color.RED;
PixelParticle pp = new PixelParticle(this, x, y, 50, 50, pixelColor);
setContentView(pp);
}
this isn't working - I implement OnClickListener and override the above method, the canvas never draws what I want it to draw.
Touch down + touch up of the same point in a short time is a onClick(Actually onClick event in the android source code is really made in this way).
Because the onTouchEvent(in activity) is made for you to check touch event of the whole screen.But onClick is designed to check the click event on a view(not the whole screen).Touch event is the original event,click isnĀ“t.
If you want to check whether your screen is clicked ,just use the onClick method of your layout(give it an id myLayout).
LinearLayout layout = findViewById(R.id.myLayout);
layout.setOnClickListener(xxx);

Categories

Resources