Grim Reaper
Grim Reaper

Reputation: 561

Libgdx Timer every 5 seconds if a condition is true until a condition is true

I am making my first LibGdx game and I need help with my energy system. So basically in my player class I have an:

int curEnergy = 100;

int maxEnergy = 100;

boolean allowRegen = false;

Then I have my movement code:

if (Gdx.input.isKeyPressed(Keys.W)) {
            if (curEnergy > 0) {
                if (Gdx.input.isKeyPressed(Keys.SHIFT_LEFT)) {
                    position.y += 2.5f;
                    curEnergy--;
                }
            } else {
                allowRegen = true;
                checkIfEnergyIsZero();

            }
            position.y += 2f;
        }

        if (Gdx.input.isKeyPressed(Keys.A)) {
            if (curEnergy > 0) {
                if (Gdx.input.isKeyPressed(Keys.SHIFT_LEFT)) {
                    position.x -= 2.5f;
                    curEnergy--;
                }
            } else {
                allowRegen = true;
                checkIfEnergyIsZero();
            }
            position.x -= 2f;
        }

        if (Gdx.input.isKeyPressed(Keys.D)) {
            if (curEnergy > 0) {
                if (Gdx.input.isKeyPressed(Keys.SHIFT_LEFT)) {
                    position.x += 2.5f;
                    curEnergy--;
                }
            } else {
                allowRegen = true;
                checkIfEnergyIsZero();
            }
            position.x += 2f;
        }

        if (Gdx.input.isKeyPressed(Keys.S)) {
            if (curEnergy > 0) {
                if (Gdx.input.isKeyPressed(Keys.SHIFT_LEFT)) {
                    position.y -= 2.5f;
                    curEnergy--;
                }
            } else {
                allowRegen = true;
                checkIfEnergyIsZero();
            }
            position.y -= 2f;
        }

    }

So, when my curEnergy is 0 I call the checkIfEnergyIsZero function, and this is what I need help with:

public void checkIfEnergyIsZero() {
        if (allowRegen) {
            float delay = 10; // seconds




            Timer.schedule(new Task() {
                @Override
                public void run() {
                    if (curEnergy == 0) {
                        for (int i = 0; i < maxEnergy; i++) {
                            curEnergy += 1;
                            allowRegen = false;
                        }
                    }
                }
            }, delay);


        }



    }

So this code basically, when I sprint by holding shift, decreases the curEnergy by 1, then if the curEnergy is 0 it makes a timer that runs after 10 seconds, but what I want it to do is: When the energy is 0, wait 5 seconds and add 10 energy, then wait 5 seconds again and add 10 energy, then wait 5 seconds and add 10 energy and so on until the curEnergy integer is equals to the maxEnergy Integer which is currently set to 100;

If I forgot to add some code please tell me.

Thank you very much!

Upvotes: 0

Views: 892

Answers (1)

P.T.
P.T.

Reputation: 25177

Instead of having a timer fire after N seconds, another approach is to set a deadline, and then check it each time through your render loop. So at the top of your loop do something like:

long now = com.badlogic.gdx.utils.TimeUtils.millis();

to get the current time. Then check to see if you need to bump the energy:

if (energyBumpTime != 0 && energyBumpTime <= now) {
   curEnergy += 5; // perhaps check for hitting the max limit.

   energyBumpTime = 0; // to disable
   // OR 
   energyBumpTime = now + (5 * 1000); // schedule another bump in 5 seconds.
}

This way you can easily change the schedule. So, for example, if the player uses some energy, you may want to reschedule the bump for 5 more seconds from now:

   curEnergy -= 1; // use a bit
   energyBumpTime = now + (5 * 1000); // and delay the regeneration

I think this will be easier to manipulate than to fire timers and cancel them and change their timeouts.

Upvotes: 1

Related Questions