Set the Actor's sprite to the default - java

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

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
}
});

LibGDX TextButton - Any event getting called repeatedly as long as it's held down?

I am making a game where you have two buttons to rotate the player, one to left and the other one to right. I'm using a TextButton in LibGDX. My problem is that the method clicked(InputEvent event, float x, float y) in ClickListener is only called once it's clicked. I want an event to be called repeatedly as long as it's held down. Here is my code:
TextButton btnLeft = new TextButton("<", styleButton);
TextButton btnRight = new TextButton(">", styleButton);
btnLeft.setSize(100, 100);
btnRight.setSize(100, 100);
btnLeft.setPosition(25, 25);
btnRight.setPosition(200, 25);
btnLeft.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
player.rotate(-1);
System.out.println("Left");
}
});
btnRight.addListener(new ClickListener() {
Override
public void clicked(InputEvent event, float x, float y) {
player.rotate(1);
System.out.println("Right");
}
});
stage.addActor(btnLeft);
stage.addActor(btnRight);
The listener is not good place to perform continuous actions since it is by definition asynchronous mechanism. The place to perform some action like this is render() method of Screen or act() method of actor.
Although you can use listener to check a state of actor (is it pressed or not) in this way:
//Global instance
ClickListener listenerLeft;
//show() method
...
listenerLeft= new ClickListener();
btnLeft.addListener(listenerLeft);
...
//render() method
...
if(listenerLeft.isPressed())
//perform turning left
...
The second option is to implement ClickListener's touchUp and touchDown methods to change some flag and then check it in render but it would not be doing anything new.
Worth to notice is than both ClickListener and DragListener have touchDragged method that is something about what you want but works only if the mouse/finger is moving when touching actor
listener = new DragListener(){
#Override
public void touchDragged(InputEvent event, float x, float y, int pointer)
{
System.out.println("Left");
}
};
Keeping touching is not an action - no action = nothing to listen

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.

Libgdx InputListener "exit()" is not being called with TextButton

I want to use the exit() method in the InputListener to see wheter the cursor is inside the button or not.
Here is the explanation in the libGDX docs.
public void exit(InputEvent event, float x, float y, int pointer, Actor toActor)
Called any time the mouse cursor or a finger touch is moved out of an actor.
But when I put my cursor on the button and then move it outside the button, the method is not called. I am testing it by a System.out.println("exited"); and I get nothing in the console.
EDIT:
LibGDX Version: Latest Stable Nightlies
InputListener implementation:
//This button class is a custom class to make button creation easier. This is the constructor.
public Button(Vector2 position, String packLocation, String text, Stage stage, BitmapFont font, Color color) {
//Removed buttonStyle creation etc. to shorten the code.
button = new TextButton(text, buttonStyle);
button.setPosition(position.x, position.y);
stage.addActor(button);
Gdx.input.setInputProcessor(stage);
pressed = false;
button.addListener(new ClickListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
pressed = true;
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
pressed = false;
}
#Override
public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) {
System.out.println("exited");
}
});
}
EDIT:
Hovering over the button also does not change the texture of the button as I set it to like so:
buttonStyle.over = skin.getDrawable("over");
But clicking does.
After searching for a couple hours I finally found what was missing. stage.act(); had to be called in the render method. This both gave functionality to the texture change when we hover over the button and also the enter/exit methods in the InputListener.

libGDX Mouse over on UI element fires same event from underlying Actor

I'm making a simple RTS game. I've created separate Stages for map and UI, and used scene2D Table class for side panel. The problem is, when i hover my side panel, if there is an actor (building) under panel at the moment, it fires its mouseover event. Click events work properly.
Here is my building class input listeners:
public class Building extends Actor {
addListener(new InputListener(){
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
System.out.println("Click");
return true;
}
public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor){
((Building)event.getTarget()).hover = true;
}
Here is my panel class listeners
public class SidePanel extends Table {
panelBg = new Image(skin,"side-panel");
addListener(new InputListener(){
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
System.out.println("Click");
return true;
}
public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor){
System.out.println("Enter");
}
});
addActor(panelBg);
}
}
Then side panel is added to UI class stage:
public class UI {
public UI(){
stage = new Stage();
sidePanel = new SidePanel();
stage.addActor(sidePanel);
Gdx.input.setInputProcessor(stage);
}
And finally i added UI to main class:
#Override
public void create () {
ui = new UI();
CP =new InputMultiplexer();
CP.addProcessor(ui.stage);
CP.addProcessor(gameStage);
Gdx.input.setInputProcessor(CP);
}
Not sure where the problem is, because click event works fine;
One quick solution would be to have your Building class check if the mouse was also over the SidePanel. For example, you could change your Building listener's enter method to something like this:
if (mouseIsOverSidePanel)
((Building)event.getTarget()).hover = true;
Your SidePanel listener's enter method can be something like this:
mouseIsOverSidePanel = true;
And your leave method in your SidePanel can be:
mouseIsOverSidePanel = false;
This is mostly pseudo code so it won't work without declaring the variables (obviously) but it should give you a basic idea of how to fix your problem.

Categories