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;
}
Related
I made clone of ""Flappy bird" game by watching video tutorials.i programmed it so that when the bird falls or collides with the tubes a game over message appears on the screen and the game restarts when the player taps on the screen.
The problem is that when the user fails to tap the bird in time and it collides with the tube,the game over screen appears immediately and the user happens to tap on the game over screen which results in restarting of the game.
This makes the user unable to see the score.I have already tried using Thread.sleep().Following is the code
(gameState == 2)
{
batch.draw(gameOver,Gdx.graphics.getWidth()/2-gameOver.getWidth()/2,Gdx.graphics.getHeight()/2-gameOver.getHeight()/2);
try
{
Thread.sleep(2000);
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
if (Gdx.input.justTouched()) {
gameState = 1;
startGame();
score =0;
scoringTube = 0;
velocity = 0;
}
}
With this code the problem is that even the gameover image is being delayed and the previous problem is still occuring but now with a delay.I basically need a way so that justTouched method becomes inactive for a while when the game over screen is there.Please help.
I really wouldn't recommend using Thread.sleep; instead, you could try to use a boolean that is changed once the game ended, and prevent the method from executing in that case. Combine that with e.g a Timer that resets it after a fixed delay, and you should have the solution to your problem.
Example Usage for the timer:
new java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
//execute code here (change boolean state)
}
},
yourDelayHere
);
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.
I'm making match3 game on libGdx. After scanning for matches I have to wait for animations to complete and run scanning again until no more matches left. I do it with Java Timer and when I run application on desktop it works fine but on Android device it crashes after one, two or few more iterations. Any ideas what is wrong?
Timer animationTimer;
scanForMatches(){
//do some stuff
//...
checkAnimationComplete();
}
checkAnimationComplete(){
animationTimer = new Timer();
animationTimer.scheduleAtFixedRate(new TimerTask(){
#Override
public void run() {
boolean animDone = true;
// do some stuff to
// check if anim done
if (animDone){
animationTimer.cancel();
scanForMatches();
}
}
}, 1000, 100);
}
Without looking at the rest of your code, I would highly suggest dropping the timer altogether as it is almost certainly unnecessary in this case and not very efficient. Are you using an Action to animate with a stage, or are you manually moving things based on position in draw()? If you are just moving something in draw(), I would use a boolean flag to signal that it has reached it's destination, like if you are dropping down solved tiles or something. If you are using an Action, it is possible to use a new Action to act as a callback like the following...
myGem.addAction(Actions.sequence(
Actions.moveTo(230f, 115f, 0.25f, Interpolation.linear),
new Action() {
public boolean act(float delta) {
System.out.println("Done moving myGem!");
scanForMatches();
return true;
}
}));
There are quite a few ways to do what you're looking for depending on how you have your grid set up. Post up how you are animating whatever it is so I can take a look. Basically, you need to know exactly when it is done animating so that you can fire off your scan method again.
I have this loop
while (true) {
game.update();
view.repaint();
Thread.sleep(DELAY);
}
In the game.update various components of the game have their position changed and those updates are reflected when the repaint() method is called on the view. The view extends JComponent and loops through the game objects and calls their print methods.
What I want to do is have a boolean called nextLevel in the game and if it's true Flash text on the screen for the player to notify them that they're going onto the next level. Maybe flash 4-5 times. Then continue the game.
Is this possible? I have been playing around with Thead.Sleep() but this only seems to pause the displaying and in the background the game is still going on.
Any ideas on how to do this?
Maybe you want to avoid threading by using a Timer object.
an example like that could be
int flashTimer = 0;
if(nextLevel) {
Timer timer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
//flash something method here
flashTimer++;
}
});
timer.start();
}
and then check your flashTimer if it reaches the number you want then just stop the timer by timer.stop();
Just an idea which seems to me a bit simpler. the 1000 value is milliseconds which is passed and executes the code inside the actionPerformed method every 1 sec.
Hope it helped
I am attempting to create a simple animation in which a series of bubble rotate around a centre point. I have one version of animation where the bubbles spread from the centrepoint before they begin to rotate, which works fine, but as soon as I click one of the images (which sparks the animation) the screen freezes for a moment and then the bubbles appear in their end position, rather than showing each step they made.
What I have so far is:
while(bubble[1].getDegree() != 270)
{
long time = System.currentTimeMillis();
//the below if statement contains the function calls for
//the rotating bubble animations.
next();
draw();
// delay for each frame - time it took for one frame
time = (1000 / fps) - (System.currentTimeMillis() - time);
if (time > 0)
{
try
{
Thread.sleep(time);
}
catch(Exception e){}
}
}
public void draw()
{
for(int i = 1; i < bubble.length; i++)
{
iconLabel[i].setLocation(bubble[i].getX(), bubble[i].getY());
textLabel[i].setLocation((bubble[i].getX()+10),(bubble[i].getY()+10));
}
}
For clarity, the method "next()" merely changes the position of the bubble to the appropriate place, I know this to be functioning as I have had the animation work before but once I implemented the animation to JLabels it stopped working.
Any help would be appreciated.
The drawing is frozen because you block the event dispatch thread. Drawing is done in the same thread as the while loop, and since the loop prevents anything else happening while it's running, swing can get to drawing only after the loop is finished, so only the last position is drawn.
Use a swing Timer instead:
timer = new Timer(delay, new ActionListener() {
public void actionPerformed(ActionEvent e) {
// whatever you need for the animation
updatePositions();
repaint();
}
});
timer.start();
And then call timer.stop() when all the frames you need have been processed.