Bug in game. May be Timer();

Anything libgdx related goes here!

Bug in game. May be Timer();

Postby BarraBod » Sat Jul 15, 2017 11:48 am

Hi,

I added Google play services to my game last week and its started a small bug. it doesn't happen very often, but it happens!

In my game, when I shoot a shark it creates an explosion, which last for around half a second. I use the Timer() class for this. Also in my game when a shark hits the Sub, the submarine explodes, the game waits for around half a second again before changing screens and ending the game. The problem I sometimes get is the explosion happens but they stay on screen. When the submarine gets hit, it creates the explosion but the game doesn't end. I am starting to think it might be a problem with the timer.


I have pasted some code below but I am wonder if there are better alternatives to using Timer().

Code: Select all
//This code is inside a while loop which checks for collisions
 if (currentShark.getBounds().overlaps(sub.getBounds()) || sub.getPosition().y <= 13 || sub.getBounds().overlaps(rock.getBounds())) {
                sub.setSprite(subExplosion);
                sub.setVelocity(new Vector2(0, 0));
                sub.isHit(true);
                sub.setSprite(subExplosion);

                Timer.schedule(new Timer.Task() {
                    @Override
                    public void run() {
                        if (isDisposed) {
                            dispose();
                            main.setScreen(new com.BodGame.SubSea.GameOverScreen(main, score, actionResolver, returnScore()));
                            isDisposed = false;
                        }
                    }
                }, 0.5f);



Thank you.
BarraBod
 
Posts: 17
Joined: Mon Mar 13, 2017 2:45 am

Re: Bug in game. May be Timer();

Postby litelitelite » Sun Jul 16, 2017 9:27 am

Best to assume that the timer is doing everything you ask it to do perfectly, so you have a bug like not starting the timer, or a race condition on isDisposed, or you show two explosions and only hide one or frankly just some random bug. V. difficult to say with the code below, but things like setting the sprite on the sub twice in the snippet suggests that you may be going a bit snow blind with the issue!

If you can't reproduce the bug reliably, then I would recommend setting a "trap" that gives you more info each time it happens. This could be as simple as adding a log line before every line of code that should show or hide the explosion. Checking which logging lines were hit and which were not will help you isolate the problem.

If you have seen enough of the Timer class now, you could make your explosion a scene2d Actor (maybe by extending Image) and then use Actions to control the wait logic (i.e. sequence of wait, then remove from stage for the explosion, wait and then change screen for the sub hit).
litelitelite
 
Posts: 7
Joined: Sat Jul 15, 2017 9:43 pm

Re: Bug in game. May be Timer();

Postby MrStahlfelge » Sun Jul 16, 2017 9:35 am

The Timers have indeed a problem if there are more instances of your application around. You are telling that you added Play services. That will not cause the problem I am describing, but if you added Play Games and started your game from the Play Games app after it was started from Android's Main Launcher before, you get an application with non-working timers. Same if you start the game from Play store or from the screen after installing an apk manually.

You can get rid of this problem in most cases by adding the following line to your AndroidManifest:

Code: Select all
            android:screenOrientation="portrait"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
--->       android:launchMode="singleTask"> <----


Then the problem is only still around when you change the system's language and start your game.
MrStahlfelge
 
Posts: 21
Joined: Thu Jun 15, 2017 6:40 am

Re: Bug in game. May be Timer();

Postby CodeMaven » Tue Jul 18, 2017 11:51 am

I think in general it would be a good idea to avoid timers in a libgdx game and just use counters or the Scene2d actions framework. I tend to use the Scene2d actions for this sort of thing quite a bit, it works great. If I don't need a whole actor then just a counter suffices. Simply set a float to the number of seconds you want to delay by and then in your render loop do something like this:
if (counter<=0) { /* do stuff */ }
else counter -= delta; // Where delta is the time elapsed since the last frame...

Doing this doesn't allow for precise timing but it keeps everything synchronised nicely on your main render thread and it's fairly clear if you have a couple of timers... Now if you have more than 2 or 3 then it can get out of hand....

Cheers,
Troy.
CodeMaven
 
Posts: 54
Joined: Sat Sep 13, 2014 5:24 pm

Re: Bug in game. May be Timer();

Postby HD_92 » Sun Jul 23, 2017 2:48 pm

I totally agree with @CodeMaven. I was using Timers myself to create delayed actions like level transitions or special effects. However it sometimes happened that the timer was not triggered. Since I switched to scene2d actions, these problems are gone.

Here is a little code snippet handy for creating delayed actions:
Code: Select all

public void runAfterDelay(float delay, Runnable run) {
     // Considering you have access to the stage.
     stage.addAction(Actions.delay(delay, Actions.run(run)));
}

HD_92
 
Posts: 433
Joined: Sun Jan 06, 2013 4:43 pm


Return to Libgdx

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 6 guests