I have created an ImageButton in my game. It has a listener and I have also added a texture, it works just fine but I couldn't find how to add a pressing effect to my buttons. Is there any premade libGDX method, or an easy way to have a pressing effect for my buttons?
You can use ImageButtonStyle to create a styling for your button, that automatically changes it's texture. This LibGDX Tutorial explains the use of buttons and button styles.
Basically you need to do something like this (from the tutorial):
ImageButton button3 = new ImageButton(mySkin);
button3.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("switch_off.png"))));
button3.getStyle().imageDown = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("switch_on.png"))));
If the button is handled by a Stage, like the following, it should be handled automatically:
public class MyGdxGame extends ApplicationAdapter {
private Stage stage;
#Override
public void create () {
stage = new Stage(new ScreenViewport());
Gdx.input.setInputProcessor(stage);
// TODO create the button
// add the button to the stage
stage.addActor(button3);
}
#Override
public void render () {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
stage.draw();
}
}
Related
I was wondering, if there is anyway to make a ScrollPane and Lists that wrap text horizontally in LibGDX. I would love the scroll pane to scroll vertically but for it to wrap its text instead of scrolling horizontally.
I know I can disable the X direction of scrolling by using
scrollPane.setScrollingDisabled(false, true);
but is there anyway to make the text wrap so that there is no horizontal scrolling and it would just go to a new line?
You can do in this way :
public class ScrollPaneTest extends ApplicationAdapter {
private Stage stage;
private Table container;
#Override
public void create () {
stage = new Stage();
Skin skin = new Skin(Gdx.files.internal("skin/glassy-ui.json"));
Gdx.input.setInputProcessor(stage);
container = new Table();
stage.addActor(container);
container.setFillParent(true);
Table table = new Table();
final ScrollPane scroll = new ScrollPane(table, skin);
scroll.setScrollingDisabled(true,false);
table.pad(10).defaults().expandX().space(4);
for (int i = 0; i < 100; i++) {
table.row();
Label label=new Label(i + ". Publish your games on Windows, Mac, Linux, Android, iOS, BlackBerry and HTML5, all with the same code base.", skin);
label.setAlignment(Align.center);
label.setWrap(true);
table.add(label).width(Gdx.graphics.getWidth());
}
container.add(scroll).expand().fill();
}
#Override
public void render () {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
#Override
public void resize (int width, int height) {
stage.getViewport().update(width, height, true);
}
#Override
public void dispose () {
stage.dispose();
}
}
And the output is :
You can wrap the text by using Labels. Then add those Labels to your scrollpane.
The title may be a bit vague, so allow me to define it a little better. I have a working piece of code (down below): a simple main menu for a game I am working on. Everything works well, except for the Start button.
What I want to be able to do is click the Start button, and have a new scene appear on the same stage (window). I do not want to see a new window open. I have talked with someone more experienced in Java, and they told me to create separate classes for the MenuFX and the GameFX. If that is the case, I would need to call some start or launch method on the GameFX class from the MenuFX class, correct? Is this the best approach, or would I want to keep all FX-related code in one class? Also, I should keep the same stage for all FX work, no?
This post shed some light on things, but I am not well-versed in some of the terms discussed- for instance, I still do not understand the concept of Root.
Also, this post talks about a similar application, but I am not using FXML or SceneBuilder... I do not know if any of it is relatable.
MenuFX.java - I have removed some of the working code, simply for brevity. You can see that all I need help with is tying the Start button to some functionality that makes a new empty scene.
/*
* This is simply working on the title screen.
*/
// Asssume all imports are correct
import java.everythingNeeded
public class MenuFX extends Application {
#Override
public void start (Stage primaryStage) {
// Make the window a set size...
primaryStage.setResizable(false);
// Create menu vbox and set the background image
VBox menuVBox = new VBox(30);
menuVBox.setBackground(new Background(new BackgroundImage(new
Image("image/bambooBG.jpg"), null, null, null, new BackgroundSize(45,
45, true, true, true, true))));
// Create start button
Button startButton = new Button("Start Game");
// TODO Some things...
// Need assistance here
// Create help button
Button helpButton = new Button("Help");
helpButton.setOnAction(e -> THINGS);
// Create music toggle button
ToggleButton musicButton = new ToggleButton("Music On/Off");
musicButton.setOnAction(e -> THINGS);
// Create credits button
Button creditsButton = new Button("Credits");
creditsButton.setOnAction(THINGS);
// Create exit button and set it to close the program when clicked
Button endButton = new Button("Exit Game");
endButton.setOnAction(e -> Platform.exit());
// Add all nodes to the vbox pane and center it all
// Must be in order from top to bottom
menuVBox.getChildren().addAll(startButton, helpButton, musicButton, creditsButton, endButton);
menuVBox.setAlignment(Pos.CENTER);
// New scene, place pane in it
Scene scene = new Scene(menuVBox, 630, 730);
// Place scene in stage
primaryStage.setTitle("-tiles-");
primaryStage.setScene(scene);
primaryStage.show();
}
// Needed to run JavaFX w/o the use of the command line
public static void main(String[] args) {
launch(args);
}
}
Restating: I want to click the Start button and have the currently open window change to an empty scene.
Here is a pastebin of the MenuFX class in its entirety:
http://pastebin.com/n6XbQfhc
Thank you for any help,
Bagger
The basic idea here is you would do something like:
public class GameFX {
private final BorderPane rootPane ; // or any other kind of pane, or Group...
public GameFX() {
rootPane = new BorderPane();
// build UI, register event handlers, etc etc
}
public Pane getRootPane() {
return rootPane ;
}
// other methods you may need to access, etc...
}
Now back in the MenuFX class you would do
Button startButton = new Button("Start Game");
startButton.setOnAction(e -> {
GameFX game = new GameFX();
primaryStage.getScene().setRoot(game.getRootPane());
});
i have to make a game for a school project and i was wondering if it's possible to lock a screen in a certain position on the screen. I have a settings button that opens a new stage and i want to make that scene immovable is this possible?
This is the code where i display the settings screen:
Public void buttonAction(){
btnSettings.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
GridPane settingsGrid = new GridPane();
Scene scene1 = new Scene(settingsGrid,375,600);
Stage settingsStage = new Stage();
settingsGrid.setHgap(10);
settingsGrid.setVgap(10);
//settingsGrid.setGridLinesVisible(true);
settingsStage.setTitle("Settings");
settingsStage.setResizable(false);
settingsStage.initStyle(StageStyle.UTILITY);
settingsStage.initModality(Modality.APPLICATION_MODAL);
settingsStage.setScene(scene1);
settingsStage.showAndWait();
}
});
}
Thanks in advance!
you could try this:
settingsStage.initStyle(StageStyle.TRANSPARENT);
However, you could only have one initStyle if I remember correctly. So you have to settingsStage.initStyle(StageStyle.UTILITY); in order to use the above code. What it does is it make the background transparent and the user could not change the position.
I want to create a button that changes when the user hovers it, or clicking it.
I created the following variable
Button buttonPlay = new Button();
I don't know what to do now, how to load the images? How to write text into the button? How to implement the events / effects (hover, click)?
It would be very helpful if someone could write some example code for a button.
A button is simply an actor in libgdx. To render an actor you use a stage that contains all the actors of the screen, renders them and updates them. I assume you want a button with text, so you should use the class TextButton and add it to a stage. A TextButton takes a string to render and a ButtonStyle, in this case a TextButtonStyle, which is basically a class that contains all the information about the button (font, drawable to render while not pressed, drawable to render while pressed etc).
public class ButtonExample extends Game{
Stage stage;
TextButton button;
TextButtonStyle textButtonStyle;
BitmapFont font;
Skin skin;
TextureAtlas buttonAtlas;
#Override
public void create() {
stage = new Stage();
Gdx.input.setInputProcessor(stage);
font = new BitmapFont();
skin = new Skin();
buttonAtlas = new TextureAtlas(Gdx.files.internal("buttons/buttons.pack"));
skin.addRegions(buttonAtlas);
textButtonStyle = new TextButtonStyle();
textButtonStyle.font = font;
textButtonStyle.up = skin.getDrawable("up-button");
textButtonStyle.down = skin.getDrawable("down-button");
textButtonStyle.checked = skin.getDrawable("checked-button");
button = new TextButton("Button1", textButtonStyle);
stage.addActor(button);
}
#Override
public void render() {
super.render();
stage.draw();
}
}
So whats happening here? I am creating a stage, a font and a textureatlas with all the textures for the buttons in "buttons.pack". Then I initialize an empty TextButtonStyle and
and i add the font and the textures for the up, down and checked states. font, up, down and checked are all static variables of type Drawable so you can really pass it any kind of Drawable (texture, 9-patch etc). Then simply add the button to the Stage.
Now in order to do something when the button is actually clicked, you have to add a listener to the button, a ChangeListener.
button.addListener(new ChangeListener() {
#Override
public void changed (ChangeEvent event, Actor actor) {
System.out.println("Button Pressed");
}
});
Of course instead of adding the button directly to the Stage you should add it to a Table and add the Table to the Stage but I didn't want to make this post too confusing. Here is a good tutorial on tables in libgdx.
This is how you do it without adding any skin
TextButton.TextButtonStyle textButtonStyle = new TextButton.TextButtonStyle();
textButtonStyle.font = yourCustomFont;
textButtonStyle.fontColor = Color.WHITE;
stage.add(new TextButton("Custom Btn ", textButtonStyle));
buttons.pack is the file generated from the libgdx texture packer, texture packer is the tool which can used to generate the texture atlas , That is multiple images you can loaded to the GUI using a single file . it also help to save some memory please refer this link`https://code.google.com/p/libgdx-texturepacker-gui/downloads/list,
https://github.com/libgdx/libgdx/wiki/Texture-packer
I have this JavaFX menu which is not working properly:
public class CreatingMenus {
// Generate Menu
public void initMenu(Stage primaryStage, Group root, Scene scene) {
// Call Menu Actions from Java Method MenuActions
final MenuActions ma = new MenuActions();
MenuBar menuBar = new MenuBar();
// File menu - new, save, close, exit
Menu menu = new Menu("File");
menu.getItems().add(new MenuItem("New"));
menu.getItems().add(new MenuItem("Save"));
menu.getItems().add(new MenuItem("Close"));
menu.getItems().add(new SeparatorMenuItem());
MenuItem menuItem = new MenuItem("Exit");
// Exit from the application
menuItem.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
// This Java Method is called from the Java Class MenuActions
ma.programExit(); // Exit program
}
});
menu.getItems().add(menuItem);
menuBar.getMenus().add(menu);
// Options menu - Preferences
Menu options = new Menu("Options");
options.getItems().add(new MenuItem("Preferences"));
menuBar.getMenus().add(options);
// Help menu - About
Menu help = new Menu("Help");
MenuItem helpItem = new MenuItem("About");
// Exit from the application
helpItem.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
aboutDialog();
}
});
help.getItems().add(helpItem);
menuBar.getMenus().add(help);
menuBar.prefWidthProperty().bind(primaryStage.widthProperty());
menuBar.setLayoutX(0);
menuBar.setLayoutY(0);
root.getChildren().add(menuBar);
}
public void aboutDialog() {
final int xSize = 640;
final int ySize = 480;
final String logoImage = "/logo.png";
final Color backgroundColor = Color.WHITE;
final String text = "SQL Browser";
final String version = "Product Version: 1.0";
final String license = "License Information";
final Stage aboutDialog = new Stage();
aboutDialog.initModality(Modality.WINDOW_MODAL);
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(20, 20, 20, 20));
// Logo
Image image = new Image(getClass().getResourceAsStream(logoImage));
ImageView logo = new ImageView(image);
grid.add(logo, 1, 0);
// Product name
Text productName = new Text(text);
productName.setFont(Font.font("Verdana", 12));
grid.add(productName, 0, 2);
// Product version
Text productVersion = new Text(version);
productVersion.setFont(Font.font("Verdana", 12));
grid.add(productVersion, 0, 3);
// Product License
Text productLicense = new Text(license);
productLicense.setFont(Font.font("Verdana", 12));
grid.add(productLicense, 0, 4);
// Close Button
Button closeButton = new Button("Close");
closeButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
// Close the dialog when "Close" button is pressed
aboutDialog.close();
}
});
grid.add(closeButton, 5, 18);
// Configure dialog size and background color
Scene aboutDialogScene = new Scene(grid, xSize, ySize, backgroundColor);
aboutDialog.setScene(aboutDialogScene);
aboutDialog.show();
}
}
When I add this menu it overrides the other components into the application and they are not responsible because I suppose they are behind this layer. Can you tell how I can isolate this menu in separate layer because I don't want to place other components behind.
EDIT
When I use the menu code I get this result:
When I remove the the menu code I get this result and the application is working properly:
The problem somewhere into the menu code.
Scene Width Binding
Stage width contains window borders and a title bar - which are irrelevant to internal layout.
To fill the scene width with something using binding, bind the preferred size of the thing to a scene size and not the stage size:
menuBar.prefWidthProperty().bind(menuBar.getScene().widthProperty());
Or (usually preferred) you can use alternate layout panes and layout constraints which perform the sizing automatically. For your particular layout a BorderPane might be useful.
You may have additional issues with your implementation which cause problems (I have not checked).
Using Groups for Layout
Your pastebin code uses a Group for the main scene layout root. Group is generally a poor choice for laying out a flexibly sized screen like your example. A group is not re-sizable. Instead it is advisable to use a re-sizable layout pane as referred to above.
Tool Support
ScenicView is invaluable in debugging existing layout issues.
SceneBuilder is great for rapid prototyping of various layouts.
I strongly advise using these tools to help understand how layouts work and to provide you with the tools and knowledge you need to debug layout issues yourself.
Works for me without any changes. You might should check your Java/JavaFx versions. I am using 1.7_17, 64 bits on windows.
I have added some images (I don't have yours) to get sure the behaviour you get is not because of them.