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.
Related
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
}
});
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.
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);
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.
I've created a simple test with a touchDown() event on an image actor. The event works on the stage but not on the actor.
Here is the code:
I set the InputProcessor in the constructor of the parent class (AbstractScreen).
Gdx.input.setInputProcessor(this.stage);
In the sub class:
private TextureAtlas atlas;
private Image boardImg;
public void show(){
super.show();
atlas = new TextureAtlas(Gdx.files.internal("data/packs/mainMenu.atlas"));
AtlasRegion board = atlas.findRegion("board");
boardImg = new Image(board);
boardImg.addListener(new InputListener(){
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){
Gdx.app.log("aaaa", "down");
return true;
}
});
stage.addActor(boardImg);
stage.addListener(new InputListener() {
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.log("aaaa", "stage down");
return true;
}
});
}
#Override
public void resize(int width, int height) {
super.resize(width, height);
boardImg.setPosition(stage.getWidth()/2 - boardImg.getWidth()/2, stage.getHeight()/4);
}
I'm testing both on the desktop and on the android (same results).
I get the "stage down" event but not the event of the actor. I've tried also without having the stage event.
Do all of these works:
boardImg.setTouchable(Touchable.enabled)
return false in stage listener or clear its listener.
do not call setInputProcessor(this.stage) in parent class instead call in child class.
I think the problem is because the touchDown() method of the stage returns true, and so the event will be "consumed" and won't be propagated to its children, the actors, and so the touchDown() method of boardImg will not be called.
Image doesn't receive touch events because it has no size.
Read documentation carefully:
Note that the actor must specify its bounds in order to receive input
events within those bounds.
Just know that boardImg = new Image(board) won't set width and height of actor for you. So you need to make it manualy. Assume you work with pixel perfect sizes:
boardImg = new Image(board);
boardImg.setWidth(board.getWidth());
boardImg.setHeight(board.getHeight());
That will do the trick. Good luck.