Mouse hover - libgdx - java

Is there any listener in libgdx that would allow me to detect just mouse hover not pressed just hover. In the button class of scene 2D you have 2 methods isOver and isPressed but they do the same thing ... Anyone else having this problem? Is there another way to detect mouse hover over actor?

There's the ClickListener which can be attached to an Actor and it offers events like the following ones:
public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor)
public void exit(InputEvent event, float x, float y, int pointer, Actor toActor)
The enter event basiscally means that the mouse started hovering over the actor, exit means it "left" the area of the actor. It also has a clicked event which you can use to execute some action in the end.

Related

How do I add touch controls to an Object in libGDX?

I'm making a balloon popping game for android in libGDX and I'm currently stuck on how to make the balloons pop when the user touches them. I tried using the touchDown() method,
b = new Balloon();
b.addListener(
new InputListener()
{
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button)
{
b.remove();
popped++;
return true;
}
});
mainStage.addActor(b);
}
but it doesn't work. I need a way so that only the balloons that I touch get popped and the others don't.
p.s I'm still learing libGDX so I'm a pretty big noob at it.
Edit: The Balloon is an Actor, and I did set the InputProcessor as well. The touch thing works but it doesn't pop the balloon that I touch it only pops the balloons that spawn at the starting x-axis.
At first you have to set your stage as input processor with Gdx.input.setInputProcessor(mainStage)
Then you can just add a ClickListener where you override the clicked method like this:
b.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
super.clicked(event, x, y);
//YOUR_CODE
}
});

How to properly create a mouse Listener for CheckBox in LibGDX Scene2D?

I've been searching online for hours and I'm new to LibGDX game development.
This link was useful, but I still have not been able make my CheckBox work.
How to properly implement CheckBox in LibGDX
I'm using LibGDX and I have to implement two Radio buttons in my menu.
I created two CheckBox and assigned them a style.
check_style = new CheckBox.CheckBoxStyle();
check_style.font = font;
check_style.fontColor = new Color(Color.WHITE);
check_style.checkboxOff = check_skin.getDrawable("checkbox");
check_style.checkboxOn = check_skin.getDrawable("checkbox2");
check_style.checked = check_skin.getDrawable("checkbox2");
I also added a listener to notice mouse clicks
controls1Check.addListener(new InputListener() {
public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
controls1Check.toggle();
System.out.println("toggle");
}
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
System.out.println("Controls1: " + controls1Check.isChecked());
return true;
};
});
When I run my program it does not respond to any mouse click.
How can I resolve this?
Thank you!
I guess you are adding your CheckBox to a Stage? If so, my only idea is that maybe you didn't call Gdx.input.setInputProcessor(yourStage); so even though your CheckBoxes have InputListeners, input is actually not being processed.

LibGDX scale Textbutton then clicked

I want to change the size of the textbutton if the user clicked down on it, and if the user dont touch it the textbutton go on the normal size. it would be perfect with a slow animation so that the user sees the well.
here my code:
textButtonStyle = new TextButton.TextButtonStyle();
textButtonStyle.up = new TextureRegionDrawable(new TextureRegion(texture));
textButtonStyle.font = font_var;
buttonHighscore = new TextButton("Highscore", textButtonStyle);
stage.addActor(buttonHighscore);
I am pretty sure that it is not possible to do this with ButtonStyle but I would attach my own ClickListener to it and adjust the size of the actor or whatever you want to do with it. ClickListener offers isOver functionality but since you want to set it back to original numbers we use enter and exit.
button.addListener(new ClickListener() {
#Override
public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) {
super.enter(event, x, y, pointer, fromActor);
if (fromActor != null)
fromActor.setSize(overSize, overSize);
}
#Override
public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) {
super.exit(event, x, y, pointer, toActor);
if (toActor != null)
toActor.setSize(defaultSize, defaultSize);
}
});
Depending on how your stage is layout this might or might not work. Maybe you need to grab the parent of the actor within the listener and set these widths. For a simple button in a table filling the stage/screen this works for me.
You can use Actor actions for the animation. No time to give you a example now but just Google it, it's easy to implement.

Set the Actor's sprite to the default

I'm having troubles with my Actor objects. When I click on the Button Actor, I want it to switch the Screen. When I do this, and I return to the last screen, the button that I clicked is still being hovered until I move my mouse again:
The code that I have for it:
// Load Game
textButtons[1].addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
// GameState is a subclass of Screen,
// GameStateManager helps me to manage my GameStates.
game.setGameState(GameStateManager.get("screenLoadGame"));
}
});
I've tried to "trick" it to fix this, by using the keyUp method, and doing the following:
#Override
public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
super.touchUp(event, x, y, pointer, button);
int[] mousePos = { Gdx.input.getX(), Gdx.input.getY() };
Gdx.input.setCursorPosition(0, 0);
stage.act(1);
game.setGameState(GameStateManager.get("screenLoadGame"));
Gdx.input.setCursorPosition(mousePos[0], mousePos[1]);
}
But it doesn't work.
In the end, I want to be able to switch from one Screen back to the Main Menu Screen, and have the button as its default sprite. Is there a way to set an Actor's (Button's) Sprite?
NOTE: For the sprites (in the Json file) The up/down is how "Start New Game" shows it. The over sprite is when it has the gray background (like "Load Game").
Use a ChangeListener instead of a ClickListener. This will also allow your buttons to behave like buttons are expected to (if you click down and move your cursor off the button before releasing, it won't fire).
You can use a single ChangeListener for many buttons quite easily to keep your code tidy.
ChangeListener changeListener = new ChangeListener() {
#Override
public void changed(ChangeEvent event, Actor actor) {
if (actor == startNewGameButton){
startNewGame();
} else if (actor == loadGameButton){
loadGame();
} else if (actor == creditsButton){
showCreditsScreen();
}
}
};
And then to add it to a button:
startNewGameButton.addListener(changeListener);

scene2d: how to fire(event) and handle at scene/root?

i am trying to escalate touchDown and touchUp events from an actor Object to my applicationListener class. To do so, i called fire(event); in the InputListener of my Actor
this.addListener(new InputListener(){
public boolean touchDown(InputEvent event, float x, float y, int pointer, int buttons){
Gdx.app.log("Example", "touch started at (" + x + ", " + y + ")");
fire(event);
return true;
}
public void touchUp(InputEvent event, float x, float y, int pointer, int buttons){
Gdx.app.log("Example", "touch ended at (" + x + ", " + y + ")");
}
});
To handle the event in my ApplicationListener class (which contains the stage of the actors), i added an InputListener to the stage
Gdx.input.setInputProcessor(stage);
stage.addListener(new InputListener(){
public boolean touchDown(InputEvent event, float x, float y, int pointer, int buttons){
Gdx.app.log("FIRE!!!", "I CAUGHT A FIRED EVENT!");
event.stop();
return true;
}
public void touchUp(InputEvent event, float x, float y, int pointer, int buttons){
Gdx.app.log("FIRE!!!", "the fired event even touchupped.");
}
});
However when i touch my actor, i get a StackOverflowError as well as a ton of exceptions from several InputListeners (i assume that the event is not stopped properly and propagated to all actors in my scene). What am i missing here?
Also after firing the event i cant cast event.getTarget() (which is an Actor) to my Actor-Subclass anymore, which works just fine if i do this in the ActorSubclass itself. Meaning the following code creates an error when used in the ApplicationListener, but works in the MyActor class:
MyActor actor = (MyActor)event.getTarget();
Since the target is in fact a MyActor Object, how can i access it not only as Actor, but as MyActor?
As #chase said you are recursivelly calling the fire(even) method, as you can only set 1 InputProcessor (your stage) and so always the same method recieves the event.
You should instead use a InputMultiplexer:
add the Stage and your ApplicationListener as InputProcessor to the InputMultiplexer
Set the InputMulitplexer as the InputProcessor by calling Gdx.input.setInputProcessor(multiplexer);.
The InputMultiplexer will then give the event to the first InputProcessor and if it returns false, it will send the event to the next one.
So in your Stage you just need to return false.
But i don't understand why you are adding your Stage as a InputProcessor if you don't want it to handle inputs...
Anyways in scene2d you don't need to add an InputProcessor to the stage as it allready has one. Also the Actor allready has a boolean touchDown(float x, float y, int pointer) and other helpful methods.
A useful link: Scene2D wiki article
Aren't you just making a recursive call at this point by refiring the event every time you handle it?
Why not just return false from your listener?

Categories