喵将传
by SwiftPirate21258 lines10.9 KB
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<title>喵将传</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:-apple-system,sans-serif;background:#1a1a2e;color:#fff;overflow-x:hidden;user-select:none}
.page{display:none;padding:10px;min-height:100vh}
.page.active{display:block}
/* 顶部 */
.topbar{background:#16213e;padding:10px;border-radius:10px;margin-bottom:10px;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:5px}
.topbar .res{font-size:12px;color:#ffd700}
/* 战斗 */
.battle-area{background:#0f3460;border-radius:10px;padding:10px;height:280px;position:relative;overflow:hidden}
.enemy{position:absolute;right:20px;top:50%;transform:translateY(-50%);font-size:50px}
.ally{position:absolute;left:20px;top:50%;transform:translateY(-50%);font-size:40px}
.hp-bar{width:120px;height:14px;background:#333;border-radius:7px;overflow:hidden;margin-top:5px}
.hp-fill{height:100%;background:linear-gradient(90deg,#e74c3c,#f39c12);transition:width .3s}
.dmg{position:absolute;color:#ff0;font-weight:bold;font-size:18px;animation:float 1s forwards;pointer-events:none}
@keyframes float{0%{opacity:1;transform:translateY(0)}100%{opacity:0;transform:translateY(-40px)}}
/* 按钮 */
.btn{background:linear-gradient(135deg,#e74c3c,#f39c12);color:#fff;border:none;border-radius:8px;padding:10px 18px;font-size:14px;font-weight:bold;cursor:pointer;margin:5px 3px}
.btn:active{transform:scale(.95)}
.btn2{background:#2980b9}
/* 底部菜单 */
.bottom-menu{position:fixed;bottom:0;left:0;right:0;background:#16213e;border-top:1px solid #0f3460;display:flex;justify-content:space-around;padding:8px 0;padding-bottom:env(safe-area-inset-bottom)}
.menu-item{text-align:center;font-size:11px;color:#aaa;cursor:pointer;padding:4px}
.menu-item.active{color:#ffd700}
.menu-item .icon{font-size:22px;display:block}
/* 养成 */
.card{background:#16213e;border-radius:10px;padding:12px;margin:8px 0}
.card h3{color:#ffd700;margin-bottom:8px;font-size:15px}
.progress{width:100%;height:10px;background:#333;border-radius:5px;overflow:hidden;margin:5px 0}
.progress-fill{height:100%;background:#27ae60}
/* 日志 */
.log{background:#0f3460;border-radius:8px;padding:8px;font-size:11px;max-height:100px;overflow-y:auto;margin-top:8px}
.log p{margin:2px 0;color:#ccc}
/* 关卡信息 */
.stage-info{text-align:center;font-size:13px;color:#aaa;margin:5px 0}
</style>
</head>
<body>
<!-- 战斗页 -->
<div class="page active" id="p-battle">
<div class="topbar">
<div>⚔️ <span id="stage">第1关</span></div>
<div class="res">💰<span id="gold">1000</span> 🐟<span id="fish">0</span> 💎<span id="gem">50</span></div>
<div class="res">战力:<span id="power">120</span></div>
</div>
<div class="stage-info">波数 <span id="wave">1</span>/5 | 敌人HP <span id="enemyHpText">100</span></div>
<div class="battle-area" id="field">
<div class="ally">🗡️<br><small id="allyHpText">120/120</small></div>
<div class="enemy" id="enemyEmoji">👹</div>
<div class="hp-bar" style="position:absolute;right:20px;top:75%"><div class="hp-fill" id="enemyHpBar" style="width:100%"></div></div>
</div>
<div style="text-align:center;margin:10px">
<button class="btn" onclick="startBattle()">▶ 开始战斗</button>
<button class="btn btn2" onclick="ult()">✦ 大招</button>
<button class="btn" onclick="toggleSpeed()">⏩ <span id="spd">1</span>x</button>
<button class="btn btn2" onclick="sweep()">📦 扫荡</button>
</div>
<div class="log" id="log"></div>
</div>
<!-- 猫将页 -->
<div class="page" id="p-cat">
<div class="topbar"><div>🐱 猫将养成</div><div class="res">碎片:<span id="frag">0</span></div></div>
<div class="card">
<h3>🗡️ 剑客喵 (主C)</h3>
<div>Lv.<span id="catLv">1</span> | 战力 <span id="catPwr">50</span></div>
<div class="progress"><div class="progress-fill" id="expBar" style="width:0%"></div></div>
<button class="btn" onclick="upgrade()">升级(200金)</button>
<button class="btn btn2" onclick="starUp()">升星(<span id="starCost">2</span>碎片)</button>
<div>星级: <span id="stars">⭐</span></div>
</div>
<div class="card">
<h3>🛡️ 盾猫 (前排)</h3>
<div>Lv.1 | 战力 40 | ⭐</div>
<button class="btn" disabled>未解锁(推到第5关)</button>
</div>
<div class="card">
<h3>🏹 弓姬 (输出)</h3>
<div>Lv.1 | 战力 30 | ⭐</div>
<button class="btn" disabled>未解锁(推到第10关)</button>
</div>
</div>
<!-- 装备页 -->
<div class="page" id="p-equip">
<div class="topbar"><div>⚔️ 装备</div></div>
<div class="card">
<h3>🗡️ 武器</h3>
<div id="eq-w">Lv.0 +0攻击</div>
<button class="btn" onclick="eqUp('w')">强化(150金)</button>
</div>
<div class="card">
<h3>🛡️ 护甲</h3>
<div id="eq-a">Lv.0 +0防御</div>
<button class="btn" onclick="eqUp('a')">强化(150金)</button>
</div>
<div class="card">
<h3>💍 饰品</h3>
<div id="eq-r">Lv.0 +0暴击</div>
<button class="btn" onclick="eqUp('r')">强化(150金)</button>
</div>
</div>
<!-- 底部菜单 -->
<div class="bottom-menu">
<div class="menu-item active" onclick="switchPage('p-battle',this)"><span class="icon">⚔️</span>战斗</div>
<div class="menu-item" onclick="switchPage('p-cat',this)"><span class="icon">🐱</span>猫将</div>
<div class="menu-item" onclick="switchPage('p-equip',this)"><span class="icon">⚔️</span>装备</div>
<div class="menu-item" onclick="alert('商店暂未开放')"><span class="icon">🏪</span>商店</div>
</div>
<script>
// ===== 数据 =====
let d = JSON.parse(localStorage.getItem('miaoSave') || 'null') || {
stage:1, wave:1, gold:1000, fish:0, gem:50, frag:0,
catLv:1, catStar:1, catExp:0, catPwr:50,
eq:{w:0,a:0,r:0}, power:120,
spd:1, fighting:false, enemyHp:100, enemyMax:100, allyHp:120, allyMax:120
};
// ===== 页面切换 =====
function switchPage(id,el){
document.querySelectorAll('.page').forEach(p=>p.classList.remove('active'));
document.getElementById(id).classList.add('active');
document.querySelectorAll('.menu-item').forEach(m=>m.classList.remove('active'));
if(el) el.classList.add('active');
render();
}
// ===== 战斗 =====
let timer=null;
function startBattle(){
if(d.fighting) return;
d.fighting=true; d.enemyMax=Math.floor(50*d.stage*Math.pow(1.15,d.stage-1));
d.enemyHp=d.enemyMax; d.allyHp=d.allyMax;
log(`⚔️ 进入第${d.stage}关!`);
render();
timer=setInterval(tick, 1000/d.spd);
}
function tick(){
if(!d.fighting) return;
// 我方攻击
let dmg = Math.floor(d.catPwr * (0.8+Math.random()*0.4));
if(Math.random()<0.2+eqBonus('r')*0.01){ dmg=Math.floor(dmg*2.5); showDmg('暴击!',d.enemyHp); }
else showDmg(dmg,d.enemyHp);
d.enemyHp-=dmg;
// 敌人攻击
if(d.enemyHp>0){
let edmg=Math.floor(15*d.stage*Math.pow(1.1,d.stage-1)/(1+eqBonus('a')*0.05));
d.allyHp-=edmg;
}
if(d.allyHp<=0){ log('💀 阵亡!'); endBattle(false); return; }
if(d.enemyHp<=0){
d.wave++;
if(d.wave>5){ log(`🎉 通关第${d.stage}关!`); d.stage++; d.wave=1; d.gold+=50*d.stage; d.frag+=d.stage; endBattle(true); return; }
else { log(`✅ 第${d.wave}波胜利`); d.enemyMax=Math.floor(50*d.stage*Math.pow(1.15,d.stage-1)*0.6); d.enemyHp=d.enemyMax; }
}
render();
}
function endBattle(win){
d.fighting=false; clearInterval(timer);
if(!win){ d.allyHp=d.allyMax; d.enemyHp=d.enemyMax; d.wave=1; }
save(); render();
}
function ult(){
if(!d.fighting) return;
let dmg=Math.floor(d.catPwr*5);
d.enemyHp-=dmg;
showDmg('喵喵五连斩!'+dmg,d.enemyHp);
log('✦ 释放大招!');
render();
}
function toggleSpeed(){
d.spd=d.spd>=4?1:d.spd*2;
document.getElementById('spd').innerText=d.spd;
if(d.fighting){ clearInterval(timer); timer=setInterval(tick,1000/d.spd); }
}
function sweep(){
if(d.stage<=1){ log('❌ 先通关第1关才能扫荡'); return; }
d.gold+=50*(d.stage-1); d.frag+=d.stage-1;
log(`📦 扫荡完成!+${50*(d.stage-1)}金 ${d.stage-1}碎片`);
save(); render();
}
function showDmg(txt,y){
let el=document.createElement('div');
el.className='dmg'; el.style.left=(Math.random()*60+120)+'px'; el.style.top=(y||100)+'px';
el.innerText=txt; document.getElementById('field').appendChild(el);
setTimeout(()=>el.remove(),1000);
}
// ===== 养成 =====
function upgrade(){
let cost=200*d.catLv;
if(d.gold<cost){ log('❌ 金币不足'); return; }
d.gold-=cost; d.catExp+=100; d.catLv++;
if(d.catExp>=d.catLv*100){ d.catExp=0; d.catStar++; d.catPwr+=30; }
d.catPwr+=5; d.power=d.catPwr+eqBonus('w')*10; d.allyMax=80+d.catLv*10+d.catStar*20; d.allyHp=d.allyMax;
log(`⬆️ 剑客喵升到Lv.${d.catLv}`);
save(); render();
}
function starUp(){
let need=d.catStar+1;
if(d.frag<need){ log('❌ 碎片不足'); return; }
d.frag-=need; d.catStar++; d.catPwr+=30; d.power=d.catPwr+eqBonus('w')*10;
log(`⭐ 升星成功!${'⭐'.repeat(d.catStar)}`);
save(); render();
}
function eqUp(t){
let cost=150*(d.eq[t]+1);
if(d.gold<cost){ log('❌ 金币不足'); return; }
d.gold-=cost; d.eq[t]++;
if(t==='w') d.catPwr+=8;
d.power=d.catPwr+eqBonus('w')*10; d.allyMax=80+d.catLv*10+d.catStar*20;
log(`🔧 装备强化 +${d.eq[t]}`);
save(); render();
}
function eqBonus(t){ return d.eq[t]*5; }
// ===== 工具 =====
function log(txt){
let el=document.getElementById('log');
el.innerHTML='<p>'+txt+'</p>'+el.innerHTML;
if(el.children.length>15) el.removeChild(el.lastChild);
}
function save(){ localStorage.setItem('miaoSave',JSON.stringify(d)); }
function render(){
document.getElementById('stage').innerText='第'+d.stage+'关';
document.getElementById('wave').innerText=d.wave;
document.getElementById('gold').innerText=d.gold;
document.getElementById('fish').innerText=d.fish;
document.getElementById('gem').innerText=d.gem;
document.getElementById('power').innerText=d.power;
document.getElementById('enemyHpText').innerText=Math.max(0,Math.floor(d.enemyHp));
document.getElementById('allyHpText').innerText=Math.floor(d.allyHp)+'/'+d.allyMax;
document.getElementById('enemyHpBar').style.width=(d.enemyHp/d.enemyMax*100)+'%';
document.getElementById('catLv').innerText=d.catLv;
document.getElementById('catPwr').innerText=d.catPwr;
document.getElementById('frag').innerText=d.frag;
document.getElementById('starCost').innerText=d.catStar+1;
document.getElementById('stars').innerText='⭐'.repeat(d.catStar);
document.getElementById('expBar').style.width=(d.catExp/(d.catLv*100)*100)+'%';
document.getElementById('eq-w').innerText='Lv.'+d.eq.w+' +'+(d.eq.w*5)+'攻击';
document.getElementById('eq-a').innerText='Lv.'+d.eq.a+' +'+(d.eq.a*5)+'防御';
document.getElementById('eq-r').innerText='Lv.'+d.eq.r+' +'+(d.eq.r*5)+'暴击';
let emojis=['👹','🧟','💀','👿','🐉','🦇','🕷️','👺'];
document.getElementById('enemyEmoji').innerText=emojis[d.stage%emojis.length];
}
render();
</script>
</body>
</html>Game Source: 喵将传
Creator: SwiftPirate21
Libraries: none
Complexity: complex (258 lines, 10.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-swiftpirate21" to link back to the original. Then publish at arcadelab.ai/publish.