mani-game-engine 1.0.0-pre.4 → 1.0.0-pre.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,45 +1,39 @@
1
- {
2
- "name": "mani-game-engine",
3
- "author": "Jan Mankopf",
4
- "version": "1.0.0-pre.4",
5
- "description": "entity component system game engine for typescript",
6
- "private": false,
7
- "scripts": {
8
- "build": "rimraf lib && tsc",
9
- "watch": "rimraf lib && tsc -w",
10
- "test": "jest",
11
- "test watch": "jest --watch",
12
- "do-pre-publish": "npm publish --dry-run",
13
- "do-publish": "npm publish",
14
- "testme": "mocha --experimental-modules -r ts-node/register tests/**/*.spec.ts "
15
- },
16
- "main": "lib/index.js",
17
- "files": [
18
- "lib/*",
19
- "src/*"
20
- ],
21
- "typings": "lib/index.d.ts",
22
- "license": "MIT",
23
- "devDependencies": {
24
- "@fluffy-spoon/substitute": "^1.88.0",
25
- "@types/jest": "^24.0.13",
26
- "chai": "^4.2.0",
27
- "jasmine-core": "^3.4.0",
28
- "jest": "^24.8.0",
29
- "mani-signal": "^1.0.3",
30
- "mocha": "^6.1.4",
31
- "nyc": "^14.1.1",
32
- "reflect-metadata": "^0.1.13",
33
- "rimraf": "^2.6.3",
34
- "ts-jest": "^24.0.2",
35
- "ts-node": "^8.2.0",
36
- "typescript": "^3.5.1"
37
- },
38
- "peerDependencies": {
39
- "mani-signal": "^1.0.3",
40
- "reflect-metadata": "^0.1.13"
41
- },
42
- "dependencies": {
43
- "mani-injector": "^0.0.2"
44
- }
45
- }
1
+ {
2
+ "name": "mani-game-engine",
3
+ "author": "Jan Mankopf",
4
+ "version": "1.0.0-pre.41",
5
+ "description": "entity component system game engine for typescript",
6
+ "private": false,
7
+ "scripts": {
8
+ "build": "rimraf lib && tsc",
9
+ "watch": "tsc -w",
10
+ "test": "jest",
11
+ "test watch": "jest --watch",
12
+ "do-pre-publish": "npm publish --dry-run",
13
+ "version-up": "npm version prerelease",
14
+ "do-publish": "npm publish"
15
+ },
16
+ "main": "lib/index.js",
17
+ "files": [
18
+ "lib/*",
19
+ "src/*"
20
+ ],
21
+ "typings": "lib/index.d.ts",
22
+ "license": "MIT",
23
+ "devDependencies": {
24
+ "@fluffy-spoon/substitute": "^1.208.0",
25
+ "@types/jest": "^29.2.3",
26
+ "jest": "^29.3.1",
27
+ "reflect-metadata": "^0.1.13",
28
+ "rimraf": "^3.0.2",
29
+ "ts-jest": "^29.0.3",
30
+ "ts-node": "^10.9.1",
31
+ "tslib": "^2.4.1",
32
+ "typescript": "^4.9.3",
33
+ "mani-signal": "^1.0.6"
34
+ },
35
+ "peerDependencies": {
36
+ "reflect-metadata": "^0.1.13",
37
+ "mani-signal": "^1.0.6"
38
+ }
39
+ }
package/src/clock.ts CHANGED
@@ -1,102 +1,163 @@
1
- import {Signal} from 'mani-signal';
2
-
3
- const MIN_TIME_SCALE = 0.00001;
4
-
5
- type OnEarlyUpdateParams = { time: number, deltaTime: number };
6
- type OnUpdateParams = { time: number, deltaTime: number, alpha: number; };
7
- type OnFixedUpdateParams = { time: number, deltaTime: number; };
8
-
9
- const defaultOptions = {
10
- autoStart: true,
11
- fixedDeltaTime: 1 / 60,
12
- maxFrameTime: 0.25,
13
- timeScale: 1,
14
- };
15
-
16
- export type GameClockOptions = Partial<typeof defaultOptions>;
17
-
18
- export class Clock {
19
- private isRunning = false;
20
- private requestId = 0;
21
- private currentTime = 0;
22
- private accumulator = 0;
23
- private gameTime = 0;
24
-
25
- private fixedDeltaTime: number;
26
- private maxFrameTime: number;
27
-
28
- readonly onPrepare = new Signal();
29
- readonly onEarlyUpdate = new Signal<OnEarlyUpdateParams>();
30
- readonly onUpdate = new Signal<OnUpdateParams>();
31
- readonly onFixedUpdate = new Signal<OnFixedUpdateParams>();
32
-
33
- constructor(options?: GameClockOptions) {
34
- const opts = {...defaultOptions, ...options} as Required<GameClockOptions>;
35
- this.fixedDeltaTime = opts.fixedDeltaTime;
36
- this.maxFrameTime = opts.maxFrameTime;
37
- this.timeScale = opts.timeScale;
38
-
39
- opts.autoStart && this.start();
40
- }
41
-
42
- private update = (time: number) => {
43
- const newTime = time * 0.001;
44
- if (!this.isRunning) {
45
- this.currentTime = newTime;
46
- this.isRunning = true;
47
- }
48
-
49
- let frameTime = (newTime - this.currentTime) * this.timeScale;
50
-
51
- if (frameTime > this.maxFrameTime) {
52
- frameTime = this.maxFrameTime;
53
- }
54
-
55
- this.currentTime = newTime;
56
- this.accumulator += frameTime;
57
- let isMultipleFixedUpdate = false;
58
-
59
- this.onPrepare.dispatch();
60
- this.onEarlyUpdate.dispatch({time: this.gameTime, deltaTime: frameTime});
61
- while (this.accumulator >= this.fixedDeltaTime) {
62
- if (isMultipleFixedUpdate) {
63
- this.onPrepare.dispatch();
64
- }
65
- this.onFixedUpdate.dispatch({time: this.gameTime, deltaTime: this.fixedDeltaTime});
66
- isMultipleFixedUpdate = true;
67
- this.accumulator -= this.fixedDeltaTime;
68
- this.gameTime += this.fixedDeltaTime;
69
- }
70
- const alpha = this.accumulator / this.fixedDeltaTime;
71
- this.onUpdate.dispatch({time: this.gameTime + alpha * this.fixedDeltaTime, deltaTime: frameTime, alpha: alpha});
72
- if (this.isRunning) {
73
- this.requestId = requestAnimationFrame(this.update);
74
- }
75
- };
76
-
77
- private _timeScale = 1;
78
-
79
- get timeScale(): number {
80
- return this._timeScale;
81
- }
82
-
83
- set timeScale(value: number) {
84
- this._timeScale = Math.max(value, MIN_TIME_SCALE);
85
- }
86
-
87
- start(): this {
88
- if (this.isRunning) {
89
- return this;
90
- }
91
- this.requestId = requestAnimationFrame(this.update);
92
- return this;
93
- }
94
-
95
- stop() {
96
- if (!this.isRunning) {
97
- return;
98
- }
99
- this.isRunning = false;
100
- cancelAnimationFrame(this.requestId);
101
- }
102
- }
1
+ import {Signal} from 'mani-signal';
2
+ import {OnEarlyUpdateParams, OnFixedUpdateParams, OnUpdateParams} from './types';
3
+
4
+ const MIN_TIME_SCALE = 0.00001;
5
+
6
+ // type OnUpdateParams = { time: number, deltaTime: number, alpha: number; };
7
+
8
+ const defaultOptions = {
9
+ autoStart: true,
10
+ fixedDeltaTime: 1 / 60,
11
+ maxFrameTime: 0.25,
12
+ timeScale: 1,
13
+ };
14
+
15
+ export type Timeout = {
16
+ recall?: number;
17
+ callback: Function;
18
+ callTime: number;
19
+ };
20
+ export type GameClockOptions = Partial<typeof defaultOptions>;
21
+
22
+ export interface Clock {
23
+
24
+ onPrepare: Signal<unknown>;
25
+ onEarlyUpdate: Signal<OnEarlyUpdateParams>;
26
+ onUpdate: Signal<OnUpdateParams>;
27
+ onFixedUpdate: Signal<OnFixedUpdateParams>;
28
+ timeScale: number;
29
+ start(): this;
30
+ stop(): this;
31
+ dispose(): void;
32
+ setTimeout(callback: Function, delay: number): number;
33
+ setInterval(callback: Function, delay: number): number;
34
+ clearTimeout(timeoutId: number): boolean;
35
+ }
36
+
37
+ export class GameClock implements Clock {
38
+ private nextTimeoutId = 0;
39
+ private timeouts = new Map<number, Timeout>();
40
+ private isRunning = false;
41
+ private requestId = 0;
42
+ private currentTime = 0;
43
+ private accumulator = 0;
44
+ private gameTime = 0;
45
+
46
+ private readonly _fixedDeltaTime: number;
47
+ private update = (time: number) => {
48
+ const newTime = time * 0.001;
49
+ if (!this.isRunning) {
50
+ this.currentTime = newTime;
51
+ this.isRunning = true;
52
+ }
53
+
54
+ let frameTime = (newTime - this.currentTime) * this.timeScale;
55
+
56
+ if (frameTime > this.maxFrameTime) {
57
+ frameTime = this.maxFrameTime;
58
+ }
59
+
60
+ this.currentTime = newTime;
61
+ this.accumulator += frameTime;
62
+ let isMultipleFixedUpdate = false;
63
+
64
+ this.onPrepare.dispatch();
65
+ this.onEarlyUpdate.dispatch({time: this.gameTime, deltaTime: frameTime});
66
+
67
+ for (const [id, timeOut] of this.timeouts) {
68
+ if (this.gameTime >= timeOut.callTime) {
69
+ timeOut.callback();
70
+ if (timeOut.recall) {
71
+ timeOut.callTime += timeOut.recall;
72
+ } else {
73
+ this.timeouts.delete(id);
74
+ }
75
+ }
76
+ }
77
+
78
+ while (this.accumulator >= this._fixedDeltaTime) {
79
+ if (isMultipleFixedUpdate) {
80
+ this.onPrepare.dispatch();
81
+ }
82
+ this.onFixedUpdate.dispatch({time: this.gameTime, deltaTime: this._fixedDeltaTime});
83
+ isMultipleFixedUpdate = true;
84
+ this.accumulator -= this._fixedDeltaTime;
85
+ this.gameTime += this._fixedDeltaTime;
86
+ }
87
+ const alpha = this.accumulator / this._fixedDeltaTime;
88
+ this.onUpdate.dispatch({time: this.gameTime + alpha * this._fixedDeltaTime, deltaTime: frameTime, alpha: alpha});
89
+ if (this.isRunning) {
90
+ this.requestId = requestAnimationFrame(this.update);
91
+ }
92
+ };
93
+
94
+ private readonly maxFrameTime: number;
95
+
96
+ readonly onPrepare = new Signal();
97
+ readonly onEarlyUpdate = new Signal<OnEarlyUpdateParams>();
98
+ readonly onUpdate = new Signal<OnUpdateParams>();
99
+ readonly onFixedUpdate = new Signal<OnFixedUpdateParams>();
100
+
101
+ constructor(options?: GameClockOptions) {
102
+ const opts = {...defaultOptions, ...options} as Required<GameClockOptions>;
103
+ this._fixedDeltaTime = opts.fixedDeltaTime;
104
+ this.maxFrameTime = opts.maxFrameTime;
105
+ this.timeScale = opts.timeScale;
106
+
107
+ opts.autoStart && this.start();
108
+ }
109
+
110
+ dispose(): void {
111
+ this.onPrepare.detachAll();
112
+ this.onEarlyUpdate.detachAll();
113
+ this.onUpdate.detachAll();
114
+ this.onFixedUpdate.detachAll();
115
+ }
116
+
117
+ get fixedDeltaTime(): number { return this._fixedDeltaTime; }
118
+
119
+ private _timeScale = 1;
120
+
121
+ get timeScale(): number {
122
+ return this._timeScale;
123
+ }
124
+
125
+ set timeScale(value: number) {
126
+ this._timeScale = Math.max(value, MIN_TIME_SCALE);
127
+ }
128
+
129
+ start(): this {
130
+ if (this.isRunning) {
131
+ return this;
132
+ }
133
+ this.requestId = requestAnimationFrame(this.update);
134
+ return this;
135
+ }
136
+
137
+ stop(): this {
138
+ if (!this.isRunning) {
139
+ return this;
140
+ }
141
+ this.isRunning = false;
142
+ cancelAnimationFrame(this.requestId);
143
+ return this;
144
+ }
145
+
146
+ setTimeout(callback: Function, delay: number) {
147
+ const timeOut: Timeout = {callback, callTime: this.gameTime + delay};
148
+ this.nextTimeoutId++;
149
+ this.timeouts.set(this.nextTimeoutId, timeOut);
150
+ return this.nextTimeoutId;
151
+ }
152
+
153
+ setInterval(callback: Function, delay: number) {
154
+ const timeOut: Timeout = {callback, callTime: this.gameTime + delay, recall: delay};
155
+ this.nextTimeoutId++;
156
+ this.timeouts.set(this.nextTimeoutId, timeOut);
157
+ return this.nextTimeoutId;
158
+ }
159
+
160
+ clearTimeout(timeoutId: number) {
161
+ return this.timeouts.delete(timeoutId);
162
+ }
163
+ }