game/index.html

237 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<title>宇森 · Yusen活的文明系统模拟</title>
<link rel="stylesheet" href="assets/fonts/yusen-fonts.css" />
<link rel="icon" type="image/png" sizes="48x48" href="assets/ui/logo_planet_48.png?v=20260723">
<link rel="icon" type="image/png" sizes="256x256" href="assets/ui/logo_planet_256.png?v=20260723">
<link rel="apple-touch-icon" href="assets/ui/logo_planet_256.png?v=20260723">
<link rel="stylesheet" href="assets/common.css" />
<!-- 首屏 hero 图预加载,提升 LCP -->
<link rel="preload" as="image" href="assets/slides/01_starry_sky.webp" fetchpriority="high">
<style>
/* 首页特有:全屏 hero 轮播 */
html,body{overflow:hidden;}
.content{flex:1;display:flex;flex-direction:column;position:relative;overflow:hidden;}
.hero{position:relative;flex:1;border-radius:0;overflow:hidden;}
.hero .slideshow{position:absolute;inset:0;overflow:hidden;}
.hero .slide-track{position:absolute;inset:0;display:flex;flex-direction:column;transition:transform 1.25s cubic-bezier(0.4,0,0.2,1);will-change:transform;}
.hero .slide{flex:0 0 100%;width:100%;height:100%;background-size:cover;background-position:center;position:relative;}
.hero .slide::before{content:"";position:absolute;inset:0;
background:linear-gradient(90deg, rgba(8,12,26,.92) 0%, rgba(8,12,26,.70) 22%, rgba(8,12,26,.40) 40%, transparent 58%),
linear-gradient(180deg, rgba(8,12,26,.55) 0%, transparent 35%);}
.hero .copy{position:absolute;left:56px;top:56px;z-index:3;pointer-events:none;}
.hero .copy h1{font-family:"ZCOOL QingKe HuangYou",sans-serif;font-size:56px;letter-spacing:10px;color:#fff;text-shadow:0 2px 24px rgba(0,0,0,.9),0 0 32px rgba(139,92,246,.7);line-height:1.2;}
.hero .copy .sub2{font-family:"Press Start 2P",monospace;font-size:11px;color:var(--gold);margin:6px 0 0;letter-spacing:2px;text-shadow:0 1px 8px rgba(0,0,0,.9);}
.hero .copy .tag{font-size:20px;font-weight:500;color:#e8ecf6;margin-top:4px;text-shadow:0 1px 10px rgba(0,0,0,.85);}
/* 轮播标签 */
.slide-label{position:absolute;left:56px;bottom:72px;z-index:4;pointer-events:none;opacity:0;transform:translateY(16px);transition:opacity .8s ease, transform .8s ease;}
.slide.active .slide-label{opacity:1;transform:translateY(0);}
.slide-label .sl-en{font-family:"Press Start 2P",monospace;font-size:13px;color:var(--cyan);letter-spacing:3px;margin-bottom:10px;display:block;text-shadow:0 1px 8px rgba(0,0,0,.9);}
.slide-label .sl-cn{font-family:"ZCOOL QingKe HuangYou",sans-serif;font-size:46px;letter-spacing:7px;color:#fff;text-shadow:0 2px 22px rgba(0,0,0,.95),0 0 30px rgba(139,92,246,.65);line-height:1.25;}
.slide-label .sl-desc{font-size:16px;color:#c8d2ec;margin-top:12px;max-width:500px;line-height:1.85;text-shadow:0 1px 8px rgba(0,0,0,.88);}
/* 指示器 */
.sl-dots{position:absolute;right:40px;bottom:96px;top:auto;transform:none;z-index:5;display:flex;flex-direction:column;gap:14px;pointer-events:auto;}
.sl-dot{width:12px;height:12px;border-radius:50%;background:rgba(255,255,255,.22);border:1px solid rgba(255,255,255,.4);cursor:pointer;transition:.3s;flex:0 0 auto;}
.sl-dot:hover{background:rgba(255,255,255,.5);}
.sl-dot.active{background:var(--gold);border-color:var(--gold);box-shadow:0 0 12px rgba(231,184,92,.6);transform:scale(1.15);}
/* 导航箭头 */
.sl-arrow{position:absolute;top:50%;z-index:6;transform:translateY(-50%);width:44px;height:44px;border-radius:50%;border:1px solid rgba(255,255,255,.15);background:rgba(8,12,26,.55);backdrop-filter:blur(8px);color:#e8ecf6;font-size:18px;cursor:pointer;transition:.2s;display:flex;align-items:center;justify-content:center;pointer-events:auto;}
.sl-arrow:hover{background:rgba(139,92,246,.25);border-color:rgba(139,92,246,.4);box-shadow:0 0 16px rgba(139,92,246,.2);transform:translateY(-50%) scale(1.08);}
.sl-arrow.prev{left:16px;}
.sl-arrow.next{right:16px;}
/* 起源文案 */
.slide-origin{position:absolute;right:72px;top:48px;z-index:4;pointer-events:none;writing-mode:vertical-rl;text-orientation:upright;
font-family:"Noto Sans SC",sans-serif;font-size:16px;font-weight:500;letter-spacing:3px;line-height:1.55;color:rgba(240,244,252,.94);
text-shadow:0 1px 3px rgba(0,0,0,.92);max-height:28vh;overflow:hidden;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;
opacity:0;transform:translateY(-12px);transition:opacity .9s ease .25s, transform .9s ease .25s;}
.slide.active .slide-origin{opacity:1;transform:translateY(0);}
.slide-origin .so-tag{color:var(--gold);font-family:"ZCOOL QingKe HuangYou",sans-serif;font-size:19px;letter-spacing:5px;margin-bottom:7px;text-shadow:0 1px 4px rgba(0,0,0,.92),0 0 10px rgba(231,184,92,.45);}
/* 进入游戏按钮 */
.hero .enter-wrap{position:absolute;left:0;right:0;bottom:28px;display:flex;justify-content:center;z-index:5;}
.hero .enter-btn{font-family:"Noto Sans SC",sans-serif;font-size:17px;font-weight:700;color:#0b1020;background:linear-gradient(120deg,var(--gold),#f0d49a);padding:13px 42px;border-radius:30px;cursor:pointer;box-shadow:0 0 26px rgba(231,184,92,.5);letter-spacing:3px;transition:.25s;border:none;}
.hero .enter-btn:hover{filter:brightness(1.1);transform:translateY(-2px);box-shadow:0 0 40px rgba(231,184,92,.75);}
@media (max-width:900px){
.hero .copy h1{font-size:42px;}
}
@media (max-width:768px){
.hero .copy{left:18px;right:18px;top:28px;}
.hero .copy h1{font-size:32px;letter-spacing:4px;}
.hero .copy .tag{font-size:16px;}
.slide-label{left:18px;bottom:78px;}
.slide-label .sl-cn{font-size:24px;letter-spacing:3px;}
.slide-label .sl-desc{font-size:13px;max-width:100%;}
.sl-dots{right:16px;gap:12px;}
.hero .enter-wrap{bottom:28px;}
.hero .enter-btn{font-size:15px;padding:11px 30px;}
}
@media (max-width:480px){
.hero .copy{left:14px;top:20px;}
.hero .copy h1{font-size:26px;letter-spacing:2px;}
.hero .copy .tag{font-size:14px;}
.slide-label{left:14px;bottom:70px;}
.slide-label .sl-cn{font-size:20px;}
.slide-label .sl-desc{font-size:12.5px;}
.sl-dots{right:12px;gap:10px;}
}
</style>
</head>
<body>
<div class="app">
<header class="topbar">
<a href="index.html" class="logo"><span class="cn">宇森</span></a>
<nav class="nav">
<a href="announce.html">公告</a>
<a href="background.html">背景</a>
<a href="rules.html">规则</a>
<a href="codex.html">图鉴</a>
<a href="story.html">剧情</a>
<a href="forum.html" class="auth-only">论坛</a>
<a href="worlddata.html" class="auth-only">世界数据</a>
</nav>
<div class="spacer"></div>
<div class="user-box" id="userBox"></div>
</header>
<main class="content">
<section class="hero">
<div class="slideshow" id="slideshow"></div>
<div class="copy">
<h1>宇森 &#183; Yusen</h1>
<div class="sub2">LIVING CIVILIZATION SIMULATOR</div>
<div class="tag">活的文明系统模拟</div>
</div>
<div class="enter-wrap">
<button class="enter-btn" id="enterGame">⚔ 进入游戏</button>
</div>
<button class="sl-arrow prev" onclick="window.slPrev && window.slPrev()"></button>
<button class="sl-arrow next" onclick="window.slNext && window.slNext()"></button>
</section>
</main>
</div>
<script src="assets/game-api.js"></script>
<script src="assets/common.js"></script>
<script>
// ============ 五层世界图片轮播 ============
(function(){
const slides = [
{ img:'assets/slides/01_starry_sky.webp', en:'STARRY SKY', cn:'星空', desc:'陨石星空带悬浮于世界最外层,是文明触及维度的起点。星轨连通各浮空岛,穹鎏晶体自星尘中凝结。',
origin:'世界未形,星尘先于万物浮游于虚无。首缕维度自星隙坍缩成形,穹鎏晶体由尘凝就,文明自此仰望苍穹之始。' },
{ img:'assets/slides/02_sky.webp', en:'SKY', cn:'天空', desc:'云朵地基块托起浮空岛群,灵气复苏的第一缕风拂过。各族初代聚落,在此仰望也更在此扎根。',
origin:'云基初结,浮空岛群自苍穹垂落凡尘。灵气复苏,初民循风而居,于云上筑城,仰望亦扎根,道统由此萌发。' },
{ img:'assets/slides/03_earth.webp', en:'EARTH', cn:'大地', desc:'平原与森林铺展成万物生灵的摇篮,玄荒文明于斯鼎盛。城邦林立,征伐与道统在沃土上并行。',
origin:'沃野铺展为万灵摇篮,玄荒先族自林泉走出。城邦并起,征伐与道统并驰沃土之上,文明于此鼎盛绵延。' },
{ img:'assets/slides/04_underground.webp',en:'UNDERGROUND',cn:'地下', desc:'溶洞晶矿与暗河在深处低语,冥玉生于幽暗玉石之中。地心工坊调度浅层资源,灯火不熄。',
origin:'溶洞深开,晶矿与暗河在幽处低语。冥玉生于幽玉深心,地心工坊取浅层之资,灯火长明,匠魂不熄。' },
{ img:'assets/slides/05_core.webp', en:'CORE', cn:'地心', desc:'熔岩奔流的地心,是世界诞生的本源。元玺在此凝聚,追溯天地初开的那一瞬永恒。',
origin:'熔岩奔流处,乃世界本源所钟。元玺于亿载炽火中凝聚成形,溯天地初开一瞬,万物归处,亦是起始。' }
];
const container = document.getElementById('slideshow');
if(!container) return;
let current = 0, timer = null;
const INTERVAL = 5500;
// —— 预加载所有图片,消除切换闪烁 ——
slides.forEach(s => { const img = new Image(); img.src = s.img; });
const track = document.createElement('div');
track.className='slide-track';
container.appendChild(track);
slides.forEach((s,i)=>{
const el = document.createElement('div');
el.className='slide'+(i===0?' active':'');
el.style.backgroundImage="url('"+s.img+"')"; // 全部直接设置(已预加载)
el.innerHTML='<div class="slide-label"><span class="sl-en">'+s.en+'</span><div class="sl-cn">'+s.cn+'</div><div class="sl-desc">'+s.desc+'</div></div>'
+'<div class="slide-origin"><span class="so-tag">起源</span>'+s.origin+'</div>';
track.appendChild(el);
});
const all = track.querySelectorAll('.slide');
const dotsWrap = document.createElement('div');
dotsWrap.className='sl-dots';
slides.forEach((_,i)=>{
const d=document.createElement('div');
d.className='sl-dot'+(i===0?' active':'');
d.addEventListener('click',()=>go(i));
dotsWrap.appendChild(d);
});
document.querySelector('.hero').appendChild(dotsWrap);
const dots = dotsWrap.querySelectorAll('.sl-dot');
function go(idx){
if(idx<0)idx=slides.length-1;if(idx>=slides.length)idx=0;
if(idx===current) return;
all[current].classList.remove('active');dots[current].classList.remove('active');
current=idx;
track.style.transform='translateY('+(-current*100)+'%)';
all[current].classList.add('active');dots[current].classList.add('active');
resetTimer();
}
function next(){ go((current+1)%slides.length); }
function prev(){ go((current-1+slides.length)%slides.length); }
function resetTimer(){ clearInterval(timer); timer=setInterval(next,INTERVAL); }
// —— 滚轮 ——
let lock=false,wAccum=0;
document.querySelector('.hero').addEventListener('wheel',function(e){
wAccum+=e.deltaY;
if(lock)return;
if(Math.abs(wAccum)>50){
lock=true;
if(wAccum>0)next();else prev();
wAccum=0;
setTimeout(function(){lock=false;},1250);
}
},{passive:true});
// —— 触屏滑动 ——
let tx=0,ty=0;
const hero = document.querySelector('.hero');
hero.addEventListener('touchstart',e=>{
const t=e.touches[0];
tx=t.clientX; ty=t.clientY;
},{passive:true});
hero.addEventListener('touchend',e=>{
const t=e.changedTouches[0];
const dx=t.clientX-tx, dy=t.clientY-ty;
if(Math.abs(dy)>Math.abs(dx) && Math.abs(dy)>50){
dy>0?prev():next();
}
},{passive:true});
// —— 键盘左右 ——
document.addEventListener('keydown',e=>{
if(e.key==='ArrowLeft')prev();
if(e.key==='ArrowRight')next();
});
// —— 暴露给箭头按钮 ——
window.slPrev=prev; window.slNext=next;
resetTimer();
})();
// ============ 进入游戏 ============
document.getElementById('enterGame').addEventListener('click', async ()=>{
try {
const me = await API.me();
if (me && me.uid) location.href = 'world.html';
else location.href = 'login.html?next=world.html';
} catch(e) {
location.href = 'login.html?next=world.html';
}
});
</script>
</body>
</html>