🎮ArcadeLab

华夏长卷·史实答题

by RapidTurtle60
996 lines55.9 KB
▶ Play
<!DOCTYPE html>
<html lang="zh-CN">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>华夏长卷·史实答题</title>
<style>
* { margin:0; padding:0; box-sizing:border-box; }
body { background:#000; overflow:hidden; font-family: "STKaiti","KaiTi",serif; user-select:none; }
canvas { display:block; }

.overlay { position:fixed; top:0; left:0; width:100%; height:100%; display:flex; flex-direction:column; align-items:center; justify-content:center; z-index:100; transition:opacity 0.5s; }

#start-screen { background:radial-gradient(ellipse at center,#0c0804 0%,#000 80%); }
#start-screen h1 { font-size:clamp(28px,6vw,52px); color:#d4af6a; letter-spacing:clamp(6px,3vw,18px); text-shadow:0 0 40px rgba(212,175,106,.5); margin-bottom:6px; }
#start-screen .sub { color:#8a7a5e; font-size:clamp(10px,2vw,14px); letter-spacing:5px; margin-bottom:clamp(20px,5vh,45px); }
#start-screen .btn { padding:clamp(10px,2vh,15px) clamp(28px,5vw,48px); background:linear-gradient(135deg,#8b5a2b,#d4af6a); border:none; border-radius:8px; color:#0a0a0a; font-size:clamp(14px,2.5vw,19px); font-family:"STKaiti",serif; letter-spacing:6px; cursor:pointer; font-weight:bold; transition:all .3s; }
#start-screen .btn:hover { transform:translateY(-3px); box-shadow:0 10px 30px rgba(212,175,106,.4); }

#level-screen { background:radial-gradient(ellipse at center,#080604 0%,#000 80%); display:none; padding:20px; overflow-y:auto; }
#level-screen h2 { color:#d4af6a; font-size:clamp(18px,4vw,30px); letter-spacing:10px; margin-bottom:20px; }
.level-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(155px,1fr)); gap:12px; max-width:900px; width:100%; padding:8px; }
.level-card { background:rgba(20,16,12,.9); border:1px solid rgba(212,175,106,.25); border-radius:10px; padding:12px 8px; text-align:center; cursor:pointer; transition:all .3s; position:relative; }
.level-card:hover { border-color:#d4af6a; transform:translateY(-4px); box-shadow:0 8px 25px rgba(212,175,106,.15); }
.level-card.cleared { border-color:rgba(100,200,100,.5); }
.level-card.cleared::after { content:'✓'; position:absolute; top:5px; right:7px; color:#6c6; font-size:13px; }
.level-card.locked { opacity:.35; pointer-events:none; filter:grayscale(.8); }
.level-num { color:#8a7a5e; font-size:10px; letter-spacing:2px; margin-bottom:3px; }
.level-name { color:#d4af6a; font-size:clamp(13px,2.5vw,16px); margin-bottom:3px; }
.level-era { color:#6a5a3e; font-size:9px; margin-bottom:5px; }
.level-desc { color:#5a4a2e; font-size:9px; line-height:1.4; }

#game-screen { position:fixed; top:0; left:0; width:100%; height:100%; z-index:10; display:none; }
#scene-canvas { position:absolute; top:0; left:0; width:100%; height:100%; transition:filter 0.3s; }
#top-info { position:absolute; top:0; left:0; right:0; height:clamp(34px,6vh,48px); background:linear-gradient(180deg,rgba(0,0,0,.9)0%,transparent 100%); display:flex; align-items:center; justify-content:space-between; padding:0 clamp(10px,3vw,18px); z-index:20; }
#top-info .lvl { color:#d4af6a; font-size:clamp(10px,1.8vw,13px); letter-spacing:2px; }
#top-info .prog { color:#8a7a5e; font-size:clamp(10px,1.8vw,13px); }
#top-info .quit { padding:5px 12px; background:transparent; border:1px solid rgba(138,122,94,.4); border-radius:5px; color:#8a7a5e; cursor:pointer; font-family:"STKaiti",serif; font-size:11px; }
#top-info .quit:hover { border-color:#c66; color:#c66; }

#question-panel { position:absolute; bottom:0; left:0; right:0; background:linear-gradient(0deg,rgba(0,0,0,.97)0%,rgba(0,0,0,.75)55%,transparent 100%); padding:clamp(14px,3vh,32px) clamp(12px,4vw,36px) clamp(10px,2vh,24px); z-index:20; }
#scene-title { color:#d4af6a; font-size:clamp(11px,2vw,14px); letter-spacing:3px; margin-bottom:5px; text-align:center; }
#scene-desc { color:#a09070; font-size:clamp(10px,1.6vw,12px); line-height:1.5; text-align:center; margin-bottom:10px; max-width:680px; margin-left:auto; margin-right:auto; }
#diff-badge { text-align:center; margin-bottom:8px; }
#diff-badge span { display:inline-block; padding:2px 10px; border-radius:10px; font-size:10px; letter-spacing:1px; }
#question-text { color:#fff; font-size:clamp(13px,2.5vw,18px); line-height:1.6; text-align:center; margin-bottom:14px; max-width:760px; margin-left:auto; margin-right:auto; font-weight:bold; }
#options-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:8px; max-width:760px; margin:0 auto; }
.opt-btn { padding:clamp(9px,1.5vh,14px) clamp(10px,2.5vw,18px); background:rgba(20,16,12,.9); border:1px solid rgba(212,175,106,.3); border-radius:8px; color:#c8b89c; cursor:pointer; font-size:clamp(11px,2vw,14px); font-family:"STKaiti",serif; transition:all .25s; text-align:left; line-height:1.5; }
.opt-btn:hover { background:rgba(212,175,106,.12); border-color:#d4af6a; color:#d4af6a; transform:translateY(-2px); }
.opt-btn.correct { background:rgba(60,140,60,.3)!important; border-color:#6c6!important; color:#6c6!important; }
.opt-btn.wrong { background:rgba(180,50,30,.3)!important; border-color:#c33!important; color:#c66!important; }
.opt-btn:disabled { pointer-events:none; opacity:.7; }

#feedback-overlay { position:absolute; top:0; left:0; width:100%; height:100%; pointer-events:none; z-index:30; display:flex; align-items:center; justify-content:center; }
#feedback-text { font-size:clamp(28px,6vw,56px); opacity:0; transition:opacity .3s; text-align:center; text-shadow:0 0 20px rgba(0,0,0,.8); }
#feedback-text.show { opacity:1; }

#story-popup { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); background:rgba(10,8,6,.97); border:1px solid rgba(212,175,106,.4); border-radius:12px; padding:20px 24px; max-width:90vw; width:420px; display:none; z-index:60; text-align:center; }
#story-popup .sp-title { color:#d4af6a; font-size:15px; margin-bottom:8px; letter-spacing:3px; }
#story-popup .sp-text { color:#c8b89c; font-size:12px; line-height:1.8; margin-bottom:14px; }
#story-popup .sp-btn { padding:8px 22px; background:linear-gradient(135deg,#8b5a2b,#d4af6a); border:none; border-radius:5px; color:#0a0a0a; font-family:"STKaiti",serif; font-size:12px; letter-spacing:3px; cursor:pointer; font-weight:bold; }

#result-screen { background:rgba(0,0,0,.96); display:none; padding:20px; }
#result-screen h2 { font-size:clamp(20px,4.5vw,38px); color:#d4af6a; letter-spacing:8px; margin-bottom:12px; text-align:center; }
#result-screen .rtext { color:#c8b89c; font-size:clamp(11px,2.2vw,14px); margin-bottom:18px; text-align:center; line-height:2; max-width:500px; }
#result-screen .rstars { text-align:center; margin-bottom:14px; font-size:clamp(15px,3vw,22px); }
#result-screen .rbtns { display:flex; gap:10px; flex-wrap:wrap; justify-content:center; }
#result-screen .rbtn { padding:10px 26px; border:1px solid rgba(212,175,106,.5); border-radius:6px; background:transparent; color:#d4af6a; font-family:"STKaiti",serif; font-size:clamp(12px,2.2vw,15px); letter-spacing:4px; cursor:pointer; transition:all .3s; }
#result-screen .rbtn:hover { background:rgba(212,175,106,.1); }
#result-screen .rbtn.primary { background:linear-gradient(135deg,#8b5a2b,#d4af6a); color:#0a0a0a; border:none; font-weight:bold; }

#transition-flash { position:absolute; top:0; left:0; width:100%; height:100%; background:#000; z-index:55; opacity:0; pointer-events:none; transition:opacity 0.4s; }
</style>
</head>
<body>

<canvas id="bg-canvas" style="position:fixed;top:0;left:0;width:100%;height:100%;z-index:1;"></canvas>

<div id="start-screen" class="overlay">
  <h1>华夏长卷</h1>
  <div class="sub">史实答题 · 分档闯关</div>
  <button class="btn" onclick="showLevels()">开 卷 答 题</button>
</div>

<div id="level-screen" class="overlay">
  <h2 style="color:#d4af6a;letter-spacing:10px;margin-bottom:20px;">— 关 卡 选 择 —</h2>
  <div class="level-grid" id="level-grid"></div>
</div>

<div id="game-screen">
  <canvas id="scene-canvas"></canvas>
  <div id="transition-flash"></div>
  <div id="top-info">
    <div class="lvl" id="lvl-name">第一关</div>
    <div class="prog" id="prog-text">第 1/9 题</div>
    <button class="quit" onclick="quitGame()">退出</button>
  </div>
  <div id="feedback-overlay"><div id="feedback-text"></div></div>
  <div id="story-popup">
    <div class="sp-title" id="sp-title">— 史实 —</div>
    <div class="sp-text" id="sp-text"></div>
    <button class="sp-btn" onclick="closeStory()">继 续</button>
  </div>
  <div id="question-panel">
    <div id="scene-title"></div>
    <div id="scene-desc"></div>
    <div id="diff-badge"><span id="diff-label"></span></div>
    <div id="question-text"></div>
    <div id="options-grid"></div>
  </div>
</div>

<div id="result-screen" class="overlay">
  <h2 id="r-title">通关</h2>
  <div class="rstars" id="r-stars"></div>
  <div class="rtext" id="r-text"></div>
  <div class="rbtns">
    <button class="rbtn" onclick="backToLevels()">关 卡 选 择</button>
    <button class="rbtn primary" id="r-next" onclick="nextLevel()">下 一 关</button>
  </div>
</div>

<script>
// ============ 题库 ============
var LEVELS = [
{
  name:"牧野之战", era:"商末·约前1046", desc:"武王伐纣,阵前倒戈", bgColor:"#1a0e0a", accent:"#c04020",
  questions:[
    { diff:0, type:"choice", scene:"muye", title:"武王之名", q:"周武王的姓名是?", options:["姬发","姬昌","姬旦","姬诵"], correct:0, story:"武王姓姬名发,文王姬昌之子。他继承父志,联合诸侯,在牧野击败商纣。" },
    { diff:0, type:"truefalse", scene:"jiu", title:"酒池肉林", q:"商纣王建造'酒池肉林'是真实可信的史实记载?", options:["对","错"], correct:1, story:"'酒池肉林'出自《史记·殷本纪》,但带有后世夸张成分。纣王确实荒淫,但细节可能经过渲染。" },
    { diff:0, type:"choice", scene:"daoge", title:"商军构成", q:"牧野之战中,商纣王临时拼凑的军队主要由什么人组成?", options:["正规军","奴隶和战俘","诸侯联军","农夫"], correct:1, story:"商纣将大量奴隶和战俘武装起来投入战场,这些人在阵前倒戈,引导周军攻入朝歌。" },
    { diff:1, type:"choice", scene:"muye", title:"牧誓罪状", q:"《尚书·牧誓》中,武王列举纣王罪状不包括以下哪一项?", options:["惟妇言是用","昏弃厥肆祀","不任亲族","暴虐百姓"], correct:2, story:"《牧誓》原文列举罪状,并未提及'不任亲族'。" },
    { diff:1, type:"truefalse", scene:"sanjian", title:"三监", q:"武王派管叔、蔡叔、霍叔监视武庚,史称'三监'?", options:["对","错"], correct:0, story:"武王封纣子武庚守殷祀,派管叔、蔡叔、霍叔监视,即'三监'。" },
    { diff:1, type:"choice", scene:"lutai", title:"纣王之死", q:"据《史记》记载,商纣王自焚时身披何物?", options:["宝玉衣","天子衮服","素缟","金缕玉衣"], correct:0, story:"《史记·殷本纪》:'蒙衣其珠玉,自燔于火而死。'" },
    { diff:2, type:"choice", scene:"liqi", title:"利簋纪年", q:"利簋铭文'岁鼎克闻夙有商'的'岁'指什么?", options:["岁星(木星)","岁贡","岁祭","岁首"], correct:0, story:"利簋铭文'岁鼎'指岁星当空。推算牧野之战为公元前1046年1月20日。" },
    { diff:2, type:"truefalse", scene:"jizi", title:"箕子朝鲜", q:"箕子率五千人东走朝鲜,武王因而封之?", options:["对","错"], correct:0, story:"箕子东走朝鲜,武王封之。箕子朝鲜传国近千年。" },
    { diff:2, type:"choice", scene:"shijing", title:"牧野洋洋", q:"《诗经·大明》'牧野洋洋,檀车煌煌,驷騵彭彭'描写的是?", options:["誓师","战车冲锋","以上都是"], correct:2, story:"《大明》篇从文王娶妻写到牧野之战,'牧野洋洋'段描写战车冲锋。" }
  ]
},
{
  name:"长平之战", era:"战国·前260", desc:"白起坑赵,四十万降卒", bgColor:"#0e1410", accent:"#4a6a3a",
  questions:[
    { diff:0, type:"choice", scene:"changping", title:"赵国主将", q:"长平之战前期,赵国坚守不出的老将是谁?", options:["赵奢","廉颇","李牧","乐毅"], correct:1, story:"廉颇筑垒固守三年不战,消耗秦军。" },
    { diff:0, type:"truefalse", scene:"zhao", title:"纸上谈兵", q:"赵括是赵奢之子,熟读兵书但缺乏实战经验?", options:["对","错"], correct:0, story:"赵奢生前评价'括不可使将'。赵括贸然出击导致全军覆没。" },
    { diff:0, type:"choice", scene:"changping", title:"秦军主将", q:"长平之战中,秦军实际主将是谁?", options:["王龁","白起","蒙骜","司马错"], correct:1, story:"秦昭王秘密换白起为上将军,赵括不知对手是白起。" },
    { diff:1, type:"choice", scene:"fanjian", title:"秦国反间", q:"秦国散布'秦之所恶,独畏马服子赵括',目的是换掉谁?", options:["蔺相如","廉颇","乐乘","赵豹"], correct:1, story:"秦相范雎行反间计,赵王中计以赵括代廉颇。" },
    { diff:1, type:"truefalse", scene:"shangdang", title:"冯亭献地", q:"上党郡守冯亭献十七城给赵国,是长平之战导火索?", options:["对","错"], correct:0, story:"冯亭不愿降秦献地于赵,平原君力主受地,触怒秦国。" },
    { diff:1, type:"choice", scene:"zhaoku", title:"赵括之死", q:"赵括最终如何阵亡?", options:["被乱箭射死","突围时被射杀","投降后被杀"], correct:1, story:"赵括率精兵突围,被秦军乱箭射杀。" },
    { diff:2, type:"choice", scene:"keng", title:"坑杀人数", q:"白起坑杀赵卒约多少人?", options:["十万","二十万","四十余万","六十万"], correct:2, story:"坑杀约四十万降卒,仅放归240名少年。" },
    { diff:2, type:"truefalse", scene:"baiqi", title:"白起之死", q:"白起因拒绝再次领兵攻赵,被秦昭王赐死?", options:["对","错"], correct:0, story:"白起与范雎有隙,拒绝攻赵,被赐剑自刎。" },
    { diff:2, type:"choice", scene:"yuqing", title:"虞卿谏言", q:"虞卿曾建议赵王联合谁制衡秦国?", options:["齐楚","魏韩","燕赵"], correct:0, story:"虞卿建议联合齐楚形成合纵抗秦之势。" }
  ]
},
{
  name:"赤壁之战", era:"东汉·208", desc:"火攻连环船,三分天下定", bgColor:"#0a1020", accent:"#4a6a9a",
  questions:[
    { diff:0, type:"choice", scene:"jiang", title:"刘琮降曹", q:"刘琮在蔡瑁劝说下选择了?", options:["抵抗","投降","联刘抗曹"], correct:1, story:"刘琮降曹,刘备被迫南走。" },
    { diff:0, type:"truefalse", scene:"chibi", title:"赵云救主", q:"长坂坡赵云单骑救阿斗有史实依据?", options:["对","错"], correct:0, story:"《云别传》记载赵云'身抱弱子,保护甘夫人,皆得免难'。" },
    { diff:0, type:"choice", scene:"sunliu", title:"主降派代表", q:"东吴主降派的代表人物是?", options:["周瑜","鲁肃","张昭","黄盖"], correct:2, story:"张昭等人主张迎降,鲁肃、周瑜力主抵抗。" },
    { diff:1, type:"choice", scene:"jiang", title:"蒋干盗书", q:"'蒋干盗书'出自?", options:["《三国志》","《三国演义》","《资治通鉴》"], correct:1, story:"蒋干确有其人,但'盗书'是演义虚构。" },
    { diff:1, type:"truefalse", scene:"huanggai", title:"苦肉计", q:"黄盖献诈降书是赤壁火攻的重要一环?", options:["对","错"], correct:0, story:"黄盖写信诈降,曹操信以为真。" },
    { diff:1, type:"choice", scene:"chibi", title:"东南风", q:"赤壁火攻时东南风的真实原因是?", options:["诸葛亮作法","冬季偶发东南风","热气流"], correct:1, story:"长江流域冬季确有偶发东南风,黄盖等人观测天象等待窗口。" },
    { diff:2, type:"choice", scene:"huarong", title:"华容道", q:"曹操败走华容道时命谁填泥路?", options:["许褚","羸兵","战马"], correct:1, story:"悉使羸兵负草填路,羸兵为人马所蹈藉,死者甚众。" },
    { diff:2, type:"truefalse", scene:"jingzhou", title:"三分雏形", q:"赤壁后刘备夺取荆州四郡奠定蜀汉基业?", options:["对","错"], correct:0, story:"刘备乘胜夺取武陵、长沙、桂阳、零陵四郡。" },
    { diff:2, type:"choice", scene:"caocao", title:"《短歌行》", q:"'周公吐哺,天下归心'表达什么?", options:["求贤","统一天下","归隐"], correct:1, story:"表达曹操渴望贤才辅佐、统一天下的雄心。" }
  ]
},
{
  name:"淝水之战", era:"东晋·383", desc:"风声鹤唳,草木皆兵", bgColor:"#0a1a1a", accent:"#3a8a8a",
  questions:[
    { diff:0, type:"choice", scene:"feishui", title:"前秦皇帝", q:"淝水之战前统一北方的是谁?", options:["苻健","苻坚","苻生"], correct:1, story:"苻坚在王猛辅佐下统一北方。" },
    { diff:0, type:"truefalse", scene:"toubian", title:"投鞭断流", q:"苻坚说投鞭断流形容秦军人多?", options:["对","错"], correct:0, story:"苻坚以此展示信心,但大臣石越反驳。" },
    { diff:0, type:"choice", scene:"xiean", title:"东晋执政", q:"淝水之战时东晋实际执政是?", options:["桓温","谢安","王导"], correct:1, story:"谢安统筹全局,派侄谢玄率北府兵迎敌。" },
    { diff:1, type:"choice", scene:"bagong", title:"八公山", q:"八公山在今哪个省?", options:["河南","安徽","江苏"], correct:1, story:"八公山在今安徽省淮南市。" },
    { diff:1, type:"truefalse", scene:"zhuxu", title:"朱序内应", q:"朱序在秦军后撤时大呼'秦军败矣'?", options:["对","错"], correct:0, story:"朱序原为晋将,降秦后在阵后大呼导致秦军溃散。" },
    { diff:1, type:"choice", scene:"beifu", title:"北府兵来源", q:"北府兵主要来自?", options:["淮南","京口","广陵"], correct:1, story:"谢玄招募京口(今镇江)骁勇之士组建北府兵。" },
    { diff:2, type:"choice", scene:"feishui", title:"战后政权", q:"慕容垂和姚苌分别建立?", options:["后燕、后秦","前燕、后秦","南燕、大夏"], correct:0, story:"慕容垂建后燕,姚苌建后秦。" },
    { diff:2, type:"truefalse", scene:"wangmeng", title:"王猛遗言", q:"王猛临终劝苻坚勿攻东晋?", options:["对","错"], correct:0, story:"王猛遗言'愿不以晋为图',苻坚未听。" },
    { diff:2, type:"choice", scene:"xiean", title:"围棋赌墅", q:"谢安得知捷报时正在?", options:["饮酒","下棋","睡觉"], correct:1, story:"《世说新语》:看书竟,默然无言,徐向局。" }
  ]
},
{
  name:"安史之乱", era:"唐·755-763", desc:"渔阳鼙鼓动地来", bgColor:"#1a0a0a", accent:"#8a3a3a",
  questions:[
    { diff:0, type:"choice", scene:"anshi", title:"安禄山身份", q:"安禄山起兵时身兼几镇节度使?", options:["一镇","两镇","三镇"], correct:2, story:"身兼平卢、范阳、河东三镇节度使。" },
    { diff:0, type:"truefalse", scene:"maweipo", title:"贵妃之死", q:"马嵬坡杨贵妃被赐白绫自缢?", options:["对","错"], correct:0, story:"高力士奉命赐贵妃自尽于佛堂梨树下。" },
    { diff:0, type:"choice", scene:"lingwu", title:"肃宗即位", q:"李亨在何处即位?", options:["太原","灵武","成都"], correct:1, story:"李亨在灵武即位,遥尊玄宗为太上皇。" },
    { diff:1, type:"choice", scene:"suiyang", title:"睢阳守将", q:"与许远共同坚守睢阳的是?", options:["张巡","南霁云","雷万春"], correct:0, story:"张巡善谋略,坚守十个月。" },
    { diff:1, type:"truefalse", scene:"yanzhenqing", title:"颜真卿起兵", q:"颜真卿在平原郡起兵抵抗?", options:["对","错"], correct:0, story:"颜真卿率先起兵,其兄颜杲卿守常山不屈被杀。" },
    { diff:1, type:"choice", scene:"anshi", title:"安禄山之死", q:"安禄山被谁所杀?", options:["史思明","安庆绪","严庄与李猪儿"], correct:2, story:"严庄与宦官李猪儿联手杀安禄山。" },
    { diff:2, type:"choice", scene:"changhen", title:"《长恨歌》", q:"'渔阳鼙鼓动地来'出自?", options:["《琵琶行》","《长恨歌》","《秦中吟》"], correct:1, story:"白居易《长恨歌》描写玄宗与贵妃悲剧。" },
    { diff:2, type:"truefalse", scene:"fan", title:"河朔三镇", q:"安史后河北形成魏博、成德、卢龙割据?", options:["对","错"], correct:0, story:"三镇表面归顺实际独立,开启藩镇割据。" },
    { diff:2, type:"choice", scene:"anshi", title:"乱世时长", q:"安史之乱持续多少年?", options:["六年","七年","八年"], correct:2, story:"755年到763年,前后八年。" }
  ]
},
{
  name:"靖康之变", era:"北宋·1127", desc:"靖康耻,犹未雪", bgColor:"#0a0a1a", accent:"#4a4a8a",
  questions:[
    { diff:0, type:"choice", scene:"hai", title:"海上之盟", q:"宋金约定联合灭哪国?", options:["辽","西夏","金"], correct:0, story:"宋金夹攻辽国,后金军南下攻宋。" },
    { diff:0, type:"truefalse", scene:"huashi", title:"花石纲", q:"蔡京童贯主持花石纲导致民怨?", options:["对","错"], correct:0, story:"花石纲劳民伤财,方腊起义即与此有关。" },
    { diff:0, type:"choice", scene:"ligang", title:"李纲守城", q:"金军第一次围开封时组织坚守的是?", options:["宗泽","李纲","种师道"], correct:1, story:"李纲亲督守御,金军退。" },
    { diff:1, type:"choice", scene:"jingkang", title:"二帝被俘", q:"金军俘虏了哪两位皇帝?", options:["徽宗、钦宗","钦宗、高宗","神宗、哲宗"], correct:0, story:"徽宗钦宗被俘北去,北宋灭亡。" },
    { diff:1, type:"truefalse", scene:"gen", title:"艮岳", q:"金军拆毁徽宗修建的艮岳?", options:["对","错"], correct:0, story:"艮岳奇石被金军运走。" },
    { diff:1, type:"choice", scene:"nan", title:"南宋建立", q:"赵构在何处即位?", options:["临安","应天府","建康"], correct:1, story:"赵构在应天府即位,后定都临安。" },
    { diff:2, type:"choice", scene:"jingkang", title:"大括金银", q:"金军搜刮汴京金银的机构叫?", options:["岁币所","大括金银所","和议局"], correct:1, story:"设'大括金银所'搜刮百年积累。" },
    { diff:2, type:"truefalse", scene:"huiqin", title:"牵羊礼", q:"钦宗被俘后被迫行'牵羊礼'?", options:["对","错"], correct:0, story:"钦宗被俘后被迫行牵羊礼受辱。" },
    { diff:2, type:"choice", scene:"menghua", title:"《东京梦华录》", q:"该书的作者是?", options:["孟元老","周密","吴自牧"], correct:0, story:"孟元老南渡后追忆汴京繁华而作。" }
  ]
}
];

// ============ 场景渲染器 ============
var sceneRenderers = {
  // 牧野战场 - 战旗阵列+士兵剪影
  "muye": function(ctx,W,H,t){
    // 天空渐变
    var sky=ctx.createLinearGradient(0,0,0,H*0.6); sky.addColorStop(0,"#1a0a0a"); sky.addColorStop(1,"#3a1a0a");
    ctx.fillStyle=sky; ctx.fillRect(0,0,W,H*0.6);
    // 地面
    ctx.fillStyle="#2a1a0a"; ctx.fillRect(0,H*0.55,W,H*0.45);
    // 战旗
    for(var i=0;i<7;i++){
      var fx=W*0.1+i*W*0.13, fy=H*0.25+Math.sin(t*0.8+i)*3;
      ctx.strokeStyle="rgba(200,50,20,"+(0.5+Math.sin(t+i)*0.2)+")"; ctx.lineWidth=2;
      ctx.beginPath(); ctx.moveTo(fx,fy+40); ctx.lineTo(fx,fy); ctx.stroke();
      ctx.fillStyle="rgba(200,50,20,"+(0.4+Math.sin(t*0.5+i)*0.1)+")";
      ctx.beginPath(); ctx.moveTo(fx,fy); ctx.lineTo(fx+14,fy+5); ctx.lineTo(fx,fy+20); ctx.fill();
    }
    // 士兵剪影
    for(var i=0;i<12;i++){
      var sx=W*0.05+i*W*0.08, sy=H*0.55+Math.sin(t*1.2+i*0.5)*2;
      ctx.fillStyle="rgba(40,20,10,0.8)";
      ctx.beginPath(); ctx.ellipse(sx,sy,6,14,0,0,Math.PI*2); ctx.fill();
      ctx.fillRect(sx-2,sy+12,4,10);
    }
    // 烟尘
    for(var i=0;i<5;i++){
      var dx=((t*20+i*W*0.2)%W);
      ctx.fillStyle="rgba(150,100,50,"+(0.05+Math.sin(t+i)*0.03)+")";
      ctx.beginPath(); ctx.ellipse(dx,H*0.65,30+Math.sin(i)*10,8,0,0,Math.PI*2); ctx.fill();
    }
  },
  // 酒池肉林 - 宫殿+酒池
  "jiu": function(ctx,W,H,t){
    var sky=ctx.createLinearGradient(0,0,0,H); sky.addColorStop(0,"#0a0a1a"); sky.addColorStop(1,"#1a1a2a");
    ctx.fillStyle=sky; ctx.fillRect(0,0,W,H);
    // 宫殿轮廓
    ctx.fillStyle="rgba(80,60,30,0.3)"; ctx.fillRect(W*0.1,H*0.2,W*0.8,H*0.5);
    ctx.strokeStyle="rgba(212,175,106,0.3)"; ctx.lineWidth=2;
    ctx.beginPath(); ctx.moveTo(W*0.1,H*0.2); ctx.lineTo(W*0.5,H*0.05); ctx.lineTo(W*0.9,H*0.2); ctx.stroke();
    // 酒池
    ctx.fillStyle="rgba(50,80,120,"+(0.2+Math.sin(t*0.5)*0.05)+")";
    ctx.beginPath(); ctx.ellipse(W*0.5,H*0.7,W*0.3,H*0.08,0,0,Math.PI*2); ctx.fill();
    // 波纹
    ctx.strokeStyle="rgba(100,150,200,0.15)"; ctx.lineWidth=1;
    for(var i=0;i<5;i++){
      var ry=H*0.7+i*8+Math.sin(t*0.8+i)*3;
      ctx.beginPath(); ctx.moveTo(W*0.2,ry); ctx.lineTo(W*0.8,ry); ctx.stroke();
    }
    // 肉林(悬挂)
    for(var i=0;i<6;i++){
      var mx=W*0.2+i*W*0.12, my=H*0.15+Math.sin(t+i)*2;
      ctx.strokeStyle="rgba(100,60,30,0.3)"; ctx.lineWidth=1;
      ctx.beginPath(); ctx.moveTo(mx,0); ctx.lineTo(mx,my); ctx.stroke();
      ctx.fillStyle="rgba(150,50,30,0.2)"; ctx.fillRect(mx-5,my,10,15);
    }
  },
  // 倒戈 - 两军对垒转向
  "daoge": function(ctx,W,H,t){
    ctx.fillStyle="#0a0e0a"; ctx.fillRect(0,0,W,H);
    ctx.fillStyle="#1a2a1a"; ctx.fillRect(0,H*0.6,W,H*0.4);
    // 左军(周)
    for(var i=0;i<8;i++){
      var sx=i*W*0.08+W*0.05, sy=H*0.5+Math.sin(t+i)*2;
      ctx.fillStyle="rgba(80,120,80,0.6)";
      ctx.beginPath(); ctx.ellipse(sx,sy,5,12,0,0,Math.PI*2); ctx.fill();
      ctx.strokeStyle="rgba(100,180,100,0.5)"; ctx.lineWidth=2;
      ctx.beginPath(); ctx.moveTo(sx+5,sy); ctx.lineTo(sx+15,sy-3); ctx.stroke();
    }
    // 右军(商,部分倒戈)
    for(var i=0;i<8;i++){
      var sx=W*0.55+i*W*0.05, sy=H*0.5+Math.sin(t+i*0.7)*2;
      var defected=i>4;
      ctx.fillStyle=defected?"rgba(80,120,80,0.6)":"rgba(120,50,30,0.6)";
      ctx.beginPath(); ctx.ellipse(sx,sy,5,12,0,0,Math.PI*2); ctx.fill();
      ctx.strokeStyle=defected?"rgba(100,180,100,0.5)":"rgba(200,80,40,0.5)"; ctx.lineWidth=2;
      ctx.beginPath(); ctx.moveTo(defected?sx-12:sx+5,sy); ctx.lineTo(defected?sx-20:sx+15,sy-3); ctx.stroke();
    }
  },
  // 三监 - 城池+三旗
  "sanjian": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 城墙
    ctx.fillStyle="rgba(60,50,30,0.5)"; ctx.fillRect(W*0.2,H*0.4,W*0.6,H*0.3);
    ctx.fillStyle="rgba(80,70,40,0.4)";
    for(var i=0;i<10;i++) ctx.fillRect(W*0.2+i*W*0.06,H*0.4,4,8);
    // 三监旗帜
    var colors=["#c04020","#2060c0","#20c040"];
    for(var i=0;i<3;i++){
      var fx=W*0.3+i*W*0.2, fy=H*0.25+Math.sin(t*0.6+i)*3;
      ctx.strokeStyle=colors[i]+"80"; ctx.lineWidth=2;
      ctx.beginPath(); ctx.moveTo(fx,fy+30); ctx.lineTo(fx,fy); ctx.stroke();
      ctx.fillStyle=colors[i]+"60";
      ctx.beginPath(); ctx.moveTo(fx,fy); ctx.lineTo(fx+12,fy+4); ctx.lineTo(fx,fy+16); ctx.fill();
    }
  },
  // 鹿台 - 高台+火焰
  "lutai": function(ctx,W,H,t){
    ctx.fillStyle="#050505"; ctx.fillRect(0,0,W,H);
    // 高台
    ctx.fillStyle="rgba(80,50,20,0.5)";
    ctx.beginPath(); ctx.moveTo(W*0.3,H*0.8); ctx.lineTo(W*0.35,H*0.2); ctx.lineTo(W*0.65,H*0.2); ctx.lineTo(W*0.7,H*0.8); ctx.fill();
    // 火焰
    for(var i=0;i<8;i++){
      var fx=W*0.35+i*W*0.05, fy=H*0.2+Math.sin(t*2+i)*5;
      var flameH=20+Math.sin(t*3+i*0.7)*15+Math.random()*10;
      var grad=ctx.createLinearGradient(fx,fy,fx,fy-flameH);
      grad.addColorStop(0,"rgba(255,200,50,0.8)"); grad.addColorStop(0.5,"rgba(255,80,0,0.5)"); grad.addColorStop(1,"transparent");
      ctx.fillStyle=grad; ctx.beginPath(); ctx.ellipse(fx,fy,8+Math.sin(i)*3,flameH,0,Math.PI,0); ctx.fill();
    }
    // 宝玉
    for(var i=0;i<5;i++){
      var bx=W*0.4+i*W*0.05, by=H*0.3+Math.sin(t*1.5+i)*2;
      ctx.fillStyle="rgba(255,100,150,"+(0.3+Math.sin(t+i)*0.2)+")";
      ctx.beginPath(); ctx.arc(bx,by,4,0,Math.PI*2); ctx.fill();
    }
  },
  // 利簋 - 青铜器
  "liqi": function(ctx,W,H,t){
    ctx.fillStyle="#0a0805"; ctx.fillRect(0,0,W,H);
    // 青铜鼎
    var cx=W*0.5, cy=H*0.5+Math.sin(t*0.3)*3;
    ctx.fillStyle="rgba(60,80,40,0.4)";
    ctx.beginPath(); ctx.ellipse(cx,cy,40,30,0,0,Math.PI*2); ctx.fill();
    ctx.fillStyle="rgba(80,100,50,0.3)";
    ctx.fillRect(cx-35,cy-50,10,30); ctx.fillRect(cx+25,cy-50,10,30);
    ctx.beginPath(); ctx.moveTo(cx-40,cy-50); ctx.lineTo(cx+40,cy-50); ctx.lineTo(cx+30,cy-60); ctx.lineTo(cx-30,cy-60); ctx.fill();
    // 铭文光效
    ctx.fillStyle="rgba(212,175,106,"+(0.1+Math.sin(t)*0.05)+")";
    ctx.font="8px serif"; ctx.textAlign="center";
    ctx.fillText("岁鼎克闻夙有商",cx,cy+5); ctx.textAlign="left";
    // 星光
    for(var i=0;i<8;i++){
      var sx=W*0.1+i*W*0.12, sy=H*0.15+Math.sin(t*0.7+i)*20;
      ctx.fillStyle="rgba(212,175,106,"+(0.3+Math.sin(t*2+i)*0.2)+")";
      ctx.beginPath(); ctx.arc(sx,sy,2,0,Math.PI*2); ctx.fill();
    }
  },
  // 箕子 - 东行
  "jizi": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a1a"; ctx.fillRect(0,0,W,H);
    // 海岸线
    ctx.fillStyle="rgba(20,30,60,0.3)"; ctx.fillRect(0,H*0.7,W,H*0.3);
    // 海浪
    ctx.strokeStyle="rgba(60,80,120,0.2)"; ctx.lineWidth=1;
    for(var i=0;i<6;i++){
      var wy=H*0.72+i*12+Math.sin(t*0.6+i)*4;
      ctx.beginPath(); ctx.moveTo(0,wy);
      for(var x=0;x<W;x+=20) ctx.lineTo(x,wy+Math.sin(x*0.02+t+i)*3);
      ctx.stroke();
    }
    // 队伍东行
    for(var i=0;i<5;i++){
      var px=((t*15+i*30)%W), py=H*0.55+Math.sin(t+i)*2;
      ctx.fillStyle="rgba(100,80,50,0.5)";
      ctx.beginPath(); ctx.ellipse(px,py,4,10,0,0,Math.PI*2); ctx.fill();
    }
  },
  // 诗经
  "shijing": function(ctx,W,H,t){
    ctx.fillStyle="#0a0e0a"; ctx.fillRect(0,0,W,H);
    // 竹简
    for(var i=0;i<8;i++){
      var jx=W*0.15+i*W*0.1, jy=H*0.3+Math.sin(t*0.3+i*0.2)*2;
      ctx.fillStyle="rgba(180,150,100,"+(0.15+Math.sin(t+i)*0.05)+")";
      ctx.fillRect(jx-15,jy,30,50);
      ctx.strokeStyle="rgba(100,70,30,0.2)"; ctx.lineWidth=0.5;
      for(var j=0;j<6;j++){ ctx.beginPath(); ctx.moveTo(jx-15,jy+8+j*7); ctx.lineTo(jx+15,jy+8+j*7); ctx.stroke(); }
    }
    // 文字飘动
    ctx.fillStyle="rgba(212,175,106,"+(0.2+Math.sin(t*0.5)*0.1)+")";
    ctx.font="12px serif"; ctx.textAlign="center";
    ctx.fillText("牧野洋洋",W*0.5,H*0.2); ctx.textAlign="left";
  },
  // 长平战场 - 山壑+军阵
  "changping": function(ctx,W,H,t){
    ctx.fillStyle="#0e1410"; ctx.fillRect(0,0,W,H);
    // 山壑
    ctx.fillStyle="rgba(30,50,30,0.3)";
    for(var i=0;i<5;i++){
      var hx=W*0.1+i*W*0.2, hy=H*0.15+Math.sin(t*0.4+i)*5;
      ctx.beginPath(); ctx.ellipse(hx,hy,W*0.12,H*0.1,0,0,Math.PI*2); ctx.fill();
    }
    // 壁垒
    ctx.fillStyle="rgba(60,50,30,0.4)";
    ctx.fillRect(W*0.05,H*0.6,W*0.35,15);
    ctx.fillRect(W*0.6,H*0.55,W*0.35,15);
    // 士兵
    for(var i=0;i<6;i++){
      var sx=W*0.1+i*W*0.05, sy=H*0.55+Math.sin(t*1.5+i)*2;
      ctx.fillStyle="rgba(80,100,60,0.5)";
      ctx.beginPath(); ctx.ellipse(sx,sy,4,10,0,0,Math.PI*2); ctx.fill();
    }
  },
  // 赵括 - 骑兵冲锋
  "zhao": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 扬尘
    for(var i=0;i<6;i++){
      var dx=((W-(t*30+i*50))%W+W)%W;
      ctx.fillStyle="rgba(120,100,60,"+(0.05+Math.sin(t+i)*0.03)+")";
      ctx.beginPath(); ctx.ellipse(dx,H*0.7,25+Math.sin(i)*8,6,0,0,Math.PI*2); ctx.fill();
    }
    // 骑兵
    for(var i=0;i<3;i++){
      var cx=W*0.3+i*W*0.2+Math.sin(t*0.5)*10, cy=H*0.55+Math.sin(t+i)*3;
      ctx.fillStyle="rgba(100,80,40,0.6)"; ctx.beginPath(); ctx.ellipse(cx,cy,8,16,0,0,Math.PI*2); ctx.fill();
      ctx.fillStyle="rgba(60,40,20,0.5)"; ctx.beginPath(); ctx.ellipse(cx-12,cy+10,14,6,0,0,Math.PI*2); ctx.fill();
    }
  },
  // 反间 - 密信
  "fanjian": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 卷轴
    var rx=W*0.5+Math.sin(t*0.2)*5, ry=H*0.4+Math.sin(t*0.3)*3;
    ctx.fillStyle="rgba(200,180,120,0.2)"; ctx.fillRect(rx-60,ry-40,120,80);
    ctx.strokeStyle="rgba(150,120,60,0.3)"; ctx.lineWidth=2;
    ctx.strokeRect(rx-60,ry-40,120,80);
    // 文字
    ctx.fillStyle="rgba(100,60,20,0.3)"; ctx.font="8px serif"; ctx.textAlign="center";
    ctx.fillText("秦之所恶",rx,ry-10); ctx.fillText("独畏马服子",rx,ry+5); ctx.fillText("赵括",rx,ry+20); ctx.textAlign="left";
    // 阴影
    ctx.fillStyle="rgba(0,0,0,0.3)"; ctx.fillRect(rx-58,ry+42,120,5);
  },
  // 上党
  "shangdang": function(ctx,W,H,t){
    ctx.fillStyle="#0a100a"; ctx.fillRect(0,0,W,H);
    // 山城
    for(var i=0;i<4;i++){
      var cx=W*0.2+i*W*0.2, cy=H*0.3+Math.sin(i)*10;
      ctx.fillStyle="rgba(60,80,50,0.3)";
      ctx.beginPath(); ctx.moveTo(cx-20,cy+30); ctx.lineTo(cx,cy-10); ctx.lineTo(cx+20,cy+30); ctx.fill();
    }
    // 旗帜
    for(var i=0;i<4;i++){
      var fx=W*0.2+i*W*0.2, fy=H*0.2+Math.sin(t+i)*2;
      ctx.strokeStyle="rgba(200,180,100,0.3)"; ctx.lineWidth=1.5;
      ctx.beginPath(); ctx.moveTo(fx,fy+20); ctx.lineTo(fx,fy); ctx.stroke();
    }
  },
  // 坑杀 - 深坑+白骨
  "keng": function(ctx,W,H,t){
    ctx.fillStyle="#050505"; ctx.fillRect(0,0,W,H);
    // 坑
    ctx.fillStyle="rgba(30,20,10,0.6)";
    ctx.beginPath(); ctx.ellipse(W*0.5,H*0.6,W*0.35,H*0.15,0,0,Math.PI*2); ctx.fill();
    // 白骨
    for(var i=0;i<8;i++){
      var bx=W*0.25+i*W*0.08+Math.sin(t*0.3+i)*3, by=H*0.55+Math.sin(i)*5;
      ctx.strokeStyle="rgba(180,170,150,"+(0.15+Math.sin(t+i)*0.05)+")"; ctx.lineWidth=2;
      ctx.beginPath(); ctx.moveTo(bx,by); ctx.lineTo(bx+15,by-5); ctx.stroke();
    }
    // 暗红光
    ctx.fillStyle="rgba(100,0,0,"+(0.05+Math.sin(t*0.5)*0.03)+")";
    ctx.beginPath(); ctx.ellipse(W*0.5,H*0.6,W*0.3,H*0.12,0,0,Math.PI*2); ctx.fill();
  },
  // 白起
  "baiqi": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 剑
    var sx=W*0.5, sy=H*0.3+Math.sin(t*0.2)*3;
    ctx.strokeStyle="rgba(180,180,200,0.3)"; ctx.lineWidth=3;
    ctx.beginPath(); ctx.moveTo(sx,sy); ctx.lineTo(sx,sy+80); ctx.stroke();
    ctx.fillStyle="rgba(100,80,40,0.4)"; ctx.fillRect(sx-8,sy+80,16,20);
    // 血迹
    ctx.fillStyle="rgba(150,0,0,"+(0.1+Math.sin(t)*0.05)+")";
    for(var i=0;i<5;i++){ ctx.beginPath(); ctx.arc(sx+Math.random()*20-10,sy+20+Math.random()*60,2,0,Math.PI*2); ctx.fill(); }
  },
  // 虞卿
  "yuqing": function(ctx,W,H,t){
    ctx.fillStyle="#0a0e0a"; ctx.fillRect(0,0,W,H);
    // 地图
    ctx.fillStyle="rgba(30,50,30,0.2)"; ctx.fillRect(W*0.2,H*0.25,W*0.6,H*0.5);
    ctx.strokeStyle="rgba(80,120,80,0.2)"; ctx.lineWidth=1;
    for(var i=0;i<5;i++){ ctx.beginPath(); ctx.moveTo(W*0.2,H*0.3+i*H*0.08); ctx.lineTo(W*0.8,H*0.3+i*H*0.08); ctx.stroke(); }
    // 标记
    ctx.fillStyle="rgba(200,180,50,0.3)"; ctx.beginPath(); ctx.arc(W*0.4,H*0.4,5,0,Math.PI*2); ctx.fill();
    ctx.fillStyle="rgba(200,50,50,0.3)"; ctx.beginPath(); ctx.arc(W*0.6,H*0.5,5,0,Math.PI*2); ctx.fill();
  },
  // 赤壁 - 江面火船
  "chibi": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a1a"; ctx.fillRect(0,0,W,H);
    // 江水
    ctx.fillStyle="rgba(10,20,40,0.5)"; ctx.fillRect(0,H*0.3,W,H*0.7);
    // 水波
    ctx.strokeStyle="rgba(40,60,100,0.15)"; ctx.lineWidth=1;
    for(var i=0;i<10;i++){
      var wy=H*0.35+i*H*0.06+Math.sin(t*0.8+i)*4;
      ctx.beginPath(); ctx.moveTo(0,wy);
      for(var x=0;x<W;x+=25) ctx.lineTo(x,wy+Math.sin(x*0.015+t*0.5+i)*3);
      ctx.stroke();
    }
    // 火船
    for(var i=0;i<3;i++){
      var bx=((t*25+i*W*0.3)%W), by=H*0.45+i*H*0.1+Math.sin(t+i)*3;
      ctx.fillStyle="rgba(60,40,20,0.6)"; ctx.fillRect(bx-20,by-5,40,12);
      // 火焰
      for(var j=0;j<5;j++){
        var fx=bx-15+j*8, fy=by-8+Math.sin(t*3+j)*3;
        var fh=10+Math.sin(t*4+j)*8;
        var fg=ctx.createLinearGradient(fx,fy,fx,fy-fh);
        fg.addColorStop(0,"rgba(255,200,50,0.7)"); fg.addColorStop(1,"transparent");
        ctx.fillStyle=fg; ctx.beginPath(); ctx.ellipse(fx,fy,5,8,0,Math.PI,0); ctx.fill();
      }
    }
  },
  // 长江
  "jiang": function(ctx,W,H,t){
    ctx.fillStyle="#0a1020"; ctx.fillRect(0,0,W,H);
    // 江面
    ctx.fillStyle="rgba(20,40,60,0.4)"; ctx.fillRect(0,H*0.25,W,H*0.75);
    ctx.strokeStyle="rgba(60,100,140,0.15)"; ctx.lineWidth=1;
    for(var i=0;i<8;i++){
      var wy=H*0.3+i*H*0.08+Math.sin(t*0.6+i)*4;
      ctx.beginPath(); ctx.moveTo(0,wy);
      for(var x=0;x<W;x+=30) ctx.lineTo(x,wy+Math.sin(x*0.01+t+i)*3);
      ctx.stroke();
    }
    // 船影
    for(var i=0;i<2;i++){
      var bx=W*0.3+i*W*0.4+Math.sin(t*0.3+i)*10, by=H*0.5+i*H*0.15;
      ctx.fillStyle="rgba(40,30,20,0.5)"; ctx.fillRect(bx-15,by-4,30,10);
    }
  },
  // 孙刘联盟
  "sunliu": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a1a"; ctx.fillRect(0,0,W,H);
    // 两张案几
    for(var i=0;i<2;i++){
      var ax=W*0.3+i*W*0.4, ay=H*0.5+Math.sin(t*0.4+i)*3;
      ctx.fillStyle="rgba(80,60,30,0.4)"; ctx.fillRect(ax-20,ay,40,5);
      // 人物剪影
      ctx.fillStyle="rgba(100,80,50,0.5)";
      ctx.beginPath(); ctx.ellipse(ax,ay-15,8,18,0,0,Math.PI*2); ctx.fill();
    }
    // 盟书
    ctx.fillStyle="rgba(200,180,120,0.2)"; ctx.fillRect(W*0.45,H*0.45,30,40);
    ctx.strokeStyle="rgba(150,120,60,0.3)"; ctx.strokeRect(W*0.45,H*0.45,30,40);
  },
  // 黄盖
  "huanggai": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a15"; ctx.fillRect(0,0,W,H);
    // 火船
    var bx=W*0.5+Math.sin(t*0.2)*5, by=H*0.5+Math.sin(t*0.3)*3;
    ctx.fillStyle="rgba(60,40,20,0.6)"; ctx.fillRect(bx-25,by-5,50,14);
    // 火焰
    for(var i=0;i<8;i++){
      var fx=bx-20+i*6, fy=by-10+Math.sin(t*2.5+i)*4;
      var fh=12+Math.sin(t*3+i)*10;
      var fg=ctx.createLinearGradient(fx,fy,fx,fy-fh);
      fg.addColorStop(0,"rgba(255,180,30,0.8)"); fg.addColorStop(1,"transparent");
      ctx.fillStyle=fg; ctx.beginPath(); ctx.ellipse(fx,fy,4,fh*0.5,0,Math.PI,0); ctx.fill();
    }
    // 信
    ctx.fillStyle="rgba(200,180,120,0.25)"; ctx.fillRect(W*0.7,H*0.3,25,35);
  },
  // 华容道
  "huarong": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 泥泞路
    ctx.fillStyle="rgba(40,30,15,0.4)"; ctx.fillRect(W*0.3,H*0.3,W*0.4,H*0.5);
    // 脚印
    for(var i=0;i<8;i++){
      var px=W*0.35+i*W*0.04+Math.sin(i)*5, py=H*0.35+i*H*0.05+Math.sin(t+i)*2;
      ctx.fillStyle="rgba(80,60,30,0.2)";
      ctx.beginPath(); ctx.ellipse(px,py,4,7,0,0,Math.PI*2); ctx.fill();
    }
    // 残兵
    for(var i=0;i<3;i++){
      var cx=W*0.38+i*W*0.1, cy=H*0.6+Math.sin(t*0.8+i)*3;
      ctx.fillStyle="rgba(80,60,40,0.4)";
      ctx.beginPath(); ctx.ellipse(cx,cy,4,12,0,0,Math.PI*2); ctx.fill();
    }
  },
  // 荆州
  "jingzhou": function(ctx,W,H,t){
    ctx.fillStyle="#0a1015"; ctx.fillRect(0,0,W,H);
    // 城池
    ctx.fillStyle="rgba(50,60,70,0.3)"; ctx.fillRect(W*0.25,H*0.3,W*0.5,H*0.4);
    ctx.strokeStyle="rgba(80,100,120,0.3)"; ctx.lineWidth=2;
    ctx.strokeRect(W*0.25,H*0.3,W*0.5,H*0.4);
    // 旗帜
    for(var i=0;i<4;i++){
      var fx=W*0.3+i*W*0.13, fy=H*0.2+Math.sin(t*0.7+i)*3;
      ctx.strokeStyle="rgba(100,150,200,0.3)"; ctx.lineWidth=1.5;
      ctx.beginPath(); ctx.moveTo(fx,fy+15); ctx.lineTo(fx,fy); ctx.stroke();
    }
  },
  // 曹操
  "caocao": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 诗卷
    ctx.fillStyle="rgba(200,180,120,0.15)"; ctx.fillRect(W*0.3,H*0.25,W*0.4,H*0.5);
    ctx.strokeStyle="rgba(150,120,60,0.2)"; ctx.strokeRect(W*0.3,H*0.25,W*0.4,H*0.5);
    ctx.fillStyle="rgba(212,175,106,"+(0.2+Math.sin(t*0.5)*0.1)+")";
    ctx.font="11px serif"; ctx.textAlign="center";
    ctx.fillText("对酒当歌",W*0.5,H*0.35);
    ctx.fillText("人生几何",W*0.5,H*0.45);
    ctx.fillText("周公吐哺",W*0.5,H*0.55);
    ctx.fillText("天下归心",W*0.5,H*0.65); ctx.textAlign="left";
  },
  // 淝水
  "feishui": function(ctx,W,H,t){
    ctx.fillStyle="#0a1a1a"; ctx.fillRect(0,0,W,H);
    // 河水
    ctx.fillStyle="rgba(20,50,50,0.3)"; ctx.fillRect(0,H*0.35,W,H*0.65);
    ctx.strokeStyle="rgba(40,100,100,0.15)"; ctx.lineWidth=1;
    for(var i=0;i<8;i++){
      var wy=H*0.4+i*H*0.07+Math.sin(t*0.7+i)*4;
      ctx.beginPath(); ctx.moveTo(0,wy);
      for(var x=0;x<W;x+=25) ctx.lineTo(x,wy+Math.sin(x*0.012+t+i)*3); ctx.stroke();
    }
    // 八公山
    for(var i=0;i<6;i++){
      var mx=W*0.1+i*W*0.16, my=H*0.1+Math.sin(t*0.3+i)*4;
      ctx.fillStyle="rgba(30,80,80,0.2)";
      ctx.beginPath(); ctx.ellipse(mx,my,W*0.08,H*0.06,0,0,Math.PI*2); ctx.fill();
    }
  },
  // 投鞭断流
  "toubian": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 江面
    ctx.fillStyle="rgba(20,30,40,0.4)"; ctx.fillRect(0,H*0.3,W,H*0.7);
    // 鞭子(密集线条)
    for(var i=0;i<20;i++){
      var bx=W*0.1+i*W*0.04, by=H*0.35+Math.sin(t+i)*2;
      ctx.strokeStyle="rgba(150,120,80,"+(0.1+Math.sin(t*2+i)*0.05)+")"; ctx.lineWidth=1.5;
      ctx.beginPath(); ctx.moveTo(bx,by); ctx.lineTo(bx+10,by-15); ctx.stroke();
    }
  },
  // 八公山
  "bagong": function(ctx,W,H,t){
    ctx.fillStyle="#0a1515"; ctx.fillRect(0,0,W,H);
    for(var i=0;i<7;i++){
      var mx=W*0.08+i*W*0.14, my=H*0.15+Math.sin(t*0.4+i)*5;
      ctx.fillStyle="rgba(40,90,90,0.25)";
      ctx.beginPath(); ctx.ellipse(mx,my,W*0.1,H*0.08,0,0,Math.PI*2); ctx.fill();
    }
    // 草木(细小竖线)
    for(var i=0;i<30;i++){
      var gx=Math.random()*W, gy=H*0.2+Math.random()*H*0.3;
      ctx.strokeStyle="rgba(60,120,80,0.15)"; ctx.lineWidth=1;
      ctx.beginPath(); ctx.moveTo(gx,gy); ctx.lineTo(gx,gy-10-Math.random()*10); ctx.stroke();
    }
  },
  // 朱序
  "zhuxu": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 军阵
    for(var i=0;i<10;i++){
      var sx=i*W*0.09+W*0.05, sy=H*0.5+Math.sin(t+i)*2;
      ctx.fillStyle="rgba(80,80,60,0.4)";
      ctx.beginPath(); ctx.ellipse(sx,sy,4,10,0,0,Math.PI*2); ctx.fill();
    }
    // 呼喊波纹
    for(var i=0;i<3;i++){
      var r=((t*40+i*30)%(W*0.4));
      ctx.strokeStyle="rgba(200,200,100,"+(1-r/(W*0.4))*0.2+")"; ctx.lineWidth=2;
      ctx.beginPath(); ctx.arc(W*0.5,H*0.5,r,0,Math.PI*2); ctx.stroke();
    }
  },
  // 北府兵
  "beifu": function(ctx,W,H,t){
    ctx.fillStyle="#0a1010"; ctx.fillRect(0,0,W,H);
    // 军旗
    for(var i=0;i<4;i++){
      var fx=W*0.2+i*W*0.2, fy=H*0.2+Math.sin(t*0.6+i)*3;
      ctx.strokeStyle="rgba(180,50,30,0.3)"; ctx.lineWidth=2;
      ctx.beginPath(); ctx.moveTo(fx,fy+30); ctx.lineTo(fx,fy); ctx.stroke();
    }
    // 士兵列阵
    for(var r=0;r<3;r++){
      for(var c=0;c<6;c++){
        var sx=W*0.2+c*W*0.1, sy=H*0.45+r*H*0.12+Math.sin(t+r+c)*2;
        ctx.fillStyle="rgba(80,100,80,0.4)";
        ctx.beginPath(); ctx.ellipse(sx,sy,3,9,0,0,Math.PI*2); ctx.fill();
      }
    }
  },
  // 谢安
  "xiean": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 棋盘
    ctx.fillStyle="rgba(120,90,50,0.2)"; ctx.fillRect(W*0.3,H*0.3,W*0.4,H*0.4);
    ctx.strokeStyle="rgba(150,120,80,0.2)"; ctx.lineWidth=1;
    for(var i=0;i<5;i++){ ctx.beginPath(); ctx.moveTo(W*0.3,H*0.3+i*H*0.08); ctx.lineTo(W*0.7,H*0.3+i*H*0.08); ctx.stroke(); ctx.beginPath(); ctx.moveTo(W*0.3+i*W*0.08,H*0.3); ctx.lineTo(W*0.3+i*W*0.08,H*0.7); ctx.stroke(); }
    // 棋子
    ctx.fillStyle="rgba(200,200,200,0.3)"; ctx.beginPath(); ctx.arc(W*0.4,H*0.4,4,0,Math.PI*2); ctx.fill();
    ctx.fillStyle="rgba(50,50,50,0.4)"; ctx.beginPath(); ctx.arc(W*0.5,H*0.5,4,0,Math.PI*2); ctx.fill();
  },
  // 王猛
  "wangmeng": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 病榻
    ctx.fillStyle="rgba(60,40,20,0.3)"; ctx.fillRect(W*0.3,H*0.4,W*0.4,H*0.25);
    // 人物
    ctx.fillStyle="rgba(100,80,50,0.4)";
    ctx.beginPath(); ctx.ellipse(W*0.5,H*0.35,10,20,0,0,Math.PI*2); ctx.fill();
    // 遗书
    ctx.fillStyle="rgba(200,180,120,0.2)"; ctx.fillRect(W*0.55,H*0.42,20,30);
  },
  // 安史之乱
  "anshi": function(ctx,W,H,t){
    ctx.fillStyle="#1a0a0a"; ctx.fillRect(0,0,W,H);
    // 烽火
    for(var i=0;i<3;i++){
      var fx=W*0.2+i*W*0.3, fy=H*0.25+Math.sin(t*0.5+i)*3;
      for(var j=0;j<5;j++){
        var ffy=fy-j*15+Math.sin(t*2+j)*3;
        ctx.fillStyle="rgba(255,"+(100-j*15)+",0,"+(0.15-j*0.02)+")";
        ctx.beginPath(); ctx.ellipse(fx,ffy,6+j*2,10+j*3,0,Math.PI,0); ctx.fill();
      }
    }
    // 烟尘
    for(var i=0;i<4;i++){
      var dx=((t*15+i*W*0.25)%W);
      ctx.fillStyle="rgba(100,50,30,0.08)";
      ctx.beginPath(); ctx.ellipse(dx,H*0.6,30,8,0,0,Math.PI*2); ctx.fill();
    }
  },
  // 马嵬坡
  "maweipo": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 佛堂
    ctx.fillStyle="rgba(60,50,40,0.3)"; ctx.fillRect(W*0.35,H*0.3,W*0.3,H*0.35);
    ctx.strokeStyle="rgba(100,80,60,0.3)"; ctx.lineWidth=2;
    ctx.beginPath(); ctx.moveTo(W*0.35,H*0.3); ctx.lineTo(W*0.5,H*0.15); ctx.lineTo(W*0.65,H*0.3); ctx.stroke();
    // 白绫
    ctx.strokeStyle="rgba(200,200,200,"+(0.2+Math.sin(t)*0.1)+")"; ctx.lineWidth=2;
    ctx.beginPath(); ctx.moveTo(W*0.5,H*0.15); ctx.lineTo(W*0.5,H*0.5); ctx.stroke();
    // 落花
    for(var i=0;i<6;i++){
      var lx=W*0.3+i*W*0.08, ly=((t*10+i*20)%(H*0.6))+H*0.1;
      ctx.fillStyle="rgba(200,100,100,"+(0.1+Math.sin(t+i)*0.05)+")";
      ctx.beginPath(); ctx.arc(lx,ly,3,0,Math.PI*2); ctx.fill();
    }
  },
  // 灵武
  "lingwu": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 城楼
    ctx.fillStyle="rgba(50,40,30,0.4)"; ctx.fillRect(W*0.25,H*0.35,W*0.5,H*0.3);
    ctx.fillStyle="rgba(70,50,30,0.3)"; ctx.fillRect(W*0.35,H*0.2,W*0.3,H*0.15);
    // 龙旗
    ctx.strokeStyle="rgba(200,30,30,0.3)"; ctx.lineWidth=2;
    ctx.beginPath(); ctx.moveTo(W*0.5,H*0.2); ctx.lineTo(W*0.5,H*0.05); ctx.stroke();
    ctx.fillStyle="rgba(200,30,30,0.25)"; ctx.fillRect(W*0.5,H*0.05,12,8);
  },
  // 睢阳
  "suiyang": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 城墙残破
    ctx.fillStyle="rgba(50,40,20,0.4)";
    ctx.fillRect(W*0.15,H*0.4,W*0.7,10);
    ctx.fillRect(W*0.15,H*0.4,10,H*0.25);
    ctx.fillRect(W*0.75,H*0.4,10,H*0.25);
    // 缺口
    ctx.clearRect(W*0.4,H*0.38,30,15);
    // 守军
    for(var i=0;i<4;i++){
      var sx=W*0.2+i*W*0.18, sy=H*0.35+Math.sin(t+i)*2;
      ctx.fillStyle="rgba(80,60,40,0.5)";
      ctx.beginPath(); ctx.ellipse(sx,sy,4,12,0,0,Math.PI*2); ctx.fill();
    }
  },
  // 颜真卿
  "yanzhenqing": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 书法
    ctx.fillStyle="rgba(200,180,150,0.1)"; ctx.fillRect(W*0.2,H*0.2,W*0.6,H*0.6);
    ctx.strokeStyle="rgba(150,120,80,0.15)"; ctx.strokeRect(W*0.2,H*0.2,W*0.6,H*0.6);
    ctx.fillStyle="rgba(50,30,20,"+(0.3+Math.sin(t*0.5)*0.1)+")";
    ctx.font="bold 24px serif"; ctx.textAlign="center";
    ctx.fillText("忠",W*0.35,H*0.4);
    ctx.fillText("烈",W*0.65,H*0.6); ctx.textAlign="left";
  },
  // 长恨歌
  "changhen": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a1a"; ctx.fillRect(0,0,W,H);
    // 月亮
    ctx.fillStyle="rgba(212,200,150,"+(0.15+Math.sin(t*0.3)*0.05)+")";
    ctx.beginPath(); ctx.arc(W*0.75,H*0.2,25,0,Math.PI*2); ctx.fill();
    // 诗句飘落
    ctx.fillStyle="rgba(212,175,106,"+(0.15+Math.sin(t*0.5)*0.08)+")";
    ctx.font="10px serif"; ctx.textAlign="center";
    var lines=["汉皇重色思倾国","御宇多年求不得","回眸一笑百媚生","六宫粉黛无颜色"];
    for(var i=0;i<4;i++){
      var ly=((t*8+i*40)%(H*0.6))+H*0.1;
      ctx.fillText(lines[i],W*0.5,ly);
    }
    ctx.textAlign="left";
  },
  // 藩镇
  "fan": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 三镇标记
    var names=["魏博","成德","卢龙"];
    var colors=["#c04020","#20c040","#2040c0"];
    for(var i=0;i<3;i++){
      var cx=W*0.2+i*W*0.3, cy=H*0.4+Math.sin(t*0.4+i)*5;
      ctx.fillStyle=colors[i]+"30";
      ctx.beginPath(); ctx.arc(cx,cy,30,0,Math.PI*2); ctx.fill();
      ctx.strokeStyle=colors[i]+"60"; ctx.lineWidth=2;
      ctx.stroke();
      ctx.fillStyle=colors[i]+"80"; ctx.font="10px serif"; ctx.textAlign="center";
      ctx.fillText(names[i],cx,cy+4); ctx.textAlign="left";
    }
  },
  // 靖康
  "jingkang": function(ctx,W,H,t){
    ctx.fillStyle="#050510"; ctx.fillRect(0,0,W,H);
    // 雪
    for(var i=0;i<20;i++){
      var sx=Math.random()*W, sy=((t*15+i*30)%H);
      ctx.fillStyle="rgba(200,200,255,"+(0.1+Math.sin(t+i)*0.05)+")";
      ctx.beginPath(); ctx.arc(sx,sy,2+Math.random()*2,0,Math.PI*2); ctx.fill();
    }
    // 汴京轮廓
    ctx.fillStyle="rgba(30,30,50,0.3)";
    ctx.fillRect(W*0.2,H*0.4,W*0.6,H*0.3);
    ctx.strokeStyle="rgba(80,80,120,0.2)"; ctx.lineWidth=1;
    ctx.strokeRect(W*0.2,H*0.4,W*0.6,H*0.3);
  },
  // 海上之盟
  "hai": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a1a"; ctx.fillRect(0,0,W,H);
    // 海浪
    ctx.strokeStyle="rgba(40,60,100,0.2)"; ctx.lineWidth=1;
    for(var i=0;i<8;i++){
      var wy=H*0.3+i*H*0.08+Math.sin(t*0.6+i)*4;
      ctx.beginPath(); ctx.moveTo(0,wy);
      for(var x=0;x<W;x+=30) ctx.lineTo(x,wy+Math.sin(x*0.01+t+i)*4); ctx.stroke();
    }
    // 船
    for(var i=0;i<2;i++){
      var bx=W*0.25+i*W*0.35+Math.sin(t*0.3+i)*8, by=H*0.5+i*H*0.15;
      ctx.fillStyle="rgba(50,40,30,0.5)"; ctx.fillRect(bx-15,by-4,30,10);
      ctx.fillStyle="rgba(80,60,40,0.4)"; ctx.fillRect(bx-2,by-12,4,8);
    }
  },
  // 花石纲
  "huashi": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 奇石
    for(var i=0;i<5;i++){
      var sx=W*0.15+i*W*0.17, sy=H*0.5+Math.sin(t*0.3+i)*3;
      ctx.fillStyle="rgba(100,120,100,0.2)";
      ctx.beginPath(); ctx.moveTo(sx-15,sy+20); ctx.lineTo(sx-5,sy-10); ctx.lineTo(sx+5,sy+5); ctx.lineTo(sx+15,sy-5); ctx.lineTo(sx+10,sy+20); ctx.fill();
    }
    // 花
    for(var i=0;i<6;i++){
      var fx=W*0.1+i*W*0.16, fy=H*0.25+Math.sin(t+i)*3;
      ctx.fillStyle="rgba(200,80,100,"+(0.1+Math.sin(t*1.5+i)*0.05)+")";
      ctx.beginPath(); ctx.arc(fx,fy,5,0,Math.PI*2); ctx.fill();
    }
  },
  // 李纲
  "ligang": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a0a"; ctx.fillRect(0,0,W,H);
    // 城墙
    ctx.fillStyle="rgba(40,35,25,0.5)"; ctx.fillRect(0,H*0.5,W,H*0.5);
    ctx.fillStyle="rgba(60,50,35,0.4)";
    for(var i=0;i<15;i++) ctx.fillRect(i*W*0.067,H*0.5,4,8);
    // 守军
    for(var i=0;i<8;i++){
      var sx=i*W*0.12+W*0.05, sy=H*0.42+Math.sin(t*1.2+i)*2;
      ctx.fillStyle="rgba(80,80,60,0.5)";
      ctx.beginPath(); ctx.ellipse(sx,sy,4,12,0,0,Math.PI*2); ctx.fill();
    }
  },
  // 艮岳
  "gen": function(ctx,W,H,t){
    ctx.fillStyle="#050505"; ctx.fillRect(0,0,W,H);
    // 假山
    for(var i=0;i<6;i++){
      var rx=W*0.15+i*W*0.14, ry=H*0.45+Math.sin(t*0.3+i)*3;
      ctx.fillStyle="rgba(60,70,60,0.3)";
      ctx.beginPath(); ctx.moveTo(rx-15,ry+20); ctx.lineTo(rx-5,ry-10); ctx.lineTo(rx+8,ry+5); ctx.lineTo(rx+12,ry-5); ctx.lineTo(rx+15,ry+20); ctx.fill();
    }
    // 残垣
    ctx.fillStyle="rgba(40,30,20,0.4)"; ctx.fillRect(W*0.05,H*0.65,W*0.9,5);
  },
  // 南宋
  "nan": function(ctx,W,H,t){
    ctx.fillStyle="#0a0a1a"; ctx.fillRect(0,0,W,H);
    // 临安轮廓
    ctx.fillStyle="rgba(20,30,50,0.3)";
    ctx.fillRect(W*0.25,H*0.35,W*0.5,H*0.35);
    ctx.strokeStyle="rgba(60,80,120,0.2)"; ctx.lineWidth=1;
    ctx.strokeRect(W*0.25,H*0.35,W*0.5,H*0.35);
    // 运河
    ctx.fillStyle="rgba(20,40,60,0.2)"; ctx.fillRect(W*0.1,H*0.6,W*0.8,8);
    // 旗帜
    for(var i=0;i<3;i++){
      var fx=W*0.35+i*W*0.15, fy=H*0.25+Math.sin(t*0.7+i)*3;
      ctx.strokeStyle="rgba(200,30,30,0.3)"; ctx.lineWidth=1.5;
      ctx.beginPath(); ctx.moveTo(fx,fy+20); ctx.lineTo(fx,fy); ctx.stroke();
    }
  },
  // 牵羊礼
  "huiqin": function(ctx,W,H,t){
    ctx.fillStyle="#050505"; ctx.fillRect(0,0,W,H);
    // 雪
    for(var i=0;i<15;i++){
      var sx=Math.random()*W, sy=((t*12+i*25)%H);
      ctx.fillStyle="rgba(200,200,255,0.08)";
      ctx.beginPath(); ctx.arc(sx,sy,2,0,Math.PI*2); ctx.fill();
    }
    // 人物(披羊皮)
    for(var i=0;i<3;i++){
      var px=W*0.3+i*W*0.2+Math.sin(t*0.2+i)*5, py=H*0.55;
      ctx.fillStyle="rgba(120,110,90,0.4)";
      ctx.beginPath(); ctx.ellipse(px,py,8,18,0,0,Math.PI*2); ctx.fill();
      // 羊皮
      ctx.fillStyle="rgba(180,170,150,0.2)";
      ctx.beginPath(); ctx.ellipse(px,py+5,12,15,0,0,Math.PI*2); ctx.fill();
    }
  },
  // 东京梦华录
  "menghua": function(ctx,W,H,t){
    ctx.fillStyle="#0a0805"; ctx.fillRect(0,0,W,H);
    // 书页
    for(var i=0;i<5;i++){
      var bx=W*0.2+i*W*0.12, by=H*0.25+Math.sin(t*0.3+i*0.3)*3;
      ctx.fillStyle="rgba(200,180,120,"+(0.12+Math.sin(t+i)*0.04)+")";
      ctx.fillRect(bx-15,by,30,50);
    }
    // 文字
    ctx.fillStyle="rgba(100,60,20,0.2)"; ctx.font="8px serif"; ctx.textAlign="center";
    ctx.fillText("暗想当年",W*0.5,H*0.2);
    ctx.fillText("节物风流",W*0.5,H*0.85); ctx.textAlign="left";
  }
};

// ============ 状态 ============
var curLevel=0, curQ=0, score=0, correctCount=0, wrongCount=0, answered=false;
var clearedLevels=[], shuffledQuestions=[];
var animId=null, sceneTime=0, flashColor="", flashTimer=0;

var scCv=document.getElementById('scene-canvas'), scCtx=scCv.getContext('2d');
var scW,scH;

function resizeSc(){ scW=scCv.width=window.innerWidth; scH=scCv.height=window.innerHeight; }
window.onresize=resizeSc; resizeSc();

// ============ 界面 ============
function showLevels(){ document.getElementById('start-screen').style.display='none'; document.getElementById('level-screen').style.display='flex'; renderLevelGrid(); }

function renderLevelGrid(){
  var grid=document.getElementById('level-grid'); grid.innerHTML='';
  for(var i=0;i<LEVELS.length;i++){
    var lv=LEVELS[i], cleared=clearedLevels.indexOf(i)>=0, locked=i>0&&clearedLevels.indexOf(i-1)<0;
    var card=document.createElement('div'); card.className='level-card'+(cleared?' cleared':'')+(locked?' locked':'');
    card.innerHTML='<div class="level-num">第'+(i+1)+'关</div><div class="level-name">'+lv.name+'</div><div class="level-era">'+lv.era+'</div><div class="level-desc">'+lv.desc+'<br>9题·三档难度</div>';
    if(!locked) card.onclick=function(idx){ return function(){ startLevel(idx); }; }(i);
    grid.appendChild(card);
  }
}

function startLevel(idx){
  curLevel=idx; curQ=0; score=0; correctCount=0; wrongCount=0;
  shuffledQuestions=LEVELS[idx].questions.slice().sort(function(){ return Math.random()-0.5; });
  document.getElementById('level-screen').style.display='none';
  document.getElementById('game-screen').style.display='block';
  loadQuestion();
  if(animId) cancelAnimationFrame(animId);
  sceneTime=0; flashColor=""; flashTimer=0;
  animateScene();
}

function loadQuestion(){
  var lv=LEVELS[curLevel], q=shuffledQuestions[curQ];
  document.getElementById('lvl-name').textContent='第'+(curLevel+1)+'关 · '+lv.name+' · '+lv.era;
  document.getElementById('prog-text').textContent='第 '+(curQ+1)+'/9 题 · 得分:'+score;
  document.getElementById('scene-title').textContent='— '+q.title+' —';
  document.getElementById('scene-desc').textContent=lv.questions.find(function(x){return x.title===q.title;}).scene||"";
  // 难度标签
  var dl=document.getElementById('diff-label');
  if(q.diff===0){ dl.textContent='⭐ 入门'; dl.style.background='rgba(100,200,100,.2)'; dl.style.color='#6c6'; }
  else if(q.diff===1){ dl.textContent='⭐⭐ 进阶'; dl.style.background='rgba(212,175,106,.2)'; dl.style.color='#d4af6a'; }
  else { dl.textContent='⭐⭐⭐ 硬核'; dl.style.background='rgba(200,60,60,.2)'; dl.style.color='#c44'; }
  document.getElementById('question-text').textContent=q.q;
  var grid=document.getElementById('options-grid'); grid.innerHTML='';
  if(q.type==="choice"){
    for(var i=0;i<q.options.length;i++){
      var btn=document.createElement('button'); btn.cla

Game Source: 华夏长卷·史实答题

Creator: RapidTurtle60

Libraries: none

Complexity: complex (996 lines, 55.9 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: game-rapidturtle60" to link back to the original. Then publish at arcadelab.ai/publish.