Player1444 commited on
Commit
4a7bddd
·
verified ·
1 Parent(s): 297832f

Upload index.html

Browse files
Files changed (1) hide show
  1. index.html +311 -0
index.html ADDED
@@ -0,0 +1,311 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
7
+ <title>Super Mario Bros. unofficial android port by Player1444</title>
8
+
9
+ <style>
10
+ * {
11
+ padding: 0; margin: 0; box-sizing: border-box;
12
+ user-select: none; -webkit-user-select: none; touch-action: none;
13
+ }
14
+ html, body {
15
+ width: 100%; height: 100%; overflow: hidden; background: #000; font-family: "Segoe UI", sans-serif;
16
+ }
17
+ #window {
18
+ display: flex; flex-direction: column; width: 100%; height: 100%;
19
+ border: 2px solid #adadad; background: transparent;
20
+ }
21
+ #titlebar {
22
+ height: 32px; background: #f0f0f0; display: flex; align-items: center;
23
+ justify-content: space-between; flex-shrink: 0; border-bottom: 1px solid #adadad;
24
+ }
25
+ #titlebar-left { display: flex; align-items: center; padding-left: 10px; }
26
+ #titlebar-text { font-size: 12px; color: #333; font-weight: 600; }
27
+ #titlebar-buttons { display: flex; height: 100%; }
28
+ .titlebar-btn {
29
+ width: 46px; height: 100%; border: none; background: transparent; font-size: 16px;
30
+ display: flex; align-items: center; justify-content: center; color: #333; cursor: pointer;
31
+ }
32
+ .titlebar-btn:hover { background: rgba(0, 0, 0, 0.1); }
33
+ #btn-close:hover { background: #e81123; color: white; }
34
+ #game-container {
35
+ flex: 1; background: #fff; display: flex; align-items: center; justify-content: center; position: relative;
36
+ }
37
+ canvas {
38
+ display: block; width: auto; height: auto; max-width: 100%; max-height: 100%;
39
+ aspect-ratio: 256 / 240; object-fit: contain; z-index: 1;
40
+ }
41
+ body.fullscreen #window { border: none; }
42
+ body.fullscreen #titlebar { display: none; }
43
+
44
+ .touch-zone { position: fixed; z-index: 99999; }
45
+ .touch-btn {
46
+ width: 70px; height: 70px; background: rgba(255, 255, 255, 0.25);
47
+ border: 3px solid rgba(0, 0, 0, 0.4); border-radius: 50%;
48
+ display: flex; align-items: center; justify-content: center;
49
+ font-weight: bold; font-size: 24px; color: rgba(0, 0, 0, 0.6);
50
+ }
51
+ .joystick-base {
52
+ width: 180px; height: 180px; background: rgba(255, 255, 255, 0.15);
53
+ border: 3px solid rgba(0, 0, 0, 0.4); border-radius: 50%; position: relative;
54
+ }
55
+ .joystick-stick {
56
+ width: 80px; height: 80px; background: rgba(0, 0, 0, 0.4); border-radius: 50%;
57
+ position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
58
+ }
59
+ #edit-toggle {
60
+ position: fixed; top: 45px; right: 15px; padding: 8px 16px;
61
+ background: rgba(0, 0, 0, 0.6); color: white; border: 2px solid white;
62
+ border-radius: 5px; font-size: 14px; z-index: 100000; cursor: pointer;
63
+ }
64
+ #edit-toggle.editing { background: #e81123; }
65
+ .editing-mode .touch-btn, .editing-mode .joystick-base {
66
+ background: rgba(232, 17, 35, 0.4) !important; border: 3px dashed #fff !important; color: #fff !important;
67
+ }
68
+ </style>
69
+ </head>
70
+ <body>
71
+
72
+ <div id="window">
73
+ <div id="titlebar">
74
+ <div id="titlebar-left"><div id="titlebar-text">Super Mario Bros. (Web)</div></div>
75
+ <div id="titlebar-buttons">
76
+ <button class="titlebar-btn" id="btn-minimize">—</button>
77
+ <button class="titlebar-btn" id="btn-maximize">▢</button>
78
+ <button class="titlebar-btn" id="btn-close">✕</button>
79
+ </div>
80
+ </div>
81
+ <div id="game-container">
82
+ <canvas id="c2canvas" width="800" height="600"></canvas>
83
+ </div>
84
+ </div>
85
+
86
+ <button id="edit-toggle">Edit</button>
87
+
88
+ <div id="zone-joystick" class="touch-zone" style="bottom: 40px; left: 40px;">
89
+ <div class="joystick-base"><div class="joystick-stick" id="joystick-stick"></div></div>
90
+ </div>
91
+ <div id="zone-enter" class="touch-zone" style="bottom: 120px; right: 30px;">
92
+ <div class="touch-btn" style="font-size: 16px;">Enter</div>
93
+ </div>
94
+ <div id="zone-shift" class="touch-zone" style="bottom: 120px; right: 110px;">
95
+ <div class="touch-btn" style="font-size: 16px;">Shift</div>
96
+ </div>
97
+ <div id="zone-run" class="touch-zone" style="bottom: 40px; right: 110px;">
98
+ <div class="touch-btn">X</div>
99
+ </div>
100
+ <div id="zone-jump" class="touch-zone" style="bottom: 40px; right: 30px;">
101
+ <div class="touch-btn">Z</div>
102
+ </div>
103
+
104
+ <input style="display:none;" id="c2nwOpenFileDialog" type="file" />
105
+ <input style="display:none;" id="c2nwChooseFolderDialog" type="file" nwdirectory />
106
+ <input style="display:none;" id="c2nwSaveDialog" type="file" nwsaveas />
107
+
108
+ <script src="jquery-3.4.1.min.js"></script>
109
+
110
+ <!-- ======================================================================= -->
111
+ <!-- АБСОЛЮТНАЯ СУПЕР-ЗАГЛУШКА NW.JS (Не дает игре выдать ни одной ошибки) -->
112
+ <!-- ======================================================================= -->
113
+ <script>
114
+ window["c2nodewebkit"] = false;
115
+
116
+ // Этот магический прокси-объект может притворяться чем угодно.
117
+ // Если игра вызовет require("fs").existsSync("file")()().path.anything...
118
+ // Прокси просто ответит "всё хорошо" и не сломает код.
119
+ function createSuperMock() {
120
+ const noop = function() {};
121
+ const proxy = new Proxy(noop, {
122
+ get: function(target, prop) {
123
+ if (prop === Symbol.toPrimitive) return () => "";
124
+ if (prop === 'toString') return () => "";
125
+ if (prop === 'valueOf') return () => 0;
126
+ if (prop === 'then') return undefined; // Защита от поломки Promise-ов
127
+
128
+ // Специфичные константы, которые игра жестко проверяет:
129
+ if (prop === 'platform') return 'win32';
130
+ if (prop === 'filename') return 'index.html';
131
+ if (prop === 'manifest') return { window: { icon: "" } };
132
+ if (prop === 'existsSync') return () => false;
133
+ if (prop === 'readFileSync') return () => "";
134
+ if (prop === 'sep') return '/';
135
+ if (prop === 'join' || prop === 'dirname') return () => "";
136
+
137
+ return proxy; // Возвращает сам себя для бесконечной вложенности
138
+ },
139
+ apply: function(target, thisArg, args) {
140
+ return proxy; // Если вызвали как функцию — не падаем
141
+ },
142
+ construct: function(target, args) {
143
+ return proxy; // Если вызвали через new — не падаем
144
+ }
145
+ });
146
+ return proxy;
147
+ }
148
+
149
+ // Подменяем все ПК-функции на нашу черную дыру
150
+ if (typeof window.require === "undefined") {
151
+ window.require = function() { return createSuperMock(); };
152
+ }
153
+
154
+ window.process = createSuperMock();
155
+ window.nw = createSuperMock();
156
+ </script>
157
+
158
+ <script src="c2runtime.js"></script>
159
+
160
+ <script>
161
+ jQuery(document).ready(function () {
162
+ cr_createRuntime("c2canvas");
163
+ loadButtonPositions();
164
+ });
165
+
166
+ document.addEventListener("visibilitychange", function() {
167
+ if (typeof cr_setSuspended !== "undefined") cr_setSuspended(!!document.hidden);
168
+ });
169
+
170
+ document.getElementById("btn-minimize").onclick = () => alert("Окно нельзя свернуть в браузере.");
171
+ document.getElementById("btn-close").onclick = () => {
172
+ document.getElementById("window").style.display = "none";
173
+ if (typeof cr_setSuspended !== "undefined") cr_setSuspended(true);
174
+ };
175
+
176
+ var btnMaximize = document.getElementById("btn-maximize");
177
+ btnMaximize.onclick = () => {
178
+ var elem = document.documentElement;
179
+ if (!document.fullscreenElement) {
180
+ if (elem.requestFullscreen) elem.requestFullscreen();
181
+ else if (elem.webkitRequestFullscreen) elem.webkitRequestFullscreen();
182
+ } else {
183
+ if (document.exitFullscreen) document.exitFullscreen();
184
+ else if (document.webkitExitFullscreen) document.webkitExitFullscreen();
185
+ }
186
+ };
187
+
188
+ document.addEventListener("fullscreenchange", () => {
189
+ if (document.fullscreenElement) document.body.classList.add("fullscreen");
190
+ else document.body.classList.remove("fullscreen");
191
+ });
192
+
193
+ var isEditing = false;
194
+ var keyMap = { 'zone-jump': [90, 32, 38], 'zone-run': [88], 'zone-shift': [16], 'zone-enter': [13] };
195
+
196
+ function simulateKeyboardEvent(keyCodes, type) {
197
+ if (!keyCodes) return;
198
+ keyCodes.forEach(code => {
199
+ var e = new KeyboardEvent(type, { keyCode: code, which: code, bubbles: true });
200
+ document.dispatchEvent(e); window.dispatchEvent(e);
201
+ var canvas = document.getElementById("c2canvas");
202
+ if (canvas) canvas.dispatchEvent(e);
203
+ });
204
+ }
205
+
206
+ var editToggle = document.getElementById('edit-toggle');
207
+ editToggle.addEventListener('click', function() {
208
+ isEditing = !isEditing;
209
+ if (isEditing) {
210
+ this.classList.add('editing'); this.innerText = 'Save'; document.body.classList.add('editing-mode');
211
+ } else {
212
+ this.classList.remove('editing'); this.innerText = 'Edit'; document.body.classList.remove('editing-mode');
213
+ saveButtonPositions();
214
+ }
215
+ });
216
+
217
+ var activeJoystickKeys = new Set();
218
+ function handleJoystick(e, zone) {
219
+ var touch = e.touches[0];
220
+ var rect = zone.getBoundingClientRect();
221
+ var centerX = rect.left + rect.width / 2;
222
+ var centerY = rect.top + rect.height / 2;
223
+ var dx = touch.clientX - centerX;
224
+ var dy = touch.clientY - centerY;
225
+ var distance = Math.sqrt(dx * dx + dy * dy);
226
+ var angle = Math.atan2(dy, dx);
227
+
228
+ var maxVisualDist = 65;
229
+ var visualDist = Math.min(distance, maxVisualDist);
230
+ var stickX = Math.cos(angle) * visualDist;
231
+ var stickY = Math.sin(angle) * visualDist;
232
+ zone.querySelector('.joystick-stick').style.transform = `translate(calc(-50% + ${stickX}px), calc(-50% + ${stickY}px))`;
233
+
234
+ var deadZone = 30;
235
+ var newKeys = new Set();
236
+ if (distance > deadZone) {
237
+ if (dx > deadZone) newKeys.add(39);
238
+ if (dx < -deadZone) newKeys.add(37);
239
+ if (dy > deadZone) newKeys.add(40);
240
+ if (dy < -deadZone) newKeys.add(38);
241
+ }
242
+
243
+ activeJoystickKeys.forEach(key => { if (!newKeys.has(key)) simulateKeyboardEvent([key], 'keyup'); });
244
+ newKeys.forEach(key => { if (!activeJoystickKeys.has(key)) simulateKeyboardEvent([key], 'keydown'); });
245
+ activeJoystickKeys = newKeys;
246
+ }
247
+
248
+ function resetJoystick(zone) {
249
+ zone.querySelector('.joystick-stick').style.transform = 'translate(-50%, -50%)';
250
+ activeJoystickKeys.forEach(key => simulateKeyboardEvent([key], 'keyup'));
251
+ activeJoystickKeys.clear();
252
+ }
253
+
254
+ var zones = document.querySelectorAll('.touch-zone');
255
+ zones.forEach(zone => {
256
+ var dragX = 0, dragY = 0;
257
+ zone.addEventListener('touchstart', e => {
258
+ if (isEditing) {
259
+ dragX = e.touches[0].clientX - zone.getBoundingClientRect().left;
260
+ dragY = e.touches[0].clientY - zone.getBoundingClientRect().top;
261
+ } else {
262
+ if (zone.id === 'zone-joystick') {
263
+ zone.querySelector('.joystick-stick').style.background = 'rgba(0, 0, 0, 0.6)';
264
+ handleJoystick(e, zone);
265
+ } else {
266
+ zone.querySelector('.touch-btn').style.background = 'rgba(255, 255, 255, 0.6)';
267
+ simulateKeyboardEvent(keyMap[zone.id], 'keydown');
268
+ }
269
+ }
270
+ }, { passive: false });
271
+
272
+ zone.addEventListener('touchmove', e => {
273
+ e.preventDefault();
274
+ if (isEditing) {
275
+ var left = e.touches[0].clientX - dragX;
276
+ var top = e.touches[0].clientY - dragY;
277
+ zone.style.left = Math.max(0, Math.min(window.innerWidth - zone.offsetWidth, left)) + 'px';
278
+ zone.style.top = Math.max(0, Math.min(window.innerHeight - zone.offsetHeight, top)) + 'px';
279
+ zone.style.bottom = 'auto';
280
+ } else if (zone.id === 'zone-joystick') handleJoystick(e, zone);
281
+ }, { passive: false });
282
+
283
+ zone.addEventListener('touchend', e => {
284
+ if (!isEditing) {
285
+ if (zone.id === 'zone-joystick') {
286
+ zone.querySelector('.joystick-stick').style.background = 'rgba(0, 0, 0, 0.4)';
287
+ resetJoystick(zone);
288
+ } else {
289
+ zone.querySelector('.touch-btn').style.background = 'rgba(255, 255, 255, 0.25)';
290
+ simulateKeyboardEvent(keyMap[zone.id], 'keyup');
291
+ }
292
+ }
293
+ }, { passive: false });
294
+ });
295
+
296
+ function saveButtonPositions() {
297
+ var pos = {};
298
+ zones.forEach(z => pos[z.id] = { left: z.style.left, top: z.style.top, bottom: z.style.bottom });
299
+ localStorage.setItem('mario_pos', JSON.stringify(pos));
300
+ }
301
+
302
+ function loadButtonPositions() {
303
+ var saved = JSON.parse(localStorage.getItem('mario_pos') || "{}");
304
+ for (var id in saved) {
305
+ var z = document.getElementById(id);
306
+ if (z) { z.style.left = saved[id].left; z.style.top = saved[id].top; z.style.bottom = saved[id].bottom; }
307
+ }
308
+ }
309
+ </script>
310
+ </body>
311
+ </html>