diff --git a/assets/game-api.js b/assets/game-api.js index 58e8669..267fdec 100644 --- a/assets/game-api.js +++ b/assets/game-api.js @@ -17,14 +17,16 @@ const _isDevPort = (port) => (port === 80 && (location.port === '' || location.port === '80')); const API_CONFIG = { + // 本地开发一律跨域直连 Odoo 8069(python http.server 无代理能力); + // 仅 8080 dev-server(自带反向代理到 Odoo)才走同源空 base。 base: _isLocalDev() - ? ((_isDevPort(8080) || _isDevPort(8888)) ? '' : `http://${location.hostname}:8080`) - : '', - db: _isLocalDev() ? 'study' : 'game', + ? (_isDevPort(8080) ? '' : `http://${location.hostname}:8069`) + : '', + db: _isLocalDev() ? 'game_a' : 'game', }; -// 世界(yt_world)所在库:本地 Odoo 钉 yt_game;线上游戏库名为 game。按域名自适应,git 同步不冲突。 -const WORLD_DB = _isLocalDev() ? 'yt_game' : 'game'; +// 世界(yt_world)所在库:与 API_CONFIG.db 保持一致(本地均为 game_a),避免跨库导致 auth 失败。 +const WORLD_DB = API_CONFIG.db; // Odoo 后端基础 URL(世界 API 专用,兼容本地跨域 / 生产同域) const WORLD_BASE = API_CONFIG.base || ''; diff --git a/world.html b/world.html index 9fd00e5..4f03027 100644 --- a/world.html +++ b/world.html @@ -779,7 +779,7 @@ body { background: #0a0e17; overflow: hidden; font-family: 'Microsoft YaHei', sa .tp-empty{text-align:center;padding:30px 10px;color:#7b8ea8;font-size:14px;line-height:1.7;} .tp-empty a{color:#8b5cf6;} /* ===== 新手抽天赋引导 ===== */ -#talentDraw{position:fixed;inset:0;z-index:1300;display:flex;align-items:flex-end;justify-content:center;background:rgba(4,7,15,.72);backdrop-filter:blur(7px);opacity:0;visibility:hidden;transition:opacity .3s,visibility .3s;padding:28px 18px 40px;} +#talentDraw{position:fixed;inset:0;z-index:1300;display:flex;align-items:center;justify-content:center;background:rgba(4,7,15,.72);backdrop-filter:blur(7px);opacity:0;visibility:hidden;transition:opacity .3s,visibility .3s;padding:28px 18px;} #talentDraw.open{opacity:1;visibility:visible;} #talentDraw[hidden]{display:none;} .td-wrap{width:760px;max-width:100%;display:flex;flex-direction:column;align-items:center;gap:18px;} @@ -792,9 +792,14 @@ body { background: #0a0e17; overflow: hidden; font-family: 'Microsoft YaHei', sa .td-bubble b{color:#c4b5fd;} .td-cards{display:flex;gap:14px;flex-wrap:wrap;justify-content:center;min-height:168px;} .td-card{width:120px;height:168px;perspective:900px;cursor:pointer;position:relative;} -.td-card.dealt{animation:td-deal .42s ease both;} -@keyframes td-deal{from{opacity:0;transform:translateY(26px) rotate(-6deg);}to{opacity:1;transform:none;}} -.td-inner{position:relative;width:100%;height:100%;transform-style:preserve-3d;transition:transform .55s cubic-bezier(.2,.8,.3,1);} +.td-card.dealt{animation:td-deal .62s cubic-bezier(.22,1.4,.36,1) both;} +@keyframes td-deal{ + 0%{opacity:0;transform:translateY(-160px) rotateZ(var(--rz,-6deg)) rotateY(-55deg) scale(.62);} + 55%{opacity:1;transform:translateY(10px) rotateZ(calc(var(--rz,0deg)*-.35)) rotateY(8deg) scale(1.05);} + 75%{transform:translateY(-4px) rotateY(-3deg) scale(.98);} + 100%{transform:none;} +} +.td-inner{position:relative;width:100%;height:100%;transform-style:preserve-3d;transition:transform 1.0s cubic-bezier(.22,.85,.28,1);} .td-card.flipped .td-inner{transform:rotateY(180deg);} .td-face{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;border-radius:14px;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:10px;box-shadow:0 6px 18px rgba(0,0,0,.45);} .td-back{background:linear-gradient(160deg,#3b2a6b,#1c1340);border:1px solid rgba(167,139,250,.5);color:#c4b5fd;font-size:40px;} @@ -807,6 +812,21 @@ body { background: #0a0e17; overflow: hidden; font-family: 'Microsoft YaHei', sa .td-front.got{box-shadow:0 0 0 2px rgba(70,224,122,.7),0 6px 18px rgba(70,224,122,.35);} .td-front .td-got{position:absolute;top:6px;right:8px;font-size:10px;color:#46e07a;font-weight:700;} .td-card.done{cursor:default;} +/* 抽卡揭晓特效:光晕扩散 + 斜向扫光 + 正面弹跳 + 星星迸发(翻面后接续播放) */ +.td-front .td-glow{position:absolute;inset:0;border-radius:14px;pointer-events:none;opacity:0; + background:radial-gradient(circle at 50% 42%,rgba(167,139,250,.9),rgba(74,175,255,.3) 45%,transparent 70%);} +.td-card.revealing .td-glow{animation:td-glow 1s ease-out .5s forwards;} +@keyframes td-glow{0%{opacity:0;transform:scale(.4);}35%{opacity:1;}100%{opacity:0;transform:scale(1.3);}} +.td-front .td-shine{position:absolute;top:0;left:-60%;width:60%;height:100%;pointer-events:none;opacity:0; + background:linear-gradient(105deg,transparent,rgba(255,255,255,.6),transparent);transform:skewX(-18deg);} +.td-card.revealing .td-shine{animation:td-shine 1s ease-in-out .55s forwards;} +@keyframes td-shine{0%{left:-60%;opacity:0;}45%{opacity:.9;}100%{left:120%;opacity:0;}} +.td-card.revealing .td-front{animation:td-pop 1s cubic-bezier(.18,1.5,.4,1) .5s both;} +@keyframes td-pop{0%{transform:scale(.82) rotateY(180deg);filter:brightness(1.7);}60%{transform:scale(1.06) rotateY(180deg);}100%{transform:scale(1) rotateY(180deg);filter:brightness(1);}} +.td-spark{position:absolute;left:50%;top:46%;width:6px;height:6px;border-radius:50%;pointer-events:none;z-index:5;opacity:0; + background:#fff;box-shadow:0 0 8px 2px rgba(167,139,250,.9);} +.td-card.revealing .td-spark{animation:td-spark .9s ease-out .5s forwards;} +@keyframes td-spark{0%{opacity:1;transform:translate(-50%,-50%) scale(1);}100%{opacity:0;transform:translate(calc(-50% + var(--dx)),calc(-50% + var(--dy))) scale(.2);}} .td-actions{display:flex;gap:12px;align-items:center;flex-wrap:wrap;justify-content:center;} .td-btn{padding:10px 22px;border:none;border-radius:10px;background:linear-gradient(135deg,#8b5cf6,#4aafff);color:#fff;font-size:15px;font-weight:700;cursor:pointer;transition:.18s;box-shadow:0 6px 18px rgba(74,175,255,.35);} .td-btn:hover{filter:brightness(1.08);} @@ -7062,11 +7082,14 @@ if (typeof fitWorld === 'function') fitWorld(); tdDeck.forEach((t, i) => { const card = document.createElement('div'); card.className = 'td-card dealt'; - card.style.animationDelay = (i * 0.08) + 's'; + card.style.animationDelay = (i * 0.12) + 's'; + card.style.setProperty('--rz', (Math.random()*18 - 9).toFixed(1) + 'deg'); + setTimeout(() => playTalentSfx('deal'), i * 120); card.innerHTML = '