@playcraft/build 0.0.11 → 0.0.14

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 (102) hide show
  1. package/dist/analyzers/__tests__/optimization-analyzer.test.d.ts +1 -0
  2. package/dist/analyzers/__tests__/optimization-analyzer.test.js +169 -0
  3. package/dist/analyzers/playable-analyzer.js +3 -2
  4. package/dist/analyzers/scene-asset-collector.js +99 -9
  5. package/dist/base-builder.d.ts +15 -78
  6. package/dist/base-builder.js +34 -735
  7. package/dist/engines/engine-detector.d.ts +38 -0
  8. package/dist/engines/engine-detector.js +201 -0
  9. package/dist/engines/generic-adapter.d.ts +71 -0
  10. package/dist/engines/generic-adapter.js +378 -0
  11. package/dist/engines/index.d.ts +7 -0
  12. package/dist/engines/index.js +7 -0
  13. package/dist/engines/playcanvas-adapter.d.ts +85 -0
  14. package/dist/engines/playcanvas-adapter.js +813 -0
  15. package/dist/generators/config-generator.js +59 -1
  16. package/dist/index.d.ts +4 -0
  17. package/dist/index.js +4 -0
  18. package/dist/loaders/playcraft-loader.js +240 -5
  19. package/dist/platforms/adikteev.d.ts +1 -1
  20. package/dist/platforms/adikteev.js +30 -34
  21. package/dist/platforms/applovin.d.ts +1 -1
  22. package/dist/platforms/applovin.js +34 -33
  23. package/dist/platforms/base.d.ts +27 -5
  24. package/dist/platforms/base.js +79 -181
  25. package/dist/platforms/bigo.d.ts +1 -1
  26. package/dist/platforms/bigo.js +28 -28
  27. package/dist/platforms/facebook.d.ts +1 -1
  28. package/dist/platforms/facebook.js +21 -10
  29. package/dist/platforms/google.d.ts +1 -1
  30. package/dist/platforms/google.js +28 -21
  31. package/dist/platforms/index.d.ts +1 -0
  32. package/dist/platforms/index.js +4 -0
  33. package/dist/platforms/inmobi.d.ts +1 -1
  34. package/dist/platforms/inmobi.js +27 -32
  35. package/dist/platforms/ironsource.d.ts +1 -1
  36. package/dist/platforms/ironsource.js +37 -37
  37. package/dist/platforms/liftoff.d.ts +1 -1
  38. package/dist/platforms/liftoff.js +24 -27
  39. package/dist/platforms/mintegral.d.ts +10 -0
  40. package/dist/platforms/mintegral.js +65 -0
  41. package/dist/platforms/moloco.d.ts +1 -1
  42. package/dist/platforms/moloco.js +18 -20
  43. package/dist/platforms/playcraft.d.ts +1 -1
  44. package/dist/platforms/playcraft.js +2 -2
  45. package/dist/platforms/remerge.d.ts +1 -1
  46. package/dist/platforms/remerge.js +19 -20
  47. package/dist/platforms/snapchat.d.ts +1 -1
  48. package/dist/platforms/snapchat.js +35 -23
  49. package/dist/platforms/tiktok.d.ts +1 -1
  50. package/dist/platforms/tiktok.js +28 -24
  51. package/dist/platforms/unity.d.ts +1 -1
  52. package/dist/platforms/unity.js +32 -32
  53. package/dist/playable-builder.d.ts +1 -0
  54. package/dist/playable-builder.js +19 -3
  55. package/dist/templates/__loading__.js +100 -0
  56. package/dist/templates/__modules__.js +47 -0
  57. package/dist/templates/__settings__.template.js +20 -0
  58. package/dist/templates/__start__.js +332 -0
  59. package/dist/templates/index.html +18 -0
  60. package/dist/templates/logo.png +0 -0
  61. package/dist/templates/manifest.json +1 -0
  62. package/dist/templates/patches/cannon.min.js +28 -0
  63. package/dist/templates/patches/lz4.js +10 -0
  64. package/dist/templates/patches/one-page-http-get.js +20 -0
  65. package/dist/templates/patches/one-page-inline-game-scripts.js +52 -0
  66. package/dist/templates/patches/one-page-mraid-resize-canvas.js +46 -0
  67. package/dist/templates/patches/p2.min.js +27 -0
  68. package/dist/templates/patches/playcraft-no-xhr.js +76 -0
  69. package/dist/templates/playcanvas-stable.min.js +16363 -0
  70. package/dist/templates/styles.css +43 -0
  71. package/dist/types.d.ts +114 -1
  72. package/dist/types.js +77 -1
  73. package/dist/utils/ammo-detector.d.ts +9 -0
  74. package/dist/utils/ammo-detector.js +76 -0
  75. package/dist/utils/build-mode-detector.js +2 -0
  76. package/dist/utils/minify.d.ts +32 -0
  77. package/dist/utils/minify.js +82 -0
  78. package/dist/vite/config-builder-generic.d.ts +70 -0
  79. package/dist/vite/config-builder-generic.js +251 -0
  80. package/dist/vite/config-builder.d.ts +8 -0
  81. package/dist/vite/config-builder.js +56 -16
  82. package/dist/vite/platform-configs.d.ts +1 -0
  83. package/dist/vite/platform-configs.js +30 -1
  84. package/dist/vite/plugin-build-state.d.ts +2 -0
  85. package/dist/vite/plugin-build-state.js +5 -3
  86. package/dist/vite/plugin-compress-js.d.ts +21 -0
  87. package/dist/vite/plugin-compress-js.js +213 -0
  88. package/dist/vite/plugin-esm-html-generator.js +15 -2
  89. package/dist/vite/plugin-platform.d.ts +5 -0
  90. package/dist/vite/plugin-platform.js +502 -36
  91. package/dist/vite/plugin-playcanvas.d.ts +1 -0
  92. package/dist/vite/plugin-playcanvas.js +181 -88
  93. package/dist/vite/plugin-source-builder.js +102 -21
  94. package/dist/vite-builder.d.ts +25 -7
  95. package/dist/vite-builder.js +141 -52
  96. package/package.json +4 -2
  97. package/physics/cannon-rigidbody-adapter.js +243 -22
  98. package/templates/__loading__.js +0 -12
  99. package/templates/index.esm.mjs +0 -11
  100. package/templates/patches/one-page-mraid-resize-canvas.js +18 -4
  101. package/templates/patches/playcraft-cta-adapter.js +129 -31
  102. package/templates/patches/scene-physics-defaults.js +49 -0
@@ -2,6 +2,7 @@ import fs from 'fs/promises';
2
2
  import path from 'path';
3
3
  import { fileURLToPath } from 'url';
4
4
  import { createPlatformAdapter } from './platforms/index.js';
5
+ import { minifyPatchCode } from './utils/minify.js';
5
6
  /**
6
7
  * Playable Ads 打包器 - 将多文件版本转换为单HTML
7
8
  *
@@ -31,8 +32,8 @@ export class PlayableBuilder {
31
32
  await this.validateBaseBuild();
32
33
  // 2. 转换为单HTML
33
34
  const html = await this.convertToSingleHTML();
34
- // 3. 应用渠道配置
35
- const finalHtml = this.platformAdapter.modifyHTML(html, []);
35
+ // 3. 应用渠道配置(现在是异步的)
36
+ const finalHtml = await this.platformAdapter.modifyHTML(html, []);
36
37
  // 4. 验证大小限制
37
38
  const htmlSize = Buffer.from(finalHtml, 'utf-8').length;
38
39
  this.sizeReport.total = htmlSize;
@@ -87,6 +88,8 @@ export class PlayableBuilder {
87
88
  if (this.options.ammoReplacement) {
88
89
  html = await this.injectPhysicsLibrary(html);
89
90
  }
91
+ // 4.2 注入 Scene applySettings 补丁,避免 settings.physics 缺失导致 gravity 报错
92
+ html = await this.injectScenePhysicsPatch(html);
90
93
  // 5. 内联 __settings__.js,并转换资源URL为data URLs
91
94
  html = await this.inlineSettings(html);
92
95
  // 6. 内联 __modules__.js
@@ -238,6 +241,8 @@ export class PlayableBuilder {
238
241
  const appProps = configJson.application_properties || {};
239
242
  const scripts = appProps.scripts || [];
240
243
  const preloadModules = this.extractPreloadModules(configJson);
244
+ // 保留原始的 powerPreference 设置,默认为 high-performance
245
+ const powerPreference = appProps.powerPreference || 'high-performance';
241
246
  const settingsCode = `
242
247
  window.ASSET_PREFIX = "";
243
248
  window.SCRIPT_PREFIX = "";
@@ -247,7 +252,7 @@ window.CONTEXT_OPTIONS = {
247
252
  'alpha': ${appProps.transparentCanvas === true},
248
253
  'preserveDrawingBuffer': ${appProps.preserveDrawingBuffer === true},
249
254
  'deviceTypes': ['webgl2', 'webgl1'],
250
- 'powerPreference': "default"
255
+ 'powerPreference': "${powerPreference}"
251
256
  };
252
257
  window.SCRIPTS = [${scripts.join(', ')}];
253
258
  window.CONFIG_FILENAME = "${configDataUrl}";
@@ -476,6 +481,17 @@ window.PRELOAD_MODULES = ${JSON.stringify(preloadModules)};
476
481
  }
477
482
  return `${tag}\n${html}`;
478
483
  }
484
+ async injectScenePhysicsPatch(html) {
485
+ const patchCode = await this.readPatchFile('scene-physics-defaults.js');
486
+ if (!patchCode)
487
+ return html;
488
+ const minified = await minifyPatchCode(patchCode, 'scene-physics-defaults.js');
489
+ const tag = `<script>${minified}</script>`;
490
+ if (html.includes('</head>')) {
491
+ return html.replace('</head>', `${tag}\n</head>`);
492
+ }
493
+ return `${tag}\n${html}`;
494
+ }
479
495
  isAmmoModule(module) {
480
496
  const moduleName = module.moduleName?.toLowerCase() ?? '';
481
497
  const glueUrl = module.glueUrl?.toLowerCase() ?? '';
@@ -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"}]}