Libgdx 在特定时间实例化类

Libgdx 在特定时间实例化类,libgdx,Libgdx,我正在尝试使用libgdx制作一个简单的游戏。我一直坚持的一件事是让敌人在特定时间繁殖。如果我做了类似的事情 if (t == 10) new Enemy(); float t = 0 float timeElapsed = 0; update (float delta) { timeElapsed += getDeltaTime(); if (timeElapsed > 0.1) { t++; timeElapsed = 0;

我正在尝试使用libgdx制作一个简单的游戏。我一直坚持的一件事是让敌人在特定时间繁殖。如果我做了类似的事情

if (t == 10) 
    new Enemy();
float t = 0
float timeElapsed = 0;

update (float delta) {
    timeElapsed += getDeltaTime();
    if (timeElapsed > 0.1) {
        t++;
        timeElapsed = 0;
    }
}
我可能会错过这个特定的时间,或者可能会两次繁殖同一个敌人。我现在有点像

if (t == 10) 
    new Enemy();
float t = 0
float timeElapsed = 0;

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

这给了我t的大概运行时间(以十分之一秒为单位),但我确实感觉不应该这样做。

此外,如果你有一个缓慢的帧,例如getDeltaTime()=0.2,敌人的繁殖将被延迟

想到的最简单的方法是去掉t-直接与时间流逝进行比较,并跟踪对象引用,以了解是否产生了每个敌人。即

if (enemy1 == NULL && elapsedTime > 10) {
    enemy1 = new Enemy();
}
if (enemy2 == NULL && elapsedTime > 30) {
    enemy2 = new Enemy();
}
对于更具可伸缩性的方法,您可以创建一个生成时间的链接列表,并且当您生成敌人时,可以推进列表指针。这样,每帧只需比较一次(当前列表节点上的繁殖时间)


附录:在浮点数的上下文中使用==很少是个好主意。查看血淋淋的详细信息。

为什么要增加
t
,然后根据
t
值生成敌人。你为什么不这样做呢

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

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

使用这种方法,当你的游戏落后,你得到了delta,比如说0.5f,你的步长是0.1,你将创造5个敌人。我不知道你是想要还是不想要这个版本

我在游戏中使用了一个可能有用的解决方案。我实际上创建了一个计时器类:

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; }
}
公共类计时器
{
剩余的受保护浮子;
保护浮动间隔;
公共计时器(浮动间隔)
{
这个。间隔=间隔;
这个。剩余=间隔;
}
公共布尔值({return(剩余<0.0F);}
public void reset(){剩余=间隔;}
公共无效重置(浮动间隔){
这个。间隔=间隔;
这个。剩余=间隔;
}
公共无效更新(浮动增量){剩余-=增量;}
}
将计时器初始化为特定的时间段,然后在update(delta)方法中对所有计时器调用Timer.update(delta),然后通过调用Timer.HastinmeeExpressd()检查是否有任何计时器已过期

在你的情况下,你只需要一个定时器对象,因为敌人是按顺序产生的。一旦你繁殖了一个敌人,你就重置计时器(如果你想改变繁殖周期的话)并等待它再次关闭


您还可以修改Timer对象以使用subject observer模式,以便在计时器关闭时触发回调。如果您有需要知道定时事件何时发生的逻辑,但该逻辑无法直接访问增量时间,则此选项非常有用。

谢谢,我以前尝试过此解决方案。我认为你提到的链表是一个更好的方法,因为我将使用很多对象。我在想,我将有一个链接,它的时间递减,直到它达到零,然后移动到列表中的下一个元素。每个元素也会有一个同时产生的敌人列表,如果我需要延迟的话,它会是空白的。听起来是个不错的方法-你也可以通过让多个敌人在时间=0的一行中保持一个列表。另外请注意,您可能必须更改实例化语义(例如,通过将.spawn()方法添加到敌方类中,而不是在构造函数中生成),因为如果您希望保留敌方列表,则需要在列表创建时实例化敌方(或使用某些工厂类型模式)实际上,我最终使用了一个单链表,其中每个节点都是敌人和延迟。敌人被实例化并添加到链表中,但在到达之前不会变为活动状态。然后它们被储存在一系列活跃的敌人中。这是为任何可能感兴趣的人准备的。