使用Decentraland的ECS延迟操作

时间:2019-07-11 12:59:22

标签: decentralized-applications decentraland decentraland-ecs

如何使动作延迟但超时后发生?

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

例如,我希望一个实体在被点击后300毫秒后才能从引擎中删除。

2 个答案:

答案 0 :(得分:0)

要实现此目的,您必须创建:

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

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

组件:

@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)

答案 1 :(得分:0)

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

这里是完整的文档,解释了如何添加库以及如何使用此功能,包括示例代码:

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