libgdx problems with make mouse reappear after seconds of inactivity - java

I have a problem which I have encountered by testing my game, made with LibGDX on my macbook pro laptop (OS X el capitan). I haven't experienced the issue on my windows PC.
The Problem
My problem is, that I have made some code, which makes the mouse hiding after 2 seconds of inactivity, and if the mouse is being dragged again, then it should reappear until it is not moved anymore, and then after 2 seconds of inactivity it should hide again. This is working fine when playing on windows PC, but when using my macbook, it is not working properly, because after the mouse has been hidden (after 2 seconds of inactivity), then it won't appear again.
I am using the method setCursorCatched(true), from the Input class, to hide the mouse, and the same method again, just with a false input, to make it reappear. To check wether the mouse has been moved relative to its last known position, i am using the methods getDeltaX() and getDeltaY(). My own method to check inactivity looks like this.
/* Time for checking mouse inactivity */
private float lastTimeMouseMoved = 0f;
private float elapsedTimeOfInactivity = 0f;
/**
* Check for mouse inactivity. If mouse is inactive for XX seconds or more, then hide it.
* If the mouse is moved show it, and then hide it again after XX seconds of inactivity.
*
* #param deltaTime the elapsed time between each frame.
* #param secondsInactive the time of inactivity in seconds
*/
private void hideMouseAfterInactivity(float deltaTime, float secondsInactive) {
/* If mouse has been moved */
if (Gdx.input.getDeltaX() != 0 || Gdx.input.getDeltaY() != 0) {
/* Show the mouse cursor */
Gdx.input.setCursorCatched(false);
/* Keep track of the last known time which the mouse was moved. */
lastTimeMouseMoved = deltaTime;
elapsedTimeOfInactivity = lastTimeMouseMoved;
} else {
/* check if the time of inactivity is XX seconds or more */
if (elapsedTimeOfInactivity >= lastTimeMouseMoved + secondsInactive) {
/* Hide the mouse cursor */
Gdx.input.setCursorCatched(true);
} else {
/* update the elapsed time of inactivity */
elapsedTimeOfInactivity += deltaTime;
}
}
}
I hope anyone can tell me what is wrong... I also have a problem with getting the mouse to show, when playing the game in fullscreen after I used the setCursorCatched(true). Thanks in advance.

Though it isn't the best solution to the problem, it does the job. What I did was to create a 1x1 pixel transparent image, and then instead of using the method setCursorCatched(boolean catched) to make the mouse visible and invisble, I have created the following method in my main game class, so I can access it in all my other game screens.
//Remember to dispose these on application exit.
private Pixmap normalMouseCursor = new Pixmap(Gdx.files.internal("normal-cursor.png"));
private Pixmap transparentMouseCursor = new Pixmap(Gdx.files.internal("transparent-cursor.png"));
/**
* Set the mouse cursor to either the normal cursor image or a transparent one if hidden.
*
* #param shouldHide true if the mouse should be invisble
*/
public void setMouseCursor(boolean shouldHide) {
if (shouldHide) {
Gdx.graphics.setCursor(Gdx.graphics.newCursor(transparentMouseCursor, 0, 0));
Gdx.app.debug(TAG, "Mouse Cursor is invisible");
} else {
Gdx.graphics.setCursor(Gdx.graphics.newCursor(normalMouseCursor, 0, 0));
Gdx.app.debug(TAG, "Mouse Cursor is visible");
}
}
Only problem here is that the cursor can still click on objects in the game, though it is invisible. A think a solution to this is to make a flag, which is set and used to determine if the mouse cursor is invisible or not.

Related

How to detect whether a sprite wasn´t touched in a certain interval

I´m sorry that the following question is very specific but I´m looking for more than one hour for a solution of my problem: A sprite changes its color every 3 seconds. I can detect whether the user taps the right color but I cannot detect if the user is just waiting for the next color to score. I tried the following code:
private float timeSeconds = 0f;
private float period = 3f;
timeSeconds += Gdx.graphics.getRawDeltaTime();
for (int i=0;i<4;i++) {
if (executed == true && !(sprite[zahl[i]].getBoundingRectangle().contains(touchPoint.x,
touchPoint.y))&& timeSeconds==0 && zahl[4] != zahl[i]) {
timeSeconds = 0;
this.dispose();
game.setScreen(new GameOverScreen(game, Integer.parseInt(score)));
return;
}
}
This code works partly: If the user doesn´t touch the screen, then the GameOverScreen will be shown. But if the user tapps the right color (=sprite), then the GameOverScreen is also shown. However, I want the game to continue if the user tapps the right sprite, and I want to end the game, which means showing the GameOverScreen, if the user doesn´t tap anything on the screen within three seconds.
It's a bit hard to understand what you're asking but I think your aim is for the user to touch the screen at least once in 3 seconds. If the user fails to touch in this time then the game over screen is shown. If the user has touched the screen and the right colour sprite was touched add 3 seconds to touch time. Then if user has touched at least 1 right sprite and fails to touch in 3 seconds move to level complete screen.
Let's star with the GameOverScreen. This screen should take your game object, the score and a boolean to say if game ended or completed. Then you can call the game screen with:
GameOverScreen(game,score,true); // game completed or
GameOverScreen(game,score,false); // game over
Now we have the end screen completed we can add a timer in your game called lastTouched:
float lastTouched = 3f; // 3 seconds of touch time
Next we add a boolean value so we know if the user touched at least one of the right colour sprites:
boolean atLeastOneTouched = false;
Now we lower the timer each frame with:
lastTouched -= Gdx.graphics.getRawDeltaTime();
We check your sprite touch as usual without the timer stuff:
for (int i=0;i<4;i++) {
if (executed == true && !(sprite[zahl[i]].getBoundingRectangle().contains(touchPoint.x,
touchPoint.y)) && zahl[4] != zahl[i]) {
// touched right colour
atLeastOneTouched = true;
lastTouched = 3f; // reset timer
}
}
Lastly we check if the timer has run out and then get according screen based on the atLeastOneTouched boolean:
if(lastTouched <= 0){
if(atLeastOneTouched){
GameOverScreen(game,score,true); // game over complete
}else{
GameOverScreen(game,score,false); // game over failed
}
}

libGDX textured disappearing when tapping home button

I am developing a mobile game for Android with libGDX. I have noticed that when I click the home button and then go back to the game, the player has disappeared. All other actors attached to the stage exist, and when I remove the code that moves the player it is also drawn. It only disappears when it is moving. I have done so much debugging, and sometimes the position seems to update corretly but the player is invisible, but sometimes it is just NaN. I have for example tried to save position and velocity in pause function and provide the player with them in the resume function, but nothing helps.
This is what I am doing in the player update function:
// When these lines are removed, the app works perfectly
velocity.add(0.0f, GRAVITY);
velocity.scl(deltaTime);
position.add(velocity);
velocity.scl(1/deltaTime);
It doesn't even help if I re-create the player in resume function
player2 = new Player(resourceManager.getRegion("player"), new Vector2(320.0f, 350.0f), 300.0f);
Finally I tried to create completely distinct player object that is drawn after the home button is clicked. It is visible, but is does not move:
player2 = new Player(resourceManager.getRegion("player"), new Vector2(320.0f, 350.0f), 300.0f);
Intrestingly enough I was dealing with the same issue today , every texture (actors) remains in screen after resume but not the main actor which was the one who was moving (main actor in my case). After hours debuging I found that when the game state changes between pause and resume the render method (mine looks like this) will get 0 for deltaTime:
#Override public void render(float deltaTime) {
update(delta);
spriteBatch.setProjectionMatrix(cam.combined);
spriteBatch.begin();
spriteBatch.draw(background, cam.position.x - (WIDTH / 2), 0, WIDTH, HEIGHT);
....
spriteBatch.end();}
deltaTime is time elapsed from last render.
apparently there is no time elapsed from pause to resume hence 0.
down the chain of actor updates I was updating my main actor like this
velocity.scl(deltaTime);
position.add(MOVEMENT * deltaTime, velocity.y);
which was passed 0 at very next render after resume hence the NaN (Not a Number).
anyway not sure if there is a better way to go about this or not but this is how I did, a simple check for zero deltaTime in my main actor update method and replace with a very small amount .001f : (please note in subsequent update deltaTime wont be zero and this if statment only get called once and exactly after resume)
public void update(float deltaTime) {
if (deltaTime <= 0) {
deltaTime=.001f;
}
velocity.scl(deltaTime);
position.add(MOVEMENT * deltaTime, velocity.y);
...
}
Oh yeah, I had the same issue before.
What I did was in onPause(), which is called when you press home button, I destroyed all assets references.
Then in onResume(), which is called when you're back, I reassigned the assets again.
render() method continue called when you press home button on Android so it's seems that you player position continue updating with gravity so when you resume your game you not able to see you player on screen so use a flag on position update code and change flag in pause() and resume() method of ApplicationListener interface.
enum GameState{
PAUSED, RESUMED
}
GameState gameState;
#Override
public void create() {
gameState=GameState.RESUMED;
...
}
#Override
public void render() {
Gdx.gl.glClearColor(1,1,1,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if(gameState==GameState.RESUMED) {
velocity.add(0.0f, GRAVITY);
velocity.scl(deltaTime);
position.add(velocity);
velocity.scl(1/deltaTime);
}
}
#Override
public void pause() {
gameState=GameState.PAUSED;
}
#Override
public void resume() {
gameState=GameState.RESUMED;
}

JScrollBar: Stop knob moving further upon hit certain value

I'd like to ask is it possible to stop knob moving further upon hit certain value in JScrollBar ?
For example, set the minimum and maximum value of a vertical scroll bar to 0 and 100. If the user scroll the knob till 60, he or she should not be able to move knob up further but able to move knob down.
Hence, I have simply wrote following adjust listener:
class MyAdjustmentListener2 implements AdjustmentListener
{
public void adjustmentValueChanged(AdjustmentEvent e)
{
label.setText("New Value is " + e.getValue() + " ");
if (e.getValue() < 60 )
{
vbar.setValue(60);
}
}
}
The label is a JLabel I used to monitor the adjusted value, the vbar is a vertical JScrollBar instance. Above code will force the knob jump back to value 60 if user try to move it above the value 60. This slightly different from what I want to achieve.
I have looked into the API of JScrollBar, I didn't found any straight method provided to use. Please share some hints to me here. Thank you for your time and suggestion.

java - Detect Mouse Clicks Anywhere On Screen

I want my app to detect mouse clicks anywhere on the screen without having to have the app focused. I want it to detect mouse events universally even if its minimized. So far I've only been able to detect mouse events within a swing gui.
Autohotkey can detect mouse clicks and get the mouse's position at any time, how can I do this with java?
It is possible with a little trick. Should be 100% cross-platform (tested on Linux & Windows). Basically, you create a small JWindow, make it "alwaysOnTop" and move it around with the mouse using a timer.
Then, you can record the click, dismiss the window and forward the click to the actual receiver using the Robot class.
Short left and right clicks work completely fine in my tests.
You could also simulate dragging and click-and-hold, just forwarding that seems harder.
I have code for this, but it is in my Java extension (JavaX). JavaX does translate into Java source code, so you can check out the example here.
The code in JavaX:
static int windowSize = 11; // odd should look nice. Set to 1 for an invisible window
static int clickDelay = 0; // Delay in ms between closing window and forwarding click. 0 seems to work fine.
static int trackingSpeed = 10; // How often to move the window (ms)
p {
final new JWindow window;
window.setSize(windowSize, windowSize);
window.setVisible(true);
window.setAlwaysOnTop(true);
JPanel panel = singleColorPanel(Color.red);
window.setContentPane(panel);
revalidate(window);
final new Robot robot;
panel.addMouseListener(new MouseAdapter {
// public void mousePressed(final MouseEvent e) {}
public void mouseReleased(final MouseEvent e) {
print("release! " + e);
window.setVisible(false);
int b = e.getButton();
final int mod =
b == 1 ? InputEvent.BUTTON1_DOWN_MASK
: b == 2 ? InputEvent.BUTTON2_DOWN_MASK
: InputEvent.BUTTON3_DOWN_MASK;
swingLater(clickDelay, r {
print("clicking " + mod);
robot.mousePress(mod);
robot.mouseRelease(mod);
});
}
});
swingEvery(window, trackingSpeed, r {
Point p = getMouseLocation();
window.setLocation(p.x-windowSize/2, p.y-windowSize/2);
//print("moving");
});
}

GWT center DialogBox on zoom

i am developing a GWT mobile application with GWT 2.4. i want my DialogBox to be seen always on the center of the user's viewport on zoom or on normal view. On normal view, center() can handle it but when the page is zoom, the DialogBox pops on center of the whole browser window which includes the scroll part of the page not on the center of the user's viewport. how to do this? please help. thanks in advance.
You need to attach a handler to your window that catches the zoom event. In this handler, you call
myDialogBox.setPopupPosition((Window.getClientWidth() - myDialogBox.getOffsetWidth())/2, (Window.getClientHeight() - myDialogBox.getOffsetHeight())/2);
}
You may need to add a check for situations when your dialog is bigger than the browser window, if you want to treat them differently.
i have to implements ResizeHandler on my window and on its constructor, i have added ResizeEvent handler > Window.addResizeHandler(this);. since i'm implementing the ResizeHandler interface, i need to override the following:
#Override
public void onResize(ResizeEvent event) {
if (isShowing() ) { //check if popup is showing
int left = (Window.getClientWidth() * 0.5 - (widthOfMyWindow * 0.5) );
int top = (Window.getClientHeight() * 0.5 - (heightOfMyWindow * 0.5) );
setPopupPosition( left < 10 ? 10 : left, top < 0 ? 0 : top );
}
}

Categories

Resources