像素农夫物语 V10 完整版(整合V1-V9全功能)
by BraveDragon92997 lines43.4 KB
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>像素农夫物语 V10 完整版(整合V1-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;}
.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;
}
.tip-text {
font-size:12px;
color:#ccc;
margin:8px 0 16px;
line-height:1.4;
}
</style>
</head>
<body>
<h2>8bit像素农夫 V10 完整版(整合V1-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-purple" onclick="goCosmos()">宇宙维度</button>
<button class="btn btn-danger" onclick="checkHorrorAccess()">愚人节恐怖V0.1入口</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>像素商店 V10完整版</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 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;">V10规则:整合全部V1-V9功能;新增通用宇宙维度;宠物升级附魔;3存档;地狱LV3/天堂LV5解锁;佣人自动收割;恐怖V0.1仅4月或Win7/8系统可进入</p>
<script>
const ctx = document.getElementById('gameCanvas').getContext('2d');
// ========== 全局变量 ==========
let gold = 0;
let level = 1;
let landMax = 4;
let landList = [];
let player = {x:380,y:320,w:44,h:64};
let hellOpen = true;
let heavenOpen = true;
let isHellMap = false;
let isHeavenMap = false;
let isCosmosMap = 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 cosmosStars = [];
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 = /Windows 7|Windows 8/.test(navigator.userAgent);
const currentMonth = new Date().getMonth() + 1;
const isApril = currentMonth === 4;
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 checkHorrorAccess(){
if(isWin7Win8 || isApril){
alert("正在跳转恐怖限定V0.1页面,请保存当前存档!");
window.open("pixel_farm_v0.1_horror.html","_blank");
}else{
alert("权限不足:仅4月整月 / Win7、Win8系统可打开恐怖V0.1");
}
}
// ========== 等级升级核心函数 ==========
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,COSMIC_PLANT:7}
const PALETTE = {
skyDay: "#58a6ff", skyDayGrad: "#87ceff",
skyDusk: "#ff8855", skyDuskGrad: "#ffdd88",
skyNight: "#101030", skyNightGrad: "#302060",
heavenSky: "#e0f0ff", heavenSkyGrad: "#ffffff",
hellSky: "#6b0000", hellSkyGrad: "#aa2222",
cosmosSky: "#000010", cosmosSkyGrad: "#100030",
ground: "#8b5a2b", grass: "#38b000", grassDark: "#2d8800",
hellGround: "#2e1010", hellGrass: "#4a1515", hellPlant: "#ff2266",
heavenGround: "#e6edf7", heavenGrass: "#d0e0f5", heavenCrop: "#f8ffff", heavenSilver:"#c8e8f8",
cosmosGround:"#050515", cosmosCrop:"#ccddff", cosmosGlow:"#ffffff", cosmosLine:"#6644ff",
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 = [];
cosmosStars = [];
}
// ========== 绘制工具 ==========
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(){
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 spawnCosmosStar(){
if(!isCosmosMap || gamePause) return;
if(tick % 5 === 0){
cosmosStars.push({
x:Math.random()*800,
y:Math.random()*500,
size:Math.random()*3+1,
alpha:Math.random(),
vy:Math.random()*0.3-0.15
})
}
}
function drawCosmosStars(){
cosmosStars.forEach((s,i)=>{
s.y += s.vy;
s.alpha = Math.sin(tick*0.03 + i)*0.4+0.6;
ctx.fillStyle = `rgba(255,255,255,${s.alpha})`;
ctx.beginPath();
ctx.arc(s.x,s.y,s.size,0,Math.PI*2);
ctx.fill();
if(s.y < -10 || s.y>510) cosmosStars.splice(i,1);
})
}
// ========== 田地作物绘制 ==========
function drawLand(){
landList.forEach(land=>{
let gColor;
if(isCosmosMap) gColor = PALETTE.cosmosGround;
else 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(isCosmosMap){
ctx.strokeStyle = PALETTE.cosmosLine;
ctx.lineWidth=1;
for(let i=0;i<3;i++){
ctx.beginPath();
ctx.moveTo(land.x+Math.random()*70, land.y);
ctx.lineTo(land.x+Math.random()*70, land.y+80);
ctx.stroke();
}
}
if(land.seed && !land.stolen){
let plantH = land.full ? 7 * 14 : land.grow * 14;
let stemColor,fruitColor;
if(isCosmosMap){
stemColor="#222255";
fruitColor=PALETTE.cosmosCrop;
// 作物星光辉光
ctx.shadowColor = PALETTE.cosmosGlow;
ctx.shadowBlur = 12;
}else if(isHeavenMap){
stemColor="#e8f4ff";
fruitColor = land.cropType === CROP_TYPE.LIFE_TREE ? PALETTE.lifeTree : PALETTE.heavenCrop;
}else if(isHellMap){
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||isCosmosMap?"#ffffff":"#ffff00");
ctx.shadowBlur = 0;
}
if(land.stolen) drawPixelRect(land.x+20, land.y-30,30,8,"#ff0000");
})
}
// ========== 盗贼系统 ==========
function spawnBandit(){
if(gamePause) return;
if(tick % 600 === 0 && bandits.length < MAX_BANDIT && !isCosmosMap){
bandits.push({x:750, y:360, w:36, h:50, hp:2, targetLand:null})
}
}
function banditStealLogic(){
if(gamePause || isCosmosMap) 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(){
if(isCosmosMap) return;
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 || isCosmosMap) return;
if(bandits.length ===0 || pets.length ===0) return;
for(let pet of pets){
if(isHellMap && pet.type === PET_TYPE.HUSKY){
pet.exp += 30;
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(){
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(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 if(isCosmosMap){
gold += 1200;
}else gold += earn;
l.seed = false; l.full = false; l.grow = 0; l.harvested = false;
break;
}
}
}
})
}
function drawServants(){
if(isCosmosMap) 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(level < 3){alert(`LV${level}不足LV3,还差${getLevelNeed()-gold}金币升级`);return;}
isHellMap = true; isHeavenMap = false; isCosmosMap = false; bandits = [];
}
function goHeaven(){
if(level < 5){alert(`当前LV${level},天堂需要LV5`);return;}
isHeavenMap = true; isHellMap = false; isCosmosMap = false; bandits = [];
heavenSeedPick = {x:680,y:330,w:24,h:24};
}
function goCosmos(){
isCosmosMap = true; isHellMap = false; isHeavenMap = false; bandits = [];
alert("进入宇宙维度:星空地面、发光宇宙作物,无盗贼");
}
function backOriginWorld(){
isHellMap = false;
isHeavenMap = false;
isCosmosMap = false;
bandits = [];
alert("已返回主世界");
}
// ========== 天堂特效 ==========
function spawnHeavenParticle(){
if(gamePause) return;
if(!isHeavenMap) 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('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 || isCosmosMap) 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 = {
gold,level,landMax,landList,player,
isHellMap,isHeavenMap,isCosmosMap,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);
gold = d.gold;
level = d.level;
landMax = d.landMax;
landList = d.landList;
player = d.player;
isHellMap = d.isHellMap;
isHeavenMap = d.isHeavenMap;
isCosmosMap = d.isCosmosMap ?? false;
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(isCosmosMap){skyTop=PALETTE.cosmosSky;skyBottom=PALETTE.cosmosSkyGrad;}
else if(isHeavenMap){skyTop=PALETTE.heavenSky;skyBottom=PALETTE.heavenSkyGrad;}
else if(isHellMap){skyTop=PALETTE.hellSky;skyBottom=PALETTE.hellSkyGrad;}
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 && !isCosmosMap && dayPhase==="day"){drawCloud(120,60);drawCloud(350,90);drawCloud(600,50);}
// 生长速度
let growSpeed = 0.03;
if(hasMachine && !isHellMap && !isHeavenMap && !isCosmosMap) growSpeed *= 2;
if(buffAngel) growSpeed *= 3;
if(buffDark && isHellMap) growSpeed *= 8;
if(isCosmosMap) growSpeed *= 4;
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();
spawnCosmosStar();
if(!isCosmosMap) updateDayCycle();
// 渲染图层
drawLand();
if(!isCosmosMap) drawHouse();
drawCosmosStars();
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(!isCosmosMap){
let h = housePos;
if(mx >= h.x && mx <= h.x+h.w && my >= h.y && my <= h.y+h.h){
openHouse();
return;
}
}
// 天堂种子拾取
if(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(!isCosmosMap){
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(isCosmosMap){
land.seed = true; land.grow = 0;
land.cropType = CROP_TYPE.COSMIC_PLANT;
return;
}
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(isHellMap && Math.random() < NETHER_SPAWN_CHANCE){
land.cropType = Math.random()>0.5 ? CROP_TYPE.NETHER_FLOWER : CROP_TYPE.NETHER_TREE;
}else{
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(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 if(isCosmosMap){
gold += 1200;
}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 renderShop(){
const list = document.getElementById('shopList');
list.innerHTML = "";
const goods = [];
goods.push({name:"扩大田地一块",cost:600,func:()=>{landMax++;initLand()}});
goods.push({name:"石锄头",cost:300,func:()=>{}});
goods.push({name:"自动灌溉机器",cost:1500,func:()=>{hasMachine=true}});
goods.push({name:"像素铁剑防盗贼",cost:2200,func:()=>{hasWeapon=true}});
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)});
goods.push({name:"冥界种子",cost:800,func:()=>{netherSeed+=1;renderShop();}});
goods.push({name:"备用生命树种子",cost:3000,func:()=>{lifeTreeSeed+=1;renderShop();}});
goods.push({name:"佣人(自动收作物) 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: 像素农夫物语 V10 完整版(整合V1-V9全功能)
Creator: BraveDragon92
Libraries: none
Complexity: complex (997 lines, 43.4 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: v10-v1-v9-bravedragon92" to link back to the original. Then publish at arcadelab.ai/publish.