From 58cec8994b75c020485ea394a97c213deee5b205 Mon Sep 17 00:00:00 2001 From: fanmingfei Date: Fri, 4 Mar 2022 17:14:52 +0800 Subject: [PATCH 1/2] feat: setTimeout --- examples/src/gameStart.ts | 77 ++++++++++++++++++++++++++++++ packages/eva.js/lib/game/Ticker.ts | 54 +++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 examples/src/gameStart.ts diff --git a/examples/src/gameStart.ts b/examples/src/gameStart.ts new file mode 100644 index 00000000..4b5dde1e --- /dev/null +++ b/examples/src/gameStart.ts @@ -0,0 +1,77 @@ +import { RendererSystem } from "@eva/plugin-renderer"; +import { Game, GameObject, RESOURCE_TYPE, resource } from "@eva/eva.js" +import { Img, ImgSystem } from "@eva/plugin-renderer-img"; +export const name = 'gameStart'; +export async function init(canvas) { + resource.addResource([ + { + name: 'imageName', + type: RESOURCE_TYPE.IMAGE, + src: { + image: { + type: 'png', + url: 'https://gw.alicdn.com/tfs/TB1DNzoOvb2gK0jSZK9XXaEgFXa-658-1152.webp', + }, + }, + preload: true, + }, + ]); + const game = new Game({ + // autoStart: false, + frameRate: 45, + systems: [ + new RendererSystem({ + canvas, + width: 750, + height: 1000, + }), + new ImgSystem(), + ], + }); + + + + const image = new GameObject('image', { + size: { width: 750, height: 1319 }, + origin: { x: 0, y: 0 }, + position: { + x: 0, + y: -319, + }, + anchor: { + x: 0, + y: 0, + }, + }); + window.game = game + + let start = performance.now() + console.log(game.ticker.time.currentTime, 'add') + game.ticker.setTimeout(() => { + console.log(game.ticker.time.currentTime, 'begin') + console.log(performance.now() - start,3) + + image.addComponent( + new Img({ + resource: 'imageName', + }), + ); + }, 1000) + + + // game.ticker.setTimeout(() => { + // console.log(game.ticker.time.frameCount) + // console.log(performance.now() - start,1) + // }, 2890) + + // game.ticker.setTimeout(() => { + // console.log(game.ticker.time.frameCount) + // console.log(performance.now() - start, 2) + // }, 2990) + + game.scene.addChild(image); + + // setTimeout(()=>{ + // game.start() + // }, 3000) +} \ No newline at end of file diff --git a/packages/eva.js/lib/game/Ticker.ts b/packages/eva.js/lib/game/Ticker.ts index ae94927a..9d4c20b9 100644 --- a/packages/eva.js/lib/game/Ticker.ts +++ b/packages/eva.js/lib/game/Ticker.ts @@ -48,6 +48,24 @@ class Ticker { /** Represents the status of the Ticker, If ticker has started, the value is true */ private _started: boolean; + private _timeoutList: { + timeoutId: number; + startTime: number; + endTime: number; + callback: Function; + delay: number; + args?: any[]; + }[] = [] + private _timeoutId: number = 0 + + public time: UpdateParams = { + deltaTime: 0, + time: 0, + currentTime: 0, + frameCount: 0, + fps: 0, + } + /** * @param autoStart - auto start game * @param frameRate - game frame rate @@ -78,6 +96,40 @@ class Ticker { } } + setTimeout(callback, delay, ...args) { + const delayInfo = { + timeoutId: this._timeoutId++, + startTime: this.time.currentTime, + endTime: this.time.currentTime + delay, + callback, + delay, + args + } + const index = this._timeoutList.findIndex(event => delayInfo.endTime >= event.endTime) + this._timeoutList.splice(index + 1, 0, delayInfo) + + return delayInfo.timeoutId + } + + clearTimeout(timeoutId: number) { + const index = this._timeoutList.findIndex(event => event.timeoutId === timeoutId) + if (index === -1) return + this._timeoutList.splice(index, 1) + } + + private resolveSetTimeout() { + const index = this._timeoutList.findIndex(event => event.endTime <= this.time.currentTime + 0.00000000001) + if (index === -1) return; + const needResolve = this._timeoutList.splice(0, index + 1) + for (const delayInfo of needResolve) { + try { + delayInfo.callback(...delayInfo.args) + } catch (e) { + throw e + } + } + } + /** Main loop, all _tickers will called in this method */ update() { const currentTime = this.timeline.currentTime; @@ -95,7 +147,9 @@ class Ticker { frameCount: ++this._frameCount, fps: Math.round(1000 / deltaTime), }; + this.time = options + this.resolveSetTimeout() for (const func of this._tickers) { if (typeof func === 'function') { func(options); From 83da49b7b5b4cbfd96ec23abca108d948d20ff77 Mon Sep 17 00:00:00 2001 From: fanmingfei Date: Thu, 10 Mar 2022 16:32:01 +0800 Subject: [PATCH 2/2] feat: add setFrameDelay --- packages/eva.js/lib/game/Ticker.ts | 46 ++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/packages/eva.js/lib/game/Ticker.ts b/packages/eva.js/lib/game/Ticker.ts index 9d4c20b9..ecba698b 100644 --- a/packages/eva.js/lib/game/Ticker.ts +++ b/packages/eva.js/lib/game/Ticker.ts @@ -58,6 +58,14 @@ class Ticker { }[] = [] private _timeoutId: number = 0 + private _frameDelayList: { + execFrameNumber: number; + callback: Function; + frameDelayId: number; + }[] = [] + + private _frameDelayId: number = 0 + public time: UpdateParams = { deltaTime: 0, time: 0, @@ -96,6 +104,38 @@ class Ticker { } } + setFrameDelay(callback, frameCount: number) { + if (frameCount < 1 || !frameCount) { + throw 'frameCount must greater than 0' + } + const frameDelayInfo = { + frameDelayId: this._frameDelayId++, + callback, + execFrameNumber: this.time.frameCount + frameCount + } + this._frameDelayList.push(frameDelayInfo) + return frameDelayInfo.frameDelayId; + } + + resolveFrameDelay() { + const index = this._frameDelayList.findIndex(event => event.execFrameNumber <= this.time.frameCount) + if (index === -1) return; + const needResolve = this._frameDelayList.splice(0, index + 1) + for (const delayInfo of needResolve) { + try { + delayInfo.callback() + } catch (e) { + throw e + } + } + } + + clearFrameDelay(frameDelayId: number) { + const index = this._frameDelayList.findIndex(event => event.frameDelayId === frameDelayId) + if (index === -1) return + this._frameDelayList.splice(index, 1) + } + setTimeout(callback, delay, ...args) { const delayInfo = { timeoutId: this._timeoutId++, @@ -118,7 +158,7 @@ class Ticker { } private resolveSetTimeout() { - const index = this._timeoutList.findIndex(event => event.endTime <= this.time.currentTime + 0.00000000001) + const index = this._timeoutList.findIndex(event => event.endTime <= this.time.currentTime + 0.0001) if (index === -1) return; const needResolve = this._timeoutList.splice(0, index + 1) for (const delayInfo of needResolve) { @@ -149,12 +189,14 @@ class Ticker { }; this.time = options - this.resolveSetTimeout() for (const func of this._tickers) { if (typeof func === 'function') { func(options); } } + + this.resolveFrameDelay() + this.resolveSetTimeout() } }