minigame 5 add more design 1.5
This commit is contained in:
@@ -21,13 +21,17 @@ GAME_SRV_HASH_BEFORE="$(hash_game_server_js "$GAME_SERVER_JS")"
|
||||
|
||||
# ไม่ rsync ทับ Game/data/maps — ฉากที่สร้าง/บันทึกบนเซิร์ฟ (Node saveMap) มักใหม่กว่าใน repo
|
||||
# หลัง deploy คัดลอกเฉพาะ *.json ที่มีใน repo แต่ยังไม่มีบนเซิร์ฟ (seed รหัสใหม่) ไม่แตะไฟล์ที่มีอยู่แล้ว
|
||||
# ไม่ทับ Game/data/game-timing.json — ค่า Minigame / รูปแพลตฟอร์มที่บันทึกจาก Admin บนเซิร์ฟต้องอยู่หลัง deploy
|
||||
MAPS_SRC="$SRC/Game/data/maps"
|
||||
MAPS_DST="$DST/Game/data/maps"
|
||||
TIMING_SRC="$SRC/Game/data/game-timing.json"
|
||||
TIMING_DST="$DST/Game/data/game-timing.json"
|
||||
|
||||
rsync -a \
|
||||
--checksum \
|
||||
--exclude 'node_modules' \
|
||||
--exclude 'Game/data/maps/' \
|
||||
--exclude 'Game/data/game-timing.json' \
|
||||
"$SRC" "$DST"
|
||||
chown -R www-data:www-data "$DST"
|
||||
|
||||
@@ -44,6 +48,14 @@ if [[ -d "$MAPS_SRC" ]]; then
|
||||
shopt -u nullglob
|
||||
chown -R www-data:www-data "$MAPS_DST"
|
||||
fi
|
||||
if [[ -f "$TIMING_SRC" ]]; then
|
||||
mkdir -p "$(dirname "$TIMING_DST")"
|
||||
if [[ ! -f "$TIMING_DST" ]]; then
|
||||
cp -a "$TIMING_SRC" "$TIMING_DST"
|
||||
echo "OK: seeded game-timing.json (missing on server)"
|
||||
fi
|
||||
chown www-data:www-data "$TIMING_DST" 2>/dev/null || true
|
||||
fi
|
||||
# รูปป้าย quiz_carry — ให้เขียน/ลบได้ชัดเจน (FTP/Node); setgid ให้ไฟล์ใหม่ได้กลุ่ม www-data
|
||||
PLAQUE="$DST/Game/public/img/quiz-carry-plaque-assets"
|
||||
mkdir -p "$PLAQUE"
|
||||
|
||||
@@ -42,17 +42,17 @@
|
||||
{
|
||||
"url": "/Game/img/Jumper/platfrom-1.png",
|
||||
"w": 1392,
|
||||
"h": 136
|
||||
"h": 60
|
||||
},
|
||||
{
|
||||
"url": "/Game/img/Jumper/platfrom-2.png",
|
||||
"w": 389,
|
||||
"h": 77
|
||||
"h": 33
|
||||
},
|
||||
{
|
||||
"url": "/Game/img/Jumper/platfrom-3.png",
|
||||
"w": 212,
|
||||
"h": 77
|
||||
"h": 33
|
||||
}
|
||||
],
|
||||
"spaceShooterMissionTimeSec": 0,
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -362,7 +362,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/version.js?v=0.0258"></script>
|
||||
<script src="js/editor.js?v=0.0318"></script>
|
||||
<script src="js/editor.js?v=0.0319"></script>
|
||||
<div class="version-tag">v —</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1299,6 +1299,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
function editorJumpSurviveVariantAtCell(x, y) {
|
||||
if (!jumpSurvivePlatformVariantArea[y]) return 1;
|
||||
let v = Math.floor(Number(jumpSurvivePlatformVariantArea[y][x]));
|
||||
if (!Number.isFinite(v) || v < 1) v = 1;
|
||||
if (v > 3) v = 3;
|
||||
return v;
|
||||
}
|
||||
|
||||
function ensureJumpSurviveHazardArea() {
|
||||
if (!jumpSurviveHazardArea.length || jumpSurviveHazardArea.length !== height) {
|
||||
const existing = jumpSurviveHazardArea.slice().map((r) => r && r.slice());
|
||||
@@ -2349,35 +2357,40 @@
|
||||
}
|
||||
}
|
||||
if (gtDraw === 'jump_survive' && jumpSurvivePlatformArea[y] && jumpSurvivePlatformArea[y][x] === 1) {
|
||||
let v = jumpSurvivePlatformVariantArea[y] ? Math.floor(Number(jumpSurvivePlatformVariantArea[y][x])) : 1;
|
||||
if (!Number.isFinite(v) || v < 1) v = 1;
|
||||
if (v > 3) v = 3;
|
||||
const cfg = editorJumpSurvivePlatformTilesCfg[v - 1] || { url: '', w: 0, h: 0 };
|
||||
const im = editorJumpSurvivePlatformTileImgs[v - 1];
|
||||
const px0 = tx + 3;
|
||||
const py0 = ty + 3;
|
||||
const pw = tileSize - 6;
|
||||
const ph = tileSize - 6;
|
||||
let dw = cfg.w > 0 ? cfg.w : pw;
|
||||
let dh = cfg.h > 0 ? cfg.h : ph;
|
||||
const maxDim = tileSize * 4;
|
||||
if (dw > maxDim) dw = maxDim;
|
||||
if (dh > maxDim) dh = maxDim;
|
||||
const dx = tx + (tileSize - dw) / 2;
|
||||
const dy = ty + tileSize - dh - 2;
|
||||
if (im && im.complete && im.naturalWidth > 0) {
|
||||
ctx.drawImage(im, dx, dy, dw, dh);
|
||||
ctx.strokeStyle = 'rgba(160, 255, 220, 0.92)';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeRect(dx, dy, dw, dh);
|
||||
ctx.lineWidth = 1;
|
||||
} else {
|
||||
ctx.fillStyle = 'rgba(125, 235, 200, 0.48)';
|
||||
ctx.fillRect(px0, py0, pw, ph);
|
||||
ctx.strokeStyle = 'rgba(160, 255, 220, 0.92)';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeRect(px0, py0, pw, ph);
|
||||
ctx.lineWidth = 1;
|
||||
const vHere = editorJumpSurviveVariantAtCell(x, y);
|
||||
const isRunContinuation = x > 0 && jumpSurvivePlatformArea[y][x - 1] === 1 && editorJumpSurviveVariantAtCell(x - 1, y) === vHere;
|
||||
if (!isRunContinuation) {
|
||||
let runLen = 1;
|
||||
while (x + runLen < width && jumpSurvivePlatformArea[y][x + runLen] === 1
|
||||
&& editorJumpSurviveVariantAtCell(x + runLen, y) === vHere) runLen += 1;
|
||||
const cfg = editorJumpSurvivePlatformTilesCfg[vHere - 1] || { url: '', w: 0, h: 0 };
|
||||
const im = editorJumpSurvivePlatformTileImgs[vHere - 1];
|
||||
const segWpx = runLen * tileSize;
|
||||
let dw = runLen > 1 ? segWpx : (cfg.w > 0 ? cfg.w : tileSize - 6);
|
||||
let dh = cfg.h > 0 ? cfg.h : tileSize - 6;
|
||||
if (runLen === 1) {
|
||||
const maxDim = tileSize * 4;
|
||||
if (dw > maxDim) dw = maxDim;
|
||||
if (dh > maxDim) dh = maxDim;
|
||||
}
|
||||
const dx = tx;
|
||||
const dy = ty + tileSize - dh - 2;
|
||||
if (im && im.complete && im.naturalWidth > 0) {
|
||||
ctx.drawImage(im, dx, dy, dw, dh);
|
||||
ctx.strokeStyle = 'rgba(160, 255, 220, 0.92)';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeRect(dx, dy, dw, dh);
|
||||
ctx.lineWidth = 1;
|
||||
} else {
|
||||
const innerW = runLen > 1 ? segWpx - 4 : tileSize - 6;
|
||||
const innerH = tileSize - 6;
|
||||
ctx.fillStyle = 'rgba(125, 235, 200, 0.48)';
|
||||
ctx.fillRect(tx + 3, ty + 3, innerW, innerH);
|
||||
ctx.strokeStyle = 'rgba(160, 255, 220, 0.92)';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeRect(tx + 3, ty + 3, innerW, innerH);
|
||||
ctx.lineWidth = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gtDraw === 'jump_survive' && jumpSurviveHazardArea[y] && jumpSurviveHazardArea[y][x] === 1) {
|
||||
|
||||
@@ -10600,10 +10600,11 @@
|
||||
md.jumpSurviveHazardArea = rows;
|
||||
}
|
||||
|
||||
/** โซนตาย jump_survive — กริดคงที่ในโลก (ไม่เลื่อนกับแพลตฟอร์ม) */
|
||||
/** โซนตาย jump_survive — กริดคงที่ในโลก (ไม่เลื่อนกับแพลตฟอร์ม) · ช่องที่มีแพลตฟอร์มอยู่ด้วย = ไม่นับ hazard (ยืนบนแพลตฟอร์มชนะ) */
|
||||
function jumpSurviveOverlapsHazardArea(md, left, top, right, bottom) {
|
||||
const ha = md && md.jumpSurviveHazardArea;
|
||||
if (!ha) return false;
|
||||
const pa = md && md.jumpSurvivePlatformArea;
|
||||
const ts = tileSize;
|
||||
const w = md.width || 20, h = md.height || 15;
|
||||
const x0 = Math.max(0, Math.floor(left / ts));
|
||||
@@ -10612,7 +10613,9 @@
|
||||
const y1 = Math.min(h - 1, Math.floor((bottom - 1e-6) / ts));
|
||||
for (let ty = y0; ty <= y1; ty++) {
|
||||
for (let tx = x0; tx <= x1; tx++) {
|
||||
if (ha[ty] && ha[ty][tx] === 1) return true;
|
||||
if (!ha[ty] || ha[ty][tx] !== 1) continue;
|
||||
if (pa && pa[ty] && pa[ty][tx] === 1) continue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -12150,6 +12153,7 @@
|
||||
|
||||
/**
|
||||
* ฟิสิกส์กระโดดร่วม (ผู้เล่น + บอท preview)
|
||||
* ตายจาก: hazard ที่วาง, บีบระหว่าง solid+object wall, หรือตกออกนอกขอบโลกแมป (ไม่ใช้ขอบกล้อง)
|
||||
* @returns {{ pxc: number, feetY: number, vy: number, onGround: boolean, died: boolean }}
|
||||
*/
|
||||
function jumpSurvivePhysicsIntegrate(md, opts) {
|
||||
@@ -12159,8 +12163,6 @@
|
||||
pxc0, feetY0, vy0, wasOnGround,
|
||||
jumpQueued,
|
||||
moveLeft, moveRight,
|
||||
camCenterY,
|
||||
halfViewH,
|
||||
} = opts;
|
||||
const w = md.width || 20, h = md.height || 15;
|
||||
const ts = tileSize;
|
||||
@@ -12245,20 +12247,15 @@
|
||||
return { pxc, feetY, vy, onGround, died: true };
|
||||
}
|
||||
|
||||
headTop = feetY - bh;
|
||||
if (jumpSurviveOverlapsEdgeKillPlatforms(md, pxc - bw, headTop, pxc + bw, feetY, jumpSurvivePlatformScrollPx)) {
|
||||
return { pxc, feetY, vy, onGround, died: true };
|
||||
}
|
||||
|
||||
headTop = feetY - bh;
|
||||
if (jumpSurviveOverlapsHazardArea(md, pxc - bw, headTop, pxc + bw, feetY)) {
|
||||
return { pxc, feetY, vy, onGround, died: true };
|
||||
}
|
||||
|
||||
headTop = feetY - bh;
|
||||
const topKill = camCenterY - halfViewH - ts * 0.35;
|
||||
const botKill = camCenterY + halfViewH + ts * 0.85;
|
||||
if (feetY < topKill || feetY > botKill || headTop < -ts * 2) {
|
||||
/* ไม่ใช้ขอบกล้อง (cam topKill/botKill) — ตายเฉพาะ hazard ที่วาง + ตกออกนอกโลกแมปจริง (ไม่ตายในอากาศระหว่างแพลตฟอร์ม) */
|
||||
const mapHpx = h * ts;
|
||||
if (feetY > mapHpx + ts * 8 || headTop < -ts * 32) {
|
||||
return { pxc, feetY, vy, onGround, died: true };
|
||||
}
|
||||
|
||||
@@ -12299,8 +12296,10 @@
|
||||
const y1 = Math.floor((bottom - 1e-6) / ts);
|
||||
for (let ty = y0; ty <= y1; ty++) {
|
||||
for (let tx = x0; tx <= x1; tx++) {
|
||||
if (tx < 0 || tx >= w || ty >= h) return true;
|
||||
if (tx < 0 || tx >= w) return true;
|
||||
if (ty < 0) continue;
|
||||
/* แพลตฟอร์มวนแนวตั้ง (period = h*ts) — worldY เกิน h*ts เป็นปกติ ห้ามถือ ty>=h เป็น “ซีลพื้นแมป” ไม่งั้น solid+กำแพงข้าง = ตายคาแอร์ */
|
||||
if (ty >= h) continue;
|
||||
const ob = md.objects && md.objects[ty] && md.objects[ty][tx];
|
||||
if (ob === 1) return true;
|
||||
}
|
||||
@@ -12577,8 +12576,6 @@
|
||||
jumpQueued: jumpQ,
|
||||
moveLeft,
|
||||
moveRight,
|
||||
camCenterY: jumpSurviveCamCenterY,
|
||||
halfViewH,
|
||||
});
|
||||
|
||||
if (r.died) {
|
||||
@@ -12652,8 +12649,6 @@
|
||||
jumpQueued: jq,
|
||||
moveLeft: !!(keys['ArrowLeft'] || keys['KeyA']),
|
||||
moveRight: !!(keys['ArrowRight'] || keys['KeyD']),
|
||||
camCenterY: jumpSurviveCamCenterY,
|
||||
halfViewH,
|
||||
});
|
||||
|
||||
if (r.died) {
|
||||
@@ -16085,86 +16080,101 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isJumpSurvive() && showGrid && mapData.jumpSurvivePlatformArea) {
|
||||
const pa = mapData.jumpSurvivePlatformArea;
|
||||
const sc = jumpSurvivePlatformScrollPx;
|
||||
const tsz = tileSize;
|
||||
const period = h * tsz;
|
||||
const visTop = worldMinY;
|
||||
const visBot = worldMaxY;
|
||||
const eps = 1e-6;
|
||||
for (let py = 0; py < h; py++) {
|
||||
for (let px = 0; px < w; px++) {
|
||||
if (!pa[py] || pa[py][px] !== 1) continue;
|
||||
const vIdx = jumpSurvivePlatformVariantIndexAtPlay(mapData, px, py);
|
||||
const cfg = playJumpSurvivePlatformTiles[vIdx - 1] || { url: '', w: 0, h: 0 };
|
||||
const jumpPlatU = normalizeGauntletAssetUrlForPlay(cfg.url || '');
|
||||
const jumpPlatRec = jumpPlatU ? ensureGauntletAssetImage(jumpPlatU) : null;
|
||||
const jumpPlatImg = jumpPlatRec && jumpPlatRec.ready && jumpPlatRec.img && jumpPlatRec.img.naturalWidth > 0 ? jumpPlatRec.img : null;
|
||||
const tileWorldLeft = px * tsz;
|
||||
const tileWorldRight = tileWorldLeft + tsz;
|
||||
if (tileWorldRight <= worldMinX || tileWorldLeft >= worldMaxX) continue;
|
||||
const rawTop = py * tsz - sc;
|
||||
const kMin = Math.ceil((visTop - rawTop - tsz + eps) / period);
|
||||
const kMax = Math.floor((visBot - rawTop - eps) / period);
|
||||
if (kMax < kMin) continue;
|
||||
for (let kk = kMin; kk <= kMax; kk++) {
|
||||
const platTop = rawTop + kk * period;
|
||||
if (platTop + tsz <= visTop || platTop >= visBot) continue;
|
||||
const [psx, psy] = worldToScreen(tileWorldLeft, platTop);
|
||||
const psz = tsz * zDraw;
|
||||
let dw = cfg.w > 0 ? cfg.w * zDraw : psz - 4;
|
||||
let dh = cfg.h > 0 ? cfg.h * zDraw : psz - 4;
|
||||
}
|
||||
if (isJumpSurvive() && mapData.jumpSurvivePlatformArea) {
|
||||
const pa = mapData.jumpSurvivePlatformArea;
|
||||
const sc = jumpSurvivePlatformScrollPx;
|
||||
const tsz = tileSize;
|
||||
const period = h * tsz;
|
||||
const visTop = worldMinY;
|
||||
const visBot = worldMaxY;
|
||||
const eps = 1e-6;
|
||||
for (let py = 0; py < h; py++) {
|
||||
for (let px = 0; px < w; px++) {
|
||||
if (!pa[py] || pa[py][px] !== 1) continue;
|
||||
const vIdx = jumpSurvivePlatformVariantIndexAtPlay(mapData, px, py);
|
||||
if (px > 0 && pa[py][px - 1] === 1 && jumpSurvivePlatformVariantIndexAtPlay(mapData, px - 1, py) === vIdx) {
|
||||
continue;
|
||||
}
|
||||
let runLen = 1;
|
||||
while (px + runLen < w && pa[py][px + runLen] === 1
|
||||
&& jumpSurvivePlatformVariantIndexAtPlay(mapData, px + runLen, py) === vIdx) runLen += 1;
|
||||
const cfg = playJumpSurvivePlatformTiles[vIdx - 1] || { url: '', w: 0, h: 0 };
|
||||
const jumpPlatU = normalizeGauntletAssetUrlForPlay(cfg.url || '');
|
||||
const jumpPlatRec = jumpPlatU ? ensureGauntletAssetImage(jumpPlatU) : null;
|
||||
const jumpPlatImg = jumpPlatRec && jumpPlatRec.ready && jumpPlatRec.img && jumpPlatRec.img.naturalWidth > 0 ? jumpPlatRec.img : null;
|
||||
const tileWorldLeft = px * tsz;
|
||||
const tileWorldRight = (px + runLen) * tsz;
|
||||
if (tileWorldRight <= worldMinX || tileWorldLeft >= worldMaxX) continue;
|
||||
const rawTop = py * tsz - sc;
|
||||
const kMin = Math.ceil((visTop - rawTop - tsz + eps) / period);
|
||||
const kMax = Math.floor((visBot - rawTop - eps) / period);
|
||||
if (kMax < kMin) continue;
|
||||
for (let kk = kMin; kk <= kMax; kk++) {
|
||||
const platTop = rawTop + kk * period;
|
||||
if (platTop + tsz <= visTop || platTop >= visBot) continue;
|
||||
const [psx, psy] = worldToScreen(tileWorldLeft, platTop);
|
||||
const psz = tsz * zDraw;
|
||||
const segScreenW = runLen * psz;
|
||||
let dw;
|
||||
let dh = cfg.h > 0 ? cfg.h * zDraw : psz - 4;
|
||||
if (runLen > 1) {
|
||||
dw = segScreenW;
|
||||
} else {
|
||||
dw = cfg.w > 0 ? cfg.w * zDraw : psz - 4;
|
||||
const maxDim = psz * 4;
|
||||
if (dw > maxDim) dw = maxDim;
|
||||
if (dh > maxDim) dh = maxDim;
|
||||
const marginBot = 2;
|
||||
const dx = psx + (psz - dw) / 2;
|
||||
const dy = psy + psz - dh - marginBot;
|
||||
if (jumpPlatImg) {
|
||||
}
|
||||
const maxDh = psz * 4;
|
||||
if (dh > maxDh) dh = maxDh;
|
||||
const marginBot = 2;
|
||||
const dx = runLen > 1 ? psx : psx + (psz - dw) / 2;
|
||||
const dy = psy + psz - dh - marginBot;
|
||||
if (jumpPlatImg) {
|
||||
ctx.save();
|
||||
try { ctx.imageSmoothingEnabled = true; } catch (e) { /* ignore */ }
|
||||
ctx.drawImage(jumpPlatImg, dx, dy, dw, dh);
|
||||
ctx.restore();
|
||||
ctx.strokeStyle = 'rgba(0, 255, 240, 0.4)';
|
||||
ctx.lineWidth = 1.5;
|
||||
ctx.strokeRect(dx, dy, dw, dh);
|
||||
ctx.lineWidth = 1;
|
||||
} else {
|
||||
const fillW = runLen > 1 ? segScreenW - 6 : psz - 6;
|
||||
ctx.fillStyle = 'rgba(0, 40, 52, 0.72)';
|
||||
ctx.fillRect(psx + 3, psy + 3, fillW, psz - 6);
|
||||
ctx.strokeStyle = 'rgba(0, 255, 240, 0.55)';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeRect(psx + 3, psy + 3, fillW, psz - 6);
|
||||
ctx.strokeStyle = 'rgba(120, 255, 255, 0.35)';
|
||||
ctx.lineWidth = 1;
|
||||
ctx.strokeRect(psx + 5, psy + 5, fillW - 4, psz - 10);
|
||||
const grad = ctx.createLinearGradient(psx, psy, psx, psy + psz);
|
||||
grad.addColorStop(0, 'rgba(0, 255, 240, 0.12)');
|
||||
grad.addColorStop(0.5, 'rgba(0, 0, 0, 0)');
|
||||
grad.addColorStop(1, 'rgba(0, 180, 200, 0.08)');
|
||||
ctx.fillStyle = grad;
|
||||
ctx.fillRect(psx + 4, psy + 4, fillW - 2, psz - 8);
|
||||
ctx.lineWidth = 1;
|
||||
if (zDraw >= 1.15 && psz > 22) {
|
||||
ctx.save();
|
||||
try { ctx.imageSmoothingEnabled = true; } catch (e) { /* ignore */ }
|
||||
ctx.drawImage(jumpPlatImg, dx, dy, dw, dh);
|
||||
ctx.font = `600 ${Math.max(7, Math.min(11, psz * 0.14))}px "Share Tech Mono", ui-monospace, monospace`;
|
||||
ctx.fillStyle = 'rgba(180, 255, 255, 0.5)';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
const cx = psx + (runLen > 1 ? segScreenW * 0.5 : psz * 0.5);
|
||||
ctx.fillText('DATA', cx, psy + psz * 0.38);
|
||||
ctx.font = `500 ${Math.max(5, Math.min(8, psz * 0.1))}px "Share Tech Mono", ui-monospace, monospace`;
|
||||
ctx.fillStyle = 'rgba(120, 230, 255, 0.38)';
|
||||
ctx.fillText('/SEC/BLOCK', cx, psy + psz * 0.62);
|
||||
ctx.restore();
|
||||
ctx.strokeStyle = 'rgba(0, 255, 240, 0.4)';
|
||||
ctx.lineWidth = 1.5;
|
||||
ctx.strokeRect(dx, dy, dw, dh);
|
||||
ctx.lineWidth = 1;
|
||||
} else {
|
||||
ctx.fillStyle = 'rgba(0, 40, 52, 0.72)';
|
||||
ctx.fillRect(psx + 3, psy + 3, psz - 6, psz - 6);
|
||||
ctx.strokeStyle = 'rgba(0, 255, 240, 0.55)';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeRect(psx + 3, psy + 3, psz - 6, psz - 6);
|
||||
ctx.strokeStyle = 'rgba(120, 255, 255, 0.35)';
|
||||
ctx.lineWidth = 1;
|
||||
ctx.strokeRect(psx + 5, psy + 5, psz - 10, psz - 10);
|
||||
const grad = ctx.createLinearGradient(psx, psy, psx, psy + psz);
|
||||
grad.addColorStop(0, 'rgba(0, 255, 240, 0.12)');
|
||||
grad.addColorStop(0.5, 'rgba(0, 0, 0, 0)');
|
||||
grad.addColorStop(1, 'rgba(0, 180, 200, 0.08)');
|
||||
ctx.fillStyle = grad;
|
||||
ctx.fillRect(psx + 4, psy + 4, psz - 8, psz - 8);
|
||||
ctx.lineWidth = 1;
|
||||
if (zDraw >= 1.15 && psz > 22) {
|
||||
ctx.save();
|
||||
ctx.font = `600 ${Math.max(7, Math.min(11, psz * 0.14))}px "Share Tech Mono", ui-monospace, monospace`;
|
||||
ctx.fillStyle = 'rgba(180, 255, 255, 0.5)';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.fillText('DATA', psx + psz * 0.5, psy + psz * 0.38);
|
||||
ctx.font = `500 ${Math.max(5, Math.min(8, psz * 0.1))}px "Share Tech Mono", ui-monospace, monospace`;
|
||||
ctx.fillStyle = 'rgba(120, 230, 255, 0.38)';
|
||||
ctx.fillText('/SEC/BLOCK', psx + psz * 0.5, psy + psz * 0.62);
|
||||
ctx.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isJumpSurvive() && mapData.jumpSurviveHazardArea) {
|
||||
if (isJumpSurvive() && showGrid && mapData.jumpSurviveHazardArea) {
|
||||
const ha = mapData.jumpSurviveHazardArea;
|
||||
const tsz = tileSize;
|
||||
for (let py = startTileY; py <= endTileY; py++) {
|
||||
|
||||
@@ -3026,7 +3026,7 @@
|
||||
</div>
|
||||
<script src="/Game/socket.io/socket.io.js"></script>
|
||||
<script src="js/version.js?v=0.0306"></script>
|
||||
<script src="js/play.js?v=0.0318"></script>
|
||||
<script src="js/play.js?v=0.0323"></script>
|
||||
<div class="version-tag">v —</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user