games/pac-survivors/index.html (view raw)
1<!DOCTYPE html>
2<html lang="en">
3 <head>
4 <meta charset="utf-8">
5 <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0">
6 <title>Pac Survivors</title>
7 <style>
8html, body, #canvas {
9 margin: 0;
10 padding: 0;
11 border: 0;
12}
13
14body {
15 color: white;
16 background-color: black;
17 overflow: hidden;
18 touch-action: none;
19}
20
21#canvas {
22 display: block;
23}
24
25#canvas:focus {
26 outline: none;
27}
28
29#status, #status-splash, #status-progress {
30 position: absolute;
31 left: 0;
32 right: 0;
33}
34
35#status, #status-splash {
36 top: 0;
37 bottom: 0;
38}
39
40#status {
41 background-color: #242424;
42 display: flex;
43 flex-direction: column;
44 justify-content: center;
45 align-items: center;
46 visibility: hidden;
47}
48
49#status-splash {
50 max-height: 100%;
51 max-width: 100%;
52 margin: auto;
53}
54
55#status-splash.show-image--false {
56 display: none;
57}
58
59#status-splash.fullsize--true {
60 height: 100%;
61 width: 100%;
62 object-fit: contain;
63}
64
65#status-splash.use-filter--false {
66 image-rendering: pixelated;
67}
68
69#status-progress, #status-notice {
70 display: none;
71}
72
73#status-progress {
74 bottom: 10%;
75 width: 50%;
76 margin: 0 auto;
77}
78
79#status-notice {
80 background-color: #5b3943;
81 border-radius: 0.5rem;
82 border: 1px solid #9b3943;
83 color: #e0e0e0;
84 font-family: 'Noto Sans', 'Droid Sans', Arial, sans-serif;
85 line-height: 1.3;
86 margin: 0 2rem;
87 overflow: hidden;
88 padding: 1rem;
89 text-align: center;
90 z-index: 1;
91}
92 </style>
93 <link id="-gd-engine-icon" rel="icon" type="image/png" href="index.icon.png" />
94<link rel="apple-touch-icon" href="index.apple-touch-icon.png"/>
95
96 </head>
97 <body>
98 <canvas id="canvas">
99 Your browser does not support the canvas tag.
100 </canvas>
101
102 <noscript>
103 Your browser does not support JavaScript.
104 </noscript>
105
106 <div id="status">
107 <img id="status-splash" class="show-image--true fullsize--true use-filter--true" src="index.png" alt="">
108 <progress id="status-progress"></progress>
109 <div id="status-notice"></div>
110 </div>
111
112 <script src="index.js"></script>
113 <script>
114const GODOT_CONFIG = {"args":[],"canvasResizePolicy":2,"emscriptenPoolSize":8,"ensureCrossOriginIsolationHeaders":true,"executable":"index","experimentalVK":false,"fileSizes":{"index.pck":21496132,"index.wasm":38034280},"focusCanvas":true,"gdextensionLibs":[],"godotPoolSize":4};
115const GODOT_THREADS_ENABLED = false;
116const engine = new Engine(GODOT_CONFIG);
117
118(function () {
119 const statusOverlay = document.getElementById('status');
120 const statusProgress = document.getElementById('status-progress');
121 const statusNotice = document.getElementById('status-notice');
122
123 let initializing = true;
124 let statusMode = '';
125
126 function setStatusMode(mode) {
127 if (statusMode === mode || !initializing) {
128 return;
129 }
130 if (mode === 'hidden') {
131 statusOverlay.remove();
132 initializing = false;
133 return;
134 }
135 statusOverlay.style.visibility = 'visible';
136 statusProgress.style.display = mode === 'progress' ? 'block' : 'none';
137 statusNotice.style.display = mode === 'notice' ? 'block' : 'none';
138 statusMode = mode;
139 }
140
141 function setStatusNotice(text) {
142 while (statusNotice.lastChild) {
143 statusNotice.removeChild(statusNotice.lastChild);
144 }
145 const lines = text.split('\n');
146 lines.forEach((line) => {
147 statusNotice.appendChild(document.createTextNode(line));
148 statusNotice.appendChild(document.createElement('br'));
149 });
150 }
151
152 function displayFailureNotice(err) {
153 console.error(err);
154 if (err instanceof Error) {
155 setStatusNotice(err.message);
156 } else if (typeof err === 'string') {
157 setStatusNotice(err);
158 } else {
159 setStatusNotice('An unknown error occurred.');
160 }
161 setStatusMode('notice');
162 initializing = false;
163 }
164
165 const missing = Engine.getMissingFeatures({
166 threads: GODOT_THREADS_ENABLED,
167 });
168
169 if (missing.length !== 0) {
170 if (GODOT_CONFIG['serviceWorker'] && GODOT_CONFIG['ensureCrossOriginIsolationHeaders'] && 'serviceWorker' in navigator) {
171 let serviceWorkerRegistrationPromise;
172 try {
173 serviceWorkerRegistrationPromise = navigator.serviceWorker.getRegistration();
174 } catch (err) {
175 serviceWorkerRegistrationPromise = Promise.reject(new Error('Service worker registration failed.'));
176 }
177 // There's a chance that installing the service worker would fix the issue
178 Promise.race([
179 serviceWorkerRegistrationPromise.then((registration) => {
180 if (registration != null) {
181 return Promise.reject(new Error('Service worker already exists.'));
182 }
183 return registration;
184 }).then(() => engine.installServiceWorker()),
185 // For some reason, `getRegistration()` can stall
186 new Promise((resolve) => {
187 setTimeout(() => resolve(), 2000);
188 }),
189 ]).then(() => {
190 // Reload if there was no error.
191 window.location.reload();
192 }).catch((err) => {
193 console.error('Error while registering service worker:', err);
194 });
195 } else {
196 // Display the message as usual
197 const missingMsg = 'Error\nThe following features required to run Godot projects on the Web are missing:\n';
198 displayFailureNotice(missingMsg + missing.join('\n'));
199 }
200 } else {
201 setStatusMode('progress');
202 engine.startGame({
203 'onProgress': function (current, total) {
204 if (current > 0 && total > 0) {
205 statusProgress.value = current;
206 statusProgress.max = total;
207 } else {
208 statusProgress.removeAttribute('value');
209 statusProgress.removeAttribute('max');
210 }
211 },
212 }).then(() => {
213 setStatusMode('hidden');
214 }, displayFailureNotice);
215 }
216}());
217 </script>
218 </body>
219</html>
220