russjohnson09
russjohnson09

Reputation: 271

Instantiate Class at Specific Time

I am trying to make a simple game using libgdx. One thing that I am stuck with is making enemies spawn at specific times. If I do something like

if (t == 10) 
    new Enemy();

I might miss this specific time or maybe spawn the same enemy twice. What I have right now is something like

float t = 0
float timeElapsed = 0;

update (float delta) {
    timeElapsed += getDeltaTime();
    if (timeElapsed > 0.1) {
        t++;
        timeElapsed = 0;
    }
}

This gives me the approximate elapsed time in tenths of seconds for t, but it really doesn't feel like the way I should be doing this.

Upvotes: 1

Views: 733

Answers (3)

user1542257
user1542257

Reputation: 36

I have a solution I use in my games that might be useful. I actually created a Timer class:

public class Timer
{
    protected float remaining;
    protected float interval;

    public Timer(float interval)
    {
        this.interval = interval;
        this.remaining = interval;
    }

    public boolean hasTimeElapsed() { return (remaining < 0.0F); }

    public void reset() { remaining = interval; }

    public void reset(float interval) {
        this.interval = interval;
        this.remaining = interval;
    }

    public void update(float delta) { remaining -= delta; }
}

You initialize the Timer to a certain time period, then in your update(delta) method you call Timer.update(delta) on all your Timers, then check if any of the timers have elapsed by calling Timer.hasTimeElapsed().

In your case, you only need one Timer object, since the enemies are spawned in sequence. Once you spawn an enemy, you reset the Timer (changing the spawn period if you want) and wait for it to go off again.

You can also modify the Timer object to use the subject-observer pattern in order to trigger callbacks when a timer goes off. This is useful if you have logic that needs to know when a timed event occurs, but the logic does not have direct access to the delta time.

Upvotes: 1

jellyfication
jellyfication

Reputation: 1605

Why do you increment t and then you spawn enemies based on t value. Why don't you do it like this ?

final float step = 0.1f;
float timeElapsed = 0f;

update (float delta) {
    timeElapsed += delta;
    while (timeElapsed > step){
         timeElapsed-=step;
         createEnemy();
    }
}

With this approach, when your game lags and you get delta lets say 0.5f and you step is 0.1, you will create 5 enemies. I don't know if you want or don't want this beviour

Upvotes: 0

sqweek
sqweek

Reputation: 1187

Also, if you have a slow frame with eg. getDeltaTime() = 0.2, the enemy's spawn will be delayed.

The simplest way that comes to mind is to get rid of t - compare directly against timeElapsed, and keep track of the object references to know whether you've spawned each enemy. ie.

if (enemy1 == NULL && elapsedTime > 10) {
    enemy1 = new Enemy();
}
if (enemy2 == NULL && elapsedTime > 30) {
    enemy2 = new Enemy();
}

For a more scalable approach, you could create a linked list of spawn times, and when you spawn an enemy advance the list pointer. That way you only have to compare against one time (the spawn-time on the current list node) per frame.

Addendum: it's rarely a good idea to use == in the context of floating point numbers. See http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html for gory details.

Upvotes: 1

Related Questions