1289 lines
60 KiB
HTML
1289 lines
60 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>PIXEL GAMES · 像素游戏厅</title>
|
||
<style>
|
||
/* ============================================================
|
||
PIXEL GAMES — 复古像素风游戏平台 (单文件, 无外部依赖)
|
||
============================================================ */
|
||
|
||
:root{
|
||
--bg:#1a1a2e; /* 深蓝底 */
|
||
--bg-2:#16213e; /* 面板底 */
|
||
--bg-3:#0f3460; /* 深面板 */
|
||
--bg-4:#0a0a1a; /* 最深 */
|
||
--green:#0fbc6e; /* 复古绿 */
|
||
--green-d:#0a8a52;
|
||
--green-l:#3ce896;
|
||
--yellow:#f9d71c; /* 暖黄 */
|
||
--yellow-d:#c9a800;
|
||
--red:#e94560; /* 珊瑚红 */
|
||
--red-d:#b8334c;
|
||
--purple:#6c5ce7; /* 像素紫 */
|
||
--purple-d:#4e3fc4;
|
||
--cyan:#00e5ff;
|
||
--text:#e8e8f0;
|
||
--text-dim:#8a8aae;
|
||
--text-dimer:#5a5a78;
|
||
--ink:#000000;
|
||
--shadow:rgba(0,0,0,.55);
|
||
--font:'Courier New',Courier,monospace;
|
||
}
|
||
|
||
*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
|
||
html{scroll-behavior:smooth}
|
||
body{
|
||
font-family:var(--font);
|
||
background:var(--bg);
|
||
color:var(--text);
|
||
font-size:14px;
|
||
line-height:1.5;
|
||
letter-spacing:.5px;
|
||
overflow-x:hidden;
|
||
image-rendering:pixelated;
|
||
background-image:
|
||
radial-gradient(circle at 20% 10%, rgba(108,92,231,.08), transparent 40%),
|
||
radial-gradient(circle at 80% 80%, rgba(15,188,110,.07), transparent 40%);
|
||
background-attachment:fixed;
|
||
}
|
||
img{display:block;max-width:100%;image-rendering:pixelated}
|
||
button{font-family:inherit;cursor:pointer;border:none;background:none;color:inherit;letter-spacing:inherit}
|
||
input,select{font-family:inherit;letter-spacing:inherit;color:inherit}
|
||
a{color:inherit;text-decoration:none}
|
||
ul{list-style:none}
|
||
::-webkit-scrollbar{width:10px;height:10px}
|
||
::-webkit-scrollbar-track{background:var(--bg-4)}
|
||
::-webkit-scrollbar-thumb{background:var(--green-d);border:2px solid var(--bg-4)}
|
||
::-webkit-scrollbar-thumb:hover{background:var(--green)}
|
||
|
||
/* ===== CRT 扫描线 & 屏幕特效 ===== */
|
||
.crt-overlay{
|
||
position:fixed;inset:0;z-index:9998;pointer-events:none;
|
||
background:repeating-linear-gradient(
|
||
to bottom,
|
||
rgba(0,0,0,0) 0,
|
||
rgba(0,0,0,0) 2px,
|
||
rgba(0,0,0,.22) 3px,
|
||
rgba(0,0,0,.22) 3px
|
||
);
|
||
mix-blend-mode:multiply;
|
||
opacity:.7;
|
||
}
|
||
.crt-vignette{
|
||
position:fixed;inset:0;z-index:9997;pointer-events:none;
|
||
box-shadow:inset 0 0 140px 30px rgba(0,0,0,.65), inset 0 0 40px 0 rgba(0,0,0,.4);
|
||
}
|
||
.crt-flicker{
|
||
position:fixed;inset:0;z-index:9999;pointer-events:none;
|
||
background:rgba(15,188,110,.012);
|
||
animation:flicker 6s steps(60) infinite;
|
||
}
|
||
@keyframes flicker{0%{opacity:.3}1%{opacity:.5}2%{opacity:.3}50%{opacity:.4}51%{opacity:.55}52%{opacity:.35}100%{opacity:.3}}
|
||
|
||
/* ===== 像素通用 ===== */
|
||
.container{max-width:1240px;margin:0 auto;padding:0 22px}
|
||
.pixel-font{font-family:var(--font);letter-spacing:2px;text-transform:uppercase}
|
||
|
||
/* 像素边框盒子 — 硬边 + 3D 阴影 */
|
||
.pbox{
|
||
background:var(--bg-2);
|
||
border:4px solid var(--ink);
|
||
box-shadow:
|
||
inset -4px -4px 0 0 rgba(0,0,0,.45),
|
||
inset 4px 4px 0 0 rgba(255,255,255,.06),
|
||
6px 6px 0 0 var(--shadow);
|
||
position:relative;
|
||
}
|
||
.pbox-green{border-color:var(--green)}
|
||
.pbox-yellow{border-color:var(--yellow)}
|
||
.pbox-red{border-color:var(--red)}
|
||
.pbox-purple{border-color:var(--purple)}
|
||
|
||
/* 像素按钮 — 按下 3D 效果 */
|
||
.pbtn{
|
||
display:inline-flex;align-items:center;justify-content:center;gap:8px;
|
||
font-family:var(--font);font-weight:bold;letter-spacing:2px;text-transform:uppercase;
|
||
background:var(--green);color:var(--ink);
|
||
border:4px solid var(--ink);
|
||
box-shadow:4px 4px 0 0 var(--ink), inset -3px -3px 0 0 rgba(0,0,0,.28), inset 3px 3px 0 0 rgba(255,255,255,.25);
|
||
padding:12px 22px;
|
||
transition:transform .04s linear, box-shadow .04s linear;
|
||
cursor:pointer;user-select:none;
|
||
image-rendering:pixelated;
|
||
}
|
||
.pbtn:hover{filter:brightness(1.1)}
|
||
.pbtn:active{transform:translate(4px,4px);box-shadow:0 0 0 0 var(--ink), inset -3px -3px 0 0 rgba(0,0,0,.28), inset 3px 3px 0 0 rgba(255,255,255,.18)}
|
||
.pbtn-yellow{background:var(--yellow)}
|
||
.pbtn-red{background:var(--red);color:#fff}
|
||
.pbtn-purple{background:var(--purple);color:#fff}
|
||
.pbtn-ghost{background:var(--bg-3);color:var(--green);box-shadow:4px 4px 0 0 var(--ink),inset -3px -3px 0 0 rgba(0,0,0,.4),inset 3px 3px 0 0 rgba(255,255,255,.06)}
|
||
.pbtn-sm{padding:7px 12px;font-size:12px;box-shadow:3px 3px 0 0 var(--ink),inset -2px -2px 0 0 rgba(0,0,0,.28),inset 2px 2px 0 0 rgba(255,255,255,.2)}
|
||
.pbtn-sm:active{transform:translate(3px,3px);box-shadow:0 0 0 0 var(--ink),inset -2px -2px 0 0 rgba(0,0,0,.28),inset 2px 2px 0 0 rgba(255,255,255,.15)}
|
||
|
||
/* 像素斜切面板角 */
|
||
.clip-corner{clip-path:polygon(0 0,calc(100% - 14px) 0,100% 14px,100% 100%,14px 100%,0 calc(100% - 14px))}
|
||
|
||
/* 动画 */
|
||
@keyframes blink{0%,49%{opacity:1}50%,100%{opacity:0}}
|
||
.blink{animation:blink 1s steps(1) infinite}
|
||
@keyframes blink-soft{0%,49%{opacity:1}50%,100%{opacity:.25}}
|
||
.blink-soft{animation:blink-soft 1.1s steps(1) infinite}
|
||
@keyframes flash{0%,100%{background:var(--red)}50%{background:var(--yellow)}}
|
||
@keyframes float-up{0%{transform:translateY(0)}50%{transform:translateY(-8px)}100%{transform:translateY(0)}}
|
||
@keyframes scroll-bg{from{background-position:0 0}to{background-position:48px 48px}}
|
||
@keyframes pulse-border{0%,100%{box-shadow:0 0 0 0 rgba(249,215,28,.6)}50%{box-shadow:0 0 0 6px rgba(249,215,28,0)}}
|
||
@keyframes marquee{from{transform:translateX(100%)}to{transform:translateX(-100%)}}
|
||
@keyframes slidein{from{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}
|
||
@keyframes coin-spin{0%{transform:scaleX(1)}50%{transform:scaleX(.1)}100%{transform:scaleX(1)}}
|
||
|
||
/* ===== 像素小图标 (CSS box-shadow 网格) ===== */
|
||
.pix{position:relative;display:inline-block;width:16px;height:16px;vertical-align:middle}
|
||
.pix-coin{background:var(--yellow);box-shadow:0 -4px 0 var(--yellow),0 4px 0 var(--yellow),-4px 0 0 var(--yellow-d),4px 0 0 var(--yellow-d);width:8px;height:8px;margin:4px}
|
||
.pix-heart{width:12px;height:12px;background:var(--red);clip-path:polygon(50% 100%,0 50%,0 25%,25% 0,50% 25%,75% 0,100% 25%,100% 50%)}
|
||
.pix-star{width:12px;height:12px;background:var(--yellow);clip-path:polygon(50% 0,61% 35%,98% 35%,68% 57%,79% 91%,50% 70%,21% 91%,32% 57%,2% 35%,39% 35%)}
|
||
.pix-bolt{width:8px;height:12px;background:var(--yellow);clip-path:polygon(60% 0,0 70%,40% 70%,30% 100%,100% 30%,55% 30%,70% 0)}
|
||
|
||
/* 像素装饰精灵 */
|
||
.sprite{image-rendering:pixelated;display:inline-block}
|
||
|
||
/* ============================================================
|
||
HEADER
|
||
============================================================ */
|
||
.header{
|
||
position:sticky;top:0;z-index:200;
|
||
background:var(--bg-4);
|
||
border-bottom:4px solid var(--green);
|
||
box-shadow:0 4px 0 0 rgba(15,188,110,.25);
|
||
}
|
||
.header-inner{display:flex;align-items:center;gap:18px;height:74px}
|
||
.logo{display:flex;align-items:center;gap:12px;flex-shrink:0;cursor:pointer}
|
||
.logo-mark{
|
||
width:44px;height:44px;background:var(--green);
|
||
border:4px solid var(--ink);
|
||
box-shadow:3px 3px 0 0 var(--ink);
|
||
display:grid;place-items:center;
|
||
position:relative;
|
||
}
|
||
.logo-mark::before{
|
||
content:"";position:absolute;width:10px;height:10px;background:var(--yellow);
|
||
box-shadow:14px 0 0 var(--red),0 14px 0 var(--purple),14px 14px 0 var(--yellow);
|
||
top:7px;left:7px;
|
||
}
|
||
.logo-txt{
|
||
font-size:20px;font-weight:bold;letter-spacing:3px;color:var(--green);
|
||
text-shadow:3px 3px 0 var(--ink), 3px 0 0 var(--ink), 0 3px 0 var(--ink);
|
||
line-height:1;
|
||
}
|
||
.logo-txt small{display:block;font-size:9px;color:var(--yellow);letter-spacing:2px;margin-top:4px;text-shadow:2px 2px 0 var(--ink)}
|
||
|
||
.nav{display:flex;gap:6px;margin-left:10px}
|
||
.nav a{
|
||
display:inline-block;padding:9px 14px;font-size:13px;font-weight:bold;letter-spacing:2px;
|
||
color:var(--text-dim);text-transform:uppercase;border:4px solid transparent;
|
||
transition:.08s;
|
||
}
|
||
.nav a:hover{color:var(--yellow)}
|
||
.nav a.active{color:var(--ink);background:var(--yellow);box-shadow:3px 3px 0 0 var(--ink)}
|
||
|
||
.search{flex:1;max-width:420px;margin-left:auto;display:flex}
|
||
.search input{
|
||
flex:1;height:46px;background:var(--bg-2);color:var(--text);
|
||
border:4px solid var(--ink);border-right:none;
|
||
padding:0 14px;font-size:13px;letter-spacing:1px;
|
||
box-shadow:inset 3px 3px 0 0 rgba(0,0,0,.5);
|
||
}
|
||
.search input::placeholder{color:var(--text-dimer)}
|
||
.search input:focus{outline:none;background:var(--bg-3)}
|
||
.search button{
|
||
height:46px;width:54px;background:var(--green);color:var(--ink);
|
||
border:4px solid var(--ink);font-size:18px;font-weight:bold;
|
||
box-shadow:3px 3px 0 0 var(--ink);
|
||
}
|
||
.search button:active{transform:translate(3px,3px);box-shadow:0 0 0 0 var(--ink)}
|
||
|
||
.coin-counter{
|
||
display:flex;align-items:center;gap:8px;padding:8px 14px;
|
||
background:var(--bg-2);border:4px solid var(--ink);box-shadow:3px 3px 0 0 var(--ink);
|
||
font-weight:bold;color:var(--yellow);font-size:13px;letter-spacing:1px;
|
||
}
|
||
|
||
/* ============================================================
|
||
HERO
|
||
============================================================ */
|
||
.hero{
|
||
position:relative;overflow:hidden;
|
||
background:
|
||
linear-gradient(180deg,var(--bg-3) 0%,var(--bg) 100%);
|
||
border-bottom:4px solid var(--ink);
|
||
padding:70px 0 90px;
|
||
}
|
||
.hero-grid-bg{
|
||
position:absolute;inset:0;opacity:.25;pointer-events:none;
|
||
background-image:
|
||
linear-gradient(rgba(15,188,110,.18) 1px,transparent 1px),
|
||
linear-gradient(90deg,rgba(15,188,110,.18) 1px,transparent 1px);
|
||
background-size:32px 32px;
|
||
animation:scroll-bg 8s linear infinite;
|
||
}
|
||
.hero-inner{position:relative;display:grid;grid-template-columns:1.2fr .8fr;gap:40px;align-items:center}
|
||
.hero-title{
|
||
font-size:clamp(40px,7vw,84px);font-weight:bold;letter-spacing:6px;line-height:1;
|
||
color:var(--green);text-shadow:6px 6px 0 var(--ink),6px 0 0 var(--ink),0 6px 0 var(--ink);
|
||
margin-bottom:18px;
|
||
}
|
||
.hero-title .y{color:var(--yellow)}
|
||
.hero-title .r{color:var(--red)}
|
||
.hero-sub{
|
||
font-size:14px;letter-spacing:3px;color:var(--text-dim);margin-bottom:10px;
|
||
}
|
||
.press-start{
|
||
font-size:clamp(22px,4vw,38px);font-weight:bold;letter-spacing:5px;
|
||
color:var(--yellow);text-shadow:4px 4px 0 var(--ink);
|
||
margin:18px 0 26px;min-height:1.2em;
|
||
}
|
||
.hero-tags{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:28px}
|
||
.hero-tag{
|
||
padding:6px 12px;font-size:11px;letter-spacing:1px;
|
||
background:var(--bg-2);border:3px solid var(--ink);box-shadow:2px 2px 0 0 var(--ink);
|
||
color:var(--green);
|
||
}
|
||
.hero-cta{display:flex;gap:16px;flex-wrap:wrap;align-items:center}
|
||
.hero-coin{font-size:12px;color:var(--text-dim);letter-spacing:1px;display:flex;align-items:center;gap:8px}
|
||
|
||
/* 像素装饰场景 (右侧) */
|
||
.hero-scene{display:flex;justify-content:center;align-items:flex-end;gap:18px;min-height:260px;position:relative}
|
||
.scene-cloud{position:absolute;background:#fff;opacity:.5}
|
||
.scene-cloud.c1{width:40px;height:14px;top:10px;left:10%;box-shadow:-10px 0 0 #fff,10px -8px 0 #fff}
|
||
.scene-cloud.c2{width:30px;height:10px;top:40px;right:12%;box-shadow:-8px 0 0 #fff,8px -6px 0 #fff;opacity:.35}
|
||
.scene-ground{
|
||
position:absolute;bottom:0;left:0;right:0;height:34px;
|
||
background:repeating-linear-gradient(90deg,var(--green-d) 0 16px,var(--green) 16px 32px);
|
||
border-top:4px solid var(--ink);
|
||
}
|
||
.scene-char{
|
||
width:64px;height:84px;position:relative;animation:float-up 2.2s ease-in-out infinite;
|
||
}
|
||
.scene-brick{
|
||
width:36px;height:36px;background:var(--red);border:4px solid var(--ink);
|
||
box-shadow:inset 4px 4px 0 rgba(255,255,255,.25),3px 3px 0 var(--ink);
|
||
position:relative;
|
||
}
|
||
.scene-brick::after{content:"";position:absolute;inset:6px;border:3px solid var(--red-d)}
|
||
.scene-pipe{
|
||
width:44px;height:70px;background:var(--green);border:4px solid var(--ink);
|
||
box-shadow:inset 4px 4px 0 rgba(255,255,255,.2),3px 3px 0 var(--ink);
|
||
}
|
||
.scene-pipe::before{content:"";display:block;height:14px;background:var(--green-l);border-bottom:4px solid var(--ink)}
|
||
.scene-coin{width:18px;height:18px;background:var(--yellow);border:3px solid var(--ink);box-shadow:inset 3px 0 0 var(--yellow-d);animation:coin-spin 1.4s steps(2) infinite;margin-top:10px}
|
||
|
||
/* 滚动公告条 */
|
||
.ticker{
|
||
background:var(--ink);border-bottom:4px solid var(--ink);
|
||
overflow:hidden;white-space:nowrap;
|
||
}
|
||
.ticker-track{display:inline-block;padding:9px 0;font-size:12px;letter-spacing:2px;color:var(--yellow);animation:marquee 22s linear infinite}
|
||
.ticker-track span{margin:0 30px}
|
||
.ticker-track .r{color:var(--red)}
|
||
.ticker-track .g{color:var(--green-l)}
|
||
|
||
/* ============================================================
|
||
SECTION 通用
|
||
============================================================ */
|
||
section{padding:54px 0}
|
||
.sec-head{display:flex;align-items:center;gap:14px;margin-bottom:30px;flex-wrap:wrap}
|
||
.sec-title{
|
||
font-size:22px;font-weight:bold;letter-spacing:3px;text-transform:uppercase;
|
||
color:var(--yellow);text-shadow:3px 3px 0 var(--ink);
|
||
display:flex;align-items:center;gap:12px;
|
||
}
|
||
.sec-title::before{content:"";display:inline-block;width:14px;height:24px;background:var(--red);box-shadow:0 0 0 3px var(--ink),4px 4px 0 var(--ink)}
|
||
.sec-sub{font-size:11px;color:var(--text-dim);letter-spacing:2px}
|
||
.sec-line{flex:1;height:4px;background:repeating-linear-gradient(90deg,var(--green-d) 0 8px,transparent 8px 16px)}
|
||
|
||
/* ============================================================
|
||
CATEGORIES
|
||
============================================================ */
|
||
.cats{display:flex;gap:10px;flex-wrap:wrap;padding:26px}
|
||
.cat-btn{
|
||
padding:10px 18px;font-size:13px;font-weight:bold;letter-spacing:2px;
|
||
background:var(--bg-3);color:var(--text-dim);
|
||
border:4px solid var(--ink);box-shadow:3px 3px 0 0 var(--ink),inset -3px -3px 0 rgba(0,0,0,.4);
|
||
cursor:pointer;transition:.06s;display:flex;align-items:center;gap:8px;
|
||
}
|
||
.cat-btn:hover{color:var(--yellow);transform:translate(-1px,-1px);box-shadow:4px 4px 0 0 var(--ink)}
|
||
.cat-btn:active{transform:translate(3px,3px);box-shadow:0 0 0 0 var(--ink)}
|
||
.cat-btn.active{background:var(--purple);color:#fff;box-shadow:3px 3px 0 0 var(--ink),inset -3px -3px 0 rgba(0,0,0,.3),inset 3px 3px 0 rgba(255,255,255,.15)}
|
||
.cat-btn .ci{font-size:16px;line-height:1}
|
||
|
||
/* ============================================================
|
||
HOT — 高分榜
|
||
============================================================ */
|
||
.hot-grid{display:grid;grid-template-columns:1.3fr 1fr;gap:26px}
|
||
.scoreboard{
|
||
background:var(--bg-2);border:4px solid var(--ink);
|
||
box-shadow:6px 6px 0 0 var(--shadow),inset -4px -4px 0 rgba(0,0,0,.4),inset 4px 4px 0 rgba(255,255,255,.05);
|
||
}
|
||
.score-head{
|
||
display:grid;grid-template-columns:60px 1fr 130px 110px 80px;gap:10px;
|
||
padding:12px 16px;background:var(--bg-4);border-bottom:4px solid var(--ink);
|
||
font-size:11px;letter-spacing:2px;color:var(--green);font-weight:bold;
|
||
}
|
||
.score-row{
|
||
display:grid;grid-template-columns:60px 1fr 130px 110px 80px;gap:10px;
|
||
padding:13px 16px;border-bottom:3px solid var(--bg-4);
|
||
align-items:center;cursor:pointer;transition:.08s;
|
||
}
|
||
.score-row:hover{background:var(--bg-3);padding-left:20px}
|
||
.score-row:last-child{border-bottom:none}
|
||
.score-rank{font-size:22px;font-weight:bold;letter-spacing:1px}
|
||
.rank-1{color:var(--yellow);text-shadow:2px 2px 0 var(--ink)}
|
||
.rank-2{color:#c0c0d0;text-shadow:2px 2px 0 var(--ink)}
|
||
.rank-3{color:var(--red);text-shadow:2px 2px 0 var(--ink)}
|
||
.rank-oth{color:var(--text-dimer)}
|
||
.score-name{font-size:14px;font-weight:bold;color:var(--text);letter-spacing:1px;display:flex;align-items:center;gap:8px}
|
||
.score-name .tag-hot{font-size:9px;background:var(--red);color:#fff;padding:2px 5px;letter-spacing:1px}
|
||
.score-rate{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--yellow)}
|
||
.score-plays{font-size:12px;color:var(--cyan);letter-spacing:1px}
|
||
.score-go{font-size:11px;color:var(--green);letter-spacing:1px;text-align:right}
|
||
.score-row:hover .score-go{color:var(--yellow)}
|
||
|
||
/* 高分榜侧栏 */
|
||
.hot-side{display:flex;flex-direction:column;gap:18px}
|
||
.featured-card{
|
||
background:var(--bg-2);border:4px solid var(--ink);
|
||
box-shadow:6px 6px 0 0 var(--shadow);overflow:hidden;
|
||
}
|
||
.featured-cover{height:170px;background:var(--bg-3);position:relative;overflow:hidden}
|
||
.featured-cover img{width:100%;height:100%;object-fit:cover}
|
||
.featured-badge{position:absolute;top:10px;left:10px;background:var(--red);color:#fff;font-size:10px;padding:4px 8px;letter-spacing:1px;border:3px solid var(--ink);box-shadow:2px 2px 0 var(--ink);animation:blink-soft 1.4s steps(1) infinite}
|
||
.featured-body{padding:16px}
|
||
.featured-body h3{font-size:16px;letter-spacing:1px;color:var(--yellow);margin-bottom:8px;text-shadow:2px 2px 0 var(--ink)}
|
||
.featured-body p{font-size:12px;color:var(--text-dim);line-height:1.6;letter-spacing:.5px;margin-bottom:12px}
|
||
.featured-meta{display:flex;gap:10px;flex-wrap:wrap;font-size:11px;color:var(--green)}
|
||
|
||
/* ============================================================
|
||
NEW GAMES — 新游速报
|
||
============================================================ */
|
||
.new-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:22px}
|
||
.new-card{
|
||
background:var(--bg-2);border:4px solid var(--ink);
|
||
box-shadow:5px 5px 0 0 var(--shadow);
|
||
cursor:pointer;transition:.08s;position:relative;overflow:hidden;
|
||
}
|
||
.new-card:hover{transform:translate(-2px,-2px);box-shadow:7px 7px 0 0 var(--shadow)}
|
||
.new-cover{height:150px;background:var(--bg-3);position:relative;overflow:hidden;border-bottom:4px solid var(--ink)}
|
||
.new-cover img{width:100%;height:100%;object-fit:cover}
|
||
.new-cover .cover-px{position:absolute;inset:0}
|
||
.new-badge{
|
||
position:absolute;top:-2px;right:-2px;background:var(--yellow);color:var(--ink);
|
||
font-size:11px;font-weight:bold;padding:6px 10px;letter-spacing:1px;
|
||
border:4px solid var(--ink);box-shadow:0 4px 0 var(--ink);
|
||
animation:flash-bg 1.5s steps(1) infinite;
|
||
}
|
||
@keyframes flash-bg{0%,100%{background:var(--yellow);color:var(--ink)}50%{background:var(--red);color:#fff}}
|
||
.new-body{padding:14px}
|
||
.new-body h4{font-size:14px;color:var(--green);letter-spacing:1px;margin-bottom:6px;text-shadow:2px 2px 0 var(--ink)}
|
||
.new-body .dev{font-size:11px;color:var(--text-dimer);margin-bottom:8px}
|
||
.new-tags{display:flex;gap:6px;flex-wrap:wrap}
|
||
.new-tags span{font-size:10px;padding:3px 6px;background:var(--bg-4);border:2px solid var(--ink);color:var(--cyan);letter-spacing:.5px}
|
||
|
||
/* ============================================================
|
||
LIBRARY — 游戏仓库
|
||
============================================================ */
|
||
.lib-bar{
|
||
display:flex;gap:14px;flex-wrap:wrap;align-items:center;margin-bottom:26px;
|
||
padding:18px;background:var(--bg-2);border:4px solid var(--ink);
|
||
box-shadow:5px 5px 0 0 var(--shadow);
|
||
}
|
||
.lib-search{display:flex;flex:1;min-width:240px}
|
||
.lib-search input{
|
||
flex:1;height:44px;background:var(--bg-4);border:4px solid var(--ink);border-right:none;
|
||
padding:0 14px;color:var(--text);font-size:13px;box-shadow:inset 3px 3px 0 rgba(0,0,0,.5);
|
||
}
|
||
.lib-search input:focus{outline:none;background:var(--bg-3)}
|
||
.lib-search button{height:44px;width:50px;background:var(--purple);color:#fff;border:4px solid var(--ink);box-shadow:3px 3px 0 var(--ink);font-size:16px}
|
||
.lib-search button:active{transform:translate(3px,3px);box-shadow:0 0 0 0 var(--ink)}
|
||
.lib-select{position:relative}
|
||
.lib-select select{
|
||
height:44px;background:var(--bg-4);border:4px solid var(--ink);color:var(--text);
|
||
padding:0 34px 0 14px;font-size:12px;letter-spacing:1px;font-weight:bold;
|
||
box-shadow:3px 3px 0 var(--ink);appearance:none;cursor:pointer;
|
||
}
|
||
.lib-select::after{content:"▼";position:absolute;right:12px;top:50%;transform:translateY(-50%);color:var(--green);font-size:10px;pointer-events:none}
|
||
.lib-select select:focus{outline:none;background:var(--bg-3)}
|
||
.lib-count{font-size:12px;color:var(--text-dim);letter-spacing:1px}
|
||
.lib-count b{color:var(--yellow)}
|
||
|
||
.game-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:22px}
|
||
.game-card{
|
||
background:var(--bg-2);border:4px solid var(--ink);box-shadow:5px 5px 0 0 var(--shadow);
|
||
cursor:pointer;transition:.08s;display:flex;flex-direction:column;
|
||
}
|
||
.game-card:hover{transform:translate(-2px,-2px);box-shadow:7px 7px 0 0 var(--shadow);border-color:var(--green)}
|
||
.gcard-cover{height:170px;background:var(--bg-3);position:relative;overflow:hidden;border-bottom:4px solid var(--ink)}
|
||
.gcard-cover img{width:100%;height:100%;object-fit:cover}
|
||
.gcard-cover .ph{position:absolute;inset:0;display:grid;place-items:center;font-size:11px;color:var(--text-dimer);letter-spacing:1px}
|
||
.gcard-badges{position:absolute;top:8px;left:8px;display:flex;gap:6px;flex-direction:column}
|
||
.gbadge{font-size:9px;padding:3px 6px;letter-spacing:1px;border:2px solid var(--ink);font-weight:bold}
|
||
.gbadge-hot{background:var(--red);color:#fff}
|
||
.gbadge-new{background:var(--yellow);color:var(--ink)}
|
||
.gbadge-cat{background:var(--purple);color:#fff}
|
||
.gcard-rating{position:absolute;bottom:8px;right:8px;background:var(--ink);color:var(--yellow);font-size:11px;padding:3px 7px;border:2px solid var(--yellow);letter-spacing:1px;font-weight:bold}
|
||
.gcard-body{padding:13px;flex:1;display:flex;flex-direction:column}
|
||
.gcard-name{font-size:14px;color:var(--green);letter-spacing:1px;margin-bottom:6px;font-weight:bold;text-shadow:1px 1px 0 var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||
.gcard-dev{font-size:11px;color:var(--text-dimer);margin-bottom:8px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||
.gcard-tags{display:flex;gap:5px;flex-wrap:wrap;margin-bottom:10px}
|
||
.gcard-tags span{font-size:9px;padding:2px 5px;background:var(--bg-4);border:2px solid var(--ink);color:var(--cyan);letter-spacing:.5px}
|
||
.gcard-foot{display:flex;justify-content:space-between;align-items:center;margin-top:auto;padding-top:8px;border-top:3px solid var(--bg-4);font-size:11px}
|
||
.gcard-plays{color:var(--cyan)}
|
||
.gcard-size{color:var(--text-dimer)}
|
||
|
||
/* 空状态 / 加载 */
|
||
.empty-state{text-align:center;padding:60px 20px;color:var(--text-dim)}
|
||
.empty-state .es-icon{font-size:40px;margin-bottom:14px;color:var(--purple)}
|
||
.empty-state p{font-size:13px;letter-spacing:1px}
|
||
.loading-px{display:flex;justify-content:center;align-items:center;padding:50px;gap:10px}
|
||
.ld{width:14px;height:14px;background:var(--green);box-shadow:0 0 0 3px var(--ink);animation:ld 1s steps(1) infinite}
|
||
.ld:nth-child(2){animation-delay:.2s;background:var(--yellow)}
|
||
.ld:nth-child(3){animation-delay:.4s;background:var(--red)}
|
||
.ld:nth-child(4){animation-delay:.6s;background:var(--purple)}
|
||
@keyframes ld{0%,100%{opacity:.2;transform:translateY(0)}50%{opacity:1;transform:translateY(-8px)}}
|
||
|
||
/* 分页 */
|
||
.pagination{display:flex;justify-content:center;gap:8px;margin-top:34px;flex-wrap:wrap}
|
||
.page-btn{
|
||
min-width:42px;height:42px;padding:0 10px;
|
||
background:var(--bg-2);color:var(--text);font-weight:bold;font-size:13px;letter-spacing:1px;
|
||
border:4px solid var(--ink);box-shadow:3px 3px 0 0 var(--ink);
|
||
cursor:pointer;display:grid;place-items:center;transition:.06s;
|
||
}
|
||
.page-btn:hover:not(:disabled){background:var(--bg-3);transform:translate(-1px,-1px);box-shadow:4px 4px 0 0 var(--ink)}
|
||
.page-btn:active:not(:disabled){transform:translate(3px,3px);box-shadow:0 0 0 0 var(--ink)}
|
||
.page-btn.active{background:var(--green);color:var(--ink)}
|
||
.page-btn:disabled{opacity:.3;cursor:not-allowed;box-shadow:3px 3px 0 0 rgba(0,0,0,.3)}
|
||
.page-dots{color:var(--text-dimer);align-self:center;padding:0 4px}
|
||
|
||
/* ============================================================
|
||
MODAL — 像素对话框
|
||
============================================================ */
|
||
.modal-mask{
|
||
position:fixed;inset:0;z-index:5000;display:none;
|
||
background:rgba(0,0,0,.82);align-items:center;justify-content:center;padding:20px;
|
||
}
|
||
.modal-mask.open{display:flex;animation:slidein .15s ease}
|
||
.modal{
|
||
width:min(880px,100%);max-height:90vh;overflow-y:auto;
|
||
background:var(--bg-2);border:6px solid var(--ink);
|
||
box-shadow:10px 10px 0 0 var(--shadow),0 0 0 6px var(--green),0 0 0 10px var(--ink);
|
||
position:relative;
|
||
}
|
||
.modal-titlebar{
|
||
display:flex;align-items:center;justify-content:space-between;
|
||
padding:12px 18px;background:var(--green);color:var(--ink);
|
||
border-bottom:6px solid var(--ink);font-weight:bold;letter-spacing:2px;font-size:14px;
|
||
}
|
||
.modal-titlebar .dots{display:flex;gap:6px}
|
||
.modal-titlebar .dots i{display:block;width:12px;height:12px;border:2px solid var(--ink)}
|
||
.modal-titlebar .dots i:nth-child(1){background:var(--red)}
|
||
.modal-titlebar .dots i:nth-child(2){background:var(--yellow)}
|
||
.modal-titlebar .dots i:nth-child(3){background:var(--green-l)}
|
||
.modal-close{
|
||
width:32px;height:32px;background:var(--red);color:#fff;font-weight:bold;font-size:16px;
|
||
border:3px solid var(--ink);box-shadow:2px 2px 0 var(--ink);display:grid;place-items:center;
|
||
}
|
||
.modal-close:active{transform:translate(2px,2px);box-shadow:0 0 0 0 var(--ink)}
|
||
.modal-body{padding:24px}
|
||
.modal-top{display:grid;grid-template-columns:280px 1fr;gap:24px;margin-bottom:22px}
|
||
.modal-cover{height:300px;background:var(--bg-3);border:4px solid var(--ink);overflow:hidden;position:relative;box-shadow:4px 4px 0 var(--ink)}
|
||
.modal-cover img{width:100%;height:100%;object-fit:cover}
|
||
.modal-info h2{font-size:24px;color:var(--yellow);letter-spacing:2px;margin-bottom:8px;text-shadow:3px 3px 0 var(--ink)}
|
||
.modal-info .m-dev{font-size:12px;color:var(--text-dim);margin-bottom:14px}
|
||
.modal-rate{display:flex;align-items:center;gap:10px;margin-bottom:14px}
|
||
.modal-rate .rate-val{font-size:20px;color:var(--yellow);font-weight:bold}
|
||
.modal-info .m-tags{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:16px}
|
||
.modal-info .m-tags span{font-size:11px;padding:3px 8px;background:var(--bg-4);border:2px solid var(--ink);color:var(--cyan)}
|
||
.m-meta{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:18px}
|
||
.m-meta-item{background:var(--bg-4);border:3px solid var(--ink);padding:8px 10px}
|
||
.m-meta-item label{display:block;font-size:10px;color:var(--text-dimer);letter-spacing:1px;margin-bottom:3px}
|
||
.m-meta-item span{font-size:12px;color:var(--green);font-weight:bold;letter-spacing:.5px}
|
||
.modal-desc{font-size:13px;color:var(--text);line-height:1.8;letter-spacing:.5px;margin-bottom:18px;background:var(--bg-4);border:3px solid var(--ink);padding:14px}
|
||
.modal-desc .lbl{color:var(--yellow);font-weight:bold;letter-spacing:2px;display:block;margin-bottom:6px}
|
||
.modal-features{margin-bottom:18px}
|
||
.modal-features .lbl{color:var(--purple);font-weight:bold;letter-spacing:2px;font-size:12px;margin-bottom:8px}
|
||
.modal-features ul{display:flex;flex-direction:column;gap:6px}
|
||
.modal-features li{font-size:12px;color:var(--text);letter-spacing:.5px;padding-left:18px;position:relative}
|
||
.modal-features li::before{content:"▶";position:absolute;left:0;color:var(--green)}
|
||
.modal-shots{margin-bottom:20px}
|
||
.modal-shots .lbl{color:var(--cyan);font-weight:bold;letter-spacing:2px;font-size:12px;margin-bottom:8px}
|
||
.shots-row{display:flex;gap:10px;overflow-x:auto;padding-bottom:6px}
|
||
.shots-row img{width:200px;height:120px;object-fit:cover;border:3px solid var(--ink);flex-shrink:0;box-shadow:3px 3px 0 var(--ink)}
|
||
.modal-actions{display:flex;gap:12px;flex-wrap:wrap;padding-top:16px;border-top:4px solid var(--bg-4)}
|
||
|
||
/* ============================================================
|
||
FOOTER
|
||
============================================================ */
|
||
.footer{
|
||
background:var(--bg-4);border-top:4px solid var(--green);padding:50px 0 24px;margin-top:30px;
|
||
}
|
||
.foot-grid{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:34px;margin-bottom:34px}
|
||
.foot-brand .logo-txt{font-size:18px}
|
||
.foot-brand p{font-size:12px;color:var(--text-dim);line-height:1.7;margin-top:14px;letter-spacing:.5px}
|
||
.foot-col h5{font-size:12px;color:var(--yellow);letter-spacing:2px;margin-bottom:14px;text-shadow:2px 2px 0 var(--ink)}
|
||
.foot-col a{display:block;font-size:12px;color:var(--text-dim);padding:5px 0;letter-spacing:.5px;transition:.08s}
|
||
.foot-col a:hover{color:var(--green-l);transform:translateX(3px)}
|
||
.foot-bottom{
|
||
border-top:3px solid var(--bg-2);padding-top:20px;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:10px;
|
||
}
|
||
.foot-bottom p{font-size:11px;color:var(--text-dimer);letter-spacing:1px}
|
||
.foot-press{font-size:11px;color:var(--green);letter-spacing:2px}
|
||
|
||
/* 返回顶部 */
|
||
.to-top{
|
||
position:fixed;right:22px;bottom:22px;z-index:400;width:54px;height:54px;
|
||
background:var(--yellow);color:var(--ink);border:4px solid var(--ink);
|
||
box-shadow:4px 4px 0 0 var(--ink);display:none;place-items:center;font-weight:bold;font-size:18px;
|
||
}
|
||
.to-top.show{display:grid}
|
||
.to-top:active{transform:translate(4px,4px);box-shadow:0 0 0 0 var(--ink)}
|
||
|
||
/* ===== 响应式 ===== */
|
||
@media (max-width:1024px){
|
||
.hero-inner{grid-template-columns:1fr}
|
||
.hero-scene{min-height:200px;order:-1}
|
||
.hot-grid{grid-template-columns:1fr}
|
||
.new-grid,.game-grid{grid-template-columns:repeat(2,1fr)}
|
||
.modal-top{grid-template-columns:1fr}
|
||
.modal-cover{height:220px}
|
||
.foot-grid{grid-template-columns:1fr 1fr}
|
||
.nav{display:none}
|
||
}
|
||
@media (max-width:640px){
|
||
.header-inner{height:auto;padding:12px 0;flex-wrap:wrap}
|
||
.search{order:3;width:100%;max-width:none;flex-basis:100%}
|
||
.coin-counter{display:none}
|
||
.new-grid,.game-grid{grid-template-columns:1fr}
|
||
.score-head,.score-row{grid-template-columns:40px 1fr 70px;gap:6px}
|
||
.score-head .h-rate,.score-head .h-go,.score-rate,.score-go{display:none}
|
||
.score-plays{font-size:11px}
|
||
.m-meta{grid-template-columns:1fr}
|
||
.sec-title{font-size:18px}
|
||
.lib-bar{flex-direction:column;align-items:stretch}
|
||
.lib-select select{width:100%}
|
||
.hero{padding:40px 0 60px}
|
||
.foot-grid{grid-template-columns:1fr}
|
||
.foot-bottom{flex-direction:column;text-align:center}
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- CRT 屏幕特效 -->
|
||
<div class="crt-overlay"></div>
|
||
<div class="crt-vignette"></div>
|
||
<div class="crt-flicker"></div>
|
||
|
||
<!-- ===== HEADER ===== -->
|
||
<header class="header">
|
||
<div class="container header-inner">
|
||
<div class="logo" onclick="scrollTop2()">
|
||
<div class="logo-mark"></div>
|
||
<div class="logo-txt">PIXEL GAMES<small>像素游戏厅</small></div>
|
||
</div>
|
||
<nav class="nav" id="nav">
|
||
<a href="#" class="active" data-nav="home">首页</a>
|
||
<a href="#library" data-nav="lib">游戏库</a>
|
||
<a href="#hot" data-nav="rank">排行榜</a>
|
||
<a href="#new" data-nav="new">新游</a>
|
||
</nav>
|
||
<form class="search" id="navSearch" onsubmit="return false">
|
||
<input type="text" id="navSearchInput" placeholder="搜索游戏..." aria-label="搜索">
|
||
<button type="submit" aria-label="搜索">Q</button>
|
||
</form>
|
||
<div class="coin-counter" title="游戏币"><span class="pix pix-coin"></span><span id="coinCount">9999</span></div>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- ===== HERO ===== -->
|
||
<section class="hero">
|
||
<div class="hero-grid-bg"></div>
|
||
<div class="container hero-inner">
|
||
<div class="hero-text">
|
||
<div class="hero-sub">▸ INSERT COIN TO PLAY ◂</div>
|
||
<h1 class="hero-title"><span class="y">像素</span> · <span class="r">世界</span></h1>
|
||
<div class="press-start blink">PRESS START</div>
|
||
<div class="hero-tags">
|
||
<span class="hero-tag">▸ 8-BIT 复古</span>
|
||
<span class="hero-tag">▸ 海量游戏</span>
|
||
<span class="hero-tag">▸ 极速下载</span>
|
||
<span class="hero-tag">▸ 玩家社区</span>
|
||
</div>
|
||
<div class="hero-cta">
|
||
<button class="pbtn pbtn-yellow" onclick="scrollTo2('library')">开始游戏 ▶</button>
|
||
<button class="pbtn pbtn-ghost" onclick="scrollTo2('hot')">查看排行</button>
|
||
<span class="hero-coin"><span class="pix pix-coin"></span> 每日登录 +100 币</span>
|
||
</div>
|
||
</div>
|
||
<div class="hero-scene" aria-hidden="true">
|
||
<div class="scene-cloud c1"></div>
|
||
<div class="scene-cloud c2"></div>
|
||
<div class="scene-brick"></div>
|
||
<div class="scene-char" id="heroChar"></div>
|
||
<div class="scene-pipe"></div>
|
||
<div class="scene-coin"></div>
|
||
<div class="scene-ground"></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 滚动公告 -->
|
||
<div class="ticker">
|
||
<div class="ticker-track" id="tickerTrack">
|
||
<span class="r">★ HOT</span><span>《龙之传说》已登顶本周排行榜</span>
|
||
<span class="g">● NEW</span><span>《星际远征》正式上线,立即下载体验</span>
|
||
<span class="r">★ EVENT</span><span>周末双倍经验活动开启中</span>
|
||
<span class="g">● TIP</span><span>每日签到领取免费游戏币</span>
|
||
<span class="r">★ UPDATE</span><span>《暗影刺客》v2.1.0 更新发布</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ===== CATEGORIES ===== -->
|
||
<section style="padding:0">
|
||
<div class="container">
|
||
<div class="pbox clip-corner" style="margin-top:30px">
|
||
<div class="cats" id="catsWrap">
|
||
<div class="loading-px"><span class="ld"></span><span class="ld"></span><span class="ld"></span><span class="ld"></span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===== HOT 高分榜 ===== -->
|
||
<section id="hot">
|
||
<div class="container">
|
||
<div class="sec-head">
|
||
<h2 class="sec-title">热门排行榜</h2>
|
||
<span class="sec-sub">HIGH SCORE TABLE</span>
|
||
<span class="sec-line"></span>
|
||
</div>
|
||
<div class="hot-grid">
|
||
<div class="scoreboard" id="scoreboard">
|
||
<div class="score-head">
|
||
<span>RANK</span><span>游戏名称</span><span class="h-rate">评分</span><span>游玩次数</span><span class="h-go"></span>
|
||
</div>
|
||
<div id="scoreRows">
|
||
<div class="loading-px"><span class="ld"></span><span class="ld"></span><span class="ld"></span><span class="ld"></span></div>
|
||
</div>
|
||
</div>
|
||
<div class="hot-side" id="hotSide">
|
||
<div class="loading-px"><span class="ld"></span><span class="ld"></span><span class="ld"></span><span class="ld"></span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===== NEW 新游速报 ===== -->
|
||
<section id="new" style="background:var(--bg-4);border-top:4px solid var(--ink);border-bottom:4px solid var(--ink)">
|
||
<div class="container">
|
||
<div class="sec-head">
|
||
<h2 class="sec-title">新游速报</h2>
|
||
<span class="sec-sub">NEW RELEASES</span>
|
||
<span class="sec-line"></span>
|
||
</div>
|
||
<div class="new-grid" id="newGrid">
|
||
<div class="loading-px"><span class="ld"></span><span class="ld"></span><span class="ld"></span><span class="ld"></span></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===== LIBRARY 游戏仓库 ===== -->
|
||
<section id="library">
|
||
<div class="container">
|
||
<div class="sec-head">
|
||
<h2 class="sec-title">游戏仓库</h2>
|
||
<span class="sec-sub">GAME LIBRARY</span>
|
||
<span class="sec-line"></span>
|
||
</div>
|
||
|
||
<div class="lib-bar">
|
||
<div class="lib-search">
|
||
<input type="text" id="libSearch" placeholder="输入游戏名称或关键词..." aria-label="搜索游戏">
|
||
<button onclick="onLibSearch()">Q</button>
|
||
</div>
|
||
<div class="lib-select">
|
||
<select id="libSort" onchange="onLibSort()">
|
||
<option value="">默认排序</option>
|
||
<option value="rating">评分最高</option>
|
||
<option value="plays">最多游玩</option>
|
||
<option value="newest">最新发布</option>
|
||
</select>
|
||
</div>
|
||
<div class="lib-select">
|
||
<select id="libCat" onchange="onLibCat()">
|
||
<option value="">全部分类</option>
|
||
</select>
|
||
</div>
|
||
<div class="lib-count">共 <b id="libTotal">0</b> 款游戏</div>
|
||
</div>
|
||
|
||
<div class="game-grid" id="gameGrid">
|
||
<div class="loading-px"><span class="ld"></span><span class="ld"></span><span class="ld"></span><span class="ld"></span></div>
|
||
</div>
|
||
|
||
<div class="pagination" id="pagination"></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ===== FOOTER ===== -->
|
||
<footer class="footer">
|
||
<div class="container">
|
||
<div class="foot-grid">
|
||
<div class="foot-brand">
|
||
<div class="logo-txt">PIXEL GAMES</div>
|
||
<p>复古像素风游戏平台 · 汇集海量经典与独立游戏 · 为玩家打造纯粹的 8-BIT 游戏体验。INSERT COIN, PRESS START, 享受游戏本来的乐趣。</p>
|
||
</div>
|
||
<div class="foot-col">
|
||
<h5>游戏中心</h5>
|
||
<a href="#library">游戏仓库</a>
|
||
<a href="#hot">热门排行</a>
|
||
<a href="#new">新游速报</a>
|
||
<a href="#" onclick="return false">分类浏览</a>
|
||
</div>
|
||
<div class="foot-col">
|
||
<h5>玩家社区</h5>
|
||
<a href="#" onclick="return false">玩家论坛</a>
|
||
<a href="#" onclick="return false">攻略中心</a>
|
||
<a href="#" onclick="return false">评分评价</a>
|
||
<a href="#" onclick="return false">创作工坊</a>
|
||
</div>
|
||
<div class="foot-col">
|
||
<h5>关于我们</h5>
|
||
<a href="#" onclick="return false">关于平台</a>
|
||
<a href="#" onclick="return false">联系我们</a>
|
||
<a href="#" onclick="return false">隐私政策</a>
|
||
<a href="#" onclick="return false">服务条款</a>
|
||
</div>
|
||
</div>
|
||
<div class="foot-bottom">
|
||
<p>© 2026 PIXEL GAMES · 像素游戏厅 · 保留所有权利</p>
|
||
<p class="foot-press blink">▲ PRESS START ▲</p>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
|
||
<!-- ===== MODAL ===== -->
|
||
<div class="modal-mask" id="modalMask" onclick="if(event.target===this)closeModal()">
|
||
<div class="modal" role="dialog" aria-modal="true">
|
||
<div class="modal-titlebar">
|
||
<span class="dots"><i></i><i></i><i></i></span>
|
||
<span id="modalTitle">游戏详情</span>
|
||
<button class="modal-close" onclick="closeModal()" aria-label="关闭">X</button>
|
||
</div>
|
||
<div class="modal-body" id="modalBody">
|
||
<div class="loading-px"><span class="ld"></span><span class="ld"></span><span class="ld"></span><span class="ld"></span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 返回顶部 -->
|
||
<button class="to-top" id="toTop" onclick="scrollTop2()" aria-label="返回顶部">▲</button>
|
||
|
||
<script>
|
||
/* ============================================================
|
||
PIXEL GAMES — 前端逻辑
|
||
============================================================ */
|
||
|
||
var API = '/api/v1/game';
|
||
|
||
/* ---------- 工具函数 ---------- */
|
||
function formatNum(n){
|
||
n = Number(n)||0;
|
||
if(n>=100000000) return (n/100000000).toFixed(1).replace(/\.0$/,'')+'亿';
|
||
if(n>=10000) return (n/10000).toFixed(1).replace(/\.0$/,'')+'万';
|
||
return String(n);
|
||
}
|
||
function parseJSON(str, fallback){
|
||
try{ return JSON.parse(str); }catch(e){ return fallback; }
|
||
}
|
||
function escapeHTML(s){
|
||
if(s==null) return '';
|
||
return String(s).replace(/[&<>"']/g, function(c){
|
||
return {'&':'&','<':'<','>':'>','"':'"',"'":'''}[c];
|
||
});
|
||
}
|
||
// 像素评分条:10 格 █/░
|
||
function ratingBlocks(rating){
|
||
var r = Number(rating)||0;
|
||
var filled = Math.round(r*2); // 0..10
|
||
var s = '';
|
||
for(var i=0;i<10;i++){ s += i<filled ? '█' : '░'; }
|
||
return '<span class="rb-fill">'+s.slice(0,filled)+'</span><span class="rb-empty">'+s.slice(filled)+'</span>';
|
||
}
|
||
function coverHTML(g, cls){
|
||
var c = g && g.cover ? g.cover : '';
|
||
if(c){
|
||
return '<img src="'+escapeHTML(c)+'" alt="'+escapeHTML(g.name||'')+'" onerror="this.style.display=\'none\';this.nextElementSibling.style.display=\'grid\'"><div class="ph" style="display:none">'+escapeHTML((g.name||'PIXEL').slice(0,4))+'</div>';
|
||
}
|
||
return '<div class="ph">'+escapeHTML((g&&g.name||'PIXEL').slice(0,6))+'</div>';
|
||
}
|
||
|
||
/* ---------- API 封装 ---------- */
|
||
function apiGet(path){
|
||
return fetch(path, {headers:{'Accept':'application/json'}})
|
||
.then(function(r){ if(!r.ok) throw new Error('HTTP '+r.status); return r.json(); })
|
||
.then(function(res){
|
||
if(res && Object.prototype.hasOwnProperty.call(res,'code')){
|
||
if(res.code!==0) throw new Error(res.message||'API错误');
|
||
return res.data;
|
||
}
|
||
return res; // 直接返回数组/对象
|
||
});
|
||
}
|
||
|
||
/* ---------- 状态 ---------- */
|
||
var state = {
|
||
cats: [],
|
||
lib: { list:[], total:0, page:1, page_size:12, keyword:'', sort:'', category_id:'' },
|
||
homeLoaded:false
|
||
};
|
||
|
||
/* ============================================================
|
||
分类
|
||
============================================================ */
|
||
function loadCategories(){
|
||
return apiGet(API+'/categories').then(function(list){
|
||
state.cats = (list||[]).slice().sort(function(a,b){return (a.sort||0)-(b.sort||0);});
|
||
renderCats(state.cats);
|
||
renderLibCatSelect(state.cats);
|
||
}).catch(function(){
|
||
state.cats = MOCK_CATS();
|
||
renderCats(state.cats);
|
||
renderLibCatSelect(state.cats);
|
||
});
|
||
}
|
||
function MOCK_CATS(){
|
||
return [
|
||
{id:1,name:'动作',icon:'⚔',sort:1},
|
||
{id:2,name:'角色扮演',icon:'★',sort:2},
|
||
{id:3,name:'射击',icon:'◉',sort:3},
|
||
{id:4,name:'冒险',icon:'▲',sort:4},
|
||
{id:5,name:'策略',icon:'♟',sort:5},
|
||
{id:6,name:'模拟',icon:'◆',sort:6},
|
||
{id:7,name:'体育',icon:'●',sort:7},
|
||
{id:8,name:'益智',icon:'♦',sort:8}
|
||
];
|
||
}
|
||
function renderCats(cats){
|
||
var html = '<button class="cat-btn active" data-cid="" onclick="onCatClick(this,\'\')"><span class="ci">★</span>全部</button>';
|
||
cats.forEach(function(c){
|
||
html += '<button class="cat-btn" data-cid="'+c.id+'" onclick="onCatClick(this,'+c.id+')"><span class="ci">'+escapeHTML(c.icon||'◆')+'</span>'+escapeHTML(c.name)+'</button>';
|
||
});
|
||
document.getElementById('catsWrap').innerHTML = html;
|
||
}
|
||
function renderLibCatSelect(cats){
|
||
var sel = document.getElementById('libCat');
|
||
cats.forEach(function(c){
|
||
var o = document.createElement('option');
|
||
o.value = c.id; o.textContent = c.name;
|
||
sel.appendChild(o);
|
||
});
|
||
}
|
||
function onCatClick(btn, cid){
|
||
var btns = document.querySelectorAll('.cat-btn');
|
||
for(var i=0;i<btns.length;i++) btns[i].classList.remove('active');
|
||
btn.classList.add('active');
|
||
// 同步仓库分类
|
||
state.lib.category_id = cid;
|
||
var sel = document.getElementById('libCat');
|
||
sel.value = cid;
|
||
state.lib.page = 1;
|
||
loadLibrary();
|
||
scrollTo2('library');
|
||
}
|
||
|
||
/* ============================================================
|
||
首页数据 (home)
|
||
============================================================ */
|
||
function loadHome(){
|
||
return apiGet(API+'/home').then(function(d){
|
||
d = d||{};
|
||
renderCats((d.categories&&d.categories.length)?d.categories:state.cats);
|
||
renderHot(d.hot||[]);
|
||
renderNew(d.new||[]);
|
||
}).catch(function(){
|
||
// 回退:分别请求
|
||
Promise.all([
|
||
apiGet(API+'/hot?limit=8').catch(function(){return mockGames(8,true);}),
|
||
apiGet(API+'/new?limit=4').catch(function(){return mockGames(4,false,true);})
|
||
]).then(function(res){
|
||
renderHot(res[0]||[]);
|
||
renderNew(res[1]||[]);
|
||
});
|
||
});
|
||
}
|
||
|
||
/* ============================================================
|
||
热门排行榜 (高分榜)
|
||
============================================================ */
|
||
function renderHot(list){
|
||
list = (list||[]).slice(0,8);
|
||
if(!list.length){
|
||
document.getElementById('scoreRows').innerHTML = emptyHTML('暂无热门游戏数据');
|
||
document.getElementById('hotSide').innerHTML = '';
|
||
return;
|
||
}
|
||
var rows = '';
|
||
list.forEach(function(g,i){
|
||
var rk = i+1;
|
||
var rkCls = rk===1?'rank-1':rk===2?'rank-2':rk===3?'rank-3':'rank-oth';
|
||
var rkStr = rk<10?'0'+rk:''+rk;
|
||
rows += '<div class="score-row" onclick="openModal('+g.id+')">'
|
||
+ '<span class="score-rank '+rkCls+'">'+rkStr+'</span>'
|
||
+ '<span class="score-name">'+(rk<=3?'<span class="pix pix-star"></span> ':'')+escapeHTML(g.name||'')+(g.is_hot?'<span class="tag-hot">HOT</span>':'')+'</span>'
|
||
+ '<span class="score-rate"><span class="rate-val-mini">'+(Number(g.rating)||0).toFixed(1)+'</span> '+ratingBlocks(g.rating)+'</span>'
|
||
+ '<span class="score-plays">'+formatNum(g.plays)+' 次</span>'
|
||
+ '<span class="score-go">▶ 详情</span>'
|
||
+ '</div>';
|
||
});
|
||
document.getElementById('scoreRows').innerHTML = rows;
|
||
|
||
// 侧栏:第一名 + 其余前几的精选
|
||
var top = list[0];
|
||
var side = '<div class="featured-card" onclick="openModal('+top.id+')">'
|
||
+ '<div class="featured-cover">'+coverHTML(top)+'</div>'
|
||
+ '<div class="featured-badge">NO.1 王者</div>'
|
||
+ '<div class="featured-body">'
|
||
+ '<h3>'+escapeHTML(top.name||'')+'</h3>'
|
||
+ '<p>'+escapeHTML((top.description||'').slice(0,70))+'</p>'
|
||
+ '<div class="featured-meta"><span>★ '+(Number(top.rating)||0).toFixed(1)+'</span><span>▶ '+formatNum(top.plays)+'</span><span>◆ '+(top.category_name||'未知')+'</span></div>'
|
||
+ '</div></div>';
|
||
// 小榜 top3
|
||
side += '<div class="featured-card"><div class="featured-body"><div style="font-size:12px;color:var(--purple);letter-spacing:2px;margin-bottom:10px">TOP 3 速览</div>';
|
||
list.slice(0,3).forEach(function(g,i){
|
||
side += '<div onclick="openModal('+g.id+')" style="display:flex;justify-content:space-between;align-items:center;padding:8px 0;border-bottom:2px solid var(--bg-4);cursor:pointer">'
|
||
+ '<span style="font-size:12px;color:var(--green)"><b style="color:'+(i===0?'var(--yellow)':i===1?'#c0c0d0':'var(--red)')+'">0'+(i+1)+'</b> '+escapeHTML(g.name||'')+'</span>'
|
||
+ '<span style="font-size:11px;color:var(--yellow)">'+(Number(g.rating)||0).toFixed(1)+'★</span></div>';
|
||
});
|
||
side += '</div></div>';
|
||
document.getElementById('hotSide').innerHTML = side;
|
||
}
|
||
|
||
/* ============================================================
|
||
新游速报
|
||
============================================================ */
|
||
function renderNew(list){
|
||
list = (list||[]).slice(0,4);
|
||
if(!list.length){
|
||
document.getElementById('newGrid').innerHTML = emptyHTML('暂无新游数据');
|
||
return;
|
||
}
|
||
var html = '';
|
||
list.forEach(function(g){
|
||
var tags = parseJSON(g.tags,[]);
|
||
var tagHTML = tags.slice(0,3).map(function(t){return '<span>'+escapeHTML(t)+'</span>';}).join('');
|
||
html += '<div class="new-card" onclick="openModal('+g.id+')">'
|
||
+ '<div class="new-cover">'+coverHTML(g)+'<div class="new-badge">NEW!</div></div>'
|
||
+ '<div class="new-body">'
|
||
+ '<h4>'+escapeHTML(g.name||'')+'</h4>'
|
||
+ '<div class="dev">'+escapeHTML(g.developer||'未知厂商')+' · '+(g.release_date||'')+'</div>'
|
||
+ '<div class="new-tags">'+tagHTML+'</div>'
|
||
+ '</div></div>';
|
||
});
|
||
document.getElementById('newGrid').innerHTML = html;
|
||
}
|
||
|
||
/* ============================================================
|
||
游戏仓库
|
||
============================================================ */
|
||
function loadLibrary(){
|
||
var q = state.lib;
|
||
var url = API+'/games?page='+q.page+'&page_size='+q.page_size;
|
||
if(q.category_id) url += '&category_id='+encodeURIComponent(q.category_id);
|
||
if(q.keyword) url += '&keyword='+encodeURIComponent(q.keyword);
|
||
if(q.sort) url += '&sort='+encodeURIComponent(q.sort);
|
||
|
||
showLoading('gameGrid');
|
||
apiGet(url).then(function(res){
|
||
res = res||{};
|
||
q.list = res.list||[];
|
||
q.total = res.total||0;
|
||
renderLibrary();
|
||
}).catch(function(){
|
||
// 模拟回退
|
||
var all = mockGames(36);
|
||
var f = all;
|
||
if(q.category_id) f = f.filter(function(g){return String(g.category_id)===String(q.category_id);});
|
||
if(q.keyword) f = f.filter(function(g){return (g.name||'').indexOf(q.keyword)>=0 || (g.description||'').indexOf(q.keyword)>=0;});
|
||
if(q.sort==='rating') f.sort(function(a,b){return (b.rating||0)-(a.rating||0);});
|
||
else if(q.sort==='plays') f.sort(function(a,b){return (b.plays||0)-(a.plays||0);});
|
||
else if(q.sort==='newest') f.sort(function(a,b){return (b.release_date||'').localeCompare(a.release_date||'');});
|
||
var start = (q.page-1)*q.page_size;
|
||
q.list = f.slice(start, start+q.page_size);
|
||
q.total = f.length;
|
||
renderLibrary();
|
||
});
|
||
}
|
||
function renderLibrary(){
|
||
document.getElementById('libTotal').textContent = state.lib.total;
|
||
var grid = document.getElementById('gameGrid');
|
||
if(!state.lib.list.length){
|
||
grid.innerHTML = emptyHTML('未找到符合条件的游戏');
|
||
document.getElementById('pagination').innerHTML = '';
|
||
return;
|
||
}
|
||
var html = '';
|
||
state.lib.list.forEach(function(g){
|
||
var tags = parseJSON(g.tags,[]);
|
||
var tagHTML = tags.slice(0,3).map(function(t){return '<span>'+escapeHTML(t)+'</span>';}).join('');
|
||
var badges = '';
|
||
if(g.is_hot) badges += '<span class="gbadge gbadge-hot">HOT</span>';
|
||
if(g.is_new) badges += '<span class="gbadge gbadge-new">NEW</span>';
|
||
if(g.category_name) badges += '<span class="gbadge gbadge-cat">'+escapeHTML(g.category_name)+'</span>';
|
||
html += '<div class="game-card" onclick="openModal('+g.id+')">'
|
||
+ '<div class="gcard-cover">'+coverHTML(g)+'<div class="gcard-badges">'+badges+'</div><div class="gcard-rating">'+(Number(g.rating)||0).toFixed(1)+'★</div></div>'
|
||
+ '<div class="gcard-body">'
|
||
+ '<div class="gcard-name">'+escapeHTML(g.name||'')+'</div>'
|
||
+ '<div class="gcard-dev">'+escapeHTML(g.developer||'')+'</div>'
|
||
+ '<div class="gcard-tags">'+tagHTML+'</div>'
|
||
+ '<div class="gcard-foot"><span class="gcard-plays">▶ '+formatNum(g.plays)+'</span><span class="gcard-size">'+escapeHTML(g.size||'')+'</span></div>'
|
||
+ '</div></div>';
|
||
});
|
||
grid.innerHTML = html;
|
||
renderPagination();
|
||
}
|
||
function renderPagination(){
|
||
var q = state.lib;
|
||
var pages = Math.ceil(q.total/q.page_size)||1;
|
||
var cur = q.page;
|
||
var el = document.getElementById('pagination');
|
||
if(pages<=1){ el.innerHTML=''; return; }
|
||
var html = '';
|
||
html += '<button class="page-btn" '+(cur<=1?'disabled':'')+' onclick="goPage('+(cur-1)+')">◀</button>';
|
||
var from = Math.max(1, cur-2), to = Math.min(pages, cur+2);
|
||
if(from>1){ html += '<button class="page-btn" onclick="goPage(1)">1</button>'; if(from>2) html+='<span class="page-dots">···</span>'; }
|
||
for(var p=from;p<=to;p++){
|
||
html += '<button class="page-btn '+(p===cur?'active':'')+'" onclick="goPage('+p+')">'+p+'</button>';
|
||
}
|
||
if(to<pages){ if(to<pages-1) html+='<span class="page-dots">···</span>'; html += '<button class="page-btn" onclick="goPage('+pages+')">'+pages+'</button>'; }
|
||
html += '<button class="page-btn" '+(cur>=pages?'disabled':'')+' onclick="goPage('+(cur+1)+')">▶</button>';
|
||
el.innerHTML = html;
|
||
}
|
||
function goPage(p){
|
||
state.lib.page = p;
|
||
loadLibrary();
|
||
scrollTo2('library');
|
||
}
|
||
function onLibSearch(){ state.lib.keyword = document.getElementById('libSearch').value.trim(); state.lib.page=1; loadLibrary(); }
|
||
function onLibSort(){ state.lib.sort = document.getElementById('libSort').value; state.lib.page=1; loadLibrary(); }
|
||
function onLibCat(){ state.lib.category_id = document.getElementById('libCat').value; syncCatBtn(state.lib.category_id); state.lib.page=1; loadLibrary(); }
|
||
function syncCatBtn(cid){
|
||
var btns = document.querySelectorAll('.cat-btn');
|
||
for(var i=0;i<btns.length;i++){
|
||
if(btns[i].getAttribute('data-cid')===String(cid)) btns[i].classList.add('active');
|
||
else btns[i].classList.remove('active');
|
||
}
|
||
}
|
||
// 搜索防抖
|
||
var navDebounce, libDebounce;
|
||
document.getElementById('libSearch').addEventListener('input', function(){
|
||
clearTimeout(libDebounce);
|
||
var v = this.value;
|
||
libDebounce = setTimeout(function(){ state.lib.keyword=v.trim(); state.lib.page=1; loadLibrary(); }, 360);
|
||
});
|
||
document.getElementById('navSearchInput').addEventListener('input', function(){
|
||
clearTimeout(navDebounce);
|
||
var v = this.value;
|
||
navDebounce = setTimeout(function(){
|
||
document.getElementById('libSearch').value = v;
|
||
state.lib.keyword = v.trim(); state.lib.page=1; loadLibrary();
|
||
if(v.trim()) scrollTo2('library');
|
||
}, 360);
|
||
});
|
||
|
||
/* ============================================================
|
||
游戏详情 Modal
|
||
============================================================ */
|
||
function openModal(id){
|
||
var mask = document.getElementById('modalMask');
|
||
mask.classList.add('open');
|
||
document.body.style.overflow='hidden';
|
||
document.getElementById('modalTitle').textContent = 'LOADING...';
|
||
document.getElementById('modalBody').innerHTML = '<div class="loading-px"><span class="ld"></span><span class="ld"></span><span class="ld"></span><span class="ld"></span></div>';
|
||
apiGet(API+'/games/'+id).then(function(g){
|
||
renderModal(g);
|
||
}).catch(function(){
|
||
var g = mockGame(id);
|
||
renderModal(g);
|
||
});
|
||
}
|
||
function renderModal(g){
|
||
if(!g){ document.getElementById('modalBody').innerHTML = emptyHTML('游戏数据加载失败'); return; }
|
||
document.getElementById('modalTitle').textContent = g.name||'游戏详情';
|
||
var tags = parseJSON(g.tags,[]);
|
||
var features = parseJSON(g.features,[]);
|
||
var shots = parseJSON(g.screenshots,[]);
|
||
var tagHTML = tags.map(function(t){return '<span>'+escapeHTML(t)+'</span>';}).join('');
|
||
var featHTML = features.map(function(f){return '<li>'+escapeHTML(f)+'</li>';}).join('');
|
||
var shotHTML = shots.length ? shots.map(function(s){return '<img src="'+escapeHTML(s)+'" alt="截图" onerror="this.style.display=\'none\'">';}).join('') : '<div class="ph" style="width:200px;height:120px;display:grid;place-items:center;color:var(--text-dimer);font-size:11px;border:3px solid var(--ink)">暂无截图</div>';
|
||
|
||
var html = '<div class="modal-top">'
|
||
+ '<div class="modal-cover">'+coverHTML(g)+'</div>'
|
||
+ '<div class="modal-info">'
|
||
+ '<h2>'+escapeHTML(g.name||'')+'</h2>'
|
||
+ '<div class="m-dev">'+escapeHTML(g.developer||'')+(g.publisher?(' / '+escapeHTML(g.publisher)):'')+'</div>'
|
||
+ '<div class="modal-rate"><span class="rate-val">'+(Number(g.rating)||0).toFixed(1)+'</span>'+ratingBlocks(g.rating)+'<span style="font-size:11px;color:var(--text-dim)">/ 5.0</span></div>'
|
||
+ '<div class="m-tags">'+tagHTML+'</div>'
|
||
+ '<div class="m-meta">'
|
||
+ metaItem('分类', g.category_name||'未知')
|
||
+ metaItem('版本', g.version||'-')
|
||
+ metaItem('大小', g.size||'-')
|
||
+ metaItem('平台', g.platform||'多平台')
|
||
+ metaItem('发售日期', g.release_date||'-')
|
||
+ metaItem('下载量', formatNum(g.downloads||g.plays||0))
|
||
+ '</div>'
|
||
+ '</div></div>'
|
||
+ '<div class="modal-desc"><span class="lbl">▸ 游戏简介</span>'+escapeHTML(g.description||'暂无简介')+'</div>'
|
||
+ (features.length?'<div class="modal-features"><div class="lbl">★ 特色玩法</div><ul>'+featHTML+'</ul></div>':'')
|
||
+ '<div class="modal-shots"><div class="lbl">▣ 游戏截图</div><div class="shots-row">'+shotHTML+'</div></div>'
|
||
+ '<div class="modal-actions">'
|
||
+ '<button class="pbtn pbtn-yellow" onclick="alert(\'开始下载:'+escapeHTML(g.name||'')+'\')">立即下载 ▶</button>'
|
||
+ '<button class="pbtn pbtn-ghost" onclick="alert(\'已加入收藏\')">加入收藏</button>'
|
||
+ '<button class="pbtn pbtn-red" onclick="closeModal()">关闭</button>'
|
||
+ '</div>';
|
||
document.getElementById('modalBody').innerHTML = html;
|
||
}
|
||
function metaItem(label, val){
|
||
return '<div class="m-meta-item"><label>'+escapeHTML(label)+'</label><span>'+escapeHTML(val)+'</span></div>';
|
||
}
|
||
function closeModal(){
|
||
document.getElementById('modalMask').classList.remove('open');
|
||
document.body.style.overflow='';
|
||
}
|
||
document.addEventListener('keydown', function(e){ if(e.key==='Escape') closeModal(); });
|
||
|
||
/* ============================================================
|
||
辅助
|
||
============================================================ */
|
||
function showLoading(id){ document.getElementById(id).innerHTML = '<div class="loading-px"><span class="ld"></span><span class="ld"></span><span class="ld"></span><span class="ld"></span></div>'; }
|
||
function emptyHTML(msg){ return '<div class="empty-state" style="grid-column:1/-1"><div class="es-icon">▣</div><p>'+escapeHTML(msg)+'</p></div>'; }
|
||
function scrollTo2(id){ var el=document.getElementById(id); if(el){ var y=el.getBoundingClientRect().top+window.pageYOffset-80; window.scrollTo({top:y,behavior:'smooth'}); } }
|
||
function scrollTop2(){ window.scrollTo({top:0,behavior:'smooth'}); }
|
||
|
||
// 滚动显示返回顶部 + 导航高亮
|
||
window.addEventListener('scroll', function(){
|
||
var t = document.getElementById('toTop');
|
||
if(window.pageYOffset>400) t.classList.add('show'); else t.classList.remove('show');
|
||
// 导航高亮
|
||
var secs = ['home','hot','new','library'];
|
||
var cur = 'home';
|
||
for(var i=0;i<secs.length;i++){ var el=document.getElementById(secs[i]); if(el && el.getBoundingClientRect().top<160) cur=secs[i]; }
|
||
// hero 无 id, 用顶部
|
||
});
|
||
|
||
// 像素评分样式注入
|
||
(function(){
|
||
var s = document.createElement('style');
|
||
s.textContent = '.rb-fill{color:var(--yellow);letter-spacing:0}.rb-empty{color:var(--bg-3);letter-spacing:0}.rate-val-mini{color:var(--yellow);font-weight:bold;margin-right:2px}';
|
||
document.head.appendChild(s);
|
||
})();
|
||
|
||
// Hero 像素角色 (CSS box-shadow 像素画)
|
||
(function(){
|
||
var el = document.getElementById('heroChar');
|
||
if(!el) return;
|
||
// 用多重 box-shadow 画一个像素小人 (绿帽红衣)
|
||
var p = 'var(--ink)';
|
||
var g = 'var(--green)';
|
||
var r = 'var(--red)';
|
||
var s = 'var(--yellow)'; // 肤色用黄
|
||
var br = 'var(--bg-4)';
|
||
var px = 8; // 每像素 8px
|
||
function row(y, str){ // str 形如 "GGGGGG"
|
||
var shadows = [];
|
||
for(var x=0;x<str.length;x++){
|
||
var ch = str[x];
|
||
var c;
|
||
if(ch==='G') c=g; else if(ch==='R') c=r; else if(ch==='S') c=s; else if(ch==='B') c=br; else if(ch==='K') c=p; else continue;
|
||
shadows.push((x*px)+'px '+(y*px)+'px 0 0 '+c);
|
||
}
|
||
return shadows.join(',');
|
||
}
|
||
var map = [
|
||
'..GGGG..',
|
||
'.GGGGGG.',
|
||
'SSKSSKSS',
|
||
'SSSSSSSS',
|
||
'SSKKKKSS',
|
||
'RRRRRRRR',
|
||
'RRRRRRRR',
|
||
'RRRRRRRR',
|
||
'.R.RR.R.',
|
||
'.S.SS.S.',
|
||
'.B.BB.B.'
|
||
];
|
||
var all=[];
|
||
for(var i=0;i<map.length;i++){ all.push(row(i, map[i])); }
|
||
el.style.cssText = 'width:'+px+'px;height:'+px+'px;position:relative;background:transparent;box-shadow:'+all.join(',')+';animation:float-up 2.2s ease-in-out infinite';
|
||
})();
|
||
|
||
/* ============================================================
|
||
模拟数据 (API 不可用时回退, 便于预览)
|
||
============================================================ */
|
||
var NAMES = ['龙之传说','星际远征','暗影刺客','钢铁战线','幻境迷宫','魔法纪元','赛车狂飙','机甲风暴','荒野求生','深海探险','天空之城','末日堡垒','剑与魔法','像素英雄','霓虹狙击','炼金术士','勇者斗恶龙','银河漂流','地下王国','雷霆战机','忍者之道','王者棋盘','农场物语','太空殖民','蒸汽朋克','光明使者','暗夜猎手','极速漂移','神秘海域','传奇战场','永恒之歌','混沌之心','机械迷城','风暴英雄','烈焰之刃'];
|
||
var CATS = [['动作','⚔'],['角色扮演','★'],['射击','◉'],['冒险','▲'],['策略','♟'],['模拟','◆'],['体育','●'],['益智','♦']];
|
||
var TAGS = ['开放世界','巨龙','史诗','多人联机','硬核','剧情','生存','沙盒','潜行','竞技','合作',' Roguelike','roguelike','解谜','建造','魔法','科幻','末日','机甲','赛车'];
|
||
var FEATS = ['无缝开放世界','实时战斗系统','动态天气系统','多结局剧情','合作多人模式','物理引擎破坏','技能树系统','宠物养成','昼夜循环','随机地下城'];
|
||
var PUB = ['像素工作室','银河游戏','雷霆互动','幻影科技','复古发行','独立工坊'];
|
||
function rand(a){ return a[Math.floor(Math.random()*a.length)]; }
|
||
function randInt(a,b){ return Math.floor(Math.random()*(b-a+1))+a; }
|
||
function mockGame(id){
|
||
var name = NAMES[(id-1)%NAMES.length] + (id>NAMES.length?(' '+Math.floor((id-1)/NAMES.length)):'');
|
||
var ci = (id-1)%CATS.length;
|
||
var tagN = randInt(2,4), tags=[]; for(var i=0;i<tagN;i++){ var t=rand(TAGS); if(tags.indexOf(t)<0)tags.push(t);}
|
||
var feN = randInt(2,3), feats=[]; for(var j=0;j<feN;j++){ var f=rand(FEATS); if(feats.indexOf(f)<0)feats.push(f);}
|
||
return {
|
||
id:id, name:name, description:'这是一款充满复古魅力的像素风游戏,融合了经典玩法与现代设计。玩家将踏上史诗般的冒险旅程,探索广袤的世界,挑战强大的敌人,揭开隐藏的秘密。精美的像素画面与动感的8-bit音效带您重温黄金游戏时代。',
|
||
category_id: ci+1, category_name: CATS[ci][0],
|
||
cover:'', developer:rand(PUB), publisher:rand(PUB),
|
||
rating: Math.round((3.5+Math.random()*1.5)*10)/10,
|
||
plays: randInt(1000,9800000), downloads: randInt(500,5000000),
|
||
size: randInt(20,120)+'.'+randInt(0,9)+' GB', version:'v'+randInt(1,3)+'.'+randInt(0,9)+'.'+randInt(0,9),
|
||
release_date:'2026-'+String(randInt(1,7)).padStart(2,'0')+'-'+String(randInt(1,28)).padStart(2,'0'),
|
||
platform:'PC / PS5 / Switch', tags:JSON.stringify(tags), screenshots:'[]', features:JSON.stringify(feats),
|
||
is_hot: Math.random()>0.5, is_new: Math.random()>0.5, sort:id, status:1
|
||
};
|
||
}
|
||
function mockGames(n, hotOnly, newOnly){
|
||
var arr=[];
|
||
for(var i=0;i<n;i++){
|
||
var g = mockGame(randInt(1,35));
|
||
if(hotOnly) g.is_hot=true;
|
||
if(newOnly){ g.is_new=true; }
|
||
arr.push(g);
|
||
}
|
||
return arr;
|
||
}
|
||
|
||
/* ============================================================
|
||
初始化
|
||
============================================================ */
|
||
function init(){
|
||
// 分类先加载
|
||
loadCategories().then(function(){
|
||
// 首页 + 仓库
|
||
loadHome();
|
||
loadLibrary();
|
||
});
|
||
// 每秒游戏币+1 小彩蛋
|
||
setInterval(function(){
|
||
var el = document.getElementById('coinCount');
|
||
var v = parseInt(el.textContent,10)||0;
|
||
if(Math.random()>0.7){ el.textContent = v+1; }
|
||
}, 2000);
|
||
}
|
||
init();
|
||
</script>
|
||
</body>
|
||
</html>
|