diff --git a/source/document.js b/source/document.js
index aa43f47..320089c 100644
--- a/source/document.js
+++ b/source/document.js
@@ -29,7 +29,11 @@ document.body.innerHTML +=
'#btn-right{position:absolute;right:0;top:50%;transform:translateY(-50%);width:48px;height:48px}'+
'.ctrl-shoot{width:64px;height:64px;border-radius:50%;font-size:24px}'+
'.ctrl-prev,.ctrl-next{width:40px;height:40px;font-size:14px}'+
- '.ctrl-jump{width:52px;height:52px;border-radius:50%;font-size:20px}'
+ '.ctrl-jump{width:52px;height:52px;border-radius:50%;font-size:20px}'+
+ '#btn-fs{position:absolute;top:8px;right:8px;width:40px;height:40px;'+
+ 'background:rgba(255,255,255,0.2);border:1px solid rgba(255,255,255,0.3);'+
+ 'border-radius:8px;color:#fff;font-size:20px;z-index:20;'+
+ 'display:flex;align-items:center;justify-content:center}'
: '')+
''+
'
'+
diff --git a/source/input.js b/source/input.js
index 248f2e6..52ec3e2 100755
--- a/source/input.js
+++ b/source/input.js
@@ -83,7 +83,8 @@ c.onmouseup = (ev) => {
// ─── Mobile virtual controls ───
-if (is_touch) {
+// Called from main.js after game start
+create_touch_controls = () => {
let ctrl = document.createElement('div');
ctrl.id = 'ctrl';
ctrl.innerHTML =
@@ -148,5 +149,5 @@ if (is_touch) {
if (t.identifier === touch_id) touch_id = null;
}
});
-}
+};
diff --git a/source/main.js b/source/main.js
index f30cd13..a424085 100755
--- a/source/main.js
+++ b/source/main.js
@@ -123,12 +123,32 @@ game_load = async () => {
requestAnimationFrame(run_frame);
f.onclick = () => g.requestFullscreen();
- g.onclick = () => {
- if (!is_touch) {
+
+ // Mobile: fullscreen button overlay in top-right
+ if (is_touch) {
+ let fs_btn = document.createElement('button');
+ fs_btn.id = 'btn-fs';
+ fs_btn.textContent = '⛶';
+ fs_btn.onclick = () => g.requestFullscreen();
+ document.getElementById('g').appendChild(fs_btn);
+ }
+
+ // Game start handler
+ let start_game = () => {
+ // Remove the entry handler so it only fires once
+ g.onclick = null;
+ if (g._touch_entry) {
+ g.removeEventListener('touchstart', g._touch_entry);
+ g._touch_entry = null;
+ }
+ if (is_touch) {
+ // Create virtual controls now that game is starting
+ create_touch_controls();
+ } else {
g.onclick = () => c.requestPointerLock();
g.onclick();
}
-
+
audio_init();
// Generate sounds
@@ -157,6 +177,13 @@ game_load = async () => {
game_init(0);
run_frame = game_run;
};
+
+ // Wire up game start: click for desktop, touch for mobile
+ g.onclick = start_game;
+ if (is_touch) {
+ g._touch_entry = (e) => { e.preventDefault(); start_game(); };
+ g.addEventListener('touchstart', g._touch_entry, {passive: false});
+ }
},
run_frame = (time_now) => {