minigame 6 rocker 1.4

This commit is contained in:
2026-05-01 11:09:11 +00:00
parent ed0f24b344
commit e548b796fc
10 changed files with 395 additions and 43 deletions
+245 -11
View File
@@ -1273,6 +1273,8 @@
if (t.carryReadMs != null) data.carryReadMs = t.carryReadMs;
if (t.carryAnswerMs != null) data.carryAnswerMs = t.carryAnswerMs;
if (t.carrySessionLength != null) data.carrySessionLength = t.carrySessionLength;
if (t.carryWalkSpeedMultForMapId !== undefined) data.carryWalkSpeedMultForMapId = t.carryWalkSpeedMultForMapId;
if (t.carryWalkSpeedMult !== undefined) data.carryWalkSpeedMult = t.carryWalkSpeedMult;
}
renderQuizCarryAdminList(data.carryQuestions || []);
var readSec = el('quiz-carry-read-sec');
@@ -1290,6 +1292,15 @@
var sl = parseInt(String(data.carrySessionLength), 10);
sessLen.value = String(Number.isFinite(sl) && sl >= 0 ? sl : 0);
}
var walkMapIdInp = el('quiz-carry-walk-map-id');
if (walkMapIdInp) {
walkMapIdInp.value = data.carryWalkSpeedMultForMapId ? String(data.carryWalkSpeedMultForMapId).trim() : '';
}
var walkMultInp = el('quiz-carry-walk-mult');
if (walkMultInp) {
var wmv = Number(data.carryWalkSpeedMult);
walkMultInp.value = String(Number.isFinite(wmv) ? wmv : 1.42);
}
quizCarrySetPlaqueMapScaleInputs(data.carryChoicePlaqueMapScale);
quizCarryBindThemePickersOnce();
var th = data.carryMapPanelTheme && typeof data.carryMapPanelTheme === 'object' ? data.carryMapPanelTheme : {};
@@ -1472,6 +1483,9 @@
var psn = parseFloat(String(plaqueScaleEl.value || '').replace(',', '.'));
if (Number.isFinite(psn)) plaqueMapScale = Math.max(0.85, Math.min(2.5, psn));
}
var walkMapIdRaw = el('quiz-carry-walk-map-id') && el('quiz-carry-walk-map-id').value ? String(el('quiz-carry-walk-map-id').value).trim() : '';
var walkMapId = walkMapIdRaw.replace(/[^a-zA-Z0-9_-]/g, '').slice(0, 64);
var walkMultRaw = el('quiz-carry-walk-mult') ? parseFloat(String(el('quiz-carry-walk-mult').value || '').replace(',', '.')) : NaN;
var putBody = {
carryReadMs: carryReadMs,
carryAnswerMs: carryAnswerMs,
@@ -1481,6 +1495,13 @@
carryChoicePlaqueThemes: quizCarryPlaqueBuildForSave(),
carryChoicePlaqueMapScale: plaqueMapScale,
};
if (walkMapId) {
putBody.carryWalkSpeedMultForMapId = walkMapId;
putBody.carryWalkSpeedMult = Number.isFinite(walkMultRaw) ? Math.max(0.5, Math.min(3, walkMultRaw)) : 1.42;
} else {
putBody.carryWalkSpeedMultForMapId = '';
putBody.carryWalkSpeedMult = null;
}
if (carryQuestions.length > 0) {
putBody.carryQuestions = carryQuestions;
}
@@ -1520,6 +1541,8 @@
carryReadMs: carryReadMs,
carryAnswerMs: carryAnswerMs,
carrySessionLength: carrySessionLength,
carryWalkSpeedMultForMapId: walkMapId,
carryWalkSpeedMult: walkMapId ? (Number.isFinite(walkMultRaw) ? Math.max(0.5, Math.min(3, walkMultRaw)) : 1.42) : null,
},
fetchDelayMs: 120,
});
@@ -2756,18 +2779,223 @@
}
}
function parseSpaceShooterAsteroidSpriteUrlsTextarea() {
var ta = el('space-shooter-asteroid-sprite-urls');
var raw = ta && ta.value ? String(ta.value) : '';
var lines = raw.split(/[\n\r]+/);
function updateSpaceShooterAstFallPreview() {
var img = el('space-shooter-ast-fall-prev');
var inp = el('space-shooter-ast-fall-url');
if (!img) return;
var v = inp && inp.value ? String(inp.value).trim() : '';
if (!v) {
img.removeAttribute('src');
img.alt = '';
return;
}
if (!/^https?:\/\//i.test(v) && v.charAt(0) !== '/') v = '/' + v.replace(/^\/+/, '');
img.alt = 'Asteroid falling';
img.src = v;
}
function updateSpaceShooterAstExplodeRowPreview(row) {
if (!row) return;
var img = row.querySelector('.space-shooter-ast-explode-prev');
var inp = row.querySelector('.space-shooter-ast-explode-url');
if (!img) return;
var v = inp && inp.value ? String(inp.value).trim() : '';
if (!v) {
img.removeAttribute('src');
img.alt = '';
return;
}
if (!/^https?:\/\//i.test(v) && v.charAt(0) !== '/') v = '/' + v.replace(/^\/+/, '');
img.alt = 'Asteroid explode frame';
img.src = v;
}
function renumberSpaceShooterAstExplodeRows() {
var wrap = el('space-shooter-ast-explode-rows');
if (!wrap) return;
var rows = wrap.querySelectorAll('.space-shooter-ast-explode-row');
rows.forEach(function (row, i) {
var slot = row.querySelector('.space-shooter-ship-slot');
if (slot) slot.textContent = String(i + 1);
});
}
function addSpaceShooterAstExplodeRow(initialUrl) {
var wrap = el('space-shooter-ast-explode-rows');
if (!wrap) return;
var rows = wrap.querySelectorAll('.space-shooter-ast-explode-row');
if (rows.length >= 31) {
setMsg('space-shooter-timing-msg', 'เฟรมแตกสูงสุด 31 แถว (รวมรูปตกแล้วไม่เกิน 32 URL) · Max 31 explosion rows', 'error');
return;
}
var ix = rows.length + 1;
var row = document.createElement('div');
row.className = 'space-shooter-ship-row space-shooter-ast-explode-row';
row.innerHTML =
'<span class="space-shooter-ship-slot space-shooter-ship-slot--ast">' +
ix +
'</span><label class="space-shooter-ship-url-label">URL <input type="text" class="space-shooter-ast-explode-url" maxlength="500" spellcheck="false" placeholder="/Game/img/gauntlet-assets/....png" autocomplete="off"></label>' +
'<input type="file" class="space-shooter-ast-explode-file space-shooter-damage-file" accept="image/png,image/webp,image/jpeg,image/gif">' +
'<button type="button" class="btn btn-ghost btn-space-shooter-ast-explode-upload">อัปโหลด</button>' +
'<img class="space-shooter-ship-prev space-shooter-damage-prev space-shooter-ast-explode-prev" alt="" width="56" height="56" decoding="async">' +
'<button type="button" class="btn btn-ghost btn-space-shooter-ast-explode-clear">ล้าง</button>' +
'<button type="button" class="btn btn-ghost btn-space-shooter-ast-explode-remove">ลบแถว</button>';
var inp = row.querySelector('.space-shooter-ast-explode-url');
if (inp && initialUrl != null && String(initialUrl).trim()) inp.value = String(initialUrl).trim();
if (inp) {
inp.addEventListener('change', function () {
updateSpaceShooterAstExplodeRowPreview(row);
});
inp.addEventListener('blur', function () {
updateSpaceShooterAstExplodeRowPreview(row);
});
}
wrap.appendChild(row);
updateSpaceShooterAstExplodeRowPreview(row);
}
function clearSpaceShooterAstExplodeRows() {
var wrap = el('space-shooter-ast-explode-rows');
if (wrap) wrap.innerHTML = '';
}
function readSpaceShooterAsteroidSpriteUrlsFromForm() {
var out = [];
for (var i = 0; i < lines.length && out.length < 32; i++) {
var t = lines[i].trim();
if (t) out.push(t);
var fallInp = el('space-shooter-ast-fall-url');
var fall = fallInp && fallInp.value ? String(fallInp.value).trim() : '';
if (fall) out.push(fall);
var wrap = el('space-shooter-ast-explode-rows');
if (wrap) {
var rows = wrap.querySelectorAll('.space-shooter-ast-explode-row');
for (var ri = 0; ri < rows.length && out.length < 32; ri++) {
var inp = rows[ri].querySelector('.space-shooter-ast-explode-url');
var u = inp && inp.value ? String(inp.value).trim() : '';
if (u) out.push(u);
}
}
return out;
}
function bindSpaceShooterAsteroidSpritePanel() {
var wrap = el('space-shooter-ast-explode-rows');
if (!wrap || wrap.getAttribute('data-bound') === '1') return;
wrap.setAttribute('data-bound', '1');
wrap.addEventListener('click', function (ev) {
var t = ev.target;
if (!t || !t.closest) return;
var rm = t.closest('.btn-space-shooter-ast-explode-remove');
if (rm) {
var row = rm.closest('.space-shooter-ast-explode-row');
if (row && row.parentNode) row.parentNode.removeChild(row);
renumberSpaceShooterAstExplodeRows();
return;
}
var clr = t.closest('.btn-space-shooter-ast-explode-clear');
if (clr) {
var rowC = clr.closest('.space-shooter-ast-explode-row');
if (!rowC) return;
var iu = rowC.querySelector('.space-shooter-ast-explode-url');
var fi = rowC.querySelector('.space-shooter-ast-explode-file');
if (iu) iu.value = '';
if (fi) fi.value = '';
updateSpaceShooterAstExplodeRowPreview(rowC);
return;
}
var up = t.closest('.btn-space-shooter-ast-explode-upload');
if (!up) return;
var rowU = up.closest('.space-shooter-ast-explode-row');
if (!rowU) return;
var fileInp = rowU.querySelector('.space-shooter-ast-explode-file');
if (!fileInp || !fileInp.files || !fileInp.files[0]) {
setMsg('space-shooter-timing-msg', 'เลือกไฟล์รูปก่อน · Pick an image file first', 'error');
return;
}
readFileAsDataURL(fileInp.files[0])
.then(function (dataUrl) {
return gauntletAssetsJsonFetch(GAME_GAUNTLET_ASSETS_API + '/upload', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
imageDataUrl: dataUrl,
label: 'space-shooter-ast-explode',
}),
});
})
.then(function (j) {
if (!j || !j.ok || !j.url) {
throw new Error((j && j.error) || 'อัปโหลดไม่สำเร็จ · Upload failed');
}
var inpU = rowU.querySelector('.space-shooter-ast-explode-url');
if (inpU) inpU.value = String(j.url).trim();
updateSpaceShooterAstExplodeRowPreview(rowU);
setMsg(
'space-shooter-timing-msg',
'อัปโหลดเฟรมแตกแล้ว — กดบันทึกด้านล่างเพื่อเก็บ · Uploaded; click Save',
'ok'
);
})
.catch(function (e) {
setMsg('space-shooter-timing-msg', e.message || 'อัปโหลดไม่สำเร็จ', 'error');
});
});
var btnAdd = el('btn-space-shooter-ast-add-explode');
if (btnAdd) {
btnAdd.addEventListener('click', function () {
setMsg('space-shooter-timing-msg', '', '');
addSpaceShooterAstExplodeRow('');
});
}
var fallInp = el('space-shooter-ast-fall-url');
var fallFile = el('space-shooter-ast-fall-file');
var fallUp = el('btn-space-shooter-ast-fall-upload');
var fallClr = el('btn-space-shooter-ast-fall-clear');
if (fallInp) {
fallInp.addEventListener('change', updateSpaceShooterAstFallPreview);
fallInp.addEventListener('blur', updateSpaceShooterAstFallPreview);
}
if (fallClr) {
fallClr.addEventListener('click', function () {
if (fallInp) fallInp.value = '';
if (fallFile) fallFile.value = '';
updateSpaceShooterAstFallPreview();
});
}
if (fallUp && fallFile) {
fallUp.addEventListener('click', function () {
if (!fallFile.files || !fallFile.files[0]) {
setMsg('space-shooter-timing-msg', 'เลือกไฟล์รูปก่อน · Pick an image file first', 'error');
return;
}
readFileAsDataURL(fallFile.files[0])
.then(function (dataUrl) {
return gauntletAssetsJsonFetch(GAME_GAUNTLET_ASSETS_API + '/upload', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
imageDataUrl: dataUrl,
label: 'space-shooter-ast-fall',
}),
});
})
.then(function (j) {
if (!j || !j.ok || !j.url) {
throw new Error((j && j.error) || 'อัปโหลดไม่สำเร็จ · Upload failed');
}
if (fallInp) fallInp.value = String(j.url).trim();
updateSpaceShooterAstFallPreview();
setMsg(
'space-shooter-timing-msg',
'อัปโหลดรูปตกแล้ว — กดบันทึกด้านล่างเพื่อเก็บ · Uploaded; click Save',
'ok'
);
})
.catch(function (e) {
setMsg('space-shooter-timing-msg', e.message || 'อัปโหลดไม่สำเร็จ', 'error');
});
});
}
}
function loadSpaceShooterTimingPanel() {
gameTimingFetch('GET')
.then(function (data) {
@@ -2788,11 +3016,16 @@
if (inpU) inpU.value = urls[k - 1] != null ? String(urls[k - 1]) : '';
updateSpaceShooterShipPreview(k);
}
var taAst = el('space-shooter-asteroid-sprite-urls');
if (taAst) {
var fallInpL = el('space-shooter-ast-fall-url');
if (fallInpL) {
var astArr = data.spaceShooterAsteroidSpriteUrls;
if (!Array.isArray(astArr)) astArr = [];
taAst.value = astArr.map(function (u) { return String(u || '').trim(); }).filter(Boolean).join('\n');
fallInpL.value = astArr[0] != null ? String(astArr[0]) : '';
updateSpaceShooterAstFallPreview();
clearSpaceShooterAstExplodeRows();
for (var ai = 1; ai < astArr.length && ai < 32; ai++) {
addSpaceShooterAstExplodeRow(astArr[ai]);
}
}
var inpFms = el('space-shooter-asteroid-explode-ms');
if (inpFms) {
@@ -2819,7 +3052,7 @@
limSs = limSs <= 0 ? 0 : Math.max(10, Math.min(7200, limSs));
var shipUrls = readSpaceShooterShipImageUrlsFromForm();
var damageUrls = readSpaceShooterShipDamageOverlayUrlsFromForm();
var astUrls = parseSpaceShooterAsteroidSpriteUrlsTextarea();
var astUrls = readSpaceShooterAsteroidSpriteUrlsFromForm();
var inpFms = el('space-shooter-asteroid-explode-ms');
var explodeMs = inpFms ? parseInt(String(inpFms.value), 10) : 70;
if (Number.isNaN(explodeMs)) explodeMs = 70;
@@ -3073,6 +3306,7 @@
}
bindSpaceShooterShipUrlInputs();
bindSpaceShooterDamageOverlayPanel();
bindSpaceShooterAsteroidSpritePanel();
var btnStackGameSave = el('btn-stack-game-save');
if (btnStackGameSave) {
btnStackGameSave.addEventListener('click', saveStackGamePanel);