5

I have now tried to set up a delay in libGDX in three different ways.

First I tried to use a Timer, but if I restart the activity, the timer won't start again. This is a known issue when using GestureDetector: https://github.com/libgdx/libgdx/issues/2274

Then I tried setting up a timer using Gdx.graphics.getDeltaTime in my render method, but this doesn't work for me as I have set it to non-continous rendering. Described in answer #2 set a delay in libgdx game

Finally I tried using a while loop and System.getCurrentTimeMilliseconds, however this prevented the application from recognizing a tap while the while loop was looping.

I have also heard of DelayAction, but how does one implement that into the code? https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/actions/DelayAction.html

Is there another way of setting a delay? How do one implement DelayAction? Or how does one fix the Timer bug in libGDX?

Community
  • 1
  • 1
anonymos
  • 167
  • 2
  • 14

3 Answers3

2

Inspired by Barodapride's comment, I found a solution where I make a new thread, and put the while loop here. This code will wait for 1000 ms, and then run foo() on the main thread.

new Thread(new Runnable() {
            @Override
            public void run() {
                long time = System.currentTimeMillis();
                while (System.currentTimeMillis() < time + 1000){}
                Gdx.app.postRunnable(new Runnable() {
                    @Override
                    public void run() {
                        foo();
                    }
                });
            }
        }).start();
Community
  • 1
  • 1
anonymos
  • 167
  • 2
  • 14
0

Well i just create an interface like this:

public interface TimeEvents {
    public void handleTime(float secondsToEvent,Events event, Object obj);
    public void resetTimer();
    public void handleEvent(Events event,Object obj);
}

and create a class implementing it for the game entity i want, the Events for my case is an enum with the event to process (Like wait for x seconds, walk for x seconds, fire for x seconds..), the object is the instance of target object i want to handle by event..

 public class FooTimeEvents implements TimeEvents{
     [...]
        private float timeSeconds = 0;
        @Override
        public void handleTime(float secondsToEvent,Events event, Object obj){
            timeSeconds +=Gdx.graphics.getRawDeltaTime();
            if(timeSeconds > secondsToEvent){
                timeSeconds-=secondsToEvent;
                handleEvent(event,obj);
            }
        }

    @Override
      public void handleEvent(Events event,Object obj){
        switch (event) {
            case EVENT_FOO_1:
                executeEventFoo1((Foo1Obj)obj);
                break;
            case EVENT_FOO_2:
                 executeEventFoo2((Foo2Obj)obj);
                break;
            default:
                break;
        }
    }
    [...]

you call the handleTime on render method of the entity, and the event will only execute each timeSeconds it was set to..

Hllink
  • 918
  • 5
  • 17
  • Thank you so much for the answer, but that became a little bit too complicated for me, I guess you would have to elaborate and specify further on what is supposed to be in which classes, and which classes implement what. Furthermore, it would also be great if you could specify exactly what I would call in my LIBGDX class to call a method with a delay. My apologies for not seeing what is probably very obvious, but I am still quite the beginner. – anonymos May 05 '16 at 17:11
  • can you tell me exactly what are you tring to do? im avaliable at the libgdx freenode chat as well if you want to chat.. – Hllink May 05 '16 at 18:40
  • ofc, thank you so much for sticking around. I really appreciate it. Once in a while in my MyGdxGame class I need to call my method foo(), but this must have a delay of a couple of seconds. While waiting for this method to run, I must still be able to detect touches etc. on the screen. That should be all, actually. – anonymos May 05 '16 at 20:44
  • on your MyGdxGame class declare: private float timeSeconds = 0;, in your render method set timeSeconds += Gdx.graphics.getRawDeltaTime(); if(timeSeconds > 4){ foo();} this code would exactly wait 4 seconds and call foo(). Eveytime you set timeSeconds to 0 it will wait 4 seconds and call foo again. – Hllink May 05 '16 at 20:49
  • Just before I test it out. Would this work when i have non-continuos rendering? That is, it only calls the render method when there are changes to the screen, which is not frequently enough to use that method as a reliable "loop" – anonymos May 05 '16 at 20:52
0

You can use a RunnableAction with a DelayAction. Here are the steps you would take:

  1. Instantiate a RunnableAction and provide it with a Runnable:

    RunnableAction runnableAction = Actions.run(new Runnable(){

    public void run(){

    // Put whatever you want to do here

    }

    }

  2. Instantiate a DelayAction and provide it with your RunnableAction:

    DelayAction delayAction = Actions.delay(secondsOfDelay, runnableAction);

  3. Now in your render or update method you need to tell your delayAction to 'act':

    delayAction.act(delta);

Once the delay has passed the code in your runnable should run. I'm sorry if this syntax isn't exactly correct but this should be the easiest way to go. Let me know if something doesn't work for you and I can help.

Barodapride
  • 3,475
  • 4
  • 25
  • 36
  • This won't work in my render method as I have non-continous rendering, will it? – anonymos May 05 '16 at 20:57
  • 1
    Oh no, I guess not. I think you'll have to do something like in the code snippet here: https://github.com/libgdx/libgdx/wiki/Threading You could probably encapsulate a timer in there so that it's running in a different thread and not affecting your gesture listener. I don't know if that will fix the Timer bug you mentioned but it's worth a shot. – Barodapride May 05 '16 at 21:40
  • This also seems to be connected to the render method, and call stuff at e.g. the next frame, thus it won't work for me with my non-continuos rendering. – anonymos May 05 '16 at 21:45
  • 1
    Are you sure? How did you see that it's tied to the render method? – Barodapride May 06 '16 at 00:39
  • Yeah, you're right, not related to the render method. However, putting the Timer in another thread didn't fix the Timer bug. – anonymos May 06 '16 at 09:35