1+ <!doctype html>
2+ < html lang ="en-us ">
3+
4+ < head >
5+ < meta charset ="utf-8 ">
6+ < meta http-equiv ="Content-Type " content ="text/html; charset=utf-8 ">
7+ < title > Cubos WebGL Player | Ondisseia</ title >
8+ < meta name ="viewport " content ="width=device-width, initial-scale=1, user-scalable=no ">
9+ < link rel ="stylesheet " href ="https://fonts.googleapis.com/css2?family=Material+Symbols " />
10+ < style >
11+ html ,
12+ body {
13+ margin : 0 ;
14+ padding : 0 ;
15+ background : black;
16+ font-family : Arial, sans-serif;
17+ color : white;
18+ overflow : hidden;
19+ height : 100% ;
20+ }
21+
22+ canvas .emscripten {
23+ display : block;
24+ width : 100vw ;
25+ height : 100vh ;
26+ background-color : black;
27+ border : none;
28+ }
29+
30+ # status-container {
31+ position : absolute;
32+ top : 10px ;
33+ left : 10px ;
34+ display : flex;
35+ align-items : center;
36+ z-index : 10 ;
37+ font-size : 14px ;
38+ color : # ccc ;
39+ }
40+
41+ .spinner {
42+ width : 20px ;
43+ height : 20px ;
44+ border : 3px solid # f4d848 ;
45+ border-top : 3px solid # dc941c ;
46+ border-radius : 50% ;
47+ animation : spin 1s linear infinite;
48+ margin-right : 10px ;
49+ }
50+
51+ @keyframes spin {
52+ 0% {
53+ transform : rotate (0deg );
54+ }
55+
56+ 100% {
57+ transform : rotate (360deg );
58+ }
59+ }
60+
61+ # progress {
62+ width : 100% ;
63+ height : 4px ;
64+ position : absolute;
65+ bottom : 0 ;
66+ left : 0 ;
67+ appearance : none;
68+ }
69+
70+ # progress ::-webkit-progress-bar {
71+ background : # 222 ;
72+ }
73+
74+ # progress ::-webkit-progress-value {
75+ background : # f4d848 ;
76+ }
77+
78+ # fullscreen-btn {
79+ position : absolute;
80+ top : 10px ;
81+ right : 10px ;
82+ background : rgba (255 , 255 , 255 , 0.1 );
83+ color : white;
84+ padding : 6px 10px ;
85+ border : none;
86+ border-radius : 5px ;
87+ z-index : 10 ;
88+ cursor : pointer;
89+ }
90+
91+ # fullscreen-btn : hover {
92+ background : rgba (255 , 255 , 255 , 0.4 );
93+ }
94+
95+ # fullscreen-btn ::before {
96+ content : "\26F6" ;
97+ /* Compass icon */
98+ font-size : clamp (14px , 3vw , 64px );
99+ }
100+
101+ # touch-controls {
102+ position : absolute;
103+ bottom : 10px ;
104+ width : 100% ;
105+ display : flex;
106+ justify-content : space-between;
107+ padding : 0 10px ;
108+ box-sizing : border-box;
109+ pointer-events : none;
110+ }
111+
112+ # left-controls ,
113+ # right-controls {
114+ display : flex;
115+ flex-direction : column;
116+ gap : 8px ;
117+ pointer-events : auto;
118+ }
119+
120+ # left-controls button ,
121+ # right-controls button {
122+ width : 48px ;
123+ height : 48px ;
124+ font-size : 18px ;
125+ background : rgba (255 , 255 , 255 , 0.1 );
126+ color : white;
127+ border : none;
128+ border-radius : 6px ;
129+ }
130+
131+ .dpad {
132+ display : grid;
133+ grid-template-columns : 60px 60px 60px ;
134+ grid-template-rows : 60px 60px 60px ;
135+ gap : 3px ;
136+ justify-content : center;
137+ align-items : center;
138+ }
139+
140+ .dpad button {
141+ width : 60px ;
142+ height : 60px ;
143+ font-size : 20px ;
144+ background : # 444 ;
145+ color : white;
146+ border : none;
147+ border-radius : 8px ;
148+ }
149+
150+ .dpad .up {
151+ grid-column : 2 ;
152+ grid-row : 1 ;
153+ }
154+
155+ .dpad .left {
156+ grid-column : 1 ;
157+ grid-row : 2 ;
158+ }
159+
160+ .dpad .right {
161+ grid-column : 3 ;
162+ grid-row : 2 ;
163+ }
164+
165+ .dpad .down {
166+ grid-column : 2 ;
167+ grid-row : 2 ;
168+ }
169+
170+ .dpad .shoot {
171+ grid-column : 2 ;
172+ grid-row : 4 ;
173+ }
174+
175+
176+ .prevent-select {
177+ -webkit-user-select : none;
178+ /* Safari */
179+ -ms-user-select : none;
180+ /* IE 10 and IE 11 */
181+ user-select : none;
182+ /* Standard syntax */
183+ }
184+ </ style >
185+ </ head >
186+
187+ < body >
188+ < canvas class ="emscripten " id ="canvas " oncontextmenu ="event.preventDefault() "> </ canvas >
189+
190+ < div id ="status-container ">
191+ < div class ="spinner " id ="spinner "> </ div >
192+ < div id ="status "> Loading...</ div >
193+ </ div >
194+
195+ < button id ="fullscreen-btn " onclick ="Module.requestFullscreen(false, true) "> </ button >
196+
197+ < div id ="touch-controls " style ="visibility: hidden; ">
198+ < div id ="left-controls " class ="prevent-select ">
199+ < div class ="dpad ">
200+ < button class ="left " ontouchstart ="simulateKey(65, true) " ontouchend ="simulateKey(65, false) "> < i
201+ class ="material-symbols "> arrow_left</ i > </ button >
202+ < button class ="up " ontouchstart ="simulateKey(87, true) " ontouchend ="simulateKey(87, false) "> < i
203+ class ="material-symbols "> arrow_drop_up</ i > </ button >
204+ < button class ="right " ontouchstart ="simulateKey(68, true) " ontouchend ="simulateKey(68, false) "> < i
205+ class ="material-symbols "> arrow_right</ i > </ button >
206+ < button class ="down " ontouchstart ="simulateKey(83, true) " ontouchend ="simulateKey(83, false) "> < i
207+ class ="material-symbols "> arrow_drop_down</ i > </ button >
208+ < button class ="shoot " ontouchstart ="simulateKey(32, true) " ontouchend ="simulateKey(32, false) "> < i
209+ class ="material-symbols "> swords</ i > </ button >
210+ </ div >
211+
212+ </ div >
213+ < div id ="right-controls " class ="prevent-select ">
214+ < div class ="dpad ">
215+ < button class ="left " ontouchstart ="simulateKey(37, true) " ontouchend ="simulateKey(37, false) "> < i
216+ class ="material-symbols "> arrow_left</ i > </ button >
217+ < button class ="up " ontouchstart ="simulateKey(38, true) " ontouchend ="simulateKey(38, false) "> < i
218+ class ="material-symbols "> arrow_drop_up</ i > </ button >
219+ < button class ="right " ontouchstart ="simulateKey(39, true) " ontouchend ="simulateKey(39, false) "> < i
220+ class ="material-symbols "> arrow_right</ i > </ button >
221+ < button class ="down " ontouchstart ="simulateKey(40, true) " ontouchend ="simulateKey(40, false) "> < i
222+ class ="material-symbols "> arrow_drop_down</ i > </ button >
223+ < button class ="shoot " ontouchstart ="simulateKey(76, true) " ontouchend ="simulateKey(76, false) "> < i
224+ class ="material-symbols "> swords</ i > </ button >
225+ </ div >
226+ </ div >
227+ </ div >
228+
229+ < progress value ="0 " max ="100 " id ="progress " hidden =1 > </ progress >
230+
231+ < script type ='text/javascript '>
232+ var statusElement = document . getElementById ( 'status' ) ;
233+ var progressElement = document . getElementById ( 'progress' ) ;
234+ var spinnerElement = document . getElementById ( 'spinner' ) ;
235+ var canvasElement = document . getElementById ( 'canvas' ) ;
236+ var outputElement = document . getElementById ( 'output' ) ;
237+ if ( outputElement ) outputElement . value = '' ; // clear browser cache
238+
239+ // As a default initial behavior, pop up an alert when webgl context is lost. To make your
240+ // application robust, you may want to override this behavior before shipping!
241+ // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
242+ canvasElement . addEventListener ( "webglcontextlost" , ( e ) => {
243+ alert ( 'WebGL context lost. You will need to reload the page.' ) ;
244+ e . preventDefault ( ) ;
245+ } , false ) ;
246+
247+ var Module = {
248+ print ( ...args ) {
249+ // These replacements are necessary if you render to raw HTML
250+ //text = text.replace(/&/g, "&");
251+ //text = text.replace(/</g, "<");
252+ //text = text.replace(/>/g, ">");
253+ //text = text.replace('\n', '<br>', 'g');
254+ console . log ( ...args ) ;
255+ if ( outputElement ) {
256+ var text = args . join ( ' ' ) ;
257+ outputElement . value += text + "\n" ;
258+ outputElement . scrollTop = outputElement . scrollHeight ; // focus on bottom
259+ }
260+ } ,
261+ canvas : canvasElement ,
262+ setStatus ( text ) {
263+ Module . setStatus . last ??= { time : Date . now ( ) , text : '' } ;
264+ if ( text === Module . setStatus . last . text ) return ;
265+ var m = text . match ( / ( [ ^ ( ] + ) \( ( \d + ( \. \d + ) ? ) \/ ( \d + ) \) / ) ;
266+ var now = Date . now ( ) ;
267+ if ( m && now - Module . setStatus . last . time < 30 ) return ; // if this is a progress update, skip it if too soon
268+ Module . setStatus . last . time = now ;
269+ Module . setStatus . last . text = text ;
270+ if ( m ) {
271+ text = m [ 1 ] ;
272+ progressElement . value = parseInt ( m [ 2 ] ) * 100 ;
273+ progressElement . max = parseInt ( m [ 4 ] ) * 100 ;
274+ progressElement . hidden = false ;
275+ spinnerElement . hidden = false ;
276+ } else {
277+ progressElement . value = null ;
278+ progressElement . max = null ;
279+ progressElement . hidden = true ;
280+ if ( ! text ) spinnerElement . hidden = true ;
281+ }
282+ statusElement . innerHTML = text ;
283+ } ,
284+ totalDependencies : 0 ,
285+ monitorRunDependencies ( left ) {
286+ this . totalDependencies = Math . max ( this . totalDependencies , left ) ;
287+ Module . setStatus ( left ? 'Preparing... (' + ( this . totalDependencies - left ) + '/' + this . totalDependencies + ')' : 'All downloads complete.' ) ;
288+ }
289+ } ;
290+ Module . setStatus ( 'Downloading...' ) ;
291+ window . onerror = ( ) => {
292+ Module . setStatus ( 'Exception thrown, see JavaScript console' ) ;
293+ spinnerElement . style . display = 'none' ;
294+ Module . setStatus = ( text ) => {
295+ if ( text ) console . error ( '[post-exception status] ' + text ) ;
296+ } ;
297+ } ;
298+
299+ // Detect if it's a touch device (Android or otherwise)
300+ if ( 'ontouchstart' in window || navigator . maxTouchPoints > 0 ) {
301+ // Detect Android specifically
302+ const isAndroid = / A n d r o i d / i. test ( navigator . userAgent ) ;
303+ if ( isAndroid ) {
304+ // If it's Android, display the touch controls and hide the fullscreen button
305+ document . getElementById ( 'touch-controls' ) . style . visibility = 'visible' ;
306+ document . getElementById ( 'fullscreen-btn' ) . style . visibility = 'hidden' ;
307+ }
308+ }
309+
310+ function simulateKey ( keyCode , isDown ) {
311+ const event = new KeyboardEvent ( isDown ? 'keydown' : 'keyup' , {
312+ keyCode : keyCode ,
313+ which : keyCode ,
314+ bubbles : true ,
315+ cancelable : true
316+ } ) ;
317+ document . dispatchEvent ( event ) ;
318+ }
319+ </ script >
320+
321+ {{{ SCRIPT }}}
322+ </ body >
0 commit comments