Minecraft RPG
by SparkShark50664 lines29.0 KB
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Minecraft RPG</title>
<style>
*{margin:0;padding:0;box-sizing:border-box;font-family:system-ui, sans-serif}
body{background:#222;color:#fff;overflow:hidden;font-size:12px}
#home{width:100vw;height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:24px}
#home h1{font-size:26px}
.btn{padding:8px 14px;background:#3a3a3a;border:1px solid #888;border-radius:4px;color:#fff;cursor:pointer;font-size:12px}
.btn:hover{background:#505050}
#game{width:100vw;height:100vh;display:none;position:relative;padding:12px}
.top-left{position:absolute;top:12px;left:12px;line-height:1.5;font-size:12px}
.battle-area{position:absolute;top:45%;left:50%;transform:translate(-50%,-50%);text-align:center;width:90%}
.monster-name{font-size:20px;margin-bottom:6px}
.hp-row{margin:3px 0;font-size:12px}
.bar-wrap{width:260px;height:14px;background:#111;border:1px solid #777;margin:6px auto;position:relative;overflow:hidden;border-radius:2px}
.bar-cd{height:100%;background:#4488ff;width:0%;transition:none;}
.modal{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.75);display:none;align-items:center;justify-content:center}
.modal-box{background:#2b2b2b;padding:18px;border:1px solid #999;border-radius:6px;width:340px;max-height:70vh;overflow-y:auto;font-size:12px}
.modal-box h3{margin-bottom:10px;font-size:16px}
.item-line{padding:4px 0;border-bottom:1px solid #444;font-size:12px}
input{width:100%;padding:5px;margin:5px 0;background:#1a1a1a;border:1px solid #666;color:#fff;border-radius:3px;font-size:12px}
.inv-row{display:flex;gap:4px;flex-wrap:wrap;margin:6px 0}
.inv-slot{width:42px;height:42px;background:#181818;border:1px solid #555;display:flex;align-items:center;justify-content:center;font-size:11px;position:relative}
.offhand{width:56px;height:56px;background:#181818;border:2px solid #888;margin:6px auto;display:flex;align-items:center;justify-content:center;font-size:12px}
.quality-common{color:#eee}
.quality-good{color:#5f5}
.quality-rare{color:#5af}
.quality-legend{color:#fa0}
.tip{position:fixed;bottom:80px;left:50%;transform:translateX(-50%);background:#111;padding:6px 12px;border:1px solid #888;border-radius:4px;display:none;font-size:12px}
#battleTip{margin-top:8px;color:#ff7777;font-size:12px}
.bottom-bar{position:absolute;bottom:16px;left:50%;transform:translateX(-50%);display:flex;gap:5px;flex-wrap:wrap;justify-content:center;width:95%}
#mineFull{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000;display:none;flex-direction:column;align-items:center;justify-content:center;gap:20px}
.mine-rock{font-size:70px;display:none;}
.langBtn{position:fixed;bottom:12px;left:12px;padding:6px 10px;background:#333;color:#fff;border:1px solid #777;border-radius:4px;cursor:pointer}
</style>
</head>
<body>
<div id="home">
<h1 id="homeTitle">Minecraft RPG</h1>
<div style="display:flex;gap:10px">
<button class="btn" onclick="startGame()" id="btnStart">开始游戏</button>
<button class="btn" onclick="openRuleModal()" id="btnRule">规则</button>
</div>
</div>
<div id="game">
<div class="top-left">
<div><span id="txtGoldLabel">金币:</span><span id="gold">0</span></div>
<div><span id="txtIronLabel">铁矿:</span><span id="iron">0</span></div>
<div><span id="txtCoalLabel">煤炭:</span><span id="coal">0</span></div>
<div><span id="txtGemLabel">宝石:</span><span id="gem">0</span></div>
<div><span id="txtStoneLabel">石头:</span><span id="stone">0</span></div>
<div><span id="txtKillLabel">击杀普通怪:</span><span id="killCount">0</span>/15</div>
<div><span id="txtPlayerHpLabel">玩家生命:</span><span id="playerHp">10</span>/<span id="playerMaxHp">40</span></div>
</div>
<div class="battle-area">
<div class="monster-name" id="monsterName">🧟 僵尸</div>
<div class="hp-row"><span id="txtMonsterHpLabel">怪物生命:</span><span id="monsterHp">20</span>/<span id="monsterMaxHp">60</span></div>
<div class="bar-wrap">
<div class="bar-cd" id="cdBar"></div>
</div>
<div id="txtAtkCd" style="font-size:12px">攻击冷却</div>
<button class="btn" onclick="attack()" id="btnAtk">攻击</button>
<div id="battleTip"></div>
</div>
<div class="bottom-bar">
<button class="btn" onclick="openMinePage()" id="btnMine">矿场</button>
<button class="btn" onclick="openBag()" id="btnBag">背包</button>
<button class="btn" onclick="openOffhand()" id="btnOff">副手</button>
<button class="btn" style="display:none" onclick="openCraft()" id="btnCraft">工作台</button>
<button class="btn" onclick="openSaveLoad()" id="btnSave">存档/读档</button>
<button class="btn" onclick="fullscreenToggle()" id="btnFull">全荧幕</button>
</div>
</div>
<div id="mineFull">
<div id="mineTitle">正在前往矿场</div>
<div id="mineCountText">5</div>
<div class="mine-rock" id="rockEl">🪨</div>
<div class="bar-wrap" style="width:220px">
<div class="bar-cd" id="mineCdBar"></div>
</div>
<button class="btn" id="mineActBtn" onclick="doMining()" style="display:none">开采</button>
<button class="btn" id="mineBackBtn" onclick="closeMinePage()" style="display:none">返回冒险</button>
</div>
<div class="modal" id="ruleModal">
<div class="modal-box">
<h3 id="ruleTitle">Minecraft RPG 新手规则</h3>
<div id="ruleContent"></div>
<br>
<button class="btn" onclick="closeModal('ruleModal')" id="btnRuleClose">关闭</button>
</div>
</div>
<div class="modal" id="craftModal">
<div class="modal-box">
<h3 id="craftTitle">工作台</h3>
<div class="item-line"><span id="craftStoneSwordTxt">石剑:石头×2</span> <button class="btn" onclick="craft('stoneSword')">合成</button></div>
<div class="item-line"><span id="craftIronSwordTxt">铁剑:铁矿×2</span> <button class="btn" onclick="craft('ironSword')">合成</button></div>
<div class="item-line"><span id="craftDiamondSwordTxt">钻石剑:宝石×3</span> <button class="btn" onclick="craft('diamondSword')">合成</button></div>
<div class="item-line"><span id="craftShieldTxt">铁盾牌:铁矿×3</span> <button class="btn" onclick="craft('shield')">合成</button></div>
<div class="item-line"><span id="craftBreadTxt">面包:石头×1</span> <button class="btn" onclick="craft('bread')">合成</button></div>
<br>
<button class="btn" onclick="closeModal('craftModal')" id="btnCraftClose">关闭</button>
</div>
</div>
<div class="modal" id="bagModal">
<div class="modal-box">
<h3><span id="bagTitle">背包</span> (<span id="bagCount">0</span>/20)</h3>
<div class="inv-row" id="bagList"></div>
<br>
<button class="btn" onclick="closeModal('bagModal')" id="btnBagClose">关闭</button>
</div>
</div>
<div class="modal" id="offhandModal">
<div class="modal-box">
<h3 id="offTitle">副手栏</h3>
<div class="offhand" id="offhandSlot">空</div>
<div id="offhandList"></div>
<br>
<button class="btn" onclick="closeModal('offhandModal')" id="btnOffClose">关闭</button>
</div>
</div>
<div class="modal" id="saveModal">
<div class="modal-box">
<h3 id="saveTitle">存档 / 读档</h3>
<div id="saveCodeLabel">存档代码:</div>
<input id="saveCodeRead" readonly>
<button class="btn" onclick="saveGame()" id="btnGenSave">生成存档</button>
<div id="loadCodeLabel" style="margin-top:6px">读取存档:</div>
<input id="saveCodeWrite" placeholder="粘贴存档代码">
<button class="btn" onclick="loadGame()" id="btnLoadSave">读取</button>
<br><br>
<button class="btn" onclick="closeModal('saveModal')" id="btnSaveClose">关闭</button>
</div>
</div>
<div class="modal" id="unlockCraftModal">
<div class="modal-box">
<h3 id="unlockTitle">提示</h3>
<p id="unlockMsg">已收集10份铁矿,可以解锁工作台,是否解锁?</p>
<button class="btn" onclick="unlockCraft()" id="btnUnlockYes">解锁</button>
<button class="btn" onclick="closeModal('unlockCraftModal')" id="btnUnlockNo">暂不解锁</button>
</div>
</div>
<div class="tip" id="tipBox"></div>
<button class="langBtn" id="langToggle" onclick="switchLang()">ENG</button>
<script>
let lang = "zh";
const texts = {
zh:{
homeTitle:"Minecraft RPG",
start:"开始游戏",
rule:"规则",
gold:"金币:",iron:"铁矿:",coal:"煤炭:",gem:"宝石:",stone:"石头:",
killTxt:"击杀普通怪:",playerHp:"玩家生命:",
monsterHp:"怪物生命:",atkCd:"攻击冷却",attack:"攻击",
mine:"矿场",bag:"背包",off:"副手",craft:"工作台",save:"存档/读档",full:"全荧幕",
mineTitle:"正在前往矿场",mineDig:"开采",mineBack:"返回冒险",
ruleModalTitle:"Minecraft RPG 新手规则",
ruleContent:`【游戏目标】<br>
击败怪物、采集矿物、收集材料合成装备,击杀15只普通怪物就会出现首领,由弱到强依次挑战。<br><br>
【基础操作】<br>
1. 点击「开始游戏」进入冒险画面<br>
2. 攻击:按攻击按钮打怪物,有攻击冷却时间,冷却条满先可以再次攻击<br>
3. 矿场:点矿场按钮,会倒数5秒,倒数完先可以开采石头<br>
4. 开采有冷却,每次开采完要等冷却完先可以再掘<br><br>
【采矿机制】<br>
- 石头:机率最高,掘到会获得金币<br>
- 煤炭:机率中等,掘到直接获得煤炭资源<br>
- 铁矿:机率最低,掘到直接获得铁矿<br>
- 储够10个铁矿,会弹提示解锁工作台<br><br>
【背包与合成】<br>
1. 背包最多可以存放20件物品<br>
2. 工作台解锁之后,可以使用矿物合成武器、盾牌、面包<br>
3. 面包、腐肉系食物,点击背包入面嘅食物可以回复血量<br>
4. 铁盾牌可以放去副手栏,受到攻击时减少伤害<br><br>
【战斗机制】<br>
1. 打怪物有机率出现暴击,造成更高伤害<br>
2. 有机率闪避怪物攻击,完全唔受伤<br>
3. 击败僵尸会随机掉落1-2块腐肉,有机率额外掉落其他道具<br>
4. 击杀普通怪物会累计击杀数,击杀满15只就会召唤首领<br>
5. 首领击败之后会切换下一只更强首领<br><br>
【存档功能】<br>
1. 点击「存档/读档」可以生成存档代码,复制保存<br>
2. 读取存档就粘贴存档代码,可以恢复游戏进度`,
close:"关闭",
craftTitle:"工作台",
swordStone:"石剑:石头×2",
swordIron:"铁剑:铁矿×2",
swordDiamond:"钻石剑:宝石×3",
shield:"铁盾牌:铁矿×3",
bread:"面包:石头×1",
bagTitle:"背包",
offTitle:"副手栏",
saveTitle:"存档 / 读档",
saveCode:"存档代码:",genSave:"生成存档",
loadCode:"读取存档:",loadSave:"读取",
unlockTitle:"提示",unlockMsg:"已收集10份铁矿,可以解锁工作台,是否解锁?",
unlockYes:"解锁",unlockNo:"暂不解锁",
tipCd:"冷却未结束",tipCd2:"冷却中",tipCrit:"暴击!",tipDodge:"闪避成功",tipLose:"你战败了,怪物重置",
tipCraftUnlock:"工作台已解锁",tipMatShort:"材料不足",tipBagFull:"背包已满",
tipBoss:"首领出现!",tipSaveOk:"存档已生成,请复制代码",
tipLoadOk:"读取存档成功",tipLoadErr:"存档代码错误",
tipFullErr:"浏览器唔支援全荧幕",
empty:"空",
equip:"装备 "
},
en:{
homeTitle:"Minecraft RPG",
start:"Start Game",
rule:"Rules",
gold:"Gold: ",iron:"Iron: ",coal:"Coal: ",gem:"Gem: ",stone:"Stone: ",
killTxt:"Kills: ",playerHp:"Player HP: ",
monsterHp:"Monster HP: ",atkCd:"Attack Cooldown",attack:"Attack",
mine:"Mine",bag:"Bag",off:"Offhand",craft:"Workbench",save:"Save/Load",full:"Fullscreen",
mineTitle:"Heading to Mine",mineDig:"Mine",mineBack:"Back to Adventure",
ruleModalTitle:"Minecraft RPG Beginner Rules",
ruleContent:`【Game Goal】<br>
Defeat monsters, mine resources, craft gears. Kill 15 normal monsters to spawn boss, bosses get stronger sequentially.<br><br>
【Controls】<br>
1. Click "Start Game" to adventure<br>
2. Attack: Click attack button, cooldown required before next hit<br>
3. Mine: Enter mine, wait 5s countdown to mine<br>
4. Mining also has cooldown.<br><br>
【Mining】<br>
- Stone: Most common, gain gold<br>
- Coal: Medium chance, get coal resource<br>
- Iron: Rare chance, get iron<br>
- Collect 10 iron to unlock workbench<br><br>
【Bag & Craft】<br>
1. Bag capacity:20 items<br>
2. Craft weapons, shield and bread in workbench<br>
3. Bread & rotten flesh restore HP<br>
4. Iron shield to offhand for damage reduction<br><br>
【Combat】<br>
1. Critical hit deals extra damage<br>
2. Chance to dodge incoming attack<br>
3. Zombies drop 1~2 rotten flesh randomly<br>
4. Every 15 kills summon boss<br>
5. Defeat boss to unlock next stronger boss<br><br>
【Save System】<br>
1. Generate save code and copy it<br>
2. Paste code to load your progress`,
close:"Close",
craftTitle:"Workbench",
swordStone:"Stone Sword: Stone×2",
swordIron:"Iron Sword: Iron×2",
swordDiamond:"Diamond Sword: Gem×3",
shield:"Iron Shield: Iron×3",
bread:"Bread: Stone×1",
bagTitle:"Bag",
offTitle:"Offhand Slot",
saveTitle:"Save / Load",
saveCode:"Save Code:",genSave:"Generate Save",
loadCode:"Load Code:",loadSave:"Load",
unlockTitle:"Notice",unlockMsg:"10 Iron collected. Unlock Workbench?",
unlockYes:"Unlock",unlockNo:"Later",
tipCd:"Cooldown not over",tipCd2:"Cooldown",tipCrit:"Critical Hit!",tipDodge:"Dodge!",tipLose:"Defeated, monster reset",
tipCraftUnlock:"Workbench Unlocked",tipMatShort:"Not enough materials",tipBagFull:"Bag Full",
tipBoss:"Boss appeared! ",tipSaveOk:"Save generated, copy code",
tipLoadOk:"Load success",tipLoadErr:"Invalid save code",
tipFullErr:"Fullscreen unsupported",
empty:"Empty",
equip:"Equip "
}
}
let game = {
gold:0, iron:0, coal:0, gem:0, stone:0,
playerHp:10, playerMaxHp:40,
bag:[], bagMax:20, offhand:null,
craftUnlocked:false,
killCount:0, bossIndex:0,
monster:{name:"🧟 Zombie", hp:20, maxHp:60, atk:6, type:"zombie"},
cd:false, cdTime:800,
critRate:0.15, dodgeRate:0.12
}
const bosses = [
{name:"Zombie King",hp:120,maxHp:120,atk:8},
{name:"Creeper Overlord",hp:180,maxHp:180,atk:12},
{name:"Wither Knight",hp:280,maxHp:280,atk:15},
{name:"Ender Guardian",hp:400,maxHp:400,atk:20}
]
const quality = {zh:["普通","优良","稀有","传奇"],en:["Common","Fine","Rare","Legendary"]};
const qualityClass = ["quality-common","quality-good","quality-rare","quality-legend"];
function switchLang(){
lang = lang === "zh" ? "en" : "zh";
document.getElementById("langToggle").innerText = lang === "zh" ? "ENG" : "中";
applyLang();
}
function applyLang(){
const t = texts[lang];
document.getElementById("homeTitle").innerText = t.homeTitle;
document.getElementById("btnStart").innerText = t.start;
document.getElementById("btnRule").innerText = t.rule;
document.getElementById("txtGoldLabel").innerText = t.gold;
document.getElementById("txtIronLabel").innerText = t.iron;
document.getElementById("txtCoalLabel").innerText = t.coal;
document.getElementById("txtGemLabel").innerText = t.gem;
document.getElementById("txtStoneLabel").innerText = t.stone;
document.getElementById("txtKillLabel").innerText = t.killTxt;
document.getElementById("txtPlayerHpLabel").innerText = t.playerHp;
document.getElementById("txtMonsterHpLabel").innerText = t.monsterHp;
document.getElementById("txtAtkCd").innerText = t.atkCd;
document.getElementById("btnAtk").innerText = t.attack;
document.getElementById("btnMine").innerText = t.mine;
document.getElementById("btnBag").innerText = t.bag;
document.getElementById("btnOff").innerText = t.off;
document.getElementById("btnCraft").innerText = t.craft;
document.getElementById("btnSave").innerText = t.save;
document.getElementById("btnFull").innerText = t.full;
document.getElementById("mineTitle").innerText = t.mineTitle;
document.getElementById("mineActBtn").innerText = t.mineDig;
document.getElementById("mineBackBtn").innerText = t.mineBack;
document.getElementById("ruleTitle").innerText = t.ruleModalTitle;
document.getElementById("ruleContent").innerHTML = t.ruleContent;
document.getElementById("btnRuleClose").innerText = t.close;
document.getElementById("craftTitle").innerText = t.craftTitle;
document.getElementById("craftStoneSwordTxt").innerText = t.swordStone;
document.getElementById("craftIronSwordTxt").innerText = t.swordIron;
document.getElementById("craftDiamondSwordTxt").innerText = t.swordDiamond;
document.getElementById("craftShieldTxt").innerText = t.shield;
document.getElementById("craftBreadTxt").innerText = t.bread;
document.getElementById("btnCraftClose").innerText = t.close;
document.getElementById("bagTitle").innerText = t.bagTitle;
document.getElementById("btnBagClose").innerText = t.close;
document.getElementById("offTitle").innerText = t.offTitle;
document.getElementById("btnOffClose").innerText = t.close;
document.getElementById("saveTitle").innerText = t.saveTitle;
document.getElementById("saveCodeLabel").innerText = t.saveCode;
document.getElementById("btnGenSave").innerText = t.genSave;
document.getElementById("loadCodeLabel").innerText = t.loadCode;
document.getElementById("btnLoadSave").innerText = t.loadSave;
document.getElementById("btnSaveClose").innerText = t.close;
document.getElementById("unlockTitle").innerText = t.unlockTitle;
document.getElementById("unlockMsg").innerText = t.unlockMsg;
document.getElementById("btnUnlockYes").innerText = t.unlockYes;
document.getElementById("btnUnlockNo").innerText = t.unlockNo;
spawnNormalMonster();
refreshUI();
}
function openRuleModal(){openModal("ruleModal")}
function startGame(){
document.getElementById("home").style.display="none";
document.getElementById("game").style.display="block";
refreshUI();
}
function showTip(text){
const t = document.getElementById("tipBox");
t.innerText=text;
t.style.display="block";
setTimeout(()=>t.style.display="none",1600);
}
function closeModal(id){document.getElementById(id).style.display="none"}
function openModal(id){document.getElementById(id).style.display="flex"}
function openBag(){renderBag();openModal("bagModal")}
function openOffhand(){renderOffhand();openModal("offhandModal")}
function openSaveLoad(){openModal("saveModal")}
function openCraft(){openModal("craftModal")}
function fullscreenToggle(){
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen().catch(e=>showTip(texts[lang].tipFullErr));
} else {
if(document.exitFullscreen) document.exitFullscreen();
}
}
function openMinePage(){
document.getElementById("mineFull").style.display="flex";
document.getElementById("mineTitle").innerText=texts[lang].mineTitle;
document.getElementById("mineCountText").innerText="5";
document.getElementById("rockEl").style.display="none";
document.getElementById("mineActBtn").style.display="none";
document.getElementById("mineBackBtn").style.display="none";
document.getElementById("mineCdBar").style.width="0%";
let count = 5;
const countTimer = setInterval(()=>{
document.getElementById("mineCountText").innerText = count;
count--;
if(count < 0){
clearInterval(countTimer);
document.getElementById("mineTitle").innerText="";
document.getElementById("rockEl").style.display="block";
document.getElementById("mineActBtn").style.display="inline-block";
document.getElementById("mineBackBtn").style.display="inline-block";
}
},1000);
}
function closeMinePage(){
document.getElementById("mineFull").style.display="none";
}
function doMining(){
if(game.cd){showTip(texts[lang].tipCd);return;}
game.cd=true;
const mineTotalTime = 500;
let elapsed = 0;
const mineTxt = document.getElementById("mineCountText");
const mineBtn = document.getElementById("mineActBtn");
const mineBar = document.getElementById("mineCdBar");
const rock = document.getElementById("rockEl");
mineBtn.disabled=true;
const mineInterval = setInterval(()=>{
elapsed += 50;
const percent = (elapsed/mineTotalTime)*100;
mineBar.style.width = percent + "%";
const remainSec = ((mineTotalTime-elapsed)/1000).toFixed(1);
mineTxt.innerText = remainSec;
if(elapsed >= mineTotalTime){
clearInterval(mineInterval);
const r = Math.random();
if(r < 0.08){
game.iron++;
rock.innerText = "🪨";
}else if(r < 0.25){
game.coal++;
rock.innerText = "⬛";
}else{
game.gold += 2;
rock.innerText = "🪨";
}
mineTxt.innerText="0";
mineBar.style.width="100%";
mineBtn.disabled=false;
game.cd=false;
mineBar.style.width="0%";
refreshUI();
checkIronUnlock();
}
},50)
}
function checkIronUnlock(){
if(game.iron>=10 && !game.craftUnlocked) openModal("unlockCraftModal");
}
function unlockCraft(){
game.craftUnlocked=true;
document.getElementById("btnCraft").style.display="flex";
closeModal("unlockCraftModal");
showTip(texts[lang].tipCraftUnlock);
refreshUI();
}
function craft(id){
const qLang = quality[lang];
if(id==="stoneSword"){
if(game.stone<2){showTip(texts[lang].tipMatShort);return}
if(game.bag.length>=game.bagMax){showTip(texts[lang].tipBagFull);return}
game.stone -=2;
const q = Math.floor(Math.random()*4);
game.bag.push({name:lang==="zh"?"石剑":"Stone Sword",type:"weapon",dmg:9,quality:qLang[q],color:qualityClass[q]})
}else if(id==="ironSword"){
if(game.iron<2){showTip(texts[lang].tipMatShort);return}
if(game.bag.length>=game.bagMax){showTip(texts[lang].tipBagFull);return}
game.iron -=2;
const q = Math.floor(Math.random()*4);
game.bag.push({name:lang==="zh"?"铁剑":"Iron Sword",type:"weapon",dmg:12,quality:qLang[q],color:qualityClass[q]})
}else if(id==="diamondSword"){
if(game.gem<3){showTip(texts[lang].tipMatShort);return}
if(game.bag.length>=game.bagMax){showTip(texts[lang].tipBagFull);return}
game.gem -=3;
const q = Math.floor(Math.random()*4);
game.bag.push({name:lang==="zh"?"钻石剑":"Diamond Sword",type:"weapon",dmg:18,quality:qLang[q],color:qualityClass[q]})
}else if(id==="shield"){
if(game.iron<3){showTip(texts[lang].tipMatShort);return}
if(game.bag.length>=game.bagMax){showTip(texts[lang].tipBagFull);return}
game.iron -=3;
game.bag.push({name:lang==="zh"?"铁盾牌":"Iron Shield",type:"shield",reduce:0.3})
}else if(id==="bread"){
if(game.stone<1){showTip(texts[lang].tipMatShort);return}
if(game.bag.length>=game.bagMax){showTip(texts[lang].tipBagFull);return}
game.stone -=1;
game.bag.push({name:lang==="zh"?"面包":"Bread",type:"food",heal:15})
}
refreshUI();renderBag();
}
function renderBag(){
const wrap = document.getElementById("bagList");
wrap.innerHTML="";
document.getElementById("bagCount").innerText=game.bag.length;
game.bag.forEach((it,i)=>{
const div = document.createElement("div");
div.className="inv-slot "+(it.color||"");
div.innerText=it.name;
div.onclick=()=>useItem(i);
wrap.appendChild(div);
})
}
function renderOffhand(){
document.getElementById("offhandSlot").innerText = game.offhand?.name??texts[lang].empty;
const list = document.getElementById("offhandList");
list.innerHTML="";
game.bag.forEach((it,i)=>{
if(it.type==="shield"){
const btn = document.createElement("button");
btn.className="btn";
btn.innerText=texts[lang].equip+it.name;
btn.onclick=()=>{
game.offhand = it;
game.bag.splice(i,1);
renderOffhand();refreshUI();
}
list.appendChild(btn);
}
})
}
function useItem(idx){
const it = game.bag[idx];
if(it.type==="food"){
game.playerHp = Math.min(game.playerHp + it.heal, game.playerMaxHp);
game.bag.splice(idx,1);
}
refreshUI();renderBag();
}
function attack(){
if(game.cd){showTip(texts[lang].tipCd2);return}
game.cd=true;
let elapsed=0;
const bar = document.getElementById("cdBar");
const interval = setInterval(()=>{
elapsed += 50;
const pct = (elapsed/game.cdTime)*100;
bar.style.width = pct+"%";
if(elapsed>=game.cdTime){
clearInterval(interval);
game.cd=false;
bar.style.width="0%";
refreshUI();
}
},50)
let dmg = 8;
if(Math.random() < game.critRate){dmg *=1.5;showTip(texts[lang].tipCrit)}
game.monster.hp -= dmg;
document.getElementById("battleTip").innerText = (lang==="zh"?"造成 ":"Hit ")+Math.round(dmg)+(lang==="zh"?" 点伤害":" damage");
if(game.monster.hp <=0){killMonster()}else{monsterAttack()}
refreshUI();
}
function monsterAttack(){
if(Math.random() < game.dodgeRate){showTip(texts[lang].tipDodge);return}
let md = game.monster.atk;
if(game.offhand?.type==="shield") md = md*(1-game.offhand.reduce);
game.playerHp -= md;
if(game.playerHp <=0){
game.playerHp=0;
showTip(texts[lang].tipLose);
spawnNormalMonster();
}
refreshUI();
}
function killMonster(){
const m = game.monster;
const meatName = lang==="zh"?"腐肉":"Rotten Flesh";
if(m.name.includes("僵尸")||m.name.includes("Zombie")){
const meat = {name:meatName,type:"food",heal:5};
for(let i=0;i<Math.floor(Math.random()*2)+1;i++){
if(game.bag.length<game.bagMax) game.bag.push(meat);
}
}
if(m.name.includes("苦力怕")||m.name.includes("Creeper")){
const gunPowder = lang==="zh"?"火药":"Gunpowder";
if(game.bag.length<game.bagMax) game.bag.push({name:gunPowder});
}
if(!m.name.includes("王") && !m.name.includes("霸主") && !m.name.includes("骑士") && !m.name.includes("守卫")
&& !m.name.includes("King") && !m.name.includes("Overlord") && !m.name.includes("Knight") && !m.name.includes("Guardian")){
game.killCount++;
if(game.killCount>=15){
spawnBoss();
game.killCount=0;
}else spawnNormalMonster();
}else{
game.bossIndex++;
if(game.bossIndex >= bosses.length) game.bossIndex=0;
spawnNormalMonster();
}
refreshUI();
}
function spawnNormalMonster(){
const r=Math.random();
if(r<0.4) game.monster={name:lang==="zh"?"🧟 僵尸":"🧟 Zombie",hp:60,maxHp:60,atk:6,type:"zombie"};
else if(r<0.7) game.monster={name:lang==="zh"?"👶 小僵尸":"👶 Baby Zombie",hp:35,maxHp:35,atk:4,type:"babyZombie"};
else game.monster={name:lang==="zh"?"💥 苦力怕":"💥 Creeper",hp:50,maxHp:50,atk:9,type:"creeper"};
}
function spawnBoss(){
const b = bosses[game.bossIndex];
game.monster = {...b, type:"boss"};
showTip(texts[lang].tipBoss+b.name);
}
function saveGame(){
const jsonStr = JSON.stringify(game);
const utf8 = unescape(encodeURIComponent(jsonStr));
const code = btoa(utf8);
document.getElementById("saveCodeRead").value = code;
showTip(texts[lang].tipSaveOk);
}
function loadGame(){
const code = document.getElementById("saveCodeWrite").value.trim();
try{
const utf8 = atob(code);
const jsonStr = decodeURIComponent(escape(utf8));
game = JSON.parse(jsonStr);
if(game.craftUnlocked) document.getElementById("btnCraft").style.display="flex";
showTip(texts[lang].tipLoadOk);
applyLang();
}catch(e){
showTip(texts[lang].tipLoadErr);
}
}
function refreshUI(){
document.getElementById("gold").innerText=game.gold;
document.getElementById("iron").innerText=game.iron;
document.getElementById("coal").innerText=game.coal;
document.getElementById("gem").innerText=game.gem;
document.getElementById("stone").innerText=game.stone;
document.getElementById("killCount").innerText=game.killCount;
document.getElementById("playerHp").innerText=game.playerHp;
document.getElementById("playerMaxHp").innerText=game.playerMaxHp;
document.getElementById("monsterName").innerText=game.monster.name;
document.getElementById("monsterHp").innerText=game.monster.hp;
document.getElementById("monsterMaxHp").innerText=game.monster.maxHp;
}
// 作弊码
document.addEventListener("keydown",(e)=>{
window.codeInput = window.codeInput || "";
window.codeInput += e.key;
if(window.codeInput.includes("!!!gsf801005!!!")){
game.craftUnlocked=true;
game.gold +=999;
game.iron +=999;
game.coal +=999;
game.gem +=999;
game.stone +=999;
document.getElementById("btnCraft").style.display="flex";
showTip(lang==="zh"?"已解锁全部内容!":"Everything Unlocked!");
window.codeInput="";
}
if(window.codeInput.length>30) window.codeInput="";
})
applyLang();
</script>
</body>
</html>Game Source: Minecraft RPG
Creator: SparkShark50
Libraries: none
Complexity: complex (664 lines, 29.0 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: minecraft-rpg-sparkshark50-mvvt4dh4" to link back to the original. Then publish at arcadelab.ai/publish.