11// Import Third-party Dependencies
22import * as THREE from "three" ;
3+ import { EventEmitter } from "@posva/event-emitter" ;
34
45// Import Internal Dependencies
56import {
@@ -18,6 +19,14 @@ import {
1819 type GlobalsAdapter ,
1920 BrowserGlobalsAdapter
2021} from "../adapters/global.ts" ;
22+ import { FixedTimeStep } from "./FixedTimeStep.ts" ;
23+
24+ export type WorldEvents = {
25+ beforeFixedUpdate : [ number ] ;
26+ afterFixedUpdate : [ number ] ;
27+ beforeUpdate : [ number ] ;
28+ afterUpdate : [ number ] ;
29+ } ;
2130
2231export interface WorldOptions <
2332 TContext = WorldDefaultContext
@@ -39,18 +48,21 @@ export interface WorldDefaultContext {
3948export class World <
4049 T = THREE . WebGLRenderer ,
4150 TContext = WorldDefaultContext
42- > {
51+ > extends EventEmitter < WorldEvents > {
4352 renderer : Renderer < T > ;
4453 input : Input ;
4554 loadingManager : THREE . LoadingManager = new THREE . LoadingManager ( ) ;
4655 sceneManager : SceneContract ;
4756 audio : GlobalAudio ;
4857 context : TContext ;
58+ loop : FixedTimeStep ;
4959
5060 constructor (
5161 renderer : Renderer < T > ,
5262 options : WorldOptions < TContext >
5363 ) {
64+ super ( ) ;
65+
5466 const {
5567 sceneManager,
5668 input = new Input ( renderer . canvas , { enableOnExit : options . enableOnExit ?? false } ) ,
@@ -64,6 +76,7 @@ export class World<
6476 this . input = input ;
6577 this . audio = audio ;
6678 this . context = context ;
79+ this . loop = new FixedTimeStep ( ) ;
6780
6881 globalsAdapter . setGame ( this ) ;
6982 }
@@ -101,24 +114,54 @@ export class World<
101114 return this ;
102115 }
103116
104- beginFrame ( ) {
105- this . input . update ( ) ;
106- this . sceneManager . beginFrame ( ) ;
117+ start ( ) {
118+ this . loop . start ( ) ;
119+
120+ return this ;
107121 }
108122
109- fixedUpdate (
110- deltaTime : number
111- ) {
112- this . sceneManager . fixedUpdate ( deltaTime ) ;
123+ stop ( ) {
124+ this . loop . stop ( ) ;
125+
126+ return this ;
113127 }
114128
115- update (
116- deltaTime : number
129+ setFps (
130+ fps : number ,
131+ fixedFps ?: number
117132 ) {
118- this . sceneManager . update ( deltaTime ) ;
133+ this . loop . setFps ( fps , fixedFps ) ;
134+
135+ return this ;
136+ }
137+
138+ tick ( ) {
139+ this . #beginFrame( ) ;
140+ this . loop . tick ( {
141+ fixedUpdate : ( fixedDelta ) => {
142+ const dt = fixedDelta / 1000 ;
143+ this . emit ( "beforeFixedUpdate" , dt ) ;
144+ this . sceneManager . fixedUpdate ( dt ) ;
145+ this . emit ( "afterFixedUpdate" , dt ) ;
146+ } ,
147+ update : ( _interpolation , delta ) => {
148+ const dt = delta / 1000 ;
149+ this . emit ( "beforeUpdate" , dt ) ;
150+ this . sceneManager . update ( dt ) ;
151+ this . renderer . draw ( ) ;
152+ this . emit ( "afterUpdate" , dt ) ;
153+ }
154+ } ) ;
155+
156+ return this . #endFrame( ) ;
119157 }
120158
121- endFrame ( ) : boolean {
159+ #beginFrame( ) {
160+ this . input . update ( ) ;
161+ this . sceneManager . beginFrame ( ) ;
162+ }
163+
164+ #endFrame( ) : boolean {
122165 this . sceneManager . endFrame ( ) ;
123166
124167 if ( this . input . exited ) {
@@ -129,8 +172,4 @@ export class World<
129172
130173 return false ;
131174 }
132-
133- render ( ) {
134- this . renderer . draw ( ) ;
135- }
136175}
0 commit comments