I have a platform button the game screen, and I'm trying to make it so the user presses it once, clicks somewhere on the screen to draw one platform, and then if they clicked the screen again, nothing would happen.
Right now, before I click the platform button, nothing happens which is what I want. When I press the platform button, the user can click the screen to draw a platform, but, after pressing the platform button once, every time they click the screen, a platform gets drawn so I'm having trouble making it so they can only draw one. I thought using removeProcessor() would've worked, but it's not.
InputController inputProcessor;
InputMultiplexer multiplexer;
public GameScreen(FallDown game) {
this.game = game;
GAMESCREEN_STATE = WORLD_STATE_READY;
this.cam = new OrthographicCamera(FRUSTUM_WIDTH, FRUSTUM_HEIGHT);
this.cam.position.set(FRUSTUM_WIDTH / 2, FRUSTUM_HEIGHT / 2, 0);
this.cam.setToOrtho(false, FRUSTUM_WIDTH, FRUSTUM_HEIGHT);
batch = new SpriteBatch();
world = new World();
renderer = new WorldRenderer(batch, world);
cam.position.set(FRUSTUM_WIDTH / 2, 105, 0);
inputProcessor = new InputController(game, world, cam);
multiplexer = new InputMultiplexer();
}
Then, at the end of my render method I have
multiplexer.addProcessor(stage);
Gdx.input.setInputProcessor(multiplexer);
These are the listeners for my buttons and I'm just using the reset button as an alternate way to stop the user from drawing platforms.
reset_button.addListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
multiplexer.removeProcessor(inputProcessor);
return true;
}
});
platform_button.addListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
if (GAMESCREEN_STATE != WORLD_STATE_RUNNING) {
multiplexer.addProcessor(new InputController(game, world, cam));
}
return true;
}
});
Well, I would advice you not to add and remove processors that many times (especially the one in the render method.. move that to the constructor/create method).
An easy way to achieve what you are looking for is just have a boolean variable:
boolean createplatform = false;
And then set it to true when the button is pressed and to false when the first platform is created.
(So when you touch the screen, that boolean decides if a platform is created).
Related
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.
So I have a game I am working on and once you finish playing I want to be able for the user to tap on the "Play Again" button and be able to reset at the start.
To do this I create a Rectangle over the Texture and use the contains() method.
if(cloud.contains((float)Gdx.input.getX(),(float)(Gdx.graphics.getHeight()-Gdx.input.getY()))){
reset();
}
Reset method:
public void reset(){
speed=0;
paraY = Gdx.graphics.getHeight() - para[parachuteState].getHeight();
gameState=0;
backY = 0-Gdx.graphics.getHeight();
bach=0;
Gdx.input.setCursorPosition(Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2);
}
So what is happening is the program recognizes the button being pressed and resets but when the game is over again it automatically resets without displaying the end screen. I think that the cursor is not being moved to the center and is instead remaining on top of the button. Am I incorrectly using the setCursorPosition() method or is there another way to do this?
The button would be just right. It might looks more complex, but it's recommended way to do what you want to do.
So, to create a button you should do something like this:
Skin skin = new Skin();
skin.addRegions(uiTextureAtlas);
TextButton.TextButtonStyle buttonStyle = new TextButton.TextButtonStyle();
buttonStyle.up = skin.getDrawable("textureName");
buttonStyle.font = font;
Button button = new Button(buttonStyle);
button.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
reset();
return true;
}
});
button.setSize(100, 100);
button.setPosition(300, 400);
then in your Screen class you create
Stage stage = new Stage();
stage.addActor(button);
Gdx.input.setInputProcessor(stage);
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.
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 am making a LibGdx game. I have a main menu with a button that sends the user to the play screen. When at play screen though, the game reacts as it would when the user clicks in the spot that the button is located in from the previous screen. Here is the code that defines the button and switches screens:
button = new TextButton("Play", button_text);
button.setWidth(Gdx.graphics.getWidth() / 4);
button.setHeight(Gdx.graphics.getHeight() / 8);
button.setPosition((Gdx.graphics.getWidth() / 2) - (button.getWidth() / 2), (Gdx.graphics.getHeight() / 2) - (button.getHeight() / 2));
stage.addActor(button);
Gdx.input.setInputProcessor(stage);
button.addListener(new InputListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){
game.setScreen(new PlayScreen(game));
dispose();
return true;
}
});
Here is the dispose method for this screen:
#Override
public void dispose() {
stage.dispose();
}
So how do I clear all input before moving from one screen to the next?
Add on the dispose method
Gdx.input.setInputProcessor(null);
and will be fixed
Upon further research I have discovered a solution to my problem.
To solve this problem, in the constructor of the new screen I set the input proccessor to a new instance of an implementation of the GestureListener interface.
private MyGestureListener myGestureListener;
public PlayScreen(Game game) {
this.game = game;
myGestureListener = new MyGestureListener();
Gdx.input.setInputProcessor(new GestureDetector(myGestureListener));
}
Giving each screen its own instance of a GestureListener will avoid the problem of input being carried on from one screen to the next.