Minecraft RPG
by SparkShark50806 lines35.3 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:10px}
.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;}
.modeBtn{position:fixed;bottom:60px;left:12px;padding:6px 10px;background:#333;color:#fff;border:1px solid #777;border-radius:4px;cursor:pointer;z-index:10;pointer-events:auto;}
.langBtn{position:fixed;bottom:12px;left:12px;padding:6px 10px;background:#333;color:#fff;border:1px solid #777;border-radius:4px;cursor:pointer;z-index:10;pointer-events:auto;}
#cheatBtn{display:none;}
#deathScreen{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000;display:none;flex-direction:column;align-items:center;justify-content:center;gap:24px}
.deathText{font-size:32px}
</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>
<button class="btn" onclick="openCheatModal()" id="cheatBtn">作弊码</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 id="deathScreen">
<div class="deathText" id="deathMsg">你输了</div>
<button class="btn" onclick="restartBattle()" id="btnRestart">重新开始</button>
<button class="btn" onclick="backHome()" id="btnBackHome">回到主页面</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="difficultyModal">
<div class="modal-box">
<h3 id="diffTitle">选择难度</h3>
<button class="btn" onclick="setDifficulty('easy')" id="btnEasy">简单</button>
<button class="btn" onclick="setDifficulty('normal')" id="btnNormal">中等</button>
<button class="btn" onclick="setDifficulty('hard')" id="btnHard">困难</button>
</div>
</div>
<div class="modal" id="cheatModal">
<div class="modal-box">
<h3 id="cheatTitle">输入作弊码</h3>
<input id="cheatInput" placeholder="输入作弊码">
<br>
<button class="btn" onclick="submitCheat()" id="btnCheatOk">确认</button>
<button class="btn" onclick="closeModal('cheatModal')" id="btnCheatCancel">取消</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="modeBtn" id="modeToggle" onclick="switchDeviceMode()">电脑</button>
<button class="langBtn" id="langToggle" onclick="switchLang()">ENG</button>
<script>
let lang = "zh";
let deviceMode = "pc";
const CHEAT_CODE = "!!!gsf801005!!!";
const texts = {
zh:{
homeTitle:"Minecraft RPG",
start:"开始游戏",
rule:"规则",
gold:"金币:",iron:"铁矿:",coal:"煤炭:",gem:"宝石:",stone:"石头:",
killTxt:"击杀普通怪:",playerHp:"玩家生命:",
monsterHp:"怪物生命:",atkCd:"攻击冷却",attack:"攻击",
mine:"矿场",bag:"背包",off:"副手",craft:"工作台",save:"存档/读档",full:"全荧幕",
cheatBtn:"作弊码",mineTitle:"正在前往矿场",mineDig:"开采",mineBack:"返回冒险",
ruleModalTitle:"Minecraft RPG 新手规则",
ruleContent:`【游戏目标】<br>
击败怪物、采集矿物、收集材料合成装备,击杀15只普通怪物就会出现首领,首领由弱到强依次挑战。<br><br>
【难度设定】<br>
简单:玩家最大血量50,开局血量50,普通怪物血量25<br>
中等:玩家最大血量50,开局血量40,普通怪物血量30<br>
困难:玩家最大血量50,开局血量30,普通怪物血量40<br><br>
【基础操作】<br>
1. 点击「开始游戏」,选择难度进入冒险画面<br>
2. 攻击:点击攻击按钮攻击怪物,攻击冷却0.8秒,冷却条顺滑,冷却结束可以再次攻击<br>
3. 矿场:点矿场按钮,进入之后会有5秒倒数,倒数期间唔可以开采;倒数完先出现石头同开采按钮<br>
4. 开采矿物冷却0.5秒,冷却完结先可以再次开采<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>
6. 击败当前首领,就会切换下一只更强嘅首领<br><br>
【死亡机制】<br>
玩家血量归零之后,画面会全黑,显示「你输了」,有两个按钮:重新开始、回到主页面。<br><br>
【存档功能】<br>
1. 点击「存档/读档」生成存档代码,复制保存<br>
2. 读取存档时粘贴存档代码,恢复游戏进度,注意唔好拣埋多余空格,否则会提示存档代码错误。
`,
close:"关闭",diffTitle:"选择难度",easy:"简单",normal:"中等",hard:"困难",
cheatTitle:"输入作弊码",cheatOk:"确认",cheatCancel:"取消",
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:"浏览器唔支援全荧幕",tipCheatSuccess:"已解锁全部内容!",
empty:"空",equip:"装备 ",deathMsg:"你输了",btnRestart:"重新开始",btnBackHome:"回到主页面"
},
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",
cheatBtn:"Cheat Code",mineTitle:"Heading to Mine",mineDig:"Mine",mineBack:"Back to Adventure",
ruleModalTitle:"Minecraft RPG Beginner Rules",
ruleContent:`【Game Goal】<br>
Defeat monsters, mine resources and craft equipment. Kill 15 normal monsters to spawn bosses, bosses get stronger in order.<br><br>
【Difficulty】<br>
Easy: Player max HP 50, starting HP 50, normal monster HP 25<br>
Normal: Player max HP 50, starting HP 40, normal monster HP 30<br>
Hard: Player max HP 50, starting HP 30, normal monster HP 40<br><br>
【Controls】<br>
1. Click "Start Game", pick difficulty to enter adventure<br>
2. Attack: Click attack button to hit monster, attack cooldown 0.8 seconds with smooth bar<br>
3. Mine: Click mine button, wait 5 seconds countdown, cannot mine during countdown<br>
4. Mining cooldown 0.5 seconds<br><br>
【Mining】<br>
- Stone: Most common, gain gold<br>
- Coal: Medium chance, get coal resource<br>
- Iron: Rarest chance, get iron ore<br>
- Collect 10 iron ore to unlock workbench<br><br>
【Bag & Craft】<br>
1. Bag capacity: 20 items<br>
2. Unlock workbench to craft weapons, shield and bread<br>
3. Food can be used inside backpack. Rotten flesh adds HP temporarily then drops back<br>
4. Iron shield can be put to offhand to reduce incoming damage<br><br>
【Combat】<br>
1. Chance of critical hit for extra damage, small critical text<br>
2. Chance to dodge monster attack and take no damage<br>
3. Killing zombie drops 1~2 rotten flesh guaranteed<br>
4. Kill 15 normal monsters to summon boss. Bosses are not counted.<br>
5. Baby zombie attacks faster<br>
6. Defeat boss to unlock next stronger boss<br><br>
【Death System】<br>
When player HP reaches zero, screen turns fully black and shows "Game Over". Buttons: Restart, Back To Home.<br><br>
【Save System】<br>
1. Click Save/Load to generate save code and copy it<br>
2. Paste code to load progress. Do not copy extra spaces or it will show invalid save code.`,
close:"Close",diffTitle:"Select Difficulty",easy:"Easy",normal:"Normal",hard:"Hard",
cheatTitle:"Input Cheat Code",cheatOk:"Confirm",cheatCancel:"Cancel",
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",
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",tipCheatSuccess:"Everything Unlocked!",
empty:"Empty",equip:"Equip ",deathMsg:"Game Over",btnRestart:"Restart",btnBackHome:"Back To Home"
}
}
let lang = "zh";
let deviceMode = "pc";
const CHEAT_CODE = "!!!gsf801005!!!";
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,
bossWave:0,
monster:{name:"🧟 Zombie", hp:20, maxHp:60, atk:6, type:"zombie"},
cd:false, cdTime:800,
critRate:0.15, dodgeRate:0.12,
monsterBaseHp:30
}
const bosses = [
{name:"僵尸王",hp:120,maxHp:120,atk:8},
{name:"苦力怕霸主",hp:180,maxHp:180,atk:12},
{name:"凋零骑士",hp:280,maxHp:280,atk:15},
{name:"末影守卫",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 switchDeviceMode(){
deviceMode = deviceMode === "pc" ? "mobile" : "pc";
document.getElementById("modeToggle").innerText = deviceMode === "pc" ? "电脑" : "手机";
updateCheatButton();
}
function updateCheatButton(){
if(deviceMode === "mobile"){
document.getElementById("cheatBtn").style.display="inline-block";
}else{
document.getElementById("cheatBtn").style.display="none";
}
}
document.addEventListener("keydown",(e)=>{
if(deviceMode==="pc" && e.key==="Enter"){
openCheatModal();
}
})
function openCheatModal(){
document.getElementById("cheatInput").value="";
openModal("cheatModal");
}
function submitCheat(){
const inputVal = document.getElementById("cheatInput").value.trim();
if(inputVal === CHEAT_CODE){
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(texts[lang].tipCheatSuccess);
}
closeModal("cheatModal");
refreshUI();
}
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("cheatBtn").innerText = t.cheatBtn;
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("diffTitle").innerText = t.diffTitle;
document.getElementById("btnEasy").innerText = t.easy;
document.getElementById("btnNormal").innerText = t.normal;
document.getElementById("btnHard").innerText = t.hard;
document.getElementById("cheatTitle").innerText = t.cheatTitle;
document.getElementById("btnCheatOk").innerText = t.cheatOk;
document.getElementById("btnCheatCancel").innerText = t.cheatCancel;
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;
document.getElementById("deathMsg").innerText = t.deathMsg;
document.getElementById("btnRestart").innerText = t.btnRestart;
document.getElementById("btnBackHome").innerText = t.btnBackHome;
spawnNormalMonster();
refreshUI();
}
function openRuleModal(){openModal("ruleModal")}
function startGame(){
openModal("difficultyModal");
}
function setDifficulty(diff){
closeModal("difficultyModal");
if(diff==="easy"){
game.playerMaxHp=50;
game.playerHp=50;
game.monsterBaseHp=25;
}else if(diff==="normal"){
game.playerMaxHp=50;
game.playerHp=40;
game.monsterBaseHp=30;
}else if(diff==="hard"){
game.playerMaxHp=50;
game.playerHp=30;
game.monsterBaseHp=40;
}
game.killCount=0;
game.bossWave=0;
document.getElementById("home").style.display="none";
document.getElementById("game").style.display="block";
spawnNormalMonster();
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"){
if(it.name === "腐肉" || it.name === "Rotten Flesh"){
const tempAdd = 5;
const baseHp = game.playerHp;
game.playerHp = Math.min(game.playerHp + tempAdd, game.playerMaxHp);
refreshUI();
const decayTimer = setInterval(()=>{
if(game.playerHp > baseHp){
game.playerHp -=0.5;
refreshUI();
}else{
clearInterval(decayTimer);
}
},1000)
}else{
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 = 5;
if(Math.random() < game.critRate){dmg *=1.5;showTip(texts[lang].tipCrit)}
game.monster.hp -= dmg;
document.getElementById("battleTip").style.fontSize="10px";
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.monster.type === "babyZombie"){
setTimeout(()=>{
if(game.playerHp>0) monsterAttack();
},600)
}
if(game.offhand?.type==="shield") md = md*(1-game.offhand.reduce);
game.playerHp -= md;
if(game.playerHp <=0){
game.playerHp=0;
showDeathScreen();
}
refreshUI();
}
function showDeathScreen(){
document.getElementById("deathScreen").style.display="flex";
}
function restartBattle(){
document.getElementById("deathScreen").style.display="none";
game.playerHp = game.playerMaxHp;
spawnNormalMonster();
refreshUI();
}
function backHome(){
document.getElementById("deathScreen").style.display="none";
document.getElementById("game").style.display="none";
document.getElementById("home").style.display="flex";
}
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};
const dropCount = Math.floor(Math.random()*2)+1;
for(let i=0;i<dropCount;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.type !== "boss"){
game.killCount++;
if(game.killCount>=15){
game.killCount=0;
game.bossWave++;
spawnBoss();
}else spawnNormalMonster();
}else{
spawnNormalMonster();
}
refreshUI();
}
function spawnNormalMonster(){
const r=Math.random();
let baseHp = game.monsterBaseHp;
if(r<0.4) game.monster={name:lang==="zh"?"🧟 僵尸":"🧟 Zombie",hp:baseHp,maxHp:baseHp,atk:6,type:"zombie"};
else if(r<0.7) game.monster={name:lang==="zh"?"👶 小僵尸":"👶 Baby Zombie",hp:baseHp*0.7,maxHp:baseHp*0.7,atk:4,type:"babyZombie"};
else game.monster={name:lang==="zh"?"💥 苦力怕":"💥 Creeper",hp:baseHp*0.9,maxHp:baseHp*0.9,atk:9,type:"creeper"};
}
function spawnBoss(){
const bIndex = (game.bossWave - 1) % bosses.length;
const b = bosses[bIndex];
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";
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;
}
applyLang();
updateCheatButton();
</script>
</body>
</html>Game Source: Minecraft RPG
Creator: SparkShark50
Libraries: none
Complexity: complex (806 lines, 35.3 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-mvvy1muq" to link back to the original. Then publish at arcadelab.ai/publish.