🎮ArcadeLab

像素农夫物语 V9 手动自动等级升级完整版

by BraveDragon92
995 lines43.7 KB
▶ Play
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>像素农夫物语 V9 手动自动等级升级完整版</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            image-rendering: pixelated;
            font-family: "Courier New", monospace;
        }
        body {
            background: #222;
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 10px;
            color: #fff;
        }
        #gameBox {
            border: 4px solid #884400;
            background: #58a6ff;
            width: 800px;
            height: 500px;
            position: relative;
            overflow: hidden;
        }
        canvas {
            display: block;
        }
        .ui-panel {
            width: 800px;
            background: #333;
            padding: 8px 12px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            border: 2px solid #555;
            gap:8px;
            flex-wrap:wrap;
            margin-bottom:6px;
        }
        .btn {
            padding: 6px 12px;
            background: #ffcc00;
            color: #000;
            border: none;
            font-weight: bold;
            cursor: pointer;
            font-size: 14px;
            image-rendering: pixelated;
        }
        .btn-danger {background: #ff4444; color:#fff;}
        .btn-green {background: #44dd44; color:#000;}
        .btn-blue {background:#66aaff;color:#000}
        .btn-purple {background:#aa44ff;color:#fff}
        .btn-orange {background:#ff7722;color:#fff;}
        .btn-sm {
            padding:3px 8px;
            font-size:12px;
        }
        .mask {
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            background: rgba(0,0,0,0.7);
            z-index: 9999;
            display: none;
        }
        .modal-box {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: #2a2a2a;
            border: 4px solid #ffcc00;
            z-index: 10000;
            display: none;
        }
        .modal-header {
            display:flex;
            justify-content: space-between;
            align-items:center;
            padding:10px 12px;
            border-bottom: 2px solid #444;
        }
        .header-btn-group {
            display:flex;
            gap:6px;
            flex-wrap:wrap;
        }
        .shop-body {
            max-height: 320px;
            overflow-y: auto;
            padding:10px 12px;
        }
        .shop-panel {width:620px;}
        .setting-panel {min-width: 520px;}
        .house-panel {min-width:360px;text-align:center;padding:20px 16px;}
        .shop-item {
            display: flex;
            justify-content: space-between;
            padding: 8px 0;
            border-bottom: 1px solid #555;
        }
        .version-desc {
            font-size:12px;
            color:#ccc;
            margin:8px 0 16px;
            line-height:1.4;
        }
    </style>
</head>
<body>
    <h2>8bit像素农夫 V9(多存档+宠物升级+手动自动等级升级)</h2>
    <div class="ui-panel">
        <div>
            等级:<span id="lv">1</span> | 升级所需金币:<span id="lvNeed">2000</span>
            | 金币:<span id="gold">0</span> | 田地数:<span id="landNum">4</span>
        </div>
        <div>
            宠物:<span id="petCount">0</span> | 佣人:<span id="servantCount">0</span>
            | 冥界种子:<span id="seedNether">0</span> | 生命树种子:<span id="seedLife">0</span>
        </div>
        <div>
            天使之力:<span id="buffAngel">无</span> | 黑暗之力:<span id="buffDark">无</span>
            | 时段:<span id="dayPhase">白天</span>
        </div>
        <div class="header-btn-group">
            <button class="btn btn-orange" onclick="manualLevelUp()">手动升级</button>
            <button class="btn btn-orange" id="autoLvBtn" onclick="toggleAutoLevel()">自动升级:关闭</button>
            <button class="btn" onclick="openShop()">商店</button>
            <button class="btn btn-green" onclick="openSetting()">切换版本</button>
        </div>
    </div>
    <div id="gameBox">
        <canvas id="gameCanvas" width="800" height="500"></canvas>
    </div>

    <div class="mask" id="mask" onclick="closeAllPopup()"></div>

    <div class="modal-box shop-panel" id="shopBox" onclick="event.stopPropagation()">
        <div class="modal-header">
            <h3>像素商店(V9解锁宠物升级)</h3>
            <div class="header-btn-group">
                <button class="btn btn-sm btn-blue" onclick="saveSlot(1)">存档1</button>
                <button class="btn btn-sm btn-blue" onclick="loadSlot(1)">读档1</button>
                <button class="btn btn-sm btn-blue" onclick="saveSlot(2)">存档2</button>
                <button class="btn btn-sm btn-blue" onclick="loadSlot(2)">读档2</button>
                <button class="btn btn-sm btn-blue" onclick="saveSlot(3)">存档3</button>
                <button class="btn btn-sm btn-blue" onclick="loadSlot(3)">读档3</button>
                <button class="btn btn-sm btn-green" onclick="backOriginWorld()">返回主世界</button>
                <button class="btn btn-sm" onclick="goHell()">地狱(LV3)</button>
                <button class="btn btn-sm btn-purple" onclick="goHeaven()">天堂(LV5)</button>
                <button class="btn btn-sm btn-danger" onclick="closeShop()">关闭</button>
            </div>
        </div>
        <div class="shop-body" id="shopList"></div>
    </div>

    <div class="modal-box setting-panel" id="settingBox" onclick="event.stopPropagation()">
        <div class="modal-header">
            <h3>版本切换</h3>
            <div class="header-btn-group">
                <button class="btn btn-sm btn-danger" onclick="closeSetting()">关闭</button>
            </div>
        </div>
        <div style="padding:10px 12px;">
            <div class="version-desc">
                V1远古|V2工业|V3异界|V4完整|V5冥界|V6天堂|V7佣人小屋基础|V8终极|V9宠物升级完整版
                <br>V9新增:宠物升级、附魔词条、3组独立存档、天堂LV5解锁、盗贼上限4只、修复小偷拖尾、成熟作物永久保留、手动/自动等级升级
            </div>
            <div>
                <button class="btn" onclick="switchVer(1)">V1</button><br><br>
                <button class="btn" onclick="switchVer(2)">V2</button><br><br>
                <button class="btn" onclick="switchVer(3)">V3</button><br><br>
                <button class="btn" onclick="switchVer(4)">V4</button><br><br>
                <button class="btn" onclick="switchVer(5)">V5</button><br><br>
                <button class="btn" onclick="switchVer(6)">V6</button><br><br>
                <button class="btn" onclick="switchVer(7)">V7</button><br><br>
                <button class="btn" onclick="switchVer(8)">V8</button><br><br>
                <button class="btn" onclick="switchVer(9)">V9 宠物升级完整版</button><br><br>
            </div>
        </div>
    </div>

    <div class="modal-box house-panel" id="houseBox" onclick="event.stopPropagation()">
        <div class="modal-header">
            <h3>自家小屋</h3>
            <div class="header-btn-group">
                <button class="btn btn-sm btn-danger" onclick="closeHouse()">离开</button>
            </div>
        </div>
        <div>
            <p style="margin:12px 0;">请选择你要做的事</p>
            <button class="btn" onclick="eatMeal()">吃饭休息</button><br><br>
            <button class="btn" onclick="sleepNight()">上床睡觉,跳过黑夜</button><br><br>
        </div>
    </div>

    <p style="margin-top:8px;">规则:昼夜循环;早午晚餐强制食用,夜宵可拒绝;佣人仅V8/V9生效;V9宠物可升级附魔,等级越高体型变大;附魔稀有度:附魔之力>天使增幅>黑暗增幅>攻速>攻击;天堂LV5解锁;盗贼最多4只;3组本地存档永久保存;升级仅可手动点击或开启自动升级扣钱提升</p>

    <script>
        const ctx = document.getElementById('gameCanvas').getContext('2d');

        // ========== 全局变量 ==========
        let gameVer = 1;
        let gold = 0;
        let level = 1;
        let landMax = 4;
        let landList = [];
        let player = {x:380,y:320,w:44,h:64};
        let hellOpen = false;
        let heavenOpen = false;
        let isHellMap = false;
        let isHeavenMap = false;
        let bandits = [];
        const MAX_BANDIT = 4;
        let hasWeapon = false;
        let hasMachine = false;
        let tick = 0;
        let pets = [];
        let servants = [];
        let netherSeed = 0;
        let lifeTreeSeed = 0;
        let buffAngel = false;
        let buffDark = false;
        let buffEat = false;
        let buffEatTick = 0;
        let heavenSeedPick = null;
        let heavenParticles = [];
        let dayCycleTick = 0;
        const DAY_CYCLE_LEN = 2400;
        let dayPhase = "day";
        let mealFlagMorning = false;
        let mealFlagNoon = false;
        let mealFlagDinner = false;
        let mealFlagMidnight = false;
        let gamePause = false;
        const housePos = {x:20,y:330,w:90,h:70};
        const isWin7Win8 = Math.random() < 0.5;
        const LIFE_TREE_GROW_CHANCE = isWin7Win8 ? 1 : 0.0001;
        const NETHER_SPAWN_CHANCE = isWin7Win8 ? 0.5 : 0.12;
        const ENCHANT_LIST = ["附魔之力","天使增幅","黑暗增幅","攻速提升","攻击强化"];
        let autoLevelSwitch = false;

        // ========== 等级升级核心函数 ==========
        function getLevelNeed(){
            return 2000 * (2 ** (level - 1));
        }

        function manualLevelUp(){
            const cost = getLevelNeed();
            if(gold >= cost){
                gold -= cost;
                level += 1;
                alert(`升级成功!当前等级${level},下一级需要${getLevelNeed()}金币`);
            }else{
                alert(`金币不足!升级需要${cost}金币,还差${cost - gold}`);
            }
        }

        function toggleAutoLevel(){
            autoLevelSwitch = !autoLevelSwitch;
            const btn = document.getElementById("autoLvBtn");
            if(autoLevelSwitch){
                btn.innerText = "自动升级:开启";
                btn.style.background = "#22dd22";
            }else{
                btn.innerText = "自动升级:关闭";
                btn.style.background = "#ff7722";
            }
        }

        // ========== 常量定义 ==========
        const PET_TYPE = {WOLF:0,HUSKY:1,CAT:2,PIG:3,COW:4,SHEEP:5}
        const CROP_TYPE = {WHEAT:0,FRUIT_TREE:1,WILD_GRASS:2,WILD_FLOWER:3,NETHER_FLOWER:4,NETHER_TREE:5,LIFE_TREE:6}

        const PALETTE = {
            skyDay: "#58a6ff", skyDayGrad: "#87ceff",
            skyDusk: "#ff8855", skyDuskGrad: "#ffdd88",
            skyNight: "#101030", skyNightGrad: "#302060",
            heavenSky: "#e0f0ff", heavenSkyGrad: "#ffffff",
            hellSky: "#6b0000", hellSkyGrad: "#aa2222",
            ground: "#8b5a2b", grass: "#38b000", grassDark: "#2d8800",
            hellGround: "#2e1010", hellGrass: "#4a1515", hellPlant: "#ff2266",
            heavenGround: "#e6edf7", heavenGrass: "#d0e0f5", heavenCrop: "#f8ffff", heavenSilver:"#c8e8f8",
            farmerSkin: "#ffdab9", farmerHair: "#8b4513", farmerCloth: "#ff0000", farmerOveralls: "#0066cc", farmerShoes: "#333333",
            crop: "#ffcc00", cropStem: "#8b4513", bandit: "#2b2b2b", banditMask: "#ff0000",
            wolf: "#a0a0a0", hellHound: "#ff2222", husky: "#d0e8ff", hellHusky: "#ff6600",
            cat: "#ffc0cb", hellCat: "#9900cc", pig: "#ff9999", hellPig: "#771111", cow: "#996633", hellCow: "#442211", sheep: "#ffffff", hellSheep: "#bbbbbb",
            fruitTree: "#ff9933", wildGrass: "#77dd22", wildFlower: "#ff77bb", netherFlower: "#cc0066", netherTree: "#990022", netherFruit: "#ff0044", lifeTree: "#ffffff", lifeFruit:"#fff8cc",
            houseWall:"#ddaa77", houseRoof:"#883322", houseDoor:"#552211", servant:"#fff2cc"
        }

        // ========== 初始化 ==========
        function initLand(){
            landList = [];
            let xStart = 120;
            for(let i=0;i<landMax;i++){
                landList.push({
                    x:xStart + i*80, y:380, w:70, h:80,
                    seed:false, grow:0, full:false, isHellCrop:false, stolen:false, cropType:CROP_TYPE.WHEAT,
                    harvested: false
                })
            }
            heavenSeedPick = null;
            heavenParticles = [];
        }

        function switchVer(v){
            gameVer = v;
            hellOpen = v>=3;
            heavenOpen = v>=6;
            closeAllPopup();
            alert(`切换至 V${v}`);
            initLand();
            bandits = [];
            pets = [];
            servants = [];
            netherSeed = 0;
            lifeTreeSeed = 0;
            buffAngel = false;
            buffDark = false;
            buffEat = false;
            dayCycleTick = 0;
            mealFlagMorning = false;
            mealFlagNoon = false;
            mealFlagDinner = false;
            mealFlagMidnight = false;
            autoLevelSwitch = false;
            const btn = document.getElementById("autoLvBtn");
            btn.innerText = "自动升级:关闭";
            btn.style.background = "#ff7722";
        }

        // ========== 绘制工具 ==========
        function drawPixelRect(x,y,w,h,color){
            ctx.fillStyle = color;
            ctx.fillRect(Math.floor(x),Math.floor(y),w,h);
        }

        function drawCloud(x,y){
            drawPixelRect(x+4,y,32,16,"#ffffff");
            drawPixelRect(x,y+8,40,12,"#ffffff");
        }

        function drawHouse(){
            if(gameVer <8) return;
            let h = housePos;
            drawPixelRect(h.x+8,h.y+20,h.w-16,h.h-20,PALETTE.houseWall);
            drawPixelRect(h.x,h.y,h.w,24,PALETTE.houseRoof);
            drawPixelRect(h.x+32,h.y+32,24,38,PALETTE.houseDoor);
            drawPixelRect(h.x+14,h.y+28,14,14,"#aaddff");
            drawPixelRect(h.x+62,h.y+28,14,14,"#aaddff");
        }

        function drawFarmer(){
            const p = player;
            drawPixelRect(p.x+10, p.y, 24,24, PALETTE.farmerSkin);
            drawPixelRect(p.x+8, p.y-4,28,10, PALETTE.farmerHair);
            drawPixelRect(p.x+12, p.y+8,5,5,"#000");
            drawPixelRect(p.x+26, p.y+8,5,5,"#000");
            drawPixelRect(p.x+16, p.y+18,12,3,"#cc6666");
            drawPixelRect(p.x+6, p.y+24,32,26, PALETTE.farmerOveralls);
            drawPixelRect(p.x+10, p.y+26,24,8, PALETTE.farmerCloth);
            drawPixelRect(p.x+8, p.y+50,12,14, PALETTE.farmerShoes);
            drawPixelRect(p.x+24, p.y+50,12,14, PALETTE.farmerShoes);
            drawPixelRect(p.x+36, p.y+30,10,6,"#ffdab9");
        }

        // ========== 田地作物绘制 ==========
        function drawLand(){
            landList.forEach(land=>{
                let gColor;
                if(isHeavenMap) gColor = PALETTE.heavenGround;
                else if(isHellMap) gColor = PALETTE.hellGround;
                else gColor = PALETTE.ground;
                drawPixelRect(land.x,land.y,land.w,land.h,gColor);
                ctx.strokeStyle="#222";
                ctx.lineWidth=2;
                ctx.strokeRect(land.x,land.y,land.w,land.h);

                if(land.seed && !land.stolen){
                    let plantH = land.full ? 7 * 14 : land.grow * 14;
                    let stemColor,fruitColor;
                    if(isHeavenMap){
                        stemColor="#e8f4ff";
                        fruitColor = land.cropType === CROP_TYPE.LIFE_TREE ? PALETTE.lifeTree : PALETTE.heavenCrop;
                    }else if(isHellMap && gameVer >=5){
                        if(land.cropType === CROP_TYPE.NETHER_FLOWER){
                            stemColor="#660033";fruitColor=PALETTE.netherFlower;
                        }else if(land.cropType === CROP_TYPE.NETHER_TREE){
                            stemColor="#440011";fruitColor=PALETTE.netherTree;
                        }else{
                            stemColor="#880033";fruitColor=PALETTE.hellPlant;
                        }
                    }else{
                        switch(land.cropType){
                            case CROP_TYPE.WHEAT: stemColor=PALETTE.cropStem;fruitColor=PALETTE.crop;break;
                            case CROP_TYPE.FRUIT_TREE: stemColor="#553311";fruitColor=PALETTE.fruitTree;break;
                            case CROP_TYPE.WILD_GRASS: stemColor="#227711";fruitColor=PALETTE.wildGrass;break;
                            case CROP_TYPE.WILD_FLOWER: stemColor="#338822";fruitColor=PALETTE.wildFlower;break;
                            default: stemColor=PALETTE.cropStem;fruitColor=PALETTE.crop;
                        }
                    }
                    drawPixelRect(land.x+34, land.y - plantH, 6, plantH, stemColor);
                    drawPixelRect(land.x+28, land.y - plantH - 12, 14, 16, fruitColor);
                    drawPixelRect(land.x+30, land.y - plantH - 18,10,8,isHeavenMap?"#ffffff":"#ffff00");
                }
                if(land.stolen) drawPixelRect(land.x+20, land.y-30,30,8,"#ff0000");
            })
        }

        // ========== 盗贼系统 ==========
        function spawnBandit(){
            if(gamePause) return;
            if(gameVer >=4 && tick % 600 === 0 && bandits.length < MAX_BANDIT){
                bandits.push({x:750, y:360, w:36, h:50, hp:2, targetLand:null})
            }
        }

        function banditStealLogic(){
            if(gamePause) return;
            if(gameVer <4) return;
            bandits.forEach(bandit=>{
                if(pets.length > 0) return;
                if(!bandit.targetLand || bandit.targetLand.stolen || !bandit.targetLand.full){
                    bandit.targetLand = null;
                    for(let l of landList){if(l.full && !l.stolen){bandit.targetLand = l;break;}}
                }
                if(bandit.targetLand){
                    let tar = bandit.targetLand;
                    let dx = tar.x - bandit.x;
                    bandit.x += dx > 0 ? 0.6 : -0.6;
                    if(Math.abs(bandit.x - tar.x) < 30){
                        tar.stolen = true; tar.seed = false; tar.full = false;
                    }
                }
            })
        }

        function drawBandits(){
            bandits.forEach(b=>{
                drawPixelRect(b.x+8,b.y,20,20,PALETTE.bandit);
                drawPixelRect(b.x+6,b.y+20,24,18,"#880000");
                drawPixelRect(b.x+10,b.y+6,16,6,PALETTE.banditMask);
                drawPixelRect(b.x+12,b.y+8,4,3,"#fff");
                drawPixelRect(b.x+20,b.y+8,4,3,"#fff");
                drawPixelRect(b.x+10,b.y+38,6,12,"#111");
                drawPixelRect(b.x+20,b.y+38,6,12,"#111");
            })
        }

        // ========== 宠物系统 ==========
        function petAttackBandit(){
            if(gamePause) return;
            if(gameVer <4 || bandits.length ===0 || pets.length ===0) return;
            for(let pet of pets){
                if(isHellMap && pet.type === PET_TYPE.HUSKY){
                    bandits.forEach(b=>{
                        pet.exp += 30;
                        if(gameVer >=9) checkPetLevelUp(pet);
                    });
                    bandits = [];
                    gold += 500;
                    return;
                }
            }
        }

        function checkPetLevelUp(pet){
            const expNeed = pet.level * 100;
            if(pet.exp >= expNeed){
                pet.exp -= expNeed;
                pet.level += 1;
                let roll = Math.random();
                let enchant;
                if(roll < 0.08) enchant = "附魔之力";
                else if(roll < 0.28) enchant = "天使增幅";
                else if(roll < 0.48) enchant = "黑暗增幅";
                else if(roll < 0.72) enchant = "攻速提升";
                else enchant = "攻击强化";
                pet.enchant = enchant;
                alert(`宠物升级!当前等级${pet.level},获得词条:${enchant}`);
            }
        }

        function createPet(type){
            let posX = 100 + pets.length * 90;
            pets.push({
                x: posX, y: 390, w:32, h:36, tickOff: Math.random()*100, type: type,
                level:1, exp:0, enchant:"无"
            })
        }

        function drawSinglePet(pet){
            pet.tickOff++;
            let bounce = Math.sin(pet.tickOff * 0.08) * 3;
            let py = pet.y + bounce;
            let t = pet.type;
            let baseColor, hellColor, eyeColor = "#000";
            let lvMod = Math.min(pet.level,5);
            switch(t){
                case PET_TYPE.WOLF: baseColor = PALETTE.wolf; hellColor = PALETTE.hellHound; break;
                case PET_TYPE.HUSKY: baseColor = PALETTE.husky; hellColor = PALETTE.hellHusky; break;
                case PET_TYPE.CAT: baseColor = PALETTE.cat; hellColor = PALETTE.hellCat; break;
                case PET_TYPE.PIG: baseColor = PALETTE.pig; hellColor = PALETTE.hellPig; break;
                case PET_TYPE.COW: baseColor = PALETTE.cow; hellColor = PALETTE.hellCow; break;
                case PET_TYPE.SHEEP: baseColor = PALETTE.sheep; hellColor = PALETTE.hellSheep; break;
            }
            let c = isHellMap ? hellColor : baseColor;
            let scale = 1 + lvMod * 0.08;
            let off = (32 - 32*scale)/2;
            drawPixelRect(pet.x+6+off, py+10+off,20*scale,18*scale, c);
            if(t === PET_TYPE.WOLF){
                drawPixelRect(pet.x+off, py+off,8*scale,10*scale,c); drawPixelRect(pet.x+24+off, py+off,8*scale,10*scale,c);
                drawPixelRect(pet.x+8+off, py+8+off,4*scale,4*scale,eyeColor); drawPixelRect(pet.x+18+off, py+8+off,4*scale,4*scale,eyeColor);
                if(isHellMap){drawPixelRect(pet.x+2+off, py+2+off,3*scale,3*scale,"#ff0000");drawPixelRect(pet.x+26+off, py+2+off,3*scale,3*scale,"#ff0000");}
            }else if(t === PET_TYPE.HUSKY){
                drawPixelRect(pet.x+2+off, py+off,28*scale,12*scale,c);
                drawPixelRect(pet.x+6+off, py+6+off,4*scale,4*scale,eyeColor); drawPixelRect(pet.x+22+off, py+6+off,4*scale,4*scale,eyeColor);
                drawPixelRect(pet.x+14+off, py+2+off,4*scale,4*scale,"#333");
                if(isHellMap){drawPixelRect(pet.x+4+off, py+4+off,3*scale,3*scale,"#ff0000");drawPixelRect(pet.x+24+off, py+4+off,3*scale,3*scale,"#ff0000");}
            }else if(t === PET_TYPE.CAT){
                drawPixelRect(pet.x+4+off, py+off,24*scale,10*scale,c);
                drawPixelRect(pet.x+8+off, py+6+off,3*scale,3*scale,eyeColor); drawPixelRect(pet.x+18+off, py+6+off,3*scale,3*scale,eyeColor);
                drawPixelRect(pet.x+2+off, py-4+off,6*scale,6*scale,c); drawPixelRect(pet.x+24+off, py-4+off,6*scale,6*scale,c);
            }else if(t === PET_TYPE.PIG){
                drawPixelRect(pet.x+8+off, py+off,16*scale,12*scale,c); drawPixelRect(pet.x+10+off, py+8+off,6*scale,4*scale,"#ff6666");
                drawPixelRect(pet.x+12+off, py+4+off,3*scale,3*scale,eyeColor); drawPixelRect(pet.x+18+off, py+4+off,3*scale,3*scale,eyeColor);
            }else if(t === PET_TYPE.COW){
                drawPixelRect(pet.x+4+off, py+off,24*scale,14*scale,c);
                drawPixelRect(pet.x+6+off, py+6+off,4*scale,4*scale,"#fff"); drawPixelRect(pet.x+18+off, py+6+off,4*scale,4*scale,"#fff");
                drawPixelRect(pet.x+2+off, py+2+off,6*scale,6*scale,"#ffffff"); drawPixelRect(pet.x+24+off, py+2+off,6*scale,6*scale,"#ffffff");
            }else if(t === PET_TYPE.SHEEP){
                drawPixelRect(pet.x+4+off, py+off,24*scale,14*scale,c);
                drawPixelRect(pet.x+8+off, py+6+off,3*scale,3*scale,eyeColor); drawPixelRect(pet.x+18+off, py+6+off,3*scale,3*scale,eyeColor);
                drawPixelRect(pet.x+6+off, py+12+off,20*scale,4*scale,"#dddddd");
            }
            drawPixelRect(pet.x+8+off, py+28+off,6*scale,8*scale,"#333"); drawPixelRect(pet.x+18+off, py+28+off,6*scale,8*scale,"#333");
        }

        function drawPets(){
            if(gameVer <3) return;
            pets.forEach(p=>drawSinglePet(p));
            document.getElementById('petCount').innerText = pets.length;
        }

        // ========== 佣人系统 ==========
        function createServant(){
            servants.push({x: 90 + servants.length * 75, y:392, w:28, h:32, tick:0})
        }

        function servantAutoHarvest(){
            if(gamePause) return;
            if(gameVer !== 8 && gameVer !==9 || servants.length ===0) return;
            servants.forEach(s=>{
                s.tick++;
                if(s.tick >=60){
                    s.tick = 0;
                    for(let l of landList){
                        if(l.full && !l.stolen && !l.harvested){
                            l.harvested = true;
                            let earn = l.isHellCrop ? 400 : 200;
                            if(l.cropType === CROP_TYPE.LIFE_TREE){
                                gold += 1000; buffAngel = true;
                            }else if(l.cropType === CROP_TYPE.NETHER_TREE){
                                gold += 800; buffDark = true;
                            }else gold += earn;
                            l.seed = false; l.full = false; l.grow = 0; l.harvested = false;
                            break;
                        }
                    }
                }
            })
        }

        function drawServants(){
            if(gameVer <8) return;
            servants.forEach(s=>{
                drawPixelRect(s.x+4,s.y,20,20,PALETTE.servant);
                drawPixelRect(s.x+6,s.y+20,16,12,"#774422");
                drawPixelRect(s.x+8,s.y+6,4,4,"#000");
                drawPixelRect(s.x+16,s.y+6,4,4,"#000");
            })
            document.getElementById('servantCount').innerText = servants.length;
        }

        // ========== 地图切换 ==========
        function goHell(){
            if(!hellOpen){alert("切换V3及以上解锁地狱");return;}
            if(level < 3){alert(`LV${level}不足LV3,还差${getLevelNeed()-gold}金币升级`);return;}
            isHellMap = true; isHeavenMap = false; bandits = [];
        }
        function goHeaven(){
            if(!heavenOpen){alert("仅V6/V7/V8/V9解锁天堂");return;}
            if(level < 5){alert(`当前LV${level},天堂需要LV5`);return;}
            isHeavenMap = true; isHellMap = false; bandits = [];
            heavenSeedPick = {x:680,y:330,w:24,h:24};
        }
        function backOriginWorld(){
            isHellMap = false;
            isHeavenMap = false;
            bandits = [];
            alert("已返回主世界");
        }

        // ========== 天堂特效 ==========
        function spawnHeavenParticle(){
            if(gamePause) return;
            if(!isHeavenMap || gameVer <6) return;
            if(tick % 8 === 0){
                heavenParticles.push({x: Math.random()*800, y:340, vy:-1-Math.random()*2, life:80})
            }
        }
        function drawHeavenParticles(){
            heavenParticles.forEach((p,i)=>{
                p.y += p.vy; p.life--;
                drawPixelRect(p.x,p.y,3,3,"#ffffff");
                if(p.life <=0) heavenParticles.splice(i,1);
            })
        }
        function drawHeavenSeedPick(){
            if(!heavenSeedPick || !isHeavenMap) return;
            let s = heavenSeedPick;
            drawPixelRect(s.x,s.y,s.w,s.h,"#fffde0");
            drawPixelRect(s.x+6,s.y+6,12,12,"#ffffff");
        }

        // ========== 弹窗控制 ==========
        function closeAllPopup(){
            document.getElementById('mask').style.display = "none";
            document.getElementById('shopBox').style.display = "none";
            document.getElementById('settingBox').style.display = "none";
            document.getElementById('houseBox').style.display = "none";
            gamePause = false;
        }
        function openHouse(){
            document.getElementById('mask').style.display = "block";
            document.getElementById('houseBox').style.display = "block";
            gamePause = true;
        }
        function closeHouse(){
            closeAllPopup();
        }
        function eatMeal(){
            buffEat = true;
            buffEatTick = 1200;
            alert("吃饱饭啦!短时间作物生长小幅加速");
            closeAllPopup();
        }
        function sleepNight(){
            dayCycleTick = 0;
            dayPhase = "day";
            alert("一觉睡到天亮,昼夜重置为白天");
            closeAllPopup();
        }

        // ========== 昼夜系统 ==========
        function updateDayCycle(){
            if(gamePause) return;
            dayCycleTick++;
            let ratio = dayCycleTick / DAY_CYCLE_LEN;
            if(ratio < 0.35){
                dayPhase = "day";
                if(!mealFlagMorning){
                    mealFlagMorning = true;
                    alert("【早餐时间】必须进屋吃饭,无法跳过!点击农场小屋用餐");
                }
            }else if(ratio < 0.65){
                dayPhase = "dusk";
                if(!mealFlagNoon){
                    mealFlagNoon = true;
                    alert("【午餐时间】强制用餐,前往小屋吃饭");
                }
            }else{
                dayPhase = "night";
                if(!mealFlagDinner){
                    mealFlagDinner = true;
                    alert("【晚餐时间】必须吃饭,不能拒绝");
                }
                if(!mealFlagMidnight){
                    mealFlagMidnight = true;
                    let ok = confirm("【夜宵】是否吃夜宵?可选择拒绝");
                    if(ok){
                        buffEat = true; buffEatTick = 800;
                    }
                }
            }
            document.getElementById('dayPhase').innerText = dayPhase==="day"?"白天":dayPhase==="dusk"?"黄昏":"夜晚";
        }

        // ========== 存档系统 ==========
        function saveSlot(num){
            const saveData = {
                gameVer,gold,level,landMax,landList,player,
                hellOpen,heavenOpen,isHellMap,isHeavenMap,bandits,
                hasWeapon,hasMachine,tick,pets,servants,
                netherSeed,lifeTreeSeed,buffAngel,buffDark,buffEat,buffEatTick,
                heavenSeedPick,heavenParticles,dayCycleTick,dayPhase,
                mealFlagMorning,mealFlagNoon,mealFlagDinner,mealFlagMidnight,MAX_BANDIT,
                autoLevelSwitch
            };
            localStorage.setItem("farmSave"+num, JSON.stringify(saveData));
            alert("✅ 存档"+num+"保存成功");
        }

        function loadSlot(num){
            const saveStr = localStorage.getItem("farmSave"+num);
            if(!saveStr){
                alert("❌ 存档"+num+"为空,无记录");
                return;
            }
            try{
                const d = JSON.parse(saveStr);
                gameVer = d.gameVer;
                gold = d.gold;
                level = d.level;
                landMax = d.landMax;
                landList = d.landList;
                player = d.player;
                hellOpen = d.hellOpen;
                heavenOpen = d.heavenOpen;
                isHellMap = d.isHellMap;
                isHeavenMap = d.isHeavenMap;
                bandits = d.bandits;
                hasWeapon = d.hasWeapon;
                hasMachine = d.hasMachine;
                tick = d.tick;
                pets = d.pets;
                servants = d.servants;
                netherSeed = d.netherSeed;
                lifeTreeSeed = d.lifeTreeSeed;
                buffAngel = d.buffAngel;
                buffDark = d.buffDark;
                buffEat = d.buffEat;
                buffEatTick = d.buffEatTick;
                heavenSeedPick = d.heavenSeedPick;
                heavenParticles = d.heavenParticles;
                dayCycleTick = d.dayCycleTick;
                dayPhase = d.dayPhase;
                mealFlagMorning = d.mealFlagMorning;
                mealFlagNoon = d.mealFlagNoon;
                mealFlagDinner = d.mealFlagDinner;
                mealFlagMidnight = d.mealFlagMidnight;
                autoLevelSwitch = d.autoLevelSwitch ?? false;
                const btn = document.getElementById("autoLvBtn");
                if(autoLevelSwitch){
                    btn.innerText = "自动升级:开启";
                    btn.style.background = "#22dd22";
                }else{
                    btn.innerText = "自动升级:关闭";
                    btn.style.background = "#ff7722";
                }
                alert("✅ 存档"+num+"读取完成");
                renderShop();
            }catch(e){
                alert("❌ 存档"+num+"损坏");
                console.error(e);
            }
        }

        // ========== 主游戏循环 ==========
        function gameLoop(){
            tick++;
            // 背景
            let skyTop,skyBottom;
            if(isHeavenMap){skyTop=PALETTE.heavenSky;skyBottom=PALETTE.heavenSkyGrad;}
            else if(isHellMap){skyTop=PALETTE.hellSky;skyBottom=PALETTE.hellSkyGradient;}
            else {
                if(dayPhase==="day"){skyTop=PALETTE.skyDay;skyBottom=PALETTE.skyDayGrad;}
                else if(dayPhase==="dusk"){skyTop=PALETTE.skyDusk;skyBottom=PALETTE.skyDuskGrad;}
                else {skyTop=PALETTE.skyNight;skyBottom=PALETTE.skyNightGrad;}
            }
            ctx.fillStyle=skyTop;ctx.fillRect(0,0,800,500);

            if(!isHellMap && !isHeavenMap && dayPhase==="day"){drawCloud(120,60);drawCloud(350,90);drawCloud(600,50);}

            // 生长速度
            let growSpeed = 0.03;
            if(hasMachine && !isHellMap && !isHeavenMap) growSpeed *= 2;
            if(buffAngel) growSpeed *= 3;
            if(buffDark && isHellMap) growSpeed *= 8;
            if(buffEat) {growSpeed *= 1.4; buffEatTick--; if(buffEatTick <=0) buffEat = false;}

            // 作物生长
            if(!gamePause){
                landList.forEach(l=>{
                    if(l.seed && !l.full){
                        l.grow += growSpeed;
                        if(l.grow >=7) l.full = true;
                    }
                })
            }

            // 自动升级逻辑
            if(autoLevelSwitch && !gamePause){
                const cost = getLevelNeed();
                if(gold >= cost){
                    gold -= cost;
                    level += 1;
                }
            }

            // 游戏逻辑
            spawnBandit();
            banditStealLogic();
            petAttackBandit();
            servantAutoHarvest();
            spawnHeavenParticle();
            updateDayCycle();

            // 渲染
            drawLand();
            drawHouse();
            drawHeavenParticles();
            drawHeavenSeedPick();
            drawFarmer();
            drawBandits();
            drawPets();
            drawServants();

            // UI更新
            document.getElementById('lv').innerText = level;
            document.getElementById('gold').innerText = gold;
            document.getElementById('landNum').innerText = landMax;
            document.getElementById('lvNeed').innerText = getLevelNeed();
            document.getElementById('seedNether').innerText = netherSeed;
            document.getElementById('seedLife').innerText = lifeTreeSeed;
            document.getElementById('buffAngel').innerText = buffAngel?"激活":"无";
            document.getElementById('buffDark').innerText = buffDark?"激活":"无";

            requestAnimationFrame(gameLoop);
        }

        // ========== 点击交互 ==========
        document.getElementById('gameCanvas').onclick = e=>{
            if(gamePause) return;
            const rect = e.target.getBoundingClientRect();
            const mx = e.clientX - rect.left;
            const my = e.clientY - rect.top;

            // 小屋
            if(gameVer >=8){
                let h = housePos;
                if(mx >= h.x && mx <= h.x+h.w && my >= h.y && my <= h.y+h.h){
                    openHouse();
                    return;
                }
            }

            // 天堂种子拾取
            if(gameVer >=6 && isHeavenMap && heavenSeedPick){
                let s = heavenSeedPick;
                if(mx>s.x && mx<s.x+s.w && my>s.y && my<s.y+s.h){
                    lifeTreeSeed +=1;
                    heavenSeedPick = null;
                    alert("拾取生命树种子!Win7/8种下100%成活");
                }
            }

            // 攻击盗贼
            if(gameVer >=4){
                for(let i=bandits.length-1;i>=0;i--){
                    const b = bandits[i];
                    if(mx>b.x && mx <b.x+b.w && my>b.y && my <b.y+b.h){
                        if(!hasWeapon){alert("商店购买铁剑才能攻击盗贼");return;}
                        b.hp--;
                        if(b.hp <=0){
                            bandits.splice(i,1);
                            gold += 100;
                        }
                        return;
                    }
                }
            }

            // 田地播种/收割
            landList.forEach(land=>{
                if(mx>land.x && mx <land.x+land.w && my>land.y && my <land.y+land.h){
                    if(!land.seed && !land.stolen){
                        // 特殊种子播种
                        if(isHellMap && netherSeed > 0){
                            netherSeed--;
                            land.seed = true; land.grow = 0;
                            land.isHellCrop = true;
                            land.cropType = CROP_TYPE.NETHER_TREE;
                            return;
                        }
                        if(isHeavenMap && lifeTreeSeed > 0){
                            lifeTreeSeed--;
                            land.seed = true; land.grow = 0;
                            land.isHellCrop = false;
                            land.cropType = CROP_TYPE.LIFE_TREE;
                            return;
                        }
                        // 普通播种
                        land.seed = true; land.grow = 0;
                        land.isHellCrop = isHellMap;
                        if(gameVer >=5 && isHellMap && Math.random() < NETHER_SPAWN_CHANCE){
                            land.cropType = Math.random()>0.5 ? CROP_TYPE.NETHER_FLOWER : CROP_TYPE.NETHER_TREE;
                        }else if(gameVer >=5 && !isHellMap && !isHeavenMap){
                            let r = Math.random();
                            if(r<0.35) land.cropType=CROP_TYPE.WHEAT;
                            else if(r<0.55) land.cropType=CROP_TYPE.FRUIT_TREE;
                            else if(r<0.78) land.cropType=CROP_TYPE.WILD_GRASS;
                            else land.cropType=CROP_TYPE.WILD_FLOWER;
                        }else if(gameVer >=6 && isHeavenMap){
                            land.cropType = Math.random()>0.7 ? CROP_TYPE.WILD_FLOWER : CROP_TYPE.WHEAT;
                        }else land.cropType=CROP_TYPE.WHEAT;
                    }else if(land.full && !land.stolen){
                        // 收割仅加金币,不再自动升级
                        let earn = land.isHellCrop ? 400 : 200;
                        if(land.cropType === CROP_TYPE.LIFE_TREE){
                            gold += 1000; buffAngel = true;
                        }else if(land.cropType === CROP_TYPE.NETHER_TREE){
                            let opt = confirm("冥界果实:吃掉获得黑暗之力|取消留存种子");
                            if(opt){buffDark = true;gold += 800;alert("黑暗之力:地狱作物×8生长");}
                            else{netherSeed +=1;alert(`冥界种子+1`);}
                        }else{
                            gold += earn;
                        }
                        land.seed = false; land.full = false; land.grow = 0;
                    }
                }
            })
        }

        // ========== 商店系统 ==========
        function openShop(){
            document.getElementById('mask').style.display = "block";
            document.getElementById('shopBox').style.display = "block";
            gamePause = true;
            renderShop();
        }
        function closeShop(){
            closeAllPopup();
        }
        function openSetting(){
            document.getElementById('mask').style.display = "block";
            document.getElementById('settingBox').style.display = "block";
            gamePause = true;
        }
        function closeSetting(){
            closeAllPopup();
        }

        function renderShop(){
            const list = document.getElementById('shopList');
            list.innerHTML = "";
            const goods = [];
            goods.push({name:"扩大田地一块",cost:600,func:()=>{landMax++;initLand()}});
            goods.push({name:"石锄头",cost:300,func:()=>{}});
            if(gameVer >=2) goods.push({name:"自动灌溉机器",cost:1500,func:()=>{hasMachine=true}});
            if(gameVer >=4) goods.push({name:"像素铁剑防盗贼",cost:2200,func:()=>{hasWeapon=true}});
            if(gameVer >=3){
                goods.push({name:"灰狼 30金币",cost:30,func:()=>createPet(PET_TYPE.WOLF)});
                goods.push({name:"哈士奇(地狱瞬杀盗贼) 120",cost:120,func:()=>createPet(PET_TYPE.HUSKY)});
                goods.push({name:"猫咪 40",cost:40,func:()=>createPet(PET_TYPE.CAT)});
                goods.push({name:"肉猪 25",cost:25,func:()=>createPet(PET_TYPE.PIG)});
                goods.push({name:"奶牛 35",cost:35,func:()=>createPet(PET_TYPE.COW)});
                goods.push({name:"绵羊 20",cost:20,func:()=>createPet(PET_TYPE.SHEEP)});
            }
            if(gameVer >=5) goods.push({name:"冥界种子",cost:800,func:()=>{netherSeed+=1;renderShop();}});
            if(gameVer >=6) goods.push({name:"备用生命树种子",cost:3000,func:()=>{lifeTreeSeed+=1;renderShop();}});
            if(gameVer === 8 || gameVer ===9) goods.push({name:"佣人(每秒自动收1块作物) 200金币",cost:200,func:()=>{createServant();renderShop();}});

            goods.forEach(item=>{
                let div = document.createElement("div");
                div.className = "shop-item";
                div.innerHTML = `<span>${item.name}</span><span>${item.cost}金币</span>`;
                let buyBtn = document.createElement("button");
                buyBtn.className = "btn";
                buyBtn.innerText = "购买";
                buyBtn.onclick = ()=>{
                    if(gold >= item.cost){gold -= item.cost;item.func();renderShop();}
                    else alert("金币不足,多种地赚钱");
                }
                div.appendChild(buyBtn);
                list.appendChild(div);
            })
        }

        // 启动游戏
        initLand();
        loadSlot(1);
        gameLoop();
    </script>
</body>
</html>

Game Source: 像素农夫物语 V9 手动自动等级升级完整版

Creator: BraveDragon92

Libraries: none

Complexity: complex (995 lines, 43.7 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: v9-bravedragon92" to link back to the original. Then publish at arcadelab.ai/publish.