diff --git a/www/html/Game/public/js/play.js b/www/html/Game/public/js/play.js index 0669e17..fba8ea9 100644 --- a/www/html/Game/public/js/play.js +++ b/www/html/Game/public/js/play.js @@ -561,6 +561,10 @@ /** quiz_carry: หยิบตัวเลือกมาวางโซนกลาง — เล่นพร้อมกัน (ไม่สลับตา) */ let quizCarryPool = []; let quizCarryCurrent = null; + /** editor embed + preview: นับ 3–2–1 ก่อนโชว์คำถามและให้เดิน/หยิบได้ */ + let quizCarryEmbedPendingQuestion = null; + let quizCarryEmbedCountdownStartAt = 0; + let quizCarryEmbedCountdownEndAt = 0; /** jump_survive — กล้องตามตัวในกรอบ + แพลตฟอร์มเลื่อนขึ้น (scroll) ไม่ลากทั้งฉาก */ let jumpSurviveCamCenterX = 0; @@ -1821,9 +1825,62 @@ return String(q.text || '').trim(); } + function quizCarryRestoreEmbedPhaseLabel() { + const phaseEl = document.getElementById('quiz-game-phase-label'); + if (!phaseEl || !mapData) return; + phaseEl.textContent = quizCarryMapHasAnswerInteractive(mapData) + ? 'กด F หยิบบนโซนตัวเลือก · กด F ส่งที่โซน interactive (เขียว) — เล่นพร้อมกันได้' + : 'กด F หยิบบนโซนตัวเลือก · กด F ส่งเมื่อชิดโซนกลาง (ม่วงเป็นกำแพง) — เล่นพร้อมกันได้'; + } + + function isQuizCarryEmbedCountdownBlockingMovement() { + return !!(previewMode && editorEmbedReturn && isQuizCarry() && quizCarryEmbedCountdownEndAt > Date.now()); + } + + function hideQuizCarryEmbedCountdownOverlay() { + const ov = document.getElementById('quiz-carry-embed-countdown'); + if (ov) { + ov.classList.add('is-hidden'); + ov.setAttribute('aria-hidden', 'true'); + } + } + + function tickQuizCarryEmbedCountdown() { + if (!previewMode || !editorEmbedReturn || !isQuizCarry()) return; + if (!quizCarryEmbedPendingQuestion || quizCarryEmbedCountdownEndAt <= 0) return; + const now = Date.now(); + const ov = document.getElementById('quiz-carry-embed-countdown'); + const numEl = document.getElementById('quiz-carry-embed-countdown-num'); + if (now >= quizCarryEmbedCountdownEndAt) { + const pq = quizCarryEmbedPendingQuestion; + quizCarryEmbedPendingQuestion = null; + quizCarryEmbedCountdownEndAt = 0; + quizCarryEmbedCountdownStartAt = 0; + hideQuizCarryEmbedCountdownOverlay(); + if (!pq) return; + quizCarryCurrent = pq; + playQuizText = formatQuizCarryQuestionHud(pq); + const qEl = document.getElementById('quiz-game-question'); + if (qEl) qEl.textContent = playQuizText; + quizCarryRestoreEmbedPhaseLabel(); + return; + } + const elapsed = now - quizCarryEmbedCountdownStartAt; + const n = 3 - Math.min(2, Math.floor(elapsed / 1000)); + if (numEl) numEl.textContent = String(Math.max(1, Math.min(3, n))); + if (ov) { + ov.classList.remove('is-hidden'); + ov.setAttribute('aria-hidden', 'false'); + } + } + function quizCarryPickNextQuestion() { if (!quizCarryPool.length) { quizCarryCurrent = null; + quizCarryEmbedPendingQuestion = null; + quizCarryEmbedCountdownEndAt = 0; + quizCarryEmbedCountdownStartAt = 0; + hideQuizCarryEmbedCountdownOverlay(); playQuizText = 'ไม่มีคำถาม — ใส่ quizQuestions ในแมป (choices + correctIndex) หรือตั้งใน Admin'; return; } @@ -1833,6 +1890,25 @@ q = quizCarryPool[Math.floor(Math.random() * quizCarryPool.length)]; guard++; } while (guard < 12 && quizCarryPool.length > 1 && quizCarryCurrent && q && q.text === quizCarryCurrent.text); + if (previewMode && editorEmbedReturn) { + quizCarryEmbedPendingQuestion = q; + quizCarryEmbedCountdownStartAt = Date.now(); + quizCarryEmbedCountdownEndAt = quizCarryEmbedCountdownStartAt + 3000; + quizCarryCurrent = null; + playQuizText = ''; + others.forEach((o) => { + if (!o) return; + o.botPath = []; + o.botPathStuckTicks = 0; + o.botQuizCarryPathfindAfter = quizCarryEmbedCountdownEndAt + 50; + }); + const qEl = document.getElementById('quiz-game-question'); + if (qEl) qEl.textContent = '…'; + const phaseEl = document.getElementById('quiz-game-phase-label'); + if (phaseEl) phaseEl.textContent = 'รอเริ่มคำถาม — นับถอยหลัง 3 · 2 · 1'; + tickQuizCarryEmbedCountdown(); + return; + } quizCarryCurrent = q; playQuizText = formatQuizCarryQuestionHud(q); const qEl = document.getElementById('quiz-game-question'); @@ -1918,6 +1994,10 @@ function resetQuizCarryPlayState() { quizCarryPool = []; quizCarryCurrent = null; + quizCarryEmbedPendingQuestion = null; + quizCarryEmbedCountdownStartAt = 0; + quizCarryEmbedCountdownEndAt = 0; + hideQuizCarryEmbedCountdownOverlay(); me.quizCarryHeld = null; others.forEach((o) => { if (!o) return; @@ -1952,11 +2032,8 @@ return; } quizCarryPickNextQuestion(); - const phaseEl = document.getElementById('quiz-game-phase-label'); - if (phaseEl) { - phaseEl.textContent = quizCarryMapHasAnswerInteractive(mapData) - ? 'กด F หยิบบนโซนตัวเลือก · กด F ส่งที่โซน interactive (เขียว) — เล่นพร้อมกันได้' - : 'กด F หยิบบนโซนตัวเลือก · กด F ส่งเมื่อชิดโซนกลาง (ม่วงเป็นกำแพง) — เล่นพร้อมกันได้'; + if (!(previewMode && editorEmbedReturn && quizCarryEmbedCountdownEndAt > Date.now())) { + quizCarryRestoreEmbedPhaseLabel(); } } @@ -5595,7 +5672,7 @@ tryHumanStackDrop(); }); canvas.addEventListener('dblclick', (e) => { - if (!mapData || isFrogger() || isGauntlet() || isStack() || isJumpSurvive() || isSpaceShooter() || isBalloonBoss() || isChatFocused()) return; + if (!mapData || isFrogger() || isGauntlet() || isStack() || isJumpSurvive() || isSpaceShooter() || isBalloonBoss() || isChatFocused() || isQuizCarryEmbedCountdownBlockingMovement()) return; const r = canvas.getBoundingClientRect(); const sx = e.clientX - r.left; const sy = e.clientY - r.top; @@ -7396,6 +7473,7 @@ if (o.tx != null) o.x += (o.tx - o.x) * LERP; if (o.ty != null) o.y += (o.ty - o.y) * LERP; }); + tickQuizCarryEmbedCountdown(); stepPreviewBots(); if (isChatFocused()) { me.isWalking = false; @@ -7404,6 +7482,14 @@ requestAnimationFrame(tick); return; } + if (isQuizCarryEmbedCountdownBlockingMovement()) { + me.isWalking = false; + playPath = []; + enforceQuizBattleLaneOnMePlay(); + draw(); + requestAnimationFrame(tick); + return; + } const w = mapData.width || 20, h = mapData.height || 15; let accX = 0, accY = 0; let usePath = false; diff --git a/www/html/Game/public/play.html b/www/html/Game/public/play.html index b557a0a..3458907 100644 --- a/www/html/Game/public/play.html +++ b/www/html/Game/public/play.html @@ -101,6 +101,26 @@ max-height: 100%; overflow: auto; } + #quiz-carry-embed-countdown { + position: fixed; + inset: 0; + z-index: 10080; + display: flex; + align-items: center; + justify-content: center; + pointer-events: none; + background: rgba(8, 10, 20, 0.42); + } + #quiz-carry-embed-countdown.is-hidden { display: none !important; } + #quiz-carry-embed-countdown-inner { + text-align: center; + } + #quiz-carry-embed-countdown-num { + font: 800 min(28vw, 132px) / 1.05 system-ui, "Kanit", sans-serif; + color: #ffe066; + text-shadow: 0 0 48px rgba(255, 224, 102, 0.55), 0 4px 24px rgba(0, 0, 0, 0.65); + letter-spacing: -0.04em; + } #play-quiz-scoreboard { position: fixed; top: max(56px, env(safe-area-inset-top)); @@ -611,6 +631,9 @@ +