mini game 4 update table
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -30,16 +30,32 @@
|
||||
"fixedBorder": "rgba(122, 200, 255, 0)",
|
||||
"fillBg": "rgba(12, 10, 20, 0)",
|
||||
"textColor": "rgba(248, 249, 255, 1)",
|
||||
"borderWidthPx": 2.5,
|
||||
"borderWidthPx": 0,
|
||||
"plaqueImageUrl": "https:\/\/srv1361159.hstgr.cloud\/Game\/img\/quiz-carry\/board-1.png"
|
||||
},
|
||||
{
|
||||
"borderMode": "neon",
|
||||
"fixedBorder": "rgba(122, 200, 255, 0.9)",
|
||||
"fillBg": "rgba(12, 10, 20, 0.88)",
|
||||
"borderMode": "fixed",
|
||||
"fixedBorder": "rgba(122, 200, 255, 0)",
|
||||
"fillBg": "rgba(12, 10, 20, 0)",
|
||||
"textColor": "rgba(248, 249, 255, 1)",
|
||||
"borderWidthPx": 2.5,
|
||||
"plaqueImageUrl": ""
|
||||
"borderWidthPx": 0,
|
||||
"plaqueImageUrl": "https:\/\/srv1361159.hstgr.cloud\/Game\/img\/quiz-carry\/board-2.png"
|
||||
},
|
||||
{
|
||||
"borderMode": "fixed",
|
||||
"fixedBorder": "rgba(122, 200, 255, 0)",
|
||||
"fillBg": "rgba(12, 10, 20, 0)",
|
||||
"textColor": "rgba(248, 249, 255, 1)",
|
||||
"borderWidthPx": 0,
|
||||
"plaqueImageUrl": "https:\/\/srv1361159.hstgr.cloud\/Game\/img\/quiz-carry\/board-3.png"
|
||||
},
|
||||
{
|
||||
"borderMode": "fixed",
|
||||
"fixedBorder": "rgba(122, 200, 255, 0)",
|
||||
"fillBg": "rgba(12, 10, 20, 0)",
|
||||
"textColor": "rgba(248, 249, 255, 1)",
|
||||
"borderWidthPx": 0,
|
||||
"plaqueImageUrl": "https:\/\/srv1361159.hstgr.cloud\/Game\/img\/quiz-carry\/board-4.png"
|
||||
},
|
||||
{
|
||||
"borderMode": "neon",
|
||||
@@ -47,23 +63,7 @@
|
||||
"fillBg": "rgba(12, 10, 20, 0.88)",
|
||||
"textColor": "rgba(248, 249, 255, 1)",
|
||||
"borderWidthPx": 2.5,
|
||||
"plaqueImageUrl": ""
|
||||
},
|
||||
{
|
||||
"borderMode": "neon",
|
||||
"fixedBorder": "rgba(122, 200, 255, 0.9)",
|
||||
"fillBg": "rgba(12, 10, 20, 0.88)",
|
||||
"textColor": "rgba(248, 249, 255, 1)",
|
||||
"borderWidthPx": 2.5,
|
||||
"plaqueImageUrl": ""
|
||||
},
|
||||
{
|
||||
"borderMode": "neon",
|
||||
"fixedBorder": "rgba(122, 200, 255, 0.9)",
|
||||
"fillBg": "rgba(12, 10, 20, 0.88)",
|
||||
"textColor": "rgba(248, 249, 255, 1)",
|
||||
"borderWidthPx": 2.5,
|
||||
"plaqueImageUrl": ""
|
||||
"plaqueImageUrl": "https:\/\/srv1361159.hstgr.cloud\/Game\/img\/quiz-carry\/board-5.png"
|
||||
},
|
||||
{
|
||||
"borderMode": "neon",
|
||||
@@ -159,7 +159,7 @@
|
||||
"fixedBorder": "rgba(122, 200, 255, 0)",
|
||||
"fillBg": "rgba(12, 10, 20, 0)",
|
||||
"textColor": "rgba(248, 249, 255, 1)",
|
||||
"borderWidthPx": 2.5,
|
||||
"borderWidthPx": 0,
|
||||
"plaqueImageUrl": "https:\/\/srv1361159.hstgr.cloud\/Game\/img\/quiz-carry\/board-1.png"
|
||||
},
|
||||
"questions": [
|
||||
@@ -278,5 +278,5 @@
|
||||
"correctIndex": 0
|
||||
}
|
||||
],
|
||||
"carryChoicePlaqueMapScale": 1.25
|
||||
"carryChoicePlaqueMapScale": 1.7
|
||||
}
|
||||
@@ -271,7 +271,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/version.js?v=0.0169"></script>
|
||||
<script src="js/editor.js?v=20260428-quiz-carry-toast-silent"></script>
|
||||
<script src="js/editor.js?v=20260428-quiz-carry-save-warn"></script>
|
||||
<div class="version-tag">v —</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2144,6 +2144,21 @@
|
||||
if (data.ok) {
|
||||
const id = data.mapId || mapId;
|
||||
statusEl.textContent = 'บันทึกแล้ว รหัสฉาก: ' + id + (showMapInGame ? '' : ' (ซ่อนกริดในเกม — รูปบนกริดยังแสดง) — ออกจากห้องแล้วเข้าใหม่ หรือกด F5 ในหน้าเล่น ถึงจะเห็นผล');
|
||||
if (gameType === 'quiz_carry' && gridImageSprites.length) {
|
||||
const used = new Set();
|
||||
gridImageSprites.forEach(function (s) {
|
||||
if (s && Number.isFinite(s.i) && s.i >= 0) used.add(Math.floor(s.i));
|
||||
});
|
||||
const noHeld = [];
|
||||
used.forEach(function (idx) {
|
||||
const e = gridImageLibrary[idx];
|
||||
if (!gridLibHeldUrl(e)) noHeld.push(idx);
|
||||
});
|
||||
if (noHeld.length) {
|
||||
const labels = noHeld.sort(function (a, b) { return a - b; }).map(function (i) { return '#' + (i + 1); });
|
||||
statusEl.textContent += ' — เตือน (หยิบมาวาง): คลัง ' + labels.join(', ') + ' ยังไม่มีรูป «หยิบแล้ว» — ในเกมรูปบนพื้น/มือจะไม่สลับ (อัปโหลดช่องที่สองในคลัง หรือให้ held ต่างจาก idle)';
|
||||
}
|
||||
}
|
||||
if (!mapId) window.history.replaceState({}, '', 'editor.html' + buildEditorSearch(id));
|
||||
} else statusEl.textContent = data.error || 'บันทึกไม่ได้';
|
||||
})
|
||||
|
||||
@@ -2147,6 +2147,34 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
/** มีใครกำลังถือตัวเลือกอยู่หรือไม่ — ใช้ให้รูปบนกริดที่ทับโซนกลาง (hub) เปลี่ยนสถานะ */
|
||||
function quizCarryAnyPlayerOrBotHolding() {
|
||||
if (me && me.quizCarryHeld != null) return true;
|
||||
for (const o of others.values()) {
|
||||
if (o && o.quizCarryHeld != null) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** สไปรต์ทับช่องโซนกลาง (ม่วง) อย่างน้อย 1 ช่อง */
|
||||
function spriteOverlapsQuizCarryHubArea(md, sp) {
|
||||
if (!md || md.gameType !== 'quiz_carry' || !sp) return false;
|
||||
const hub = md.quizCarryHubArea;
|
||||
if (!hub || !hub.length) return false;
|
||||
const mw = md.width || 20, mh = md.height || 15;
|
||||
const x0 = sp.x | 0, y0 = sp.y | 0, ww = sp.w | 0, hh = sp.h | 0;
|
||||
for (let yy = y0; yy < y0 + hh; yy++) {
|
||||
if (yy < 0 || yy >= mh) continue;
|
||||
const row = hub[yy];
|
||||
if (!row) continue;
|
||||
for (let xx = x0; xx < x0 + ww; xx++) {
|
||||
if (xx < 0 || xx >= mw) continue;
|
||||
if (row[xx] === 1) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** ตัวเลือกหนึ่งข้อ — มีคนถือป้ายอยู่ได้แค่คนเดียว (หยิบซ้ำไม่ได้) */
|
||||
function pickQuizCarryTargetOptionIndexAvoidingTaken(preferredIdx) {
|
||||
const n = quizCarryCurrent && quizCarryCurrent.choices ? quizCarryCurrent.choices.length : 0;
|
||||
@@ -6298,26 +6326,37 @@
|
||||
});
|
||||
}
|
||||
|
||||
/** โซนตัวเลือกที่ทับสไปรต์มากที่สุด — quiz_carry สลับรูป idle/held */
|
||||
/** โซนตัวเลือกที่ทับสไปรต์มากที่สุด — quiz_carry สลับรูป idle/held · ถ้าไม่ทับเลยลองขยายขอบ 1 ช่อง (มาร์กเกอร์ชิดขอบสไปรต์) */
|
||||
function dominantQuizCarryOptionInSpriteRect(md, sp) {
|
||||
if (!md || md.gameType !== 'quiz_carry' || !md.quizCarryOptionArea) return null;
|
||||
const g = md.quizCarryOptionArea;
|
||||
const mw = md.width || 20, mh = md.height || 15;
|
||||
const x0 = sp.x | 0, y0 = sp.y | 0, ww = sp.w | 0, hh = sp.h | 0;
|
||||
const bx = sp.x | 0, by = sp.y | 0, bw = sp.w | 0, bh = sp.h | 0;
|
||||
const counts = new Map();
|
||||
for (let yy = y0; yy < y0 + hh; yy++) {
|
||||
if (yy < 0 || yy >= mh) continue;
|
||||
const row = g[yy];
|
||||
if (!row) continue;
|
||||
for (let xx = x0; xx < x0 + ww; xx++) {
|
||||
if (xx < 0 || xx >= mw) continue;
|
||||
const v = row[xx];
|
||||
const n = typeof v === 'number' ? v : parseInt(String(v), 10);
|
||||
if (!Number.isFinite(n) || n < 1 || n > QUIZ_CARRY_MAX_OPTION_SLOTS) continue;
|
||||
const idx = n - 1;
|
||||
counts.set(idx, (counts.get(idx) || 0) + 1);
|
||||
function addOverlapRect(x0, y0, ww, hh) {
|
||||
for (let yy = y0; yy < y0 + hh; yy++) {
|
||||
if (yy < 0 || yy >= mh) continue;
|
||||
const row = g[yy];
|
||||
if (!row) continue;
|
||||
for (let xx = x0; xx < x0 + ww; xx++) {
|
||||
if (xx < 0 || xx >= mw) continue;
|
||||
const v = row[xx];
|
||||
const n = typeof v === 'number' ? v : parseInt(String(v), 10);
|
||||
if (!Number.isFinite(n) || n < 1 || n > QUIZ_CARRY_MAX_OPTION_SLOTS) continue;
|
||||
const idx = n - 1;
|
||||
counts.set(idx, (counts.get(idx) || 0) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
addOverlapRect(bx, by, bw, bh);
|
||||
if (!counts.size) {
|
||||
const pad = 1;
|
||||
const x0 = Math.max(0, bx - pad);
|
||||
const y0 = Math.max(0, by - pad);
|
||||
const x1 = Math.min(mw, bx + bw + pad);
|
||||
const y1 = Math.min(mh, by + bh + pad);
|
||||
addOverlapRect(x0, y0, x1 - x0, y1 - y0);
|
||||
}
|
||||
if (!counts.size) return null;
|
||||
let best = null;
|
||||
let bestN = -1;
|
||||
@@ -8291,11 +8330,18 @@
|
||||
const wh = sp.h * tileSize;
|
||||
if (wx0 + ww <= worldMinX || wx0 >= worldMaxX || wy0 + wh <= worldMinY || wy0 >= worldMaxY) continue;
|
||||
let gim = mapGridImageImgs[sp.i];
|
||||
if (isQuizCarry() && quizCarryCurrent) {
|
||||
let carrySpriteAlpha = 1;
|
||||
if (isQuizCarry()) {
|
||||
const domOpt = quizCarryOptionIndexForGridSprite(mapData, sp);
|
||||
if (domOpt != null && quizCarryOptionHeldByAnyone(domOpt)) {
|
||||
const onHub = spriteOverlapsQuizCarryHubArea(mapData, sp);
|
||||
const anyHeld = quizCarryAnyPlayerOrBotHolding();
|
||||
let carryVisualActive = false;
|
||||
if (domOpt != null && quizCarryOptionHeldByAnyone(domOpt)) carryVisualActive = true;
|
||||
else if (domOpt == null && onHub && anyHeld) carryVisualActive = true;
|
||||
if (carryVisualActive) {
|
||||
const gh = mapGridImageHeldImgs[sp.i];
|
||||
if (gh && gh.complete && gh.naturalWidth) gim = gh;
|
||||
else carrySpriteAlpha = 0.32;
|
||||
}
|
||||
}
|
||||
if (!gim || !gim.complete || !gim.naturalWidth) continue;
|
||||
@@ -8304,6 +8350,7 @@
|
||||
const sw = ww * zDraw;
|
||||
const sh = wh * zDraw;
|
||||
ctx.save();
|
||||
if (carrySpriteAlpha < 1) ctx.globalAlpha = carrySpriteAlpha;
|
||||
ctx.beginPath();
|
||||
ctx.rect(sx0, sy0, sw, sh);
|
||||
ctx.clip();
|
||||
|
||||
@@ -980,7 +980,7 @@
|
||||
</div>
|
||||
<script src="/Game/socket.io/socket.io.js"></script>
|
||||
<script src="js/version.js?v=0.0166"></script>
|
||||
<script src="js/play.js?v=0.133"></script>
|
||||
<script src="js/play.js?v=0.135"></script>
|
||||
<div class="version-tag">v —</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user