main web4

This commit is contained in:
2026-05-06 20:55:11 +00:00
parent cb42c2c669
commit 8b09c6d11f
4 changed files with 202 additions and 22 deletions
@@ -30,6 +30,8 @@
/** Lobby หลังคดี — ต้องตรงกับ server POST_CASE_LOBBY_SPACE_ID */
const POST_CASE_LOBBY_SPACE_ID = 'mn8nx46h';
const PLAYER_KEY = 'jdPlayerKey';
/** ตรงกับ character.js / Main-Lobby — composite idle ทิศ down */
const LOBBY_IDLE_DOWN_LS = 'jdCharLobbyIdleDown:';
const LOBBY_EVIDENCE_ASSET_BASE = typeof appPath === 'function' ? appPath('/Main-Lobby/IMAGE/See%20evidence') : '/Main-Lobby/IMAGE/See%20evidence';
const LOBBY_EVIDENCE_RARITY = { common: 'Common', rare: 'Rare', legendary: 'Legendary' };
@@ -144,6 +146,21 @@
return { ...p, x: nx, y: ny, tx: nx, ty: ny };
}
const characterImages = {};
/** ลำดับโหลดรูปยืนเฉย/เดิน ต่อทิศ — idle ก่อน (ตรงกับเซิร์ฟ upload) */
function characterSpriteUrlCandidates(id, dir) {
const d = dir || 'down';
const enc = encodeURIComponent(id);
const q = '?ch=' + enc;
const base = SERVER + '/img/characters/' + enc + '_' + d;
return [
base + '_idle.png' + q,
base + '_idle_0.png' + q,
base + '.png' + q,
base + '_0.png' + q,
];
}
function createDefaultAvatarImg() {
const c = document.createElement('canvas');
c.width = 64; c.height = 64;
@@ -187,10 +204,21 @@
function getCharacterImg(id, direction) {
if (!id) return null;
const key = id + '_' + (direction || 'down');
const dir = direction || 'down';
const key = id + '_' + dir;
if (characterImages[key]) return characterImages[key];
const img = new Image();
img.src = SERVER + '/img/characters/' + encodeURIComponent(id) + '_' + (direction || 'down') + '.png';
const urls = characterSpriteUrlCandidates(id, dir);
let uidx = 0;
img.onerror = function () {
uidx += 1;
if (uidx >= urls.length) {
img.onerror = null;
return;
}
img.src = urls[uidx];
};
img.src = urls[0];
characterImages[key] = img;
return img;
}
@@ -204,17 +232,27 @@
anim = { frames: [], fallback: null };
characterAnimations[key] = anim;
anim.fallback = getCharacterImg(id, dir);
var q = '?ch=' + encodeURIComponent(id);
var tryIdleWalk = characterSpriteUrlCandidates(id, dir);
var frame0 = new Image();
frame0.onload = function () {
for (var i = 1; i < CHARACTER_ANIM_FRAMES; i++) {
var img = new Image();
img.src = SERVER + '/img/characters/' + encodeURIComponent(id) + '_' + dir + '_' + i + '.png';
img.src = SERVER + '/img/characters/' + encodeURIComponent(id) + '_' + dir + '_' + i + '.png' + q;
anim.frames.push(img);
}
if (mapData && canvas) drawLobbyMap();
};
frame0.onerror = function () { if (mapData && canvas) drawLobbyMap(); };
frame0.src = SERVER + '/img/characters/' + encodeURIComponent(id) + '_' + dir + '_0.png';
var tix = 0;
frame0.onerror = function () {
tix += 1;
if (tix >= tryIdleWalk.length) {
if (mapData && canvas) drawLobbyMap();
return;
}
frame0.src = tryIdleWalk[tix];
};
frame0.src = tryIdleWalk[0];
anim.frames.push(frame0);
}
var phase = walkAnimPhaseIndex(now, isWalking);
@@ -1154,17 +1192,50 @@
if (quizModeActive) renderQuizScoreboard(lastQuizScores);
}
const DEFAULT_CHARACTER_ID = 'Chatest';
function getStoredCharacterId() {
try { return localStorage.getItem('gameCharacterId') || DEFAULT_CHARACTER_ID; } catch (e) { return DEFAULT_CHARACTER_ID; }
try {
const v = (localStorage.getItem('gameCharacterId') || '').trim();
return v;
} catch (e) {
return '';
}
}
function updateLobbyProfileAvatar() {
const img = document.getElementById('room-lobby-profile-avatar');
if (!img) return;
const id = getStoredCharacterId();
img.src = SERVER + '/img/characters/' + encodeURIComponent(id) + '_down.png?ch=' + encodeURIComponent(id);
if (!id) {
img.removeAttribute('src');
img.alt = (profileDisplayName || nick || 'ผู้เล่น');
return;
}
try {
const du = localStorage.getItem(LOBBY_IDLE_DOWN_LS + id);
if (du && typeof du === 'string' && du.indexOf('data:image/') === 0) {
img.onload = null;
img.onerror = null;
img.src = du;
img.alt = (profileDisplayName || nick || 'ผู้เล่น') + ' — ตัวละคร';
return;
}
} catch (e) { /* ignore */ }
const urls = characterSpriteUrlCandidates(id, 'down');
let uidx = 0;
img.alt = (profileDisplayName || nick || 'ผู้เล่น') + ' — ตัวละคร';
img.onerror = function () {
uidx += 1;
if (uidx >= urls.length) {
img.onerror = null;
img.removeAttribute('src');
return;
}
img.src = urls[uidx];
};
img.onload = function () {
img.onerror = null;
};
img.src = urls[0];
}
function loadProfileDisplayName() {
@@ -1760,7 +1831,26 @@
av.className = 'quiz-sb-avatar';
if (row.characterId) {
av.alt = '';
av.src = SERVER + '/img/characters/' + encodeURIComponent(row.characterId) + '_down.png';
var duSb = '';
try {
duSb = localStorage.getItem(LOBBY_IDLE_DOWN_LS + row.characterId) || '';
} catch (eDu) { duSb = ''; }
if (duSb && duSb.indexOf('data:image/') === 0) {
av.src = duSb;
} else {
var urlsSb = characterSpriteUrlCandidates(row.characterId, 'down');
var qi = 0;
av.onerror = function () {
qi += 1;
if (qi >= urlsSb.length) {
av.onerror = null;
av.removeAttribute('src');
return;
}
av.src = urlsSb[qi];
};
av.src = urlsSb[0];
}
}
var meta = document.createElement('div');
meta.className = 'quiz-sb-meta';
@@ -1255,7 +1255,7 @@
<section class="room-lobby-profile-left-pane">
<div class="room-lobby-profile-inner-frame">
<p class="room-lobby-profile-coins">
<img src="img/03-6-Profile/icon-coin.png" alt="" class="room-lobby-profile-coins-icon" onerror="this.style.display='none'">
<img src="/Main-Lobby/IMAGE/coin-JD.png" alt="" class="room-lobby-profile-coins-icon" width="18" height="18" decoding="async">
<img src="img/03-6-Profile/profile-pop-coin.png" alt="My Coins" class="room-lobby-profile-coins-label" decoding="async">
<strong id="room-lobby-profile-coins-val">150</strong>
</p>
@@ -1520,7 +1520,7 @@
<script src="../app-base.js"></script>
<script>document.write('<script src="' + (typeof GAME_SERVER !== 'undefined' ? GAME_SERVER : '') + '/Game/socket.io/socket.io.js"><\/script>');</script>
<script src="js/version.js?v=0.0122"></script>
<script src="js/room-lobby.js?v=0.0189"></script>
<script src="js/room-lobby.js?v=0.0192"></script>
<div class="version-tag">v —</div>
</body>
</html>
+99 -9
View File
@@ -30,6 +30,8 @@
/** Lobby หลังคดี — ต้องตรงกับ server POST_CASE_LOBBY_SPACE_ID */
const POST_CASE_LOBBY_SPACE_ID = 'mn8nx46h';
const PLAYER_KEY = 'jdPlayerKey';
/** ตรงกับ character.js / Main-Lobby — composite idle ทิศ down */
const LOBBY_IDLE_DOWN_LS = 'jdCharLobbyIdleDown:';
const LOBBY_EVIDENCE_ASSET_BASE = typeof appPath === 'function' ? appPath('/Main-Lobby/IMAGE/See%20evidence') : '/Main-Lobby/IMAGE/See%20evidence';
const LOBBY_EVIDENCE_RARITY = { common: 'Common', rare: 'Rare', legendary: 'Legendary' };
@@ -144,6 +146,21 @@
return { ...p, x: nx, y: ny, tx: nx, ty: ny };
}
const characterImages = {};
/** ลำดับโหลดรูปยืนเฉย/เดิน ต่อทิศ — idle ก่อน (ตรงกับเซิร์ฟ upload) */
function characterSpriteUrlCandidates(id, dir) {
const d = dir || 'down';
const enc = encodeURIComponent(id);
const q = '?ch=' + enc;
const base = SERVER + '/img/characters/' + enc + '_' + d;
return [
base + '_idle.png' + q,
base + '_idle_0.png' + q,
base + '.png' + q,
base + '_0.png' + q,
];
}
function createDefaultAvatarImg() {
const c = document.createElement('canvas');
c.width = 64; c.height = 64;
@@ -187,10 +204,21 @@
function getCharacterImg(id, direction) {
if (!id) return null;
const key = id + '_' + (direction || 'down');
const dir = direction || 'down';
const key = id + '_' + dir;
if (characterImages[key]) return characterImages[key];
const img = new Image();
img.src = SERVER + '/img/characters/' + encodeURIComponent(id) + '_' + (direction || 'down') + '.png';
const urls = characterSpriteUrlCandidates(id, dir);
let uidx = 0;
img.onerror = function () {
uidx += 1;
if (uidx >= urls.length) {
img.onerror = null;
return;
}
img.src = urls[uidx];
};
img.src = urls[0];
characterImages[key] = img;
return img;
}
@@ -204,17 +232,27 @@
anim = { frames: [], fallback: null };
characterAnimations[key] = anim;
anim.fallback = getCharacterImg(id, dir);
var q = '?ch=' + encodeURIComponent(id);
var tryIdleWalk = characterSpriteUrlCandidates(id, dir);
var frame0 = new Image();
frame0.onload = function () {
for (var i = 1; i < CHARACTER_ANIM_FRAMES; i++) {
var img = new Image();
img.src = SERVER + '/img/characters/' + encodeURIComponent(id) + '_' + dir + '_' + i + '.png';
img.src = SERVER + '/img/characters/' + encodeURIComponent(id) + '_' + dir + '_' + i + '.png' + q;
anim.frames.push(img);
}
if (mapData && canvas) drawLobbyMap();
};
frame0.onerror = function () { if (mapData && canvas) drawLobbyMap(); };
frame0.src = SERVER + '/img/characters/' + encodeURIComponent(id) + '_' + dir + '_0.png';
var tix = 0;
frame0.onerror = function () {
tix += 1;
if (tix >= tryIdleWalk.length) {
if (mapData && canvas) drawLobbyMap();
return;
}
frame0.src = tryIdleWalk[tix];
};
frame0.src = tryIdleWalk[0];
anim.frames.push(frame0);
}
var phase = walkAnimPhaseIndex(now, isWalking);
@@ -1154,17 +1192,50 @@
if (quizModeActive) renderQuizScoreboard(lastQuizScores);
}
const DEFAULT_CHARACTER_ID = 'Chatest';
function getStoredCharacterId() {
try { return localStorage.getItem('gameCharacterId') || DEFAULT_CHARACTER_ID; } catch (e) { return DEFAULT_CHARACTER_ID; }
try {
const v = (localStorage.getItem('gameCharacterId') || '').trim();
return v;
} catch (e) {
return '';
}
}
function updateLobbyProfileAvatar() {
const img = document.getElementById('room-lobby-profile-avatar');
if (!img) return;
const id = getStoredCharacterId();
img.src = SERVER + '/img/characters/' + encodeURIComponent(id) + '_down.png?ch=' + encodeURIComponent(id);
if (!id) {
img.removeAttribute('src');
img.alt = (profileDisplayName || nick || 'ผู้เล่น');
return;
}
try {
const du = localStorage.getItem(LOBBY_IDLE_DOWN_LS + id);
if (du && typeof du === 'string' && du.indexOf('data:image/') === 0) {
img.onload = null;
img.onerror = null;
img.src = du;
img.alt = (profileDisplayName || nick || 'ผู้เล่น') + ' — ตัวละคร';
return;
}
} catch (e) { /* ignore */ }
const urls = characterSpriteUrlCandidates(id, 'down');
let uidx = 0;
img.alt = (profileDisplayName || nick || 'ผู้เล่น') + ' — ตัวละคร';
img.onerror = function () {
uidx += 1;
if (uidx >= urls.length) {
img.onerror = null;
img.removeAttribute('src');
return;
}
img.src = urls[uidx];
};
img.onload = function () {
img.onerror = null;
};
img.src = urls[0];
}
function loadProfileDisplayName() {
@@ -1760,7 +1831,26 @@
av.className = 'quiz-sb-avatar';
if (row.characterId) {
av.alt = '';
av.src = SERVER + '/img/characters/' + encodeURIComponent(row.characterId) + '_down.png';
var duSb = '';
try {
duSb = localStorage.getItem(LOBBY_IDLE_DOWN_LS + row.characterId) || '';
} catch (eDu) { duSb = ''; }
if (duSb && duSb.indexOf('data:image/') === 0) {
av.src = duSb;
} else {
var urlsSb = characterSpriteUrlCandidates(row.characterId, 'down');
var qi = 0;
av.onerror = function () {
qi += 1;
if (qi >= urlsSb.length) {
av.onerror = null;
av.removeAttribute('src');
return;
}
av.src = urlsSb[qi];
};
av.src = urlsSb[0];
}
}
var meta = document.createElement('div');
meta.className = 'quiz-sb-meta';
+2 -2
View File
@@ -1258,7 +1258,7 @@
<section class="room-lobby-profile-left-pane">
<div class="room-lobby-profile-inner-frame">
<p class="room-lobby-profile-coins">
<img src="img/03-6-Profile/icon-coin.png" alt="" class="room-lobby-profile-coins-icon" onerror="this.style.display='none'">
<img src="/Main-Lobby/IMAGE/coin-JD.png" alt="" class="room-lobby-profile-coins-icon" width="18" height="18" decoding="async">
<img src="img/03-6-Profile/profile-pop-coin.png" alt="My Coins" class="room-lobby-profile-coins-label" decoding="async">
<strong id="room-lobby-profile-coins-val">150</strong>
</p>
@@ -1523,7 +1523,7 @@
<script src="/app-base.js?v=1"></script>
<script src="/Game/socket.io/socket.io.js"></script>
<script src="js/version.js?v=0.0122"></script>
<script src="js/room-lobby.js?v=0.0190"></script>
<script src="js/room-lobby.js?v=0.0192"></script>
<div class="version-tag">v —</div>
</body>
</html>