方塊RPG冒險
by SparkShark50594 lines19.5 KB
<!DOCTYPE html>
<html lang="zh-HK">
<head>
<meta charset="UTF-8">
<title>方塊RPG冒險</title>
<style>
*{margin:0;padding:0;box-sizing:border-box;font-family:system-ui, sans-serif}
body{background:#222;color:#fff;overflow:hidden}
/* 主頁 */
#主頁{width:100vw;height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:24px}
#主頁 h1{font-size:24px}
#開始按鈕{padding:14px 32px;font-size:17px;background:#444;border:2px solid #777;border-radius:4px;cursor:pointer;transition:background 0.2s}
#開始按鈕:hover{background:#555}
/* 難度頁 */
#難度頁{width:100vw;height:100vh;display:none;flex-direction:column;align-items:center;justify-content:center;gap:20px}
#難度頁 h2{font-size:20px}
.難度掣{width:120px;padding:10px;font-size:15px;margin:5px;background:#333;border:2px solid #666;border-radius:4px;cursor:pointer;transition:0.2s}
.難度掣:hover{background:#505050}
/* 戰鬥頁 */
#戰鬥頁{width:100vw;height:100vh;display:none;position:relative}
.左上資訊{position:absolute;top:12px;left:12px;font-size:14px;line-height:1.4}
.右側功能欄{position:absolute;top:12px;right:12px;display:flex;flex-direction:column;gap:6px}
.功能掣{padding:6px 10px;background:#333;border:1px solid #888;border-radius:3px;cursor:pointer;font-size:13px}
.中間戰鬥區{position:absolute;top:48%;left:50%;transform:translate(-50%,-50%);text-align:center;width:80%}
#怪物圖{width:110px;height:110px;object-fit:contain;cursor:pointer;transition:0.15s;user-select:none}
#怪物圖:active{transform:scale(0.95)}
.血量行{font-size:14px;margin:6px 0}
#怪血量{color:#ff6666}
#我血量{color:#66ff66}
#吸收血量{color:#ffdd44}
#倒數提示{color:#ffaa00;font-size:15px;height:20px;margin:5px 0}
.應對按鈕{margin:5px;padding:7px 12px;font-size:14px;cursor:pointer;display:none}
/* 攻擊冷卻 */
#攻擊冷卻容器{width:220px;height:5px;background:#444;margin:7px auto;border-radius:2px}
#攻擊冷卻條{height:100%;background:#77dd77;width:100%;transition:width 0.05s linear}
/* 彈窗通用 */
.彈窗{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:#333;border:2px solid #aaa;padding:16px;display:none;z-index:99;width:360px;max-height:80vh;overflow-y:auto}
.彈窗 h3{margin-bottom:10px;font-size:17px}
.彈窗 p,.彈窗 label{font-size:13px;margin-bottom:6px}
.彈窗掣{margin:4px 3px 0 0;padding:6px 10px;font-size:13px;cursor:pointer}
/* 商店 */
.商店分類欄{display:flex;gap:4px;margin-bottom:10px;flex-wrap:wrap}
.分類標籤{padding:5px 9px;font-size:12px;background:#444;cursor:pointer;border-radius:2px}
.分類標籤.揀中{background:#668}
.物品格{padding:6px;margin:4px 0;background:#3a3a3a;border-radius:3px;font-size:13px}
.物品格 button{margin-left:6px;padding:3px 7px;font-size:12px}
/* 背包 */
.背包物品欄{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.背包物品{padding:6px 10px;background:#444;border-radius:3px;font-size:12px;cursor:pointer;display:flex;flex-direction:column;gap:4px;min-width:90px}
.背包物品 button{font-size:12px;padding:3px 6px}
/* 礦場項目 + 獨立挖礦冷卻條 */
.mine-item{padding:8px;margin:6px 0;background:#3a3a3a;border-radius:3px;font-size:13px}
.mine-cooldown-wrap{width:100%;height:4px;background:#222;margin-top:4px;border-radius:2px}
.mine-cooldown-bar{height:100%;background:#6cf;width:100%;transition:width 0.05s linear}
</style>
</head>
<body>
<!-- 主頁 -->
<div id="主頁">
<h1>方塊RPG冒險</h1>
<div id="開始按鈕">開始遊戲</div>
</div>
<!-- 難度頁 -->
<div id="難度頁">
<h2>選擇難度</h2>
<div class="難度掣" data-d="簡單">簡單</div>
<div class="難度掣" data-d="中等">中等</div>
<div class="難度掣" data-d="困難">困難</div>
</div>
<!-- 戰鬥頁 -->
<div id="戰鬥頁">
<div class="左上資訊">
金幣:<span id="金幣">0</span><br>
挖礦次數:<span id="挖礦次數">50</span>
</div>
<div class="右側功能欄">
<button class="功能掣" onclick="開設定()">設定</button>
<button class="功能掣" onclick="開商店()">商店</button>
<button class="功能掣" onclick="開背包()">背包</button>
<button class="功能掣" onclick="開礦場()">礦場</button>
</div>
<div class="中間戰鬥區">
<img id="怪物圖" alt="怪物">
<div id="倒數提示"></div>
<div class="血量行">怪物血量:<span id="怪血量">30 / 30</span></div>
<div class="血量行">我方血量:<span id="我血量">50 / <span id="最大血">50</span></span></div>
<div class="血量行" id="吸收行" style="display:none">吸收血量:<span id="吸收血量">0</span></div>
<div id="攻擊冷卻容器"><div id="攻擊冷卻條"></div></div>
<button class="應對按鈕" id="後退掣" onclick="後退()">後退</button>
</div>
</div>
<!-- 設定彈窗 -->
<div class="彈窗" id="設定彈窗">
<h3>設定</h3>
<button class="彈窗掣" onclick="重新開始()">重新開始遊戲</button>
<button class="彈窗掣" onclick="關彈窗('設定彈窗')">關閉</button>
</div>
<!-- 商店彈窗 -->
<div class="彈窗" id="商店彈窗">
<h3>商店</h3>
<div class="商店分類欄">
<div class="分類標籤" data-cat="weapon">武器</div>
<div class="分類標籤" data-cat="enchant">附魔簿</div>
<div class="分類標籤" data-cat="food">食物</div>
<div class="分類標籤" data-cat="bow">弓箭</div>
<div class="分類標籤" data-cat="armor">護甲</div>
<div class="分類標籤" data-cat="block">方塊</div>
</div>
<div id="商店物品區"></div>
<button class="彈窗掣" onclick="關彈窗('商店彈窗')">關閉</button>
</div>
<!-- 背包彈窗 -->
<div class="彈窗" id="背包彈窗">
<h3>背包</h3>
<div id="背包物品欄" class="背包物品欄"></div>
<button class="彈窗掣" onclick="關彈窗('背包彈窗')">關閉</button>
</div>
<!-- 礦場彈窗 -->
<div class="彈窗" id="礦場彈窗">
<h3>礦場</h3>
<div id="礦場物品區"></div>
<button class="彈窗掣" onclick="關彈窗('礦場彈窗')">關閉</button>
</div>
<script>
// 元素
const 主頁 = document.getElementById('主頁');
const 難度頁 = document.getElementById('難度頁');
const 戰鬥頁 = document.getElementById('戰鬥頁');
const 開始按鈕 = document.getElementById('開始按鈕');
const 怪物圖 = document.getElementById('怪物圖');
const 怪血量文字 = document.getElementById('怪血量');
const 我血量文字 = document.getElementById('我血量');
const 最大血文字 = document.getElementById('最大血');
const 金幣文字 = document.getElementById('金幣');
const 挖礦次數文字 = document.getElementById('挖礦次數');
const 倒數提示 = document.getElementById('倒數提示');
const 後退掣 = document.getElementById('後退掣');
const 攻擊冷卻條 = document.getElementById('攻擊冷卻條');
const 吸收行 = document.getElementById('吸收行');
const 吸收血量文字 = document.getElementById('吸收血量');
// 怪物列表:只保留殭屍、苦力怕
const 怪物列表 = [
{
名稱:"殭屍",
圖:"",
血量:30
},
{
名稱:"苦力怕",
圖:"",
血量:10,
係苦力怕:true
}
];
// 商店物品
const 商店物品 = {
weapon:[
{name:"木劍",price:10,type:"weapon",durability:20,damage:7},
{name:"鐵劍",price:30,type:"weapon",durability:30,damage:12},
{name:"鑽石劍",price:80,type:"weapon",durability:40,damage:18}
],
enchant:[
{name:"附魔簿Ⅰ",price:15,type:"enchant",level:1},
{name:"附魔簿Ⅱ",price:30,type:"enchant",level:2},
{name:"附魔簿Ⅲ",price:50,type:"enchant",level:3},
{name:"附魔簿Ⅳ",price:75,type:"enchant",level:4},
{name:"鋒利Ⅰ",price:20,type:"sharp",level:1},
{name:"鋒利Ⅱ",price:40,type:"sharp",level:2},
{name:"鋒利Ⅲ",price:60,type:"sharp",level:3},
{name:"鋒利Ⅳ",price:85,type:"sharp",level:4},
{name:"鋒利Ⅴ",price:110,type:"sharp",level:5}
],
food:[
{name:"麵包",price:8,type:"food",heal:15},
{name:"牛排",price:16,type:"food",heal:30},
{name:"金蘋果",price:40,type:"goldenApple",absorb:20,duration:30000}
],
bow:[
{name:"普通弓",price:25,type:"bow",durability:25,dmg:9},
{name:"強化弓",price:60,type:"bow",durability:35,dmg:16},
{name:"普通箭",price:3,type:"arrow"},
{name:"火焰箭",price:12,type:"fireArrow"}
],
armor:[
{name:"皮甲",price:25,type:"armor",maxHpAdd:10,blockTimes:5},
{name:"鐵甲",price:60,type:"armor",maxHpAdd:15,blockTimes:10},
{name:"鑽石甲",price:120,type:"armor",maxHpAdd:20,blockTimes:20}
],
block:[
{name:"羊毛",price:12,type:"wool"},
{name:"石頭",price:18,type:"stoneBlock"}
]
};
// 礦場設定
const 礦場列表 = [
{name:"石頭",unlockCost:0,reward:1},
{name:"煤炭",unlockCost:20,reward:3},
{name:"鐵礦",unlockCost:50,reward:5},
{name:"鑽石礦",unlockCost:100,reward:20}
];
// 遊戲變數
let 基礎最大血 = 50;
let 玩家血 = 50;
let 吸收血量 = 0;
let 吸收計時器 = null;
let 金幣 = 0;
let 挖礦次數 = 50;
let 已解鎖礦 = [true,false,false,false];
let 背包 = [];
let 當前怪物序號 = 0;
let 怪物最大血 = 30;
let 怪物血 = 30;
let 爆炸計時器 = null;
let 緊急狀態 = false;
let 攻擊冷卻中 = false;
let 攻擊冷卻時間 = 800;
let 挖礦冷卻時間 = 500;
let 打中次數 = 0;
let 裝備護甲 = null;
let 礦冷卻狀態 = [false,false,false,false];
function getMaxHp(){
let add = 0;
if(裝備護甲) add += 裝備護甲.maxHpAdd;
return 基礎最大血 + add;
}
function 更新畫面(){
const maxHp = getMaxHp();
怪血量文字.textContent = `${怪物血} / ${怪物最大血}`;
我血量文字.textContent = `${玩家血} / `;
最大血文字.textContent = maxHp;
金幣文字.textContent = 金幣;
挖礦次數文字.textContent = 挖礦次數;
if(吸收血量 > 0){
吸收行.style.display = "block";
吸收血量文字.textContent = 吸收血量;
}else{
吸收行.style.display = "none";
}
}
function 載入怪物(序號){
const m = 怪物列表[序號];
怪物圖.src = m.圖;
怪物圖.alt = m.名稱;
怪物最大血 = m.血量;
怪物血 = 怪物最大血;
緊急狀態 = false;
倒數提示.textContent = "";
後退掣.style.display = "none";
更新畫面();
}
// 開始按鈕
開始按鈕.onclick = ()=>{
主頁.style.display = 'none';
難度頁.style.display = 'flex';
}
// 揀難度
document.querySelectorAll('.難度掣').forEach(btn=>{
btn.onclick = ()=>{
const d = btn.dataset.d;
if(d === '簡單') window.怪攻擊 = 4;
else if(d === '中等') window.怪攻擊 = 7;
else window.怪攻擊 = 10;
玩家血 = getMaxHp();
當前怪物序號 = 0;
打中次數 = 0;
載入怪物(當前怪物序號);
難度頁.style.display = 'none';
戰鬥頁.style.display = 'block';
}
})
// 攻擊怪物
怪物圖.onclick = async ()=>{
if(緊急狀態 || 攻擊冷卻中) return;
攻擊冷卻中 = true;
let t = 攻擊冷卻時間;
攻擊冷卻條.style.width = "0%";
const step = 40;
while(t>0){
await sleep(step);
t -= step;
攻擊冷卻條.style.width = ((攻擊冷卻時間 - t)/攻擊冷卻時間 *100)+"%";
}
攻擊冷卻條.style.width = "100%";
攻擊冷卻中 = false;
const 劍 = 背包.find(x=>x.type==="weapon");
let dmg = 7;
if(劍 && 劍.durability>0){
dmg = 劍.damage;
劍.durability--;
if(劍.durability <= 0){
alert(`${劍.name}已損毀`);
const i = 背包.indexOf(劍);
if(i>-1)背包.splice(i,1);
}
}
怪物血 -= dmg;
打中次數 ++;
if(打中次數 %5 === 0){
挖礦次數 +=1;
alert("累計命中5次,挖礦次數+1");
}
if(怪物血 <= 0){
怪物血 = 0;
更新畫面();
挖礦次數 +=3;
alert("擊敗目標,挖礦次數+3");
打中次數 = 0;
if(當前怪物序號 < 怪物列表.length -1){
當前怪物序號++;
載入怪物(當前怪物序號);
}else{
alert("已擊敗全部怪物!");
}
return;
}
// 怪物反擊
let hitDmg = window.怪攻擊;
if(裝備護甲 && 裝備護甲.blockTimes>0){
裝備護甲.blockTimes--;
hitDmg = Math.floor(hitDmg/2);
if(裝備護甲.blockTimes <=0){
alert(`${裝備護甲.name}已損毀`);
const i = 背包.indexOf(裝備護甲);
if(i>-1)背包.splice(i,1);
裝備護甲 = null;
}
}
if(吸收血量>0){
const sub = Math.min(吸收血量, hitDmg);
吸收血量 -= sub;
hitDmg -= sub;
}
玩家血 -= hitDmg;
if(玩家血 <=0){
玩家血 = 0;
更新畫面();
alert('你被擊敗,遊戲結束');
return;
}
更新畫面();
if(怪物列表[當前怪物序號].係苦力怕){
緊急狀態 = true;
倒數提示.textContent = "苦力怕爆炸倒數 3 秒";
後退掣.style.display = "inline-block";
let sec =3;
爆炸計時器 = setInterval(()=>{
sec--;
倒數提示.textContent = `苦力怕爆炸倒數 ${sec} 秒`;
if(sec <=0){
clearInterval(爆炸計時器);
let bombDmg =50;
if(吸收血量>0){
const sub = Math.min(吸收血量,bombDmg);
吸收血量 -= sub;
bombDmg -= sub;
}
玩家血 -= bombDmg;
alert(`苦力怕爆炸,未進行應對,受到50點傷害`);
if(玩家血 <=0){
玩家血=0;
更新畫面();
alert('你被擊敗');
}else{
緊急狀態=false;
倒數提示.textContent="";
後退掣.style.display="none";
}
更新畫面();
}
},1000);
}
}
function 後退(){
if(!緊急狀態) return;
clearInterval(爆炸計時器);
緊急狀態 = false;
let dmg =30;
if(吸收血量>0){
const sub = Math.min(吸收血量,dmg);
吸收血量 -= sub;
dmg -= sub;
}
玩家血 -= dmg;
倒數提示.textContent = "執行後退,受到30點傷害";
後退掣.style.display = "none";
更新畫面();
if(玩家血 <=0){
alert('你被擊敗');
}
}
// 彈窗
function 關彈窗(id){document.getElementById(id).style.display='none'}
function 開設定(){document.getElementById('設定彈窗').style.display='block'}
function 開商店(){
document.getElementById('商店彈窗').style.display='block';
renderShop("weapon");
}
function 開背包(){
document.getElementById('背包彈窗').style.display='block';
renderBag();
}
function 開礦場(){
document.getElementById('礦場彈窗').style.display='block';
renderMine();
}
// 渲染商店
let nowShopCat = "weapon";
document.querySelectorAll('.分類標籤').forEach(t=>{
t.onclick = ()=>{
document.querySelectorAll('.分類標籤').forEach(x=>x.classList.remove('揀中'));
t.classList.add('揀中');
nowShopCat = t.dataset.cat;
renderShop(nowShopCat);
}
})
function renderShop(cat){
const box = document.getElementById("商店物品區");
box.innerHTML = "";
const list = 商店物品[cat];
list.forEach(it=>{
const div = document.createElement("div");
div.className="物品格";
div.innerHTML = `${it.name} - ${it.price}金幣 <button>購買</button>`;
div.querySelector("button").onclick = ()=>{
if(金幣 >= it.price){
金幣 -= it.price;
背包.push({...it});
更新畫面();
alert(`購入${it.name}`);
}else alert("金幣不足");
}
box.appendChild(div);
})
}
// 渲染背包:直接按使用,唔使手持
function renderBag(){
const box = document.getElementById("背包物品欄");
box.innerHTML = "";
背包.forEach((it,i)=>{
const div = document.createElement("div");
div.className = "背包物品";
div.innerHTML = `${it.name}<button>使用</button>`;
div.querySelector("button").onclick = ()=>{
if(it.type === "wool"){
if(!緊急狀態){alert("當前無法放置羊毛");return;}
clearInterval(爆炸計時器);
緊急狀態=false;
let dmg=10;
if(吸收血量>0){
const sub = Math.min(吸收血量,dmg);
吸收血量 -= sub;
dmg -= sub;
}
玩家血 -= dmg;
背包.splice(i,1);
倒數提示.textContent="放置羊毛阻擋爆炸,受到10點傷害";
後退掣.style.display="none";
}else if(it.type === "stoneBlock"){
if(!緊急狀態){alert("當前無法放置石頭");return;}
clearInterval(爆炸計時器);
緊急狀態=false;
let dmg=5;
if(吸收血量>0){
const sub = Math.min(吸收血量,dmg);
吸收血量 -= sub;
dmg -= sub;
}
玩家血 -= dmg;
背包.splice(i,1);
倒數提示.textContent="放置石頭阻擋爆炸,受到5點傷害";
後退掣.style.display="none";
}else if(it.type === "food"){
玩家血 = Math.min(玩家血 + it.heal, getMaxHp());
背包.splice(i,1);
alert(`使用${it.name},回復${it.heal}生命值`);
}else if(it.type === "goldenApple"){
吸收血量 = it.absorb;
if(吸收計時器) clearTimeout(吸收計時器);
吸收計時器 = setTimeout(()=>{
吸收血量=0;更新畫面();
alert("金蘋果吸收效果結束");
},it.duration);
背包.splice(i,1);
alert("使用金蘋果,30秒內獲得20點吸收血量");
}else if(it.type === "armor"){
裝備護甲 = it;
alert(`裝備${it.name},生命值上限+${it.maxHpAdd},可抵擋${it.blockTimes}次攻擊`);
}else if(it.type === "weapon" || it.type === "bow"){
alert("武器與弓自動生效,攻擊時自動消耗耐久");
}else{
alert("該物品暫無法使用");
}
更新畫面();
renderBag();
}
box.appendChild(div);
})
}
// 渲染礦場,每個礦物獨立冷卻條
async function renderMine(){
const box = document.getElementById("礦場物品區");
box.innerHTML = "";
for(let i=0;i<礦場列表.length;i++){
const m = 礦場列表[i];
const wrap = document.createElement("div");
wrap.className="mine-item";
if(!已解鎖礦[i]){
wrap.innerHTML = `
<div>${m.name}|解鎖費用:${m.unlockCost}金幣 <button>解鎖</button></div>
<div class="mine-cooldown-wrap"><div class="mine-cooldown-bar" style="width:100%"></div></div>
`;
wrap.querySelector("button").onclick = ()=>{
if(金幣 >= m.unlockCost){
金幣 -= m.unlockCost;
已解鎖礦[i]=true;
更新畫面();
renderMine();
}else alert("金幣不足");
}
}else{
wrap.innerHTML = `
<div>${m.name}|每次獲得+${m.reward}金幣 <button>挖礦</button></div>
<div class="mine-cooldown-wrap"><div class="mine-cooldown-bar" style="width:100%"></div></div>
`;
const bar = wrap.querySelector(".mine-cooldown-bar");
wrap.querySelector("button").onclick = async ()=>{
if(礦冷卻狀態[i]) return;
if(挖礦次數 <=0){alert("挖礦次數已用盡");return;}
礦冷卻狀態[i]=true;
bar.style.width = "0%";
let t = 挖礦冷卻時間;
const step = 40;
while(t>0){
await sleep(step);
t -= step;
bar.style.width = ((挖礦冷卻時間 - t)/挖礦冷卻時間 *100)+"%";
}
bar.style.width = "100%";
礦冷卻狀態[i]=false;
挖礦次數--;
金幣 += m.reward;
alert(`開採${m.name},獲得${m.reward}金幣`);
更新畫面();
renderMine();
}
}
box.appendChild(wrap);
}
}
function sleep(ms){return new Promise(r=>setTimeout(r,ms))}
function 重新開始(){location.reload()}
更新畫面();
</script>
</body>
</html>Game Source: 方塊RPG冒險
Creator: SparkShark50
Libraries: none
Complexity: complex (594 lines, 19.5 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: rpg-sparkshark50" to link back to the original. Then publish at arcadelab.ai/publish.