Задержка действий с использованием ECS Decentraland - PullRequest
1 голос
/ 11 июля 2019

Как заставить действие произойти с задержкой, но по истечении времени ожидания?

Функция setTimeout() не работает в сценах Decentraland, поэтому есть альтернатива?

Например, я хочу, чтобы объект ждал 300 миллисекунд после щелчка, прежде чем удалить его из движка.

1 Ответ

1 голос
/ 12 июля 2019

Для этого вам нужно создать:

  • Пользовательский компонент для отслеживания времени
  • Группа компонентов для отслеживания всех объектов с задержкой в ​​сцене
  • Система, которая обновляет таймеры со всеми этими компоненты на каждом кадре.

Звучит довольно сложно, но как только вы создали одну задержку, реализация другой задержки займет всего одну строку.

Компонент:

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

...