minigame fixed zoom2

This commit is contained in:
2026-05-05 08:13:53 +00:00
parent 91669bb65b
commit f69a12e655
3 changed files with 121 additions and 52 deletions
+24 -3
View File
@@ -4019,10 +4019,18 @@
let py = sumCy / ents.length;
const minCamX = halfW;
const maxCamX = Math.max(minCamX, mapWpx - halfW);
px = Math.max(minCamX, Math.min(maxCamX, px));
const minCamY = halfH;
const maxCamY = Math.max(minCamY, mapHpx - halfH);
py = Math.max(minCamY, Math.min(maxCamY, py));
const viewW = halfW * 2;
const viewH = halfH * 2;
/*
* ามมมองกวาง/งกวาแมป: อยาใช clamp แบบ minCamX (= กลองชดซายโลก) จะดเหมอนแมปตดมมซายบน (เดนใน embed / มออก)
* ใหดกลางแมปแทน างจาก mng8a80o กลองตาม me อยแล
*/
if (viewW >= mapWpx) px = mapWpx * 0.5;
else px = Math.max(minCamX, Math.min(maxCamX, px));
if (viewH >= mapHpx) py = mapHpx * 0.5;
else py = Math.max(minCamY, Math.min(maxCamY, py));
return { px, py };
}
@@ -13538,6 +13546,7 @@
const header = document.querySelector('.game-header');
const headerH = header && header.offsetHeight ? header.offsetHeight : 48;
const stage = document.getElementById('play-canvas-stage');
const stackEl = document.getElementById('play-canvas-stack');
const parent = stage || (canvas && canvas.parentElement);
let cw = canvas.clientWidth || 0;
let ch = canvas.clientHeight || 0;
@@ -13550,8 +13559,20 @@
if (ow > 80) cw = Math.max(cw, ow);
if (oh > 80) ch = Math.max(ch, oh);
}
/* embed: stage อาจยัง 0 แต่ stack วัดได้แล้ว — อย่าให้ fallback เป็น vw/vh เต็มจอแล้ว CSS ย่อเข้า stage = ดูชิดมุม */
if (previewMode && editorEmbedReturn && stackEl) {
const sw = Math.max(stackEl.clientWidth || 0, stackEl.offsetWidth || 0);
const sh = Math.max(stackEl.clientHeight || 0, stackEl.offsetHeight || 0);
if (sw > 80) cw = Math.max(cw, sw);
if (sh > 80) ch = Math.max(ch, sh);
}
if (ch < 120) ch = Math.max(240, vh - headerH - 6);
if (cw < 120) cw = Math.max(320, vw);
if (cw < 120) {
if (previewMode && editorEmbedReturn && stackEl) {
const sw = Math.max(stackEl.clientWidth || 0, stackEl.offsetWidth || 0);
cw = sw > 80 ? Math.max(320, sw) : Math.max(320, vw);
} else cw = Math.max(320, vw);
}
canvas.width = Math.max(320, cw);
canvas.height = Math.max(240, ch);
syncQuizCarryEmbedCountdownLayout();
+1 -1
View File
@@ -1,6 +1,6 @@
// ทุกครั้งที่มีการเพิ่มหรือเปลี่ยน ให้เพิ่ม v +0.0001
// หลังแก้ค่าแล้วต้อง copy ไป path ที่ Nginx ชี้ (หรือรัน copy-frogger-files-only.sh) ถึงจะเห็นบนเว็บ
window.APP_VERSION = '0.0286';
window.APP_VERSION = '0.0292';
document.addEventListener('DOMContentLoaded', function () {
var t = document.querySelector('.version-tag');
if (t) t.textContent = 'v ' + window.APP_VERSION;
+96 -48
View File
@@ -5,6 +5,17 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Cache-Control" content="no-store, max-age=0">
<title>เล่น — Game</title>
<!-- คลาส embed ต้องมีก่อน first paint — ถ้ารอ play.js ท้าย body จะ layout รอบแรกผิด (แคนวาสชิดซ้ายบน / stack สูงไม่เต็ม) -->
<script>
(function () {
try {
var q = typeof location !== 'undefined' && location.search ? location.search : '';
if (q.indexOf('preview=1') !== -1 && q.indexOf('editorEmbed=1') !== -1) {
document.documentElement.classList.add('play-preview-editor-embed');
}
} catch (e) { /* ignore */ }
})();
</script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;800&family=Share+Tech+Mono&display=swap" rel="stylesheet">
@@ -21,21 +32,53 @@
width: 100%;
box-sizing: border-box;
}
/* พรีวิว editor embed: ให้คอลัมน์แคนวาสเต็มพื้นที่ iframe/หน้าต่าง — กันพื้นดำล้นเมื่อจอใหญ่ */
html.play-preview-editor-embed,
html.play-preview-editor-embed body {
/* พรีวิว editor embed — ห้าม display:flex บน <html> (จะทำให้ <head> กับ <body> เป็น flex items คู่กัน → ความสูง body/เกมคำนวณผิด แคนวาสชิดซ้ายบน แต่ stack ยังเต็มจอ) */
html.play-preview-editor-embed {
width: 100%;
height: 100%;
min-height: 100vh;
min-height: 100dvh;
box-sizing: border-box;
display: block;
}
html.play-preview-editor-embed body {
width: 100%;
height: 100%;
margin: 0;
box-sizing: border-box;
min-height: 100vh;
min-height: 100dvh;
display: flex;
flex-direction: column;
}
html.play-preview-editor-embed .game-wrap {
width: 100%;
min-height: 0;
flex: 1 1 auto;
min-height: 0;
width: 100%;
display: flex;
flex-direction: column;
position: relative;
}
html.play-preview-editor-embed .play-canvas-stack {
flex: 1 1 0% !important;
min-height: 0 !important;
min-width: 0 !important;
width: 100%;
min-height: 0;
display: flex !important;
flex-direction: column !important;
position: relative;
}
html.play-preview-editor-embed #play-canvas-stage.play-canvas-stage {
flex: 1 1 0% !important;
min-height: 0 !important;
min-width: 0 !important;
width: 100%;
display: flex !important;
align-items: center !important;
justify-content: center !important;
}
html.play-preview-editor-embed #play-canvas-stage #game-canvas {
align-self: center !important;
}
html.play-preview-editor-embed .version-tag {
display: none !important;
@@ -1577,6 +1620,11 @@
pointer-events: none;
font-family: 'Share Tech Mono', ui-monospace, monospace;
}
/* embed: HUD อยู่ใน .game-wrap — absolute ยึดกรอบเกม ไม่ใช่ viewport ทั้งจอ (แก้ TIME/SCORE หลุดคนละกรอบกับแคนวาสกลาง) */
html.play-preview-editor-embed #play-cyber-hud.play-cyber-hud {
position: absolute;
inset: 0;
}
.play-cyber-hud.is-hidden { display: none !important; }
/* mng8a80o — แผง SCORE: มุมคม, หัว SCORE ใหญ่, แถวแนวนอน = [อวาตาร์เล็ก + ชื่อไทย] ซ้าย | คะแนนใหญ่ขวา */
#play-cyber-hud.play-cyber-hud--question-mission .play-cyber-scoreboard {
@@ -2778,6 +2826,46 @@
<img id="quiz-carry-result-end-img" class="qc-result-end-img" src="" alt="" width="900" height="520" decoding="async" />
</div>
</div>
<div id="play-cyber-hud" class="play-cyber-hud is-hidden" aria-hidden="true">
<aside class="play-cyber-scoreboard" aria-label="SCORE">
<div id="play-cyber-crown-score-head" class="play-cyber-crown-score-head is-hidden" aria-hidden="true">
<img id="play-cyber-crown-score-img" alt="" width="120" height="32" decoding="async" />
</div>
<div class="play-cyber-panel-title">SCORE</div>
<ul id="play-cyber-score-list" class="play-cyber-score-list"></ul>
</aside>
<div class="play-cyber-center-stack">
<div class="play-cyber-time-block">
<div class="play-cyber-time-head">
<img id="play-cyber-time-plaque-img" class="play-cyber-time-plaque-img is-hidden" alt="TIME" decoding="async" aria-hidden="true" />
<div class="play-cyber-time-label">TIME</div>
<span class="play-cyber-time-colon" aria-hidden="true">:</span>
<div id="play-cyber-time-val" class="play-cyber-time-val">0</div>
</div>
<div id="play-cyber-time-sub" class="play-cyber-time-sub"></div>
</div>
<div id="play-cyber-quiz-mission-q-band" class="play-cyber-quiz-mission-q-band is-hidden" aria-hidden="true">
<img id="play-cyber-quiz-mission-q-plaque" class="play-cyber-quiz-mission-q-plaque is-hidden" alt="" decoding="async" />
<p id="play-cyber-quiz-mission-q-text" class="play-cyber-quiz-mission-q-text"></p>
</div>
</div>
<div class="play-cyber-self">
<div class="play-cyber-self-frame">
<img id="play-cyber-portrait-img" alt="" width="72" height="72" />
</div>
<div id="play-cyber-self-status" class="play-cyber-self-status"></div>
<div id="play-cyber-op-widgets" class="play-cyber-op-widgets" aria-hidden="true">
<div id="play-cyber-voice-chip" class="play-cyber-voice-chip"></div>
<div class="play-cyber-link-status" title="LINK">O</div>
</div>
</div>
<p id="play-cyber-hint" class="play-cyber-hint"></p>
<p id="play-cyber-preview-line" class="play-cyber-preview-line is-hidden"></p>
<div class="play-cyber-corruption" aria-hidden="true">
<div class="play-cyber-corruption-scanlines"></div>
<div class="play-cyber-corruption-text">RAM ERROR · CORRUPTING · DELETE INITIATED · 01001101 01110011 01100101 01100011</div>
</div>
</div>
</div>
<div id="play-quiz-scoreboard" class="is-hidden" aria-live="polite">
<div class="play-quiz-scoreboard-title">คะแนน</div>
@@ -2820,46 +2908,6 @@
<p class="quiz-play-legend" id="quiz-play-legend"></p>
</div>
</div>
<div id="play-cyber-hud" class="play-cyber-hud is-hidden" aria-hidden="true">
<aside class="play-cyber-scoreboard" aria-label="SCORE">
<div id="play-cyber-crown-score-head" class="play-cyber-crown-score-head is-hidden" aria-hidden="true">
<img id="play-cyber-crown-score-img" alt="" width="120" height="32" decoding="async" />
</div>
<div class="play-cyber-panel-title">SCORE</div>
<ul id="play-cyber-score-list" class="play-cyber-score-list"></ul>
</aside>
<div class="play-cyber-center-stack">
<div class="play-cyber-time-block">
<div class="play-cyber-time-head">
<img id="play-cyber-time-plaque-img" class="play-cyber-time-plaque-img is-hidden" alt="TIME" decoding="async" aria-hidden="true" />
<div class="play-cyber-time-label">TIME</div>
<span class="play-cyber-time-colon" aria-hidden="true">:</span>
<div id="play-cyber-time-val" class="play-cyber-time-val">0</div>
</div>
<div id="play-cyber-time-sub" class="play-cyber-time-sub"></div>
</div>
<div id="play-cyber-quiz-mission-q-band" class="play-cyber-quiz-mission-q-band is-hidden" aria-hidden="true">
<img id="play-cyber-quiz-mission-q-plaque" class="play-cyber-quiz-mission-q-plaque is-hidden" alt="" decoding="async" />
<p id="play-cyber-quiz-mission-q-text" class="play-cyber-quiz-mission-q-text"></p>
</div>
</div>
<div class="play-cyber-self">
<div class="play-cyber-self-frame">
<img id="play-cyber-portrait-img" alt="" width="72" height="72" />
</div>
<div id="play-cyber-self-status" class="play-cyber-self-status"></div>
<div id="play-cyber-op-widgets" class="play-cyber-op-widgets" aria-hidden="true">
<div id="play-cyber-voice-chip" class="play-cyber-voice-chip"></div>
<div class="play-cyber-link-status" title="LINK">O</div>
</div>
</div>
<p id="play-cyber-hint" class="play-cyber-hint"></p>
<p id="play-cyber-preview-line" class="play-cyber-preview-line is-hidden"></p>
<div class="play-cyber-corruption" aria-hidden="true">
<div class="play-cyber-corruption-scanlines"></div>
<div class="play-cyber-corruption-text">RAM ERROR · CORRUPTING · DELETE INITIATED · 01001101 01110011 01100101 01100011</div>
</div>
</div>
<div id="quiz-battle-mcq-overlay" class="is-hidden" role="dialog" aria-modal="true" aria-labelledby="quiz-battle-mcq-title">
<div class="quiz-battle-mcq-backdrop" aria-hidden="true"></div>
<div class="quiz-battle-mcq-card">
@@ -2954,8 +3002,8 @@
</div>
</div>
<script src="/Game/socket.io/socket.io.js"></script>
<script src="js/version.js?v=0.0286"></script>
<script src="js/play.js?v=0.0286"></script>
<script src="js/version.js?v=0.0292"></script>
<script src="js/play.js?v=0.0292"></script>
<div class="version-tag">v —</div>
</body>
</html>