@playcraft/build 0.0.3 → 0.0.8

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 (64) hide show
  1. package/dist/analyzers/scene-asset-collector.js +210 -1
  2. package/dist/base-builder.d.ts +17 -0
  3. package/dist/base-builder.js +211 -16
  4. package/dist/generators/config-generator.js +29 -3
  5. package/dist/loaders/playcanvas-loader.d.ts +7 -0
  6. package/dist/loaders/playcanvas-loader.js +53 -3
  7. package/dist/platforms/adikteev.d.ts +10 -0
  8. package/dist/platforms/adikteev.js +72 -0
  9. package/dist/platforms/base.d.ts +12 -0
  10. package/dist/platforms/base.js +208 -0
  11. package/dist/platforms/facebook.js +5 -2
  12. package/dist/platforms/index.d.ts +4 -0
  13. package/dist/platforms/index.js +16 -0
  14. package/dist/platforms/inmobi.d.ts +10 -0
  15. package/dist/platforms/inmobi.js +68 -0
  16. package/dist/platforms/ironsource.js +5 -2
  17. package/dist/platforms/moloco.js +5 -2
  18. package/dist/platforms/playcraft.d.ts +33 -0
  19. package/dist/platforms/playcraft.js +44 -0
  20. package/dist/platforms/remerge.d.ts +10 -0
  21. package/dist/platforms/remerge.js +56 -0
  22. package/dist/templates/__loading__.js +100 -0
  23. package/dist/templates/__modules__.js +47 -0
  24. package/dist/templates/__settings__.template.js +20 -0
  25. package/dist/templates/__start__.js +332 -0
  26. package/dist/templates/index.html +18 -0
  27. package/dist/templates/logo.png +0 -0
  28. package/dist/templates/manifest.json +1 -0
  29. package/dist/templates/patches/cannon.min.js +28 -0
  30. package/dist/templates/patches/lz4.js +10 -0
  31. package/dist/templates/patches/one-page-http-get.js +20 -0
  32. package/dist/templates/patches/one-page-inline-game-scripts.js +52 -0
  33. package/dist/templates/patches/one-page-mraid-resize-canvas.js +46 -0
  34. package/dist/templates/patches/p2.min.js +27 -0
  35. package/dist/templates/patches/playcraft-no-xhr.js +76 -0
  36. package/dist/templates/playcanvas-stable.min.js +16363 -0
  37. package/dist/templates/styles.css +43 -0
  38. package/dist/types.d.ts +14 -1
  39. package/dist/utils/build-mode-detector.d.ts +9 -0
  40. package/dist/utils/build-mode-detector.js +42 -0
  41. package/dist/vite/config-builder.d.ts +29 -1
  42. package/dist/vite/config-builder.js +169 -39
  43. package/dist/vite/platform-configs.d.ts +4 -0
  44. package/dist/vite/platform-configs.js +98 -14
  45. package/dist/vite/plugin-esm-html-generator.d.ts +22 -0
  46. package/dist/vite/plugin-esm-html-generator.js +1061 -0
  47. package/dist/vite/plugin-platform.js +56 -17
  48. package/dist/vite/plugin-playcanvas.d.ts +2 -0
  49. package/dist/vite/plugin-playcanvas.js +579 -49
  50. package/dist/vite/plugin-source-builder.d.ts +3 -0
  51. package/dist/vite/plugin-source-builder.js +920 -23
  52. package/dist/vite-builder.d.ts +19 -2
  53. package/dist/vite-builder.js +162 -12
  54. package/package.json +2 -1
  55. package/physics/cannon-es-bundle.js +13092 -0
  56. package/physics/cannon-rigidbody-adapter.js +375 -0
  57. package/physics/connon-integration.js +411 -0
  58. package/templates/__start__.js +8 -3
  59. package/templates/index.esm.html +20 -0
  60. package/templates/index.esm.mjs +502 -0
  61. package/templates/patches/one-page-inline-game-scripts.js +33 -1
  62. package/templates/patches/playcraft-cta-adapter.js +297 -0
  63. package/templates/patches/playcraft-no-xhr.js +25 -1
  64. package/templates/playcanvas-esm-wrapper.mjs +827 -0
@@ -0,0 +1,56 @@
1
+ import { PlatformAdapter } from './base.js';
2
+ export class RemergeAdapter extends PlatformAdapter {
3
+ getName() {
4
+ return 'Remerge';
5
+ }
6
+ getSizeLimit() {
7
+ // Remerge: 5MB
8
+ return 5 * 1024 * 1024;
9
+ }
10
+ getDefaultFormat() {
11
+ return 'html';
12
+ }
13
+ modifyHTML(html, assets) {
14
+ // Remerge 使用 FbPlayableAd API(与 Facebook/Moloco 相同)
15
+ const remergeScript = `
16
+ <script>
17
+ // Remerge 使用 FbPlayableAd API
18
+ window.FbPlayableAd = window.FbPlayableAd || {
19
+ onCTAClick: function() {
20
+ console.log('Remerge CTA clicked');
21
+ // Remerge 要求:必须以"无参数"方式调用
22
+ }
23
+ };
24
+ </script>
25
+ <!--
26
+ 注意:
27
+ - Remerge 使用单文件 HTML 格式,<5MB
28
+ - CTA 必须以"无参数"方式调用 FbPlayableAd.onCTAClick()
29
+ - 不允许任何外部引用或 HTTP 动态加载
30
+ - 禁止 XMLHttpRequest 和 JS 重定向
31
+ -->
32
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
33
+ `;
34
+ // 在 </head> 之前插入平台特定的 API
35
+ html = html.replace('</head>', `${remergeScript}</head>`);
36
+ // 注入统一的 CTA 适配器
37
+ html = this.injectCTAAdapter(html);
38
+ return html;
39
+ }
40
+ getPlatformScript() {
41
+ return `
42
+ // Remerge Playable Ad
43
+ // 使用 FbPlayableAd.onCTAClick() 跳转(无参数)
44
+
45
+ if (typeof FbPlayableAd !== 'undefined') {
46
+ // 在 CTA 按钮点击时调用
47
+ // FbPlayableAd.onCTAClick();
48
+ }
49
+ `;
50
+ }
51
+ validateOptions() {
52
+ if (this.options.format && this.options.format !== 'html') {
53
+ console.warn('警告: Remerge 使用单文件 HTML 格式');
54
+ }
55
+ }
56
+ }
@@ -0,0 +1,100 @@
1
+ pc.script.createLoadingScreen((app) => {
2
+ const createCss = () => {
3
+ const css = `
4
+ body {
5
+ background-color: #283538;
6
+ }
7
+
8
+ #application-splash-wrapper {
9
+ position: absolute;
10
+ top: 0;
11
+ left: 0;
12
+ height: 100%;
13
+ width: 100%;
14
+ background-color: #283538;
15
+ }
16
+
17
+ #application-splash {
18
+ position: absolute;
19
+ top: calc(50% - 28px);
20
+ width: 264px;
21
+ left: calc(50% - 132px);
22
+ }
23
+
24
+ #application-splash img {
25
+ width: 100%;
26
+ }
27
+
28
+ #progress-bar-container {
29
+ margin: 20px auto 0 auto;
30
+ height: 2px;
31
+ width: 100%;
32
+ background-color: #1d292c;
33
+ }
34
+
35
+ #progress-bar {
36
+ width: 0%;
37
+ height: 100%;
38
+ background-color: #f60;
39
+ }
40
+
41
+ @media (max-width: 480px) {
42
+ #application-splash {
43
+ width: 170px;
44
+ left: calc(50% - 85px);
45
+ }
46
+ }
47
+ `;
48
+
49
+ const style = document.createElement('style');
50
+ style.textContent = css;
51
+ document.head.appendChild(style);
52
+ };
53
+
54
+ const showSplash = () => {
55
+ const wrapper = document.createElement('div');
56
+ wrapper.id = 'application-splash-wrapper';
57
+ document.body.appendChild(wrapper);
58
+
59
+ const splash = document.createElement('div');
60
+ splash.id = 'application-splash';
61
+ wrapper.appendChild(splash);
62
+ splash.style.display = 'none';
63
+
64
+ const logo = document.createElement('img');
65
+ logo.src = `${ASSET_PREFIX}logo.png`;
66
+ splash.appendChild(logo);
67
+ logo.onload = () => {
68
+ splash.style.display = 'block';
69
+ };
70
+
71
+ const container = document.createElement('div');
72
+ container.id = 'progress-bar-container';
73
+ splash.appendChild(container);
74
+
75
+ const bar = document.createElement('div');
76
+ bar.id = 'progress-bar';
77
+ container.appendChild(bar);
78
+ };
79
+
80
+ const setProgress = (value) => {
81
+ const bar = document.getElementById('progress-bar');
82
+ if (bar) {
83
+ value = Math.min(1, Math.max(0, value));
84
+ bar.style.width = `${value * 100}%`;
85
+ }
86
+ };
87
+
88
+ const hideSplash = () => {
89
+ document.getElementById('application-splash-wrapper').remove();
90
+ };
91
+
92
+ createCss();
93
+ showSplash();
94
+
95
+ app.on('preload:end', () => {
96
+ app.off('preload:progress');
97
+ });
98
+ app.on('preload:progress', setProgress);
99
+ app.on('start', hideSplash);
100
+ });
@@ -0,0 +1,47 @@
1
+ var loadModules = function (modules, urlPrefix, doneCallback) { // eslint-disable-line no-unused-vars
2
+
3
+ if (typeof modules === "undefined" || modules.length === 0) {
4
+ // caller may depend on callback behaviour being async
5
+ setTimeout(doneCallback);
6
+ } else {
7
+ let remaining = modules.length;
8
+ const moduleLoaded = () => {
9
+ if (--remaining === 0) {
10
+ doneCallback();
11
+ }
12
+ };
13
+
14
+ modules.forEach(function (m) {
15
+ pc.WasmModule.setConfig(m.moduleName, {
16
+ glueUrl: urlPrefix + m.glueUrl,
17
+ wasmUrl: urlPrefix + m.wasmUrl,
18
+ fallbackUrl: urlPrefix + m.fallbackUrl
19
+ });
20
+
21
+ if (!m.hasOwnProperty('preload') || m.preload) {
22
+ if (m.moduleName === 'BASIS') {
23
+ // preload basis transcoder
24
+ pc.basisInitialize();
25
+ moduleLoaded();
26
+ } else if (m.moduleName === 'DracoDecoderModule') {
27
+ // preload draco decoder
28
+ if (pc.dracoInitialize) {
29
+ // 1.63 onwards
30
+ pc.dracoInitialize();
31
+ moduleLoaded();
32
+ } else {
33
+ // 1.62 and earlier
34
+ pc.WasmModule.getInstance(m.moduleName, () => { moduleLoaded(); });
35
+ }
36
+ } else {
37
+ // load remaining modules in global scope
38
+ pc.WasmModule.getInstance(m.moduleName, () => { moduleLoaded(); });
39
+ }
40
+ } else {
41
+ moduleLoaded();
42
+ }
43
+ });
44
+ }
45
+ };
46
+
47
+ window.loadModules = loadModules;
@@ -0,0 +1,20 @@
1
+ window.ASSET_PREFIX = "";
2
+ window.SCRIPT_PREFIX = "";
3
+ window.SCENE_PATH = "{{SCENE_PATH}}";
4
+ window.CONTEXT_OPTIONS = {
5
+ 'antialias': {{ANTIALIAS}},
6
+ 'alpha': false,
7
+ 'preserveDrawingBuffer': {{PRESERVE_DRAWING_BUFFER}},
8
+ 'deviceTypes': [`webgl2`, `webgl1`],
9
+ 'powerPreference': "{{POWER_PREFERENCE}}"
10
+ };
11
+ window.SCRIPTS = {{SCRIPTS}};
12
+ window.CONFIG_FILENAME = "config.json";
13
+ window.INPUT_SETTINGS = {
14
+ useKeyboard: {{USE_KEYBOARD}},
15
+ useMouse: {{USE_MOUSE}},
16
+ useGamepads: {{USE_GAMEPAD}},
17
+ useTouch: {{USE_TOUCH}}
18
+ };
19
+ pc.script.legacy = {{USE_LEGACY_SCRIPTS}};
20
+ window.PRELOAD_MODULES = {{PRELOAD_MODULES}};
@@ -0,0 +1,332 @@
1
+ (function () {
2
+ // Shared Lib
3
+ var CANVAS_ID = 'application-canvas';
4
+
5
+ // Needed as we will have edge cases for particular versions of iOS
6
+ // returns null if not iOS
7
+ var getIosVersion = function () {
8
+ if (/iP(hone|od|ad)/.test(navigator.platform)) {
9
+ var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
10
+ var version = [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)];
11
+ return version;
12
+ }
13
+
14
+ return null;
15
+ };
16
+
17
+ var lastWindowHeight = window.innerHeight;
18
+ var lastWindowWidth = window.innerWidth;
19
+ var windowSizeChangeIntervalHandler = null;
20
+
21
+ var pcBootstrap = {
22
+ reflowHandler: null,
23
+ iosVersion: getIosVersion(),
24
+
25
+ createCanvas: function () {
26
+ var canvas = document.createElement('canvas');
27
+ canvas.setAttribute('id', CANVAS_ID);
28
+ canvas.setAttribute('tabindex', 0);
29
+
30
+ // Disable I-bar cursor on click+drag
31
+ canvas.onselectstart = function () { return false; };
32
+
33
+ // Disable long-touch select on iOS devices
34
+ canvas.style['-webkit-user-select'] = 'none';
35
+
36
+ document.body.appendChild(canvas);
37
+
38
+ return canvas;
39
+ },
40
+
41
+
42
+ resizeCanvas: function (app, canvas) {
43
+ canvas.style.width = '';
44
+ canvas.style.height = '';
45
+ app.resizeCanvas(canvas.width, canvas.height);
46
+
47
+ var fillMode = app._fillMode;
48
+
49
+ if (fillMode === pc.FILLMODE_NONE || fillMode === pc.FILLMODE_KEEP_ASPECT) {
50
+ if ((fillMode === pc.FILLMODE_NONE && canvas.clientHeight < window.innerHeight) || (canvas.clientWidth / canvas.clientHeight >= window.innerWidth / window.innerHeight)) {
51
+ canvas.style.marginTop = Math.floor((window.innerHeight - canvas.clientHeight) / 2) + 'px';
52
+ } else {
53
+ canvas.style.marginTop = '';
54
+ }
55
+ }
56
+
57
+ lastWindowHeight = window.innerHeight;
58
+ lastWindowWidth = window.innerWidth;
59
+
60
+ // Work around when in landscape to work on iOS 12 otherwise
61
+ // the content is under the URL bar at the top
62
+ if (this.iosVersion && this.iosVersion[0] <= 12) {
63
+ window.scrollTo(0, 0);
64
+ }
65
+ },
66
+
67
+ reflow: function (app, canvas) {
68
+ this.resizeCanvas(app, canvas);
69
+
70
+ // Poll for size changes as the window inner height can change after the resize event for iOS
71
+ // Have one tab only, and rotate from portrait -> landscape -> portrait
72
+ if (windowSizeChangeIntervalHandler === null) {
73
+ windowSizeChangeIntervalHandler = setInterval(function () {
74
+ if (lastWindowHeight !== window.innerHeight || lastWindowWidth !== window.innerWidth) {
75
+ this.resizeCanvas(app, canvas);
76
+ }
77
+ }.bind(this), 100);
78
+
79
+ // Don't want to do this all the time so stop polling after some short time
80
+ setTimeout(function () {
81
+ if (!!windowSizeChangeIntervalHandler) {
82
+ clearInterval(windowSizeChangeIntervalHandler);
83
+ windowSizeChangeIntervalHandler = null;
84
+ }
85
+ }, 2000);
86
+ }
87
+ }
88
+ };
89
+
90
+ // Expose the reflow to users so that they can override the existing
91
+ // reflow logic if need be
92
+ window.pcBootstrap = pcBootstrap;
93
+ })();
94
+
95
+
96
+ (function () {
97
+ // template varants
98
+ var LTC_MAT_1 = [];
99
+ var LTC_MAT_2 = [];
100
+
101
+ // varants
102
+ var canvas = pcBootstrap.createCanvas();
103
+ var app = new pc.AppBase(canvas);
104
+
105
+ function initCSS() {
106
+ if (document.head.querySelector) {
107
+ // css media query for aspect ratio changes
108
+ // TODO: Change these from private properties
109
+ var css = `@media screen and (min-aspect-ratio: ${app._width}/${app._height}) {
110
+ #application-canvas.fill-mode-KEEP_ASPECT {
111
+ width: auto;
112
+ height: 100%;
113
+ margin: 0 auto;
114
+ }
115
+ }`;
116
+ document.head.querySelector('style').innerHTML += css;
117
+ }
118
+
119
+ // Configure resolution and resize event
120
+ if (canvas.classList) {
121
+ canvas.classList.add(`fill-mode-${app.fillMode}`);
122
+ }
123
+ }
124
+
125
+ function displayError(html) {
126
+ var div = document.createElement('div');
127
+ div.innerHTML = `<table style="background-color: #8CE; width: 100%; height: 100%;">
128
+ <tr>
129
+ <td align="center">
130
+ <div style="display: table-cell; vertical-align: middle;">
131
+ <div style="">${html}</div>
132
+ </div>
133
+ </td>
134
+ </tr>
135
+ </table>`;
136
+ document.body.appendChild(div);
137
+ }
138
+
139
+ function createGraphicsDevice(callback) {
140
+ var deviceOptions = window.CONTEXT_OPTIONS ? window.CONTEXT_OPTIONS : {};
141
+
142
+ if (typeof window.Promise === 'function') {
143
+ var LEGACY_WEBGL = 'webgl';
144
+ var deviceTypes = [...deviceOptions.deviceTypes, LEGACY_WEBGL];
145
+
146
+ var gpuLibPath = window.ASSET_PREFIX ? (window.ASSET_PREFIX.replace(/\/$/g, '') + '/') : '';
147
+
148
+ // new graphics device creation function with promises
149
+ var gfxOptions = {
150
+ deviceTypes: deviceTypes,
151
+ glslangUrl: gpuLibPath + 'glslang.js',
152
+ twgslUrl: gpuLibPath + 'twgsl.js',
153
+ powerPreference: deviceOptions.powerPreference,
154
+ antialias: deviceOptions.antialias !== false,
155
+ alpha: deviceOptions.alpha === true,
156
+ preserveDrawingBuffer: !!deviceOptions.preserveDrawingBuffer
157
+ };
158
+
159
+ pc.createGraphicsDevice(canvas, gfxOptions).then((device) => {
160
+ callback(device);
161
+ }).catch((e) => {
162
+ console.error('Device creation error:', e);
163
+ callback(null);
164
+ })
165
+ } else {
166
+ var igl1 = deviceOptions.deviceTypes.indexOf('webgl1');
167
+ var igl2 = deviceOptions.deviceTypes.indexOf('webgl2');
168
+
169
+ // old webgl graphics device creation
170
+ var options = {
171
+ powerPreference: deviceOptions.powerPreference,
172
+ antialias: deviceOptions.antialias !== false,
173
+ alpha: deviceOptions.transparentCanvas !== false,
174
+ preserveDrawingBuffer: !!deviceOptions.preserveDrawingBuffer,
175
+ preferWebGl2: igl2 > igl1
176
+ };
177
+
178
+ if (pc.platform.browser && !!navigator.xr) {
179
+ options.xrCompatible = true;
180
+ }
181
+
182
+ callback(new pc.WebglGraphicsDevice(canvas, options));
183
+ }
184
+ }
185
+
186
+ function initApp(device) {
187
+ try {
188
+ var createOptions = new pc.AppOptions();
189
+ createOptions.graphicsDevice = device;
190
+
191
+ createOptions.componentSystems = [
192
+ pc.RigidBodyComponentSystem,
193
+ pc.CollisionComponentSystem,
194
+ pc.JointComponentSystem,
195
+ pc.AnimationComponentSystem,
196
+ pc.AnimComponentSystem,
197
+ pc.ModelComponentSystem,
198
+ pc.RenderComponentSystem,
199
+ pc.CameraComponentSystem,
200
+ pc.LightComponentSystem,
201
+ pc.script.legacy ? pc.ScriptLegacyComponentSystem : pc.ScriptComponentSystem,
202
+ pc.AudioSourceComponentSystem,
203
+ pc.SoundComponentSystem,
204
+ pc.AudioListenerComponentSystem,
205
+ pc.ParticleSystemComponentSystem,
206
+ pc.ScreenComponentSystem,
207
+ pc.ElementComponentSystem,
208
+ pc.ButtonComponentSystem,
209
+ pc.ScrollViewComponentSystem,
210
+ pc.ScrollbarComponentSystem,
211
+ pc.SpriteComponentSystem,
212
+ pc.LayoutGroupComponentSystem,
213
+ pc.LayoutChildComponentSystem,
214
+ pc.ZoneComponentSystem,
215
+ pc.GSplatComponentSystem,
216
+ ].filter(Boolean);
217
+
218
+ createOptions.resourceHandlers = [
219
+ pc.RenderHandler,
220
+ pc.AnimationHandler,
221
+ pc.AnimClipHandler,
222
+ pc.AnimStateGraphHandler,
223
+ pc.ModelHandler,
224
+ pc.MaterialHandler,
225
+ pc.TextureHandler,
226
+ pc.TextHandler,
227
+ pc.JsonHandler,
228
+ pc.AudioHandler,
229
+ pc.ScriptHandler,
230
+ pc.SceneHandler,
231
+ pc.CubemapHandler,
232
+ pc.HtmlHandler,
233
+ pc.CssHandler,
234
+ pc.ShaderHandler,
235
+ pc.HierarchyHandler,
236
+ pc.FolderHandler,
237
+ pc.FontHandler,
238
+ pc.BinaryHandler,
239
+ pc.TextureAtlasHandler,
240
+ pc.SpriteHandler,
241
+ pc.TemplateHandler,
242
+ pc.ContainerHandler,
243
+ pc.GSplatHandler
244
+ ].filter(Boolean);
245
+
246
+ createOptions.elementInput = new pc.ElementInput(canvas, {
247
+ useMouse: INPUT_SETTINGS.useMouse,
248
+ useTouch: INPUT_SETTINGS.useTouch
249
+ });
250
+ createOptions.keyboard = INPUT_SETTINGS.useKeyboard ? new pc.Keyboard(window) : null;
251
+ createOptions.mouse = INPUT_SETTINGS.useMouse ? new pc.Mouse(canvas) : null;
252
+ createOptions.gamepads = INPUT_SETTINGS.useGamepads ? new pc.GamePads() : null;
253
+ createOptions.touch = INPUT_SETTINGS.useTouch && pc.platform.touch ? new pc.TouchDevice(canvas) : null;
254
+ createOptions.assetPrefix = window.ASSET_PREFIX || '';
255
+ createOptions.scriptPrefix = window.SCRIPT_PREFIX || '';
256
+ createOptions.scriptsOrder = window.SCRIPTS || [];
257
+ createOptions.soundManager = new pc.SoundManager();
258
+ createOptions.lightmapper = pc.Lightmapper;
259
+ createOptions.batchManager = pc.BatchManager;
260
+ createOptions.xr = pc.XrManager;
261
+
262
+ app.init(createOptions);
263
+ return true;
264
+
265
+ } catch (e) {
266
+ displayError('Could not initialize application. Error: ' + e);
267
+ console.error(e);
268
+ return false;
269
+ }
270
+ }
271
+
272
+ function configure() {
273
+ app.configure(window.CONFIG_FILENAME, (err) => {
274
+ if (err) {
275
+ console.error(err);
276
+ return;
277
+ }
278
+
279
+ initCSS();
280
+
281
+ if (LTC_MAT_1.length && LTC_MAT_2.length && app.setAreaLightLuts.length === 2) {
282
+ app.setAreaLightLuts(LTC_MAT_1, LTC_MAT_2);
283
+ }
284
+
285
+ // do the first reflow after a timeout because of
286
+ // iOS showing a squished iframe sometimes
287
+ setTimeout(() => {
288
+ pcBootstrap.reflow(app, canvas);
289
+ pcBootstrap.reflowHandler = function () {
290
+ pcBootstrap.reflow(app, canvas);
291
+ };
292
+
293
+ window.addEventListener('resize', pcBootstrap.reflowHandler, false);
294
+ window.addEventListener('orientationchange', pcBootstrap.reflowHandler, false);
295
+
296
+ app.preload(() => {
297
+ app.scenes.loadScene(window.SCENE_PATH, (err) => {
298
+ if (err) {
299
+ console.error(err);
300
+ return;
301
+ }
302
+
303
+ app.start();
304
+ })
305
+ })
306
+ });
307
+ });
308
+ }
309
+
310
+ function main() {
311
+ createGraphicsDevice((device) => {
312
+ if (!device) {
313
+ return;
314
+ }
315
+
316
+ if (!initApp(device)) {
317
+ return;
318
+ }
319
+
320
+ if (window.PRELOAD_MODULES.length) {
321
+ loadModules(window.PRELOAD_MODULES, window.ASSET_PREFIX, () => {
322
+ configure(() => {
323
+ console.timeEnd('start');
324
+ });
325
+ })
326
+ } else {
327
+ configure();
328
+ }
329
+ });
330
+ }
331
+ main();
332
+ })(); // Add scope to avoid polluting window scope
@@ -0,0 +1,18 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover' />
5
+ <meta charset='utf-8'>
6
+ <link rel="stylesheet" type="text/css" href="styles.css">
7
+ <link rel="manifest" href="manifest.json">
8
+ <style></style>
9
+ <title>{{PROJECT_NAME}}</title>
10
+ <script src="playcanvas-stable.min.js"></script>
11
+ <script src="__settings__.js"></script>
12
+ </head>
13
+ <body>
14
+ <script src="__modules__.js"></script>
15
+ <script src="__start__.js"></script>
16
+ <script src="__loading__.js"></script>
17
+ </body>
18
+ </html>
Binary file
@@ -0,0 +1 @@
1
+ {"short_name":"Roll a Ball","name":"Roll a Ball","start_url":"","display":"fullscreen","icons":[{"src":"thumbs/180.jpg","sizes":"180x180","type":"image/jpeg"},{"src":"thumbs/360.jpg","sizes":"360x360","type":"image/jpeg"},{"src":"thumbs/540.jpg","sizes":"540x540","type":"image/jpeg"},{"src":"thumbs/720.jpg","sizes":"720x720","type":"image/jpeg"}]}