My game has a lot of text onscreen as a debug purpose and I need much more text on screen to help me. Here is an image of the debug text on screen.
When I run the application, this is what appears. However what I would like to happen (for debugging) is for another window to pop up. By window I mean like another libgdx application running alongside the game application. And in this second window I want to have all the debug text lay there so that I can see the game for how it will look while it's running without all the debug junk. Any help is extremely appreciated.
You can have a Window pop up when you want to view debug information. It is draggable, which means you can move it around, and you can make is semi transparent if you want to see through it. The window can pop up upon a double click (for example) on your stage. Your Stage code would look roughly like this:
public class MyStage extends Stage {
private boolean debug = false;
private Window debugWindow = new DebugWindow(); // your customized Window that contains the debug info
public MyStage(...) {
addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
if (getTapCount() >= 2) { // i.e., double click
debug = !debug;
}
}
});
}
public void act() {
// ...
if (debug && debugWindow.getStage() != this) {
addActor(debugWindow); // This will add the debug window to your stage, making the debug info visible
}
else if (!debug && debugWindow.getStage() == this) {
debugWindow.remove(); // When you want the debug window out of the way
}
}
}
Related
I am making a game in Android Studio using LibGDX, and I am attempting to add a pause button to the top corner of the main game screen. My game has been pausing fine thus far, but I have only been pausing when a key was pressed. Now I want to add a button, and I got the button to render in the top right corner, but when I press it it only works once. The first time I press it, my game pauses fine. But every time I try and pause it after that, it doesn't work. I have used extensive log statements and debugging and have found out that after pressing it once, the Listener doesn't even detect the button being pressed at all, so I am lead to believe that is where my issue is.
This is how I create my button in my HUD class, which is the class that prints the score onscreen at all times:
TextureAtlas buttonAtlas = new TextureAtlas(Gdx.files.internal("Buttons.pack"));
Skin skin = new Skin();
skin.addRegions(buttonAtlas);
ImageButton.ImageButtonStyle style = new ImageButton.ImageButtonStyle();
style.imageUp = skin.getDrawable("PauseButton");
style.imageDown = skin.getDrawable("PauseButton");
style.imageChecked = skin.getDrawable("PauseButton");
button = new ImageButton(style);
I then added a Listener to check if the button is clicked:
button.addListener(new ClickListener()
{
#Override
public void clicked(InputEvent event, float x, float y)
{
Gdx.app.log("","Button was pressed");
pauseGame();
}
});
The method pauseGame() that is called after the Listener detects the button being clicked:
public void pauseGame()
{
Gdx.app.log("","Game should be pausing");
screen.pauseGame();
}
screen is a class called PlayScreen that is the main game screen for my game, and its pauseGame() method works perfectly. The game before you press the pause button is as follows(You can see the pause button in the top right corner, please excuse the graphics, they are simply placeholders until I make and add my own graphics):
Game before pause
In my main PlayScreen class, this is my pauseGame method:
public void pauseGame()
{
gamePaused = true;
if(music.isPlaying())
{
musicType = type.NORMAL;
music.pause();
}
else if(barrageMusic.isPlaying())
{
musicType = type.BARRAGE;
barrageMusic.pause();
}
createPauseWindow();
}
And then in my render method, I call another method called update. In this method, I update my viewport, my HUD, and create new enemies. This is the only method that stops being called when gamePaused is true. The rest of my rendering and other necessary updates still take place. I have been trying to fix this problem for a long time but no matter how many different ways I rewrite the code to pause the game or make different listeners, the pause button only works one time and then never again.
Have you ever tried with touchDown method?
It might works.
button.addListener(new ClickListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
pause();
event.handle();
return true;
}
});
And try to change to a global variable base, a variable that is checked inside your render method and if it is true call the pause method. That to avoid call complex actions like pause from a listener, something like this:
button.addListener(new ClickListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
pause = true;
event.handle();
return true;
}
});
...
public void render(){
if (pause == true){
pauseGame();
}
...
}
It simplifies your listener and let you find easily your error.
I just want to check that the power button is pressed or not in LibGDX and if it is pressed then exit/close the game or something else like change screen.
I used this code:
#Override
public void render(SpriteBatch sb) {
sb.begin();
if(Gdx.input.isKeyPressed(Input.Keys.POWER)){
Gdx.app.exit();
}
sb.end();
}
but this is not working. After I press the button screen turns off and when I turn it back on the game resumes from exactly where I left it.
I wanted to keep the screen on on power button press but I didn't find any solution on that.
Now I at least want to access the button and then do something on button press.
the same code works for volume up/down button.
Code:
#Override
public void render(SpriteBatch sb) {
sb.begin();
if(Gdx.input.isKeyPressed(Input.Keys.VOLUME_UP)){
Gdx.app.exit();
}
sb.end();
}
Please describe if I'm doing anything wrong and what shall I do.
You can do all saves in pause method that is available in Screen and ApplicationListener classes. It will be called when you exit the app or block device.
#Override
public void pause () {
// save here
}
like the title implies i've got a problem with my application. The application is supposed to run in fullscreen mode (no intention for switching back to window mode), so i designed a footer-bar holding some images (with a Label, in a VBox) so the user could navigate or exit the program.
So after starting the application all Buttons work just fine with touch. Even the Exit-button in my footer-bar responded correctly by opening my custom Dialog. But here starts my Problem. The Dialog is shown by showAndWait()-Method call, but does not respond to Touch-Events. In contrary mouse-events are still processed (i still can use a mouse to click the Buttons in my Dialog and the Dialog is responding correctly).
I hope someone got an idea what i'm doing wrong.
MyDialog.java:
public static boolean showExitDialog(Window owner, ResourceBundle resources) {
LOGGER.info("Showing exit dialog...");
final Dialog<ButtonType> dialog = new Dialog<ButtonType>();
dialog.getDialogPane().getStylesheets().add(MyDialog.getInstace().getCssPath());
dialog.setContentText(resources.getString("label.exitdialog.text"));
dialog.setHeaderText(resources.getString("label.exitdialog.header"));
dialog.initOwner(owner);
dialog.initStyle(StageStyle.TRANSPARENT);
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.getDialogPane().getButtonTypes().add(new ButtonType(resources.getString("btn.Exitdialog.exit"), ButtonData.OK_DONE););
dialog.getDialogPane().getButtonTypes().add(new ButtonType(resources.getString("btn.Exitdialog.cancel"), ButtonData.FINISH));
Optional<ButtonType> result = dialog.showAndWait();
LOGGER.debug("Result: {}", result.get());
if(result.isPresent() && result.get().getButtonData() == ButtonData.OK_DONE) {
LOGGER.info("Closing exit dialog returning true...");
return true;
} else {
LOGGER.info("Closing exit dialog returning false...");
return false;
}
}
In MainApp.java:
private EventHandler<WindowEvent> confirmCloseEventHandler = event -> {
// close event handling logic.
// consume the event if you wish to cancel the close operation.
if(MyDialog.showExitDialog(primaryStage, rb)) {
event.consume();
System.exit(0);
}
};
...
primaryStage.setOnCloseRequest(confirmCloseEventHandler);
In FooterBar.java:
#FXML
private void exitProgramPressedTouch(TouchEvent event) {
event.consume();
controller.getWindow().fireEvent(new WindowEvent(controller.getWindow(), WindowEvent.WINDOW_CLOSE_REQUEST));
}
*Edit* Oh totally forgot: No Exception or anything else is thrown.
I don't know the reason for the described behavior - maybe a bug. However, you could try to listen for ActionEvent instead of TouchEvent. It handles both touch and mouse events:
#FXML
private void exitProgramPressedTouch(ActionEvent event) {
event.consume();
controller.getWindow().fireEvent(new WindowEvent(controller.getWindow(), WindowEvent.WINDOW_CLOSE_REQUEST));
}
Maybe you need also to change the attribute which binds the event listener (from onTouch to onAction) in your FXML file.
Finally, I think, you could avoid System.exit(0); if you consume the close event only when the cancel button has been clicked:
if(!MyDialog.showExitDialog(primaryStage)) {
event.consume();
}
How to hide a tab bar at bottom.
I used android:windowSoftInputMode="adjustPan|adjustResize". I do not get the desired result. I also added the event bus and when the focus on the edit text disappears tab bar:
public void showTabBar()
{
mTabHost.getTabWidget().setVisibility(View.VISIBLE);
}
public void hideTabBar()
{
mTabHost.getTabWidget().setVisibility(View.GONE);
}
But, it flickers, too, is not suitable. What else can I do?
(source: cs629227.vk.me)
I have an SWT WizardDialog with a number of pages. When this dialog first opens I have to do a check for some conditions and if those conditions are met I need to show a popup over the freshly opened dialog.
So I have this code to listen for SWT.Show event. The event listener responds to SWT.Show to conduct its tests and show a message box:
final WizardDialog dialog = new WizardDialog(shell, wizard);
dialog.setTitle("New Wizard");
dialog.create();
dialog.getShell().addListener(SWT.Show, new Listener()
{
private boolean firstShowing = true;
#Override
public void handleEvent(Event event)
{
if (firstShowing && someConditionExists())
{
MessageBox messageBox = new MessageBox(dialog.getShell(), SWT.OK
| SWT.ICON_WARNING);
messageBox.setMessage("Test");
messageBox.open();
firstShowing = false;
}
}
});
dialog.open();
Except it's called too soon! The dialog is not visible when the handler is called. My message box appears before the dialog is visible and the dialog only appears when I dismiss the message box.
So clearly the SWT.Show is unreliable, at least on Windows where I'm running it. I've also tried putting this code into a ShellListener on the activation but that happens even before the SWT.Show example above.
So how do I reliably show a message box when the dialog is made visible?
Plan B is a dirty timer based hack where a timer is set to fire 200 ms into the future and hope that it triggers when the dialog is visible but obviously this could introduce it's own issues.
I'm using in similar situation (need that appStarted() is called after application window is visible) something like below.
public class App extends ApplicationWindow {
#Override
protected Control createContents(Composite parent) {
// ...
getShell().addShellListener(new ShellAdapter() {
#Override
public void shellActivated(ShellEvent shellevent) {
if (!started) {
Shell s = (Shell) shellevent.getSource();
s.setVisible(true);
appStarted();
started = true;
}
}
});
}
}
Maybe You can use the same like below:
final WizardDialog dialog = new WizardDialog(shell, wizard);
dialog.setTitle("New Wizard");
dialog.create();
dialog.getShell().addShellListener(new ShellAdapter() {
#Override
public void shellActivated(ShellEvent shellevent) {
if (firstShowing && someConditionExists()) {
Shell s = (Shell) shellevent.getSource();
s.setVisible(true);
MessageBox messageBox = new MessageBox(dialog.getShell(), SWT.OK | SWT.ICON_WARNING);
messageBox.setMessage("Test");
messageBox.open();
firstShowing = false;
}
}
});
dialog.open();
Instead of hooking the SWT.Show event, you may get more luck with hooking a PaintListener on to your dialog's Composite. (You'll probably want to unhook it during the first execution.)
What about overriding dialog.open() methodon your WizardDialog class? The first line of the overridden method would call super.open(), which would make it visible. Just put your custom code after that, in the .open() method.
The issue with the approach you're taking above appears to be that it responds to a Show event, which is simply notification that Show has been requested, not that the dialog is visible. The Show event could very well be designed to allow you to know when something is about to be shown, and take some action before that happens, as you've experienced.
I know that this is an old thread. But in case someone finds it useful, I found that overriding Dialog.create() rather than Dialog.open() worked for me.
it's called too soon!
I also run recently in the same trouble. The code was executed too early - my upload action (which I wanted to start automatically under some conditions) was started before the page was displayed.
This happens because the page can only be shown after the code in the SWT.SHOW listener or in the inherited setVisible() method is completed.
#Override
public void setVisible(boolean visible) {
if (visible) {
org.eclipse.ui.progress.UIJob("Auto start the upload") {
#Override
public IStatus runInUIThread(IProgressMonitor monitor) {
if (isAutoStartQcUploadSelected)
startUpload();
return Status.OK_STATUS;
}
};
uiJob.schedule();
}
super.setVisible(visible);
}
org.eclipse.ui.progress.UIJob as described FAQ_Can_I_make_a_job_run_in_the_UI_thread has solved the issue.
P.S.: Yes, I know that's an old question :-)
But it is the first one propesed by google and the hint with the UI Job was missing.
The code of marioosh can be further improved, by storing the ShellAdapter in a variable.
Remove the ShellAdapter when the listener is triggered for the first time.
The variable started is no longer needed.
The statement s.setVisible(true); is not necessary, because this event is just triggered when the shell gets visible.
public class App extends ApplicationWindow {
#Override
protected Control createContents(Composite parent) {
// ...
ShellAdapter shellActivatedAdapter = new ShellAdapter() {
#Override
public void shellActivated(ShellEvent shellevent) {
shellevent.getSource().removeShellListener(shellActivatedAdapter);
appStarted();
}
};
getShell().addShellListener(shellActivatedAdapter);
}
}