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) => {