肉鸽文字地牢

一款为小屏幕定制的极简打怪游戏。没有画面,只有数值。 玩法: 点点【攻击】互砍,掉落金币。 用金币买药,或永久升级“攻防血”。 小心,喝药会白挨一刀;每 5 层有 Boss 守关。

适配设备:Pro / RW

作者:dengyuhang

下载量:53 · 点赞:2

可信源码风险提示:保存或下载前请阅读源码和权限声明。
SHA-256ab0babafe560e266f593a98cb847ec767019334c36073b8321c03b9d805717a7
let state = {
    hp: 100,
    maxHp: 100,
    atk: 10,
    def: 2,
    gold: 0,
    potions: 2,
    floor: 1,
    maxFloor: 1,
    inBattle: false,
    enemy: null,
    logs: ["[系统] 欢迎来到幽暗地牢。", "[系统] 你的目标是生存并向下探索。"],
    isBusy: false,
    isDead: false
};

const MONSTERS = [
    { name: "史莱姆", baseHp: 40, baseAtk: 6, baseDef: 0, gold: 15 },
    { name: "哥布林", baseHp: 80, baseAtk: 12, baseDef: 2, gold: 30 },
    { name: "骷髅兵", baseHp: 150, baseAtk: 20, baseDef: 5, gold: 50 },
    { name: "石像鬼", baseHp: 250, baseAtk: 30, baseDef: 10, gold: 80 },
    { name: "幼龙", baseHp: 400, baseAtk: 45, baseDef: 15, gold: 150 }
];

function addLog(msg) {
    state.logs.unshift(msg); // 最新的在最上面
    if (state.logs.length > 4) state.logs.pop(); // 只保留最近4条
}

function generateEnemy(floor) {
    // 每5层一个Boss
    if (floor % 5 === 0) {
        return {
            name: "魔王·巴风特",
            maxHp: 200 + floor * 80,
            hp: 200 + floor * 80,
            atk: 15 + floor * 5,
            def: 5 + floor * 2,
            gold: 100 + floor * 20,
            isBoss: true
        };
    }
    
    // 普通怪物随层数成长
    let tier = Math.min(Math.floor((floor - 1) / 2), MONSTERS.length - 1);
    let base = MONSTERS[tier];
    let multiplier = 1 + ((floor - 1) * 0.15); // 每层增加15%属性
    
    return {
        name: base.name,
        maxHp: Math.floor(base.baseHp * multiplier),
        hp: Math.floor(base.baseHp * multiplier),
        atk: Math.floor(base.baseAtk * multiplier),
        def: Math.floor(base.baseDef * multiplier),
        gold: Math.floor(base.gold * multiplier),
        isBoss: false
    };
}

async function saveProgress() {
    if (state.floor > state.maxFloor) {
        state.maxFloor = state.floor;
        try {
            await script.data.set('dungeon_max_floor', state.maxFloor);
        } catch (e) {
            console.error("保存最高记录失败", e);
        }
    }
}

async function main() {
    try {
        const savedFloor = await script.data.get('dungeon_max_floor', 1);
        state.maxFloor = savedFloor;
    } catch (e) {
        console.error("读取存档失败", e);
    }
    
    addLog(`[系统] 历史最高记录: 第 ${state.maxFloor} 层`);
    updateUI();
}

function updateUI() {
    let elements = [];

    // 1. 顶部状态栏
    elements.push(ui.row([
        ui.text(`第 ${state.floor} 层`, { flex: 1, color: '#FFB143', bold: true, size: 18 }),
        ui.text(`金币: ${state.gold}`, { flex: 1, align: 'right', color: '#FFD700', bold: true, size: 18 })
    ]));
    
    elements.push(ui.divider({ color: '#333333', height: 1 }));

    // 2. 怪物区域 (如果在战斗)
    if (state.inBattle) {
        elements.push(ui.row([
            ui.text(state.enemy.name, { flex: 1, color: state.enemy.isBoss ? '#FF453A' : '#FFFFFF', bold: true, size: 16 }),
            ui.text(`攻:${state.enemy.atk} 防:${state.enemy.def}`, { align: 'right', color: '#888888', size: 12 })
        ]));
        elements.push(ui.progress(`HP: ${state.enemy.hp}/${state.enemy.maxHp}`, (state.enemy.hp / state.enemy.maxHp) * 100, { 
            color: '#FF453A', background: '#1c1c1e', height: 14 
        }));
        elements.push(ui.spacer(4));
    }

    // 3. 玩家区域
    elements.push(ui.row([
        ui.text(`生命`, { flex: 1, color: '#1a8f38', bold: true, size: 16 }),
        ui.text(`攻:${state.atk} 防:${state.def} 药水:${state.potions}`, { align: 'right', color: '#aaaaaa', size: 12 })
    ]));
    elements.push(ui.progress(`${state.hp} / ${state.maxHp}`, (state.hp / state.maxHp) * 100, { 
        color: '#1a8f38', background: '#1c1c1e', height: 14 
    }));

    elements.push(ui.spacer(8));

    // 4. 战斗日志区 (固定高度,避免跳动)
    let logsNodes = state.logs.map((log, index) => {
        let color = '#aaaaaa';
        if (log.includes('[伤害]')) color = '#FF453A';
        if (log.includes('[恢复]')) color = '#1a8f38';
        if (log.includes('[系统]')) color = '#FFB143';
        if (index === 0) color = '#FFFFFF'; // 最新一条高亮
        return ui.text(log, { color: color, size: 13, lines: 1 });
    });
    
    elements.push(ui.column(logsNodes, { 
        background: '#0a0a0a', radius: 6, padding: 8, height: 100, gap: 4 
    }));

    elements.push(ui.spacer(8));

    // 5. 操作按钮区
    if (state.isDead) {
        elements.push(ui.button("重新挑战", () => resetGame(), { tone: 'primary', height: 56 }));
    } else if (state.inBattle) {
        elements.push(ui.row([
            ui.button("攻击", () => playerAttack(), { flex: 1, tone: 'danger', disabled: state.isBusy, height: 50 }),
            ui.button("喝药", () => drinkPotion(), { flex: 1, tone: 'neutral', disabled: state.isBusy || state.potions <= 0, height: 50 })
        ], { gap: 10 }));
    } else {
        elements.push(ui.button("向下探索", () => explore(), { tone: 'primary', height: 56 }));
        
        // 升级面板
        elements.push(ui.row([
            ui.button("升攻(50)", () => upgrade('atk'), { flex: 1, tone: 'neutral', disabled: state.gold < 50, height: 40, size: 14 }),
            ui.button("升防(50)", () => upgrade('def'), { flex: 1, tone: 'neutral', disabled: state.gold < 50, height: 40, size: 14 }),
            ui.button("补血(30)", () => upgrade('hp'), { flex: 1, tone: 'neutral', disabled: state.gold < 30, height: 40, size: 14 })
        ], { gap: 6 }));
    }

    ui.render(elements);
}

// 逻辑函数
function explore() {
    if (state.isBusy) return;
    state.floor++;
    state.enemy = generateEnemy(state.floor);
    state.inBattle = true;
    addLog(`[系统] 进入第 ${state.floor} 层,遭遇 ${state.enemy.name}!`);
    saveProgress();
    updateUI();
}

function playerAttack() {
    if (state.isBusy) return;
    state.isBusy = true;
    
    // 命中与暴击判定
    let isCrit = Math.random() < 0.15;
    let dmg = Math.max(1, state.atk - state.enemy.def + Math.floor(Math.random() * 4));
    if (isCrit) dmg = Math.floor(dmg * 2);
    
    state.enemy.hp -= dmg;
    addLog(`[伤害] 你${isCrit ? '暴击' : '攻击'}敌人,造成 ${dmg} 伤害。`);
    if (script.canUse('@system.vibrator.vibrate')) system.vibration.vibrate({ mode: 'short' });
    
    updateUI();

    setTimeout(() => {
        if (state.enemy.hp <= 0) {
            addLog(`[系统] 击败了 ${state.enemy.name},获得 ${state.enemy.gold} 金币!`);
            state.gold += state.enemy.gold;
            state.inBattle = false;
            state.enemy = null;
            state.isBusy = false;
            updateUI();
        } else {
            enemyAttack();
        }
    }, 600);
}

function enemyAttack() {
    let dmg = Math.max(1, state.enemy.atk - state.def + Math.floor(Math.random() * 3));
    state.hp -= dmg;
    addLog(`[伤害] ${state.enemy.name} 反击,造成 ${dmg} 伤害。`);
    if (script.canUse('@system.vibrator.vibrate')) system.vibration.vibrate({ mode: 'short' });
    
    if (state.hp <= 0) {
        state.hp = 0;
        state.isDead = true;
        state.inBattle = false;
        addLog(`[系统] 你倒下了... 挑战结束。`);
        if (script.canUse('@system.vibrator.vibrate')) system.vibration.vibrate({ mode: 'long' });
    }
    
    state.isBusy = false;
    updateUI();
}

function drinkPotion() {
    if (state.potions <= 0 || state.isBusy) return;
    state.potions--;
    let heal = 50;
    state.hp = Math.min(state.maxHp, state.hp + heal);
    addLog(`[恢复] 喝下药水,恢复 ${heal} 生命。`);
    
    state.isBusy = true;
    updateUI();
    setTimeout(() => enemyAttack(), 600); // 喝药消耗回合
}

function upgrade(type) {
    if (type === 'atk' && state.gold >= 50) {
        state.gold -= 50;
        state.atk += 3;
        addLog(`[系统] 攻击力永久提升至 ${state.atk}。`);
    } else if (type === 'def' && state.gold >= 50) {
        state.gold -= 50;
        state.def += 2;
        addLog(`[系统] 防御力永久提升至 ${state.def}。`);
    } else if (type === 'hp' && state.gold >= 30) {
        state.gold -= 30;
        state.hp = Math.min(state.maxHp, state.hp + 40);
        addLog(`[恢复] 花费30金币,恢复40点生命。`);
    }
    updateUI();
}

function resetGame() {
    state.hp = 100;
    state.maxHp = 100;
    state.atk = 10;
    state.def = 2;
    state.gold = 0;
    state.potions = 2;
    state.floor = 1;
    state.inBattle = false;
    state.enemy = null;
    state.logs = ["[系统] 你重获新生,再次踏入地牢。"];
    state.isBusy = false;
    state.isDead = false;
    updateUI();
}

return main();