1

我如何使动作延迟发生,但在超时之后?

setTimeout()功能在 Decentraland 场景中不起作用,那么有替代方案吗?

例如,我希望实体300在单击后等待几毫秒,然后再将其从引擎中删除。

4

2 回答 2

1

要实现这一点,您必须创建:

  • 用于跟踪时间的自定义组件
  • 一个组件组,用于跟踪场景中所有具有延迟的实体
  • 更新计时器的系统在每一帧上都包含所有这些组件。

这听起来相当复杂,但是一旦你创建了一个延迟,实现另一个延迟只需要一行。

组件:

@Component("timerDelay")
export class Delay implements ITimerComponent{
    elapsedTime: number;
    targetTime: number;
    onTargetTimeReached: (ownerEntity: IEntity) => void;
    private onTimeReachedCallback?: ()=> void

    /**
     * @param millisecs amount of time in milliseconds
     * @param onTimeReachedCallback callback for when time is reached
     */
    constructor(millisecs: number, onTimeReachedCallback?: ()=> void){
        this.elapsedTime = 0
        this.targetTime = millisecs / 1000
        this.onTimeReachedCallback = onTimeReachedCallback
        this.onTargetTimeReached = (entity)=>{
            if (this.onTimeReachedCallback) this.onTimeReachedCallback()
            entity.removeComponent(this)
        }
    }
}

组件组:

export const delayedEntities = engine.getComponentGroup(Delay)

系统:

// define system

class TimerSystem implements ISystem {   

        update(dt: number){
            for (let entity of delayedEntities.entities) {
                let timerComponent = entity.getComponent(component)
                timerComponent.elapsedTime += dt
                if (timerComponent.elapsedTime >= timerComponent.targetTime){
                    timerComponent.onTargetTimeReached(entity)
                }
            })
        }    
    }

// instance system
engine.addSystem(new TimerSystem())

一旦所有这些部分都到位,您可以简单地执行以下操作来延迟场景中的执行:

const myEntity = new Entity()

myEntity.addComponent(new Delay(1000, () => {
    log("time ran out")
}))

engine.addEntity(myEntity)

于 2019-07-12T16:43:39.993 回答
0

使用 utils 库中的 utils.Delay() 函数。这个函数只需要以毫秒为单位的延迟时间,以及你想要执行的函数。

这是完整的文档,解释了如何添加库+如何使用这个函数,包括示例代码:

https://www.npmjs.com/package/decentraland-ecs-utils

于 2019-09-10T15:59:44.057 回答