@cjcoding-git/gamelib 0.0.0-stage → 1.1.3

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.
Files changed (136) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  3. package/.github/dependabot.yml +6 -0
  4. package/.github/workflows/build.yml +54 -0
  5. package/.github/workflows/release.yml +79 -0
  6. package/LICENSE +21 -0
  7. package/README.md +6 -2
  8. package/assets/test-frog.gltf +1921 -0
  9. package/assets/test-frog.gml +0 -0
  10. package/buildtime.txt +1 -0
  11. package/buildversion.txt +1 -0
  12. package/dist/GameLib.js +71599 -0
  13. package/dist/GameLib.min.js +8 -0
  14. package/docs/2D/API.md +1 -0
  15. package/docs/2D/GETTING_STARTED.md +1 -0
  16. package/docs/3D/API.md +1 -0
  17. package/docs/3D/GETTING_STARTED.md +23 -0
  18. package/docs/Core/API.md +1 -0
  19. package/docs/Core/GETTING_STARTED.md +1 -0
  20. package/docs/README.md +32 -0
  21. package/package.json +21 -4
  22. package/scripts/gltf2gml.html +312 -0
  23. package/src/2D/Box.js +42 -0
  24. package/src/2D/Coord.js +17 -0
  25. package/src/2D/GameLib.js +317 -0
  26. package/src/2D/Renderable.js +31 -0
  27. package/src/2D/Rotation.js +42 -0
  28. package/src/2D/Size.js +17 -0
  29. package/src/2D/Sprite.js +56 -0
  30. package/src/2D/UI/Button.js +52 -0
  31. package/src/2D/UI/TextInput.js +77 -0
  32. package/src/2D/UI/UIElement.js +10 -0
  33. package/src/2D/UI/index.js +15 -0
  34. package/src/2D/index.js +24 -0
  35. package/src/3D/Camera.js +25 -0
  36. package/src/3D/GameLib.js +202 -0
  37. package/src/3D/Geometry/Box.js +39 -0
  38. package/src/3D/Geometry/Cone.js +45 -0
  39. package/src/3D/Geometry/ModelLoaders/GLBLoader.js +12 -0
  40. package/src/3D/Geometry/ModelLoaders/GLTFLoader.js +12 -0
  41. package/src/3D/Geometry/ModelLoaders/GMLLoader.js +114 -0
  42. package/src/3D/Geometry/ModelLoaders/OBJLoader.js +12 -0
  43. package/src/3D/Geometry/ModelLoaders/index.js +17 -0
  44. package/src/3D/Geometry/Pyramid.js +55 -0
  45. package/src/3D/Geometry/Sphere.js +37 -0
  46. package/src/3D/Geometry/index.js +19 -0
  47. package/src/3D/Lighting/AmbientLight.js +17 -0
  48. package/src/3D/Lighting/DirectionalLight.js +17 -0
  49. package/src/3D/Lighting/PointLight.js +17 -0
  50. package/src/3D/Lighting/index.js +15 -0
  51. package/src/3D/Material.js +181 -0
  52. package/src/3D/Mesh.js +142 -0
  53. package/src/3D/Object.js +13 -0
  54. package/src/3D/Position.js +15 -0
  55. package/src/3D/Rotation.js +21 -0
  56. package/src/3D/Scale.js +10 -0
  57. package/src/3D/ShaderFactory/FunctionParam.js +14 -0
  58. package/src/3D/ShaderFactory/Modifiers/Variable.js +85 -0
  59. package/src/3D/ShaderFactory/Modifiers/index.js +11 -0
  60. package/src/3D/ShaderFactory/Node.js +25 -0
  61. package/src/3D/ShaderFactory/NodeTypes/A.js +9 -0
  62. package/src/3D/ShaderFactory/NodeTypes/Add.js +13 -0
  63. package/src/3D/ShaderFactory/NodeTypes/AssignVariable.js +11 -0
  64. package/src/3D/ShaderFactory/NodeTypes/Clamp.js +14 -0
  65. package/src/3D/ShaderFactory/NodeTypes/Constant.js +9 -0
  66. package/src/3D/ShaderFactory/NodeTypes/Define.js +11 -0
  67. package/src/3D/ShaderFactory/NodeTypes/Divide.js +13 -0
  68. package/src/3D/ShaderFactory/NodeTypes/Dot.js +14 -0
  69. package/src/3D/ShaderFactory/NodeTypes/Exp2.js +9 -0
  70. package/src/3D/ShaderFactory/NodeTypes/Function.js +36 -0
  71. package/src/3D/ShaderFactory/NodeTypes/Group.js +9 -0
  72. package/src/3D/ShaderFactory/NodeTypes/Header.js +12 -0
  73. package/src/3D/ShaderFactory/NodeTypes/Length.js +9 -0
  74. package/src/3D/ShaderFactory/NodeTypes/MainFunction.js +7 -0
  75. package/src/3D/ShaderFactory/NodeTypes/Max.js +14 -0
  76. package/src/3D/ShaderFactory/NodeTypes/Mix.js +14 -0
  77. package/src/3D/ShaderFactory/NodeTypes/Multiply.js +13 -0
  78. package/src/3D/ShaderFactory/NodeTypes/Negative.js +9 -0
  79. package/src/3D/ShaderFactory/NodeTypes/NodeTypes.js +9 -0
  80. package/src/3D/ShaderFactory/NodeTypes/Normalize.js +10 -0
  81. package/src/3D/ShaderFactory/NodeTypes/Precision.js +11 -0
  82. package/src/3D/ShaderFactory/NodeTypes/RGB.js +9 -0
  83. package/src/3D/ShaderFactory/NodeTypes/Subtract.js +13 -0
  84. package/src/3D/ShaderFactory/NodeTypes/Symbol.js +9 -0
  85. package/src/3D/ShaderFactory/NodeTypes/Texture2D.js +10 -0
  86. package/src/3D/ShaderFactory/NodeTypes/Variable.js +22 -0
  87. package/src/3D/ShaderFactory/NodeTypes/Vector.js +15 -0
  88. package/src/3D/ShaderFactory/NodeTypes/XYZ.js +9 -0
  89. package/src/3D/ShaderFactory/NodeTypes/index.js +32 -0
  90. package/src/3D/ShaderFactory/PrecisionTypes.js +8 -0
  91. package/src/3D/ShaderFactory/Program.js +41 -0
  92. package/src/3D/ShaderFactory/VariableTypes.js +49 -0
  93. package/src/3D/ShaderFactory/index.js +45 -0
  94. package/src/3D/Texture.js +59 -0
  95. package/src/3D/TextureFactory.js +22 -0
  96. package/src/3D/Transform.js +35 -0
  97. package/src/3D/UI/UIImage.js +24 -0
  98. package/src/3D/UI/UILoading.js +41 -0
  99. package/src/3D/UI/UIObject.js +16 -0
  100. package/src/3D/UI/UIPath.js +25 -0
  101. package/src/3D/UI/UIRenderer.js +207 -0
  102. package/src/3D/UI/UIText.js +35 -0
  103. package/src/3D/UI/index.js +19 -0
  104. package/src/3D/Utils.js +9 -0
  105. package/src/3D/index.js +43 -0
  106. package/src/Core/AssetManager.js +116 -0
  107. package/src/Core/AudioManager.js +151 -0
  108. package/src/Core/Error.js +9 -0
  109. package/src/Core/FullscreenManager.js +49 -0
  110. package/src/Core/GameLibBase.js +29 -0
  111. package/src/Core/InputManager.js +195 -0
  112. package/src/Core/Loading.js +111 -0
  113. package/src/Core/Matrix/index.js +11 -0
  114. package/src/Core/Matrix/mat4.js +178 -0
  115. package/src/Core/Multiplayer.js +54 -0
  116. package/src/Core/Network/PeerNetwork.js +410 -0
  117. package/src/Core/Network/index.js +11 -0
  118. package/src/Core/Storage.js +45 -0
  119. package/src/Core/Store.js +45 -0
  120. package/src/Core/Utils.js +34 -0
  121. package/src/Core/index.js +30 -0
  122. package/src/Lib/Ammo.js +72 -0
  123. package/src/Lib/Matter.js +1 -0
  124. package/src/Shaders/Material/Fragment/GL1.glsl +49 -0
  125. package/src/Shaders/Material/Fragment/GL2.glsl +51 -0
  126. package/src/Shaders/Material/Vertex/GL1.glsl +19 -0
  127. package/src/Shaders/Material/Vertex/GL2.glsl +20 -0
  128. package/src/Shaders/UI/Fragment/GL1.glsl +5 -0
  129. package/src/Shaders/UI/Fragment/GL2.glsl +7 -0
  130. package/src/Shaders/UI/Vertex/GL1.glsl +10 -0
  131. package/src/Shaders/UI/Vertex/GL2.glsl +11 -0
  132. package/src/Shaders/UITexture/Fragment/GL1.glsl +6 -0
  133. package/src/Shaders/UITexture/Fragment/GL2.glsl +8 -0
  134. package/src/Shaders/UITexture/Vertex/GL1.glsl +10 -0
  135. package/src/Shaders/UITexture/Vertex/GL2.glsl +11 -0
  136. package/src/index.js +19 -0
@@ -0,0 +1,207 @@
1
+ import { GameLibCore } from "../../Core/index.js"
2
+ import GL1Vertex from "../../Shaders/UI/Vertex/GL1.glsl"
3
+ import GL1Fragment from "../../Shaders/UI/Fragment/GL1.glsl"
4
+ import GL2Vertex from "../../Shaders/UI/Vertex/GL2.glsl"
5
+ import GL2Fragment from "../../Shaders/UI/Fragment/GL2.glsl"
6
+ import TextureGL1Vertex from "../../Shaders/UITexture/Vertex/GL1.glsl"
7
+ import TextureGL1Fragment from "../../Shaders/UITexture/Fragment/GL1.glsl"
8
+ import TextureGL2Vertex from "../../Shaders/UITexture/Vertex/GL2.glsl"
9
+ import TextureGL2Fragment from "../../Shaders/UITexture/Fragment/GL2.glsl"
10
+ class UIRenderer {
11
+ constructor(gameLib) {
12
+ this._gameLib = gameLib;
13
+ this._uiObjects = [];
14
+ this._vertices = [];
15
+ this._program = null;
16
+ this._buffer = null
17
+ this._positionLocation = null;
18
+ this._colorLocation = null;
19
+ this._resolutionLocation = null;
20
+ this._textureProgram = null;
21
+ this._textureBuffer = null;
22
+ this._texturePositionLocation = null;
23
+ this._textureUVLocation = null;
24
+ this._textureResolutionLocation = null;
25
+ this._textureSamplerLocation = null;
26
+ }
27
+ _getVertexShaderSource(webgl2) {
28
+ if(webgl2) {
29
+ return GL2Vertex;
30
+ } else {
31
+ return GL1Vertex;
32
+ }
33
+ }
34
+ _getFragmentShaderSource(webgl2) {
35
+ if(webgl2) {
36
+ return GL2Fragment;
37
+ } else {
38
+ return GL1Fragment;
39
+ }
40
+ }
41
+ _getTextureVertexShaderSource(webgl2) {
42
+ if(webgl2) {
43
+ return TextureGL2Vertex;
44
+ } else {
45
+ return TextureGL1Vertex;
46
+ }
47
+ }
48
+ _getTextureFragmentShaderSource(webgl2) {
49
+ if(webgl2) {
50
+ return TextureGL2Fragment;
51
+ } else {
52
+ return TextureGL1Fragment;
53
+ }
54
+ }
55
+ _initializeTextureRenderer() {
56
+ if(this._textureProgram) return true;
57
+ var gl = this._gameLib.webgl;
58
+ var webgl2 = !this._gameLib.options || this._gameLib.options.webGL2 !== false;
59
+ var vertexSource = this._getTextureVertexShaderSource(webgl2);
60
+ var fragmentSource = this._getTextureFragmentShaderSource(webgl2);
61
+ var vertexShader = this._gameLib.compileShader(gl.VERTEX_SHADER, vertexSource);
62
+ var fragmentShader = this._gameLib.compileShader(gl.FRAGMENT_SHADER, fragmentSource);
63
+ if(!vertexShader || !fragmentShader) return false;
64
+ this._textureProgram = this._gameLib.createProgram(vertexShader, fragmentShader);
65
+ if(!this._textureProgram) return false;
66
+ this._textureBuffer = gl.createBuffer();
67
+ this._texturePositionLocation = gl.getAttribLocation(this._textureProgram, "aPosition");
68
+ this._textureUVLocation = gl.getAttribLocation(this._textureProgram, "aUV");
69
+ this._textureResolutionLocation = gl.getUniformLocation(this._textureProgram, "uResolution");
70
+ this._textureSamplerLocation = gl.getUniformLocation(this._textureProgram, "uTexture");
71
+ return Boolean(this._textureBuffer);
72
+ }
73
+ _renderTexturedObject(object) {
74
+ var gl = this._gameLib.webgl;
75
+ var source = object.source;
76
+ if(!source || !this._initializeTextureRenderer()) return;
77
+ if(!this._textureProgram || !this._textureBuffer) return;
78
+ if(!object._glTexture) {
79
+ object._glTexture = gl.createTexture();
80
+ object.textureDirty = true;
81
+ gl.bindTexture(gl.TEXTURE_2D, object._glTexture);
82
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
83
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
84
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
85
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
86
+ }
87
+ gl.activeTexture(gl.TEXTURE0);
88
+ gl.bindTexture(gl.TEXTURE_2D, object._glTexture);
89
+ if(object.textureDirty && source.complete !== false) {
90
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
91
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
92
+ object.textureDirty = false;
93
+ }
94
+ var x = object.x;
95
+ var y = object.y;
96
+ var right = x + object.width;
97
+ var bottom = y + object.height;
98
+ var vertices = new Float32Array([
99
+ x, y, 0, 0,
100
+ right, y, 1, 0,
101
+ x, bottom, 0, 1,
102
+ x, bottom, 0, 1,
103
+ right, y, 1, 0,
104
+ right, bottom, 1, 1
105
+ ]);
106
+ gl.useProgram(this._textureProgram);
107
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._textureBuffer);
108
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.DYNAMIC_DRAW);
109
+ var stride = 4 * Float32Array.BYTES_PER_ELEMENT;
110
+ gl.enableVertexAttribArray(this._texturePositionLocation);
111
+ gl.vertexAttribPointer(this._texturePositionLocation, 2, gl.FLOAT, false, stride, 0);
112
+ gl.enableVertexAttribArray(this._textureUVLocation);
113
+ gl.vertexAttribPointer(this._textureUVLocation, 2, gl.FLOAT, false, stride, 2 * Float32Array.BYTES_PER_ELEMENT);
114
+ gl.uniform2f(this._textureResolutionLocation, gl.drawingBufferWidth, gl.drawingBufferHeight);
115
+ gl.uniform1i(this._textureSamplerLocation, 0);
116
+ gl.disable(gl.DEPTH_TEST);
117
+ gl.depthMask(false);
118
+ gl.enable(gl.BLEND);
119
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
120
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
121
+ gl.depthMask(true);
122
+ gl.enable(gl.DEPTH_TEST);
123
+ }
124
+ addObject(object) {
125
+ object.id = GameLibCore.Utils.UUID();
126
+ this._uiObjects.push(object);
127
+ return object.id;
128
+ }
129
+ getObjects() {
130
+ return this._uiObjects;
131
+ }
132
+ removeObject(id) {
133
+ this._uiObjects = this._uiObjects.filter(object => object.id !== id);
134
+ }
135
+ _initialize() {
136
+ if(this._program) return true;
137
+ var gl = this._gameLib.webgl;
138
+ var isWebGL2 = !this._gameLib.options || this._gameLib.options.webGL2 !== false;
139
+ var vertexSource = this._getVertexShaderSource(isWebGL2);
140
+ var fragmentSource = this._getFragmentShaderSource(isWebGL2);
141
+ var vertexShader = this._gameLib.compileShader(gl.VERTEX_SHADER, vertexSource);
142
+ var fragmentShader = this._gameLib.compileShader(gl.FRAGMENT_SHADER, fragmentSource);
143
+ if(!vertexShader || !fragmentShader) return false;
144
+ this._program = this._gameLib.createProgram(vertexShader, fragmentShader);
145
+ if(!this._program) return false;
146
+ this._buffer = gl.createBuffer();
147
+ this._positionLocation = gl.getAttribLocation(this._program, "aPosition");
148
+ this._colorLocation = gl.getAttribLocation(this._program, "aColor");
149
+ this._resolutionLocation = gl.getUniformLocation(this._program, "uResolution");
150
+ return Boolean(this._buffer);
151
+ }
152
+ render(scene) {
153
+ this._vertices = [];
154
+ for(var i=0;i<this._uiObjects.length;i++) {
155
+ var object = this._uiObjects[i];
156
+ if(object.scene === scene && object.visible !== false) {
157
+ if(object.update && typeof object.update === "function") object.update();
158
+ this.renderObject(object);
159
+ }
160
+ }
161
+ if(this._vertices.length === 0 || !this._initialize()) return;
162
+ var gl = this._gameLib.webgl;
163
+ var vertices = new Float32Array(this._vertices);
164
+ var bytesPerFloat = Float32Array.BYTES_PER_ELEMENT;
165
+ var vertexStride = 6 * bytesPerFloat;
166
+ gl.useProgram(this._program);
167
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._buffer);
168
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.DYNAMIC_DRAW);
169
+ gl.enableVertexAttribArray(this._positionLocation);
170
+ gl.vertexAttribPointer(this._positionLocation, 2, gl.FLOAT, false, vertexStride, 0);
171
+ gl.enableVertexAttribArray(this._colorLocation);
172
+ gl.vertexAttribPointer(this._colorLocation, 4, gl.FLOAT, false, vertexStride, 2 * bytesPerFloat);
173
+ gl.uniform2f(this._resolutionLocation, gl.drawingBufferWidth, gl.drawingBufferHeight);
174
+ gl.disable(gl.DEPTH_TEST);
175
+ gl.depthMask(false);
176
+ gl.enable(gl.BLEND);
177
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
178
+ gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 6);
179
+ gl.depthMask(true);
180
+ gl.enable(gl.DEPTH_TEST);
181
+ }
182
+ renderObject(object) {
183
+ if(object.update && typeof object.update == "function") object.update();
184
+ if(object.isTexturedUI) return this._renderTexturedObject(object);
185
+ var x = object.x;
186
+ var y = object.y;
187
+ var width = object.width;
188
+ var height = object.height;
189
+ var color = object.color || [1.0, 1.0, 1.0, 1.0];
190
+ var r = color[0];
191
+ var g = color[1];
192
+ var b = color[2];
193
+ var a = color[3];
194
+ var addVertex = (px, py) => {
195
+ this._vertices.push(px, py, r, g, b, a);
196
+ };
197
+ addVertex(x, y);
198
+ addVertex(x + width, y);
199
+ addVertex(x, y + height);
200
+ addVertex(x, y + height);
201
+ addVertex(x + width, y);
202
+ addVertex(x + width, y + height);
203
+ }
204
+ }
205
+ export {
206
+ UIRenderer
207
+ }
@@ -0,0 +1,35 @@
1
+ import { UIObject } from "./UIObject.js"
2
+ class UIText extends UIObject {
3
+ constructor(gameLib, scene, x, y, width, height, text, options={}) {
4
+ super(gameLib, scene, x, y, width, height, options.color);
5
+ this.isTexturedUI = true;
6
+ this.source = document.createElement('canvas');
7
+ this.source.width = Math.max(1, Math.ceil(width));
8
+ this.source.height = Math.max(1, Math.ceil(height));
9
+ this.text = text;
10
+ this.font = options.font || "24px sans-serif";
11
+ this.fillStyle = options.fillStyle || "#ffffff";
12
+ this.textAlign = options.textAlign || "left";
13
+ this.textBaseline = options.textBaseline || "top";
14
+ this.textureDirty = true;
15
+ this._drawText();
16
+ }
17
+ setText(text) {
18
+ this.text = text;
19
+ this._drawText();
20
+ return this;
21
+ }
22
+ _drawText() {
23
+ var ctx = this.source.getContext('2d');
24
+ ctx.clearRect(0, 0, this.source.width, this.source.height);
25
+ ctx.font = this.font;
26
+ ctx.fillStyle = this.fillStyle;
27
+ ctx.textAlign = this.textAlign;
28
+ ctx.textBaseline = this.textBaseline;
29
+ ctx.fillText(this.text, 0, 0, this.source.width);
30
+ this.textureDirty = true;
31
+ }
32
+ }
33
+ export {
34
+ UIText
35
+ }
@@ -0,0 +1,19 @@
1
+ import { GameLibCore } from "../../Core/index.js"
2
+ import { UIRenderer } from "./UIRenderer.js"
3
+ import { UIObject } from "./UIObject.js"
4
+ import { UIPath } from "./UIPath.js"
5
+ import { UIImage } from "./UIImage.js"
6
+ import { UIText } from "./UIText.js"
7
+ class UI {
8
+ constructor() {
9
+ throw new GameLibCore.Error("Class UI may not be constructed!");
10
+ }
11
+ static UIRenderer = UIRenderer;
12
+ static UIObject = UIObject;
13
+ static Path = UIPath;
14
+ static Image = UIImage;
15
+ static Text = UIText;
16
+ }
17
+ export {
18
+ UI
19
+ }
@@ -0,0 +1,9 @@
1
+ import { GameLibError } from "../Core/Error.js"
2
+ class Utils {
3
+ constructor() {
4
+ throw new GameLibError("Class GameLib3D.Utils may not be constructed!");
5
+ }
6
+ }
7
+ export {
8
+ Utils
9
+ }
@@ -0,0 +1,43 @@
1
+ import { GameLibCore } from "../Core/index.js"
2
+ import { Utils } from "./Utils.js"
3
+ import { Object } from "./Object.js"
4
+ import { ShaderFactory } from "./ShaderFactory/index.js"
5
+ import { GameLib } from "./GameLib.js"
6
+ import { Transform } from "./Transform.js"
7
+ import { Position } from "./Position.js"
8
+ import { Rotation } from "./Rotation.js"
9
+ import { Scale } from "./Scale.js"
10
+ import { Camera } from "./Camera.js"
11
+ import { Geometry } from "./Geometry/index.js"
12
+ import { Ammo } from "../Lib/Ammo.js"
13
+ import { Mesh } from "./Mesh.js"
14
+ import { Material } from "./Material.js"
15
+ import { Texture } from "./Texture.js"
16
+ import { TextureFactory } from "./TextureFactory.js"
17
+ import { UI } from "./UI/index.js"
18
+ import { Lighting } from "./Lighting/index.js"
19
+ class GameLib3D {
20
+ constructor() {
21
+ throw new GameLibCore.Error("Wrapper class GameLib3D may not be constructed!");
22
+ }
23
+ static Utils = Utils;
24
+ static Object = Object;
25
+ static ShaderFactory = ShaderFactory;
26
+ static GameLib = GameLib;
27
+ static Transform = Transform;
28
+ static Position = Position;
29
+ static Rotation = Rotation;
30
+ static Scale = Scale;
31
+ static Geometry = Geometry;
32
+ static Camera = Camera;
33
+ static Ammo = Ammo;
34
+ static Mesh = Mesh;
35
+ static Material = Material;
36
+ static Texture = Texture;
37
+ static TextureFactory = TextureFactory;
38
+ static UI = UI;
39
+ static Lighting = Lighting;
40
+ }
41
+ export {
42
+ GameLib3D
43
+ }
@@ -0,0 +1,116 @@
1
+ import { GameLibError } from "./Error.js"
2
+ class AssetManager {
3
+ static _shared = null;
4
+ static get shared() {
5
+ if (!AssetManager._shared) {
6
+ AssetManager._shared = new AssetManager();
7
+ }
8
+ return AssetManager._shared;
9
+ }
10
+ constructor() {
11
+ this._cache = new Map();
12
+ this._loaders = new Map();
13
+ this.registerLoader("image", (url, options = {}) => {
14
+ return new Promise((resolve, reject) => {
15
+ const image = new Image();
16
+ if (options.crossOrigin !== undefined) {
17
+ image.crossOrigin = options.crossOrigin;
18
+ }
19
+ image.onload = () => resolve(image);
20
+ image.onerror = () => reject(new GameLibError(`Failed to load image: ${url}`));
21
+ image.src = url;
22
+ });
23
+ });
24
+ this.registerLoader("json", async (url, options = {}) => {
25
+ const response = await fetch(url, options.fetchOptions);
26
+ if (!response.ok) {
27
+ throw new GameLibError(`Failed to load JSON "${url}": ${response.status}`);
28
+ }
29
+ return response.json();
30
+ });
31
+ this.registerLoader("text", async (url, options = {}) => {
32
+ const response = await fetch(url, options.fetchOptions);
33
+ if (!response.ok) {
34
+ throw new GameLibError(`Failed to load text "${url}": ${response.status}`);
35
+ }
36
+ return response.text();
37
+ });
38
+ this.registerLoader("arrayBuffer", async (url, options = {}) => {
39
+ const response = await fetch(url, options.fetchOptions);
40
+ if (!response.ok) {
41
+ throw new GameLibError(`Failed to load data "${url}": ${response.status}`);
42
+ }
43
+ return response.arrayBuffer();
44
+ });
45
+ }
46
+ registerLoader(type, loader) {
47
+ if (typeof loader !== "function") {
48
+ throw new TypeError("Asset loader must be a function");
49
+ }
50
+ this._loaders.set(type, loader);
51
+ return this;
52
+ }
53
+ load(type, url, options = {}) {
54
+ const loader = this._loaders.get(type);
55
+ if (!loader) {
56
+ return Promise.reject(new GameLibError(`No asset loader registered for type "${type}"`));
57
+ }
58
+ const key = `${type}:${url}`;
59
+ if (this._cache.has(key)) {
60
+ return this._cache.get(key);
61
+ }
62
+ const promise = Promise.resolve()
63
+ .then(() => loader(url, options))
64
+ .catch(error => {
65
+ this._cache.delete(key);
66
+ throw error;
67
+ });
68
+ this._cache.set(key, promise);
69
+ return promise;
70
+ }
71
+ loadImage(url, options) {
72
+ return this.load("image", url, options);
73
+ }
74
+ loadJSON(url, options) {
75
+ return this.load("json", url, options);
76
+ }
77
+ loadText(url, options) {
78
+ return this.load("text", url, options);
79
+ }
80
+ loadArrayBuffer(url, options) {
81
+ return this.load("arrayBuffer", url, options);
82
+ }
83
+ async loadBatch(manifest, onProgress = null) {
84
+ const total = manifest.length;
85
+ let completed = 0;
86
+ const entries = await Promise.all(manifest.map(async asset => {
87
+ try {
88
+ const value = await this.load(asset.type, asset.url, asset.options);
89
+ return [asset.name, value];
90
+ } finally {
91
+ completed++;
92
+ if (onProgress) {
93
+ onProgress({
94
+ completed,
95
+ total,
96
+ progress: total === 0 ? 1 : completed / total,
97
+ asset
98
+ });
99
+ }
100
+ }
101
+ }));
102
+ return Object.fromEntries(entries);
103
+ }
104
+ has(type, url) {
105
+ return this._cache.has(`${type}:${url}`);
106
+ }
107
+ unload(type, url) {
108
+ return this._cache.delete(`${type}:${url}`);
109
+ }
110
+ clear() {
111
+ this._cache.clear();
112
+ }
113
+ }
114
+ export {
115
+ AssetManager
116
+ }
@@ -0,0 +1,151 @@
1
+ import { GameLibCore } from "./index.js"
2
+ class AudioManager {
3
+ constructor() {
4
+ if (GameLibCore.AudioManager._instance) {
5
+ return GameLibCore.AudioManager._instance;
6
+ } else {
7
+ console.log("[GameLib] No AudioManager instance found. Creating new instance...");
8
+ this._musicPool = [];
9
+ this._loopingSoundPool = {};
10
+ this._sfxPool = {};
11
+ this._activeLoopingSoundPool = {};
12
+ this._currentMusic = null;
13
+ this._musicPaused = true;
14
+ this._musicSource = null;
15
+ this._musicOffset = 0;
16
+ this._musicStartedAt = 0;
17
+ this._audioCtx = new AudioContext();
18
+ this.bindEvents();
19
+ GameLibCore.AudioManager._instance = this;
20
+ }
21
+ }
22
+ bindEvents() {
23
+ window.addEventListener('click', this.resumeMusic.bind(this), false);
24
+ document.addEventListener('visibilitychange', this.visibilityChange.bind(this), false);
25
+ }
26
+ visibilityChange() {
27
+ if (document.visibilityState != 'visible') {
28
+ this._audioCtx.suspend();
29
+ } else {
30
+ this._audioCtx.resume();
31
+ }
32
+ }
33
+ async loadLoopingSound(name, url) {
34
+ var data = await GameLibCore.AssetManager.shared.loadArrayBuffer(url);
35
+ this._loopingSoundPool[name] = await this._audioCtx.decodeAudioData(data.slice(0));
36
+ }
37
+ playLoopingSound(name) {
38
+ if (this._loopingSoundPool[name] != null) {
39
+ var source = this._audioCtx.createBufferSource();
40
+ source.loop = true;
41
+ source.buffer = this._loopingSoundPool[name];
42
+ source.connect(this._audioCtx.destination);
43
+ this._activeLoopingSoundPool[name] = source;
44
+ source.start(0);
45
+ } else {
46
+ console.warn("[GameLib] Attempted to play a looping sound that does not exist!");
47
+ }
48
+ }
49
+ stopLoopingSound(name) {
50
+ if (this._activeLoopingSoundPool[name] != null) {
51
+ this._activeLoopingSoundPool[name].stop();
52
+ delete this._activeLoopingSoundPool[name];
53
+ }
54
+ }
55
+ async addSong(url) {
56
+ var data = await GameLibCore.AssetManager.shared.loadArrayBuffer(url);
57
+ var buffer = await this._audioCtx.decodeAudioData(data.slice(0));
58
+ this._musicPool.push(buffer);
59
+ }
60
+ stopCurrentMusicSource() {
61
+ if (this._musicSource != null) {
62
+ this._musicSource.onended = null;
63
+ try {
64
+ this._musicSource.stop();
65
+ } catch (error) {}
66
+ this._musicSource.disconnect();
67
+ this._musicSource = null;
68
+ }
69
+ }
70
+ startCurrentMusic() {
71
+ if (this._currentMusic == null || this._musicPaused || this._musicSource != null) {
72
+ return;
73
+ }
74
+ var source = this._audioCtx.createBufferSource();
75
+ source.buffer = this._currentMusic;
76
+ source.connect(this._audioCtx.destination);
77
+ source.onended = () => {
78
+ if (this._musicSource === source) {
79
+ this._musicSource = null;
80
+ this._musicOffset = 0;
81
+ if (!this._musicPaused) {
82
+ this.nextSong();
83
+ }
84
+ }
85
+ };
86
+ this._musicSource = source;
87
+ this._musicStartedAt = this._audioCtx.currentTime;
88
+ source.start(0, this._musicOffset);
89
+ }
90
+ nextSong() {
91
+ if (this._musicPool.length <= 0) {
92
+ throw new GameLibCore.Error("Music Pool is empty!");
93
+ }
94
+ this.stopCurrentMusicSource();
95
+ this._currentMusic = GameLibCore.Utils.getRandomListItem(this._musicPool);
96
+ this._musicOffset = 0;
97
+ this.startCurrentMusic();
98
+ }
99
+ async playMusic() {
100
+ this._musicPaused = false;
101
+ if (this._currentMusic == null) {
102
+ if (this._musicPool.length <= 0) {
103
+ this._musicPaused = true;
104
+ throw new GameLibCore.Error("Music Pool is empty!");
105
+ }
106
+ this._currentMusic = GameLibCore.Utils.getRandomListItem(this._musicPool);
107
+ this._musicOffset = 0;
108
+ }
109
+ if (this._audioCtx.state === 'suspended') {
110
+ await this._audioCtx.resume();
111
+ }
112
+ this.startCurrentMusic();
113
+ }
114
+ async resumeMusic() {
115
+ if (this._audioCtx.state === 'suspended') {
116
+ await this._audioCtx.resume();
117
+ }
118
+ if (!this._musicPaused) {
119
+ this.startCurrentMusic();
120
+ }
121
+ }
122
+ pauseMusic() {
123
+ this._musicPaused = true;
124
+ if (this._musicSource != null) {
125
+ this._musicOffset += this._audioCtx.currentTime - this._musicStartedAt;
126
+ this._musicOffset %= this._currentMusic.duration;
127
+ this.stopCurrentMusicSource();
128
+ }
129
+ }
130
+ async loadSfx(name, url) {
131
+ var data = await GameLibCore.AssetManager.shared.loadArrayBuffer(url);
132
+ this._sfxPool[name] = await this._audioCtx.decodeAudioData(data.slice(0));
133
+ }
134
+ playSfx(name, speed = 1, gain = 1.5) {
135
+ if (this._sfxPool[name]) {
136
+ var source = this._audioCtx.createBufferSource();
137
+ source.buffer = this._sfxPool[name];
138
+ source.playbackRate.value = speed;
139
+ var gainNode = this._audioCtx.createGain();
140
+ gainNode.gain.setValueAtTime(gain, 0);
141
+ gainNode.connect(this._audioCtx.destination);
142
+ source.connect(gainNode);
143
+ source.start(0);
144
+ } else {
145
+ console.warn("[GameLib] Attempted to play SFX that does not exist!");
146
+ }
147
+ }
148
+ }
149
+ export {
150
+ AudioManager
151
+ }
@@ -0,0 +1,9 @@
1
+ class GameLibError extends Error {
2
+ constructor(message, options) {
3
+ super(message);
4
+ this.name = "GameLibError";
5
+ }
6
+ }
7
+ export {
8
+ GameLibError
9
+ }
@@ -0,0 +1,49 @@
1
+ class FullscreenManager {
2
+ constructor() {
3
+ this._fullscreen = 0;
4
+ this._pointerLocked = false;
5
+ this.bindEvents();
6
+ }
7
+ bindEvents() {
8
+ window.addEventListener('click', this.fullscreen.bind(this), false);
9
+ }
10
+ async fullscreen() {
11
+ if (this._pointerLocked && document.pointerLockElement == null) {
12
+ document.documentElement.requestPointerLock().catch(function(err) {});
13
+ }
14
+ if (this._fullscreen > 0 && document.fullscreenElement == null) {
15
+ document.documentElement.requestFullscreen().catch(function(err) {});
16
+ }
17
+ if (this._fullscreen == 2 && document.fullscreenElement == null) {
18
+ try {
19
+ await navigator.keyboard.lock(['Escape']);
20
+ } catch (err) {}
21
+ }
22
+ }
23
+ setFullscreen(isFullscreen, locked = false) {
24
+ if (isFullscreen) {
25
+ document.documentElement.requestFullscreen();
26
+ if (locked) {
27
+ this._fullscreen = 2;
28
+ navigator.keyboard.lock(['Escape']);
29
+ } else {
30
+ this._fullscreen = 1;
31
+ }
32
+ } else {
33
+ this._fullscreen = 0;
34
+ document.exitFullscreen();
35
+ }
36
+ }
37
+ setPointerLocked(isLocked) {
38
+ if (isLocked == true) {
39
+ this._pointerLocked = true;
40
+ document.documentElement.requestPointerLock();
41
+ } else {
42
+ this._pointerLocked = false;
43
+ document.exitPointerLock();
44
+ }
45
+ }
46
+ }
47
+ export {
48
+ FullscreenManager
49
+ }
@@ -0,0 +1,29 @@
1
+ class GameLibBase {
2
+ constructor() {
3
+ this._active = true;
4
+ this._rendering = true;
5
+ this._hooks = {};
6
+ }
7
+ setActive(active) {
8
+ this._active = active;
9
+ }
10
+ setRendering(rendering) {
11
+ this._rendering = rendering;
12
+ }
13
+ addHook(event, hook) {
14
+ if(!this._hooks[event]) {
15
+ this._hooks[event] = [];
16
+ }
17
+ this._hooks[event].push(hook);
18
+ }
19
+ callHook(type) {
20
+ if(!this._hooks[type]) return;
21
+ var hooks = this._hooks[type];
22
+ for(var i=0;i<hooks.length;i++) {
23
+ hooks[i]();
24
+ }
25
+ }
26
+ }
27
+ export {
28
+ GameLibBase
29
+ }