前言
在网页开发学习中,制作小游戏是巩固前端基础知识的绝佳方式。本文将带大家从零开始,一步步构建一个功能完整的修仙模拟器,涵盖游戏状态管理、UI 交互设计、数据持久化等核心知识点。通过这个项目,你不仅能掌握 JavaScript、HTML、CSS 的综合应用,还能理解游戏开发的基本逻辑和设计思路。
代码已进行模块化拆分,每个部分都有详细解释,确保大家能轻松跟上节奏。
先给大家附上完整代码,共有三份文件,全复制到同一个文件夹下,双击.html文件就能运行
game.js
let gameState = {
cultivation: 0, // 修为
maxCultivation: 100, // 最大修为
spiritualEnergy: 0, // 灵气
spiritualStones: 100, // 灵石
realm: "凡人", // 当前境界
realmLevel: 0, // 当前境界等级
realmOrder: ["凡人", "练气期", "筑基期", "金丹期", "元婴期", "化神期", "合体期", "渡劫期", "大乘期", "成仙"], // 境界顺序
breakthroughChance: 30, // 突破成功率
breakthroughBonus: 0, // 突破加成(百分比)
cultivationSpeed: 1, // 修炼速度
energyGatheringSpeed: 1, // 灵气采集速度
autoCultivation: false, // 自动修炼状态
autoCultivationInterval: null, // 自动修炼间隔
equippedArtifacts: 0, // 装备的法宝数量
lastUpdateTime: Date.now(), // 上次更新时间
// 灵根系统
spiritualRoot: {
type: "凡根",
quality: "普通",
level: 1,
bonus: 0
},
// 成就系统
achievements: [
{ id: "first_cultivation", name: "初入修仙", description: "完成第一次修炼", completed: false, progress: 0, target: 1, reward: 50 },
{ id: "gather_energy", name: "灵气入体", description: "采集10次灵气", completed: false, progress: 0, target: 10, reward: 30 },
{ id: "first_breakthrough", name: "突破境界", description: "突破到练气一层", completed: false, progress: 0, target: 1, reward: 100 },
{ id: "buy_item", name: "初次购物", description: "在商店购买第一件物品", completed: false, progress: 0, target: 1, reward: 20 },
{ id: "spiritual_master", name: "灵根大师", description: "提升灵根品质", completed: false, progress: 0, target: 1, reward: 150 },
{ id: "energy_master", name: "聚气成海", description: "灵气达到1000点", completed: false, progress: 0, target: 1000, reward: 200 },
{ id: "treasure_hunter", name: "寻宝专家", description: "收集所有类型的物品", completed: false, progress: 0, target: 4, reward: 300 },
{ id: "realm_lord", name: "境界之主", description: "突破到练气五层", completed: false, progress: 0, target: 1, reward: 500 }
],
// 任务系统
quests: [
{ id: "main_1", name: "修仙之路", description: "完成一次修炼", progress: 0, target: 1, completed: false, reward: { cultivation: 50, stones: 50 } },
{ id: "main_2", name: "灵气积累", description: "采集5次灵气", progress: 0, target: 5, completed: false, reward: { cultivation: 100, stones: 80 } },
{ id: "main_3", name: "初入练气", description: "突破到练气一层", progress: 0, target: 1, completed: false, reward: { cultivation: 200, stones: 150, energy: 200 } },
{ id: "main_4", name: "提升灵根", description: "提升一次灵根品质", progress: 0, target: 1, completed: false, reward: { cultivation: 300, stones: 200 } },
{ id: "main_5", name: "商店购物", description: "在商店购买一个物品", progress: 0, target: 1, completed: false, reward: { cultivation: 150, stones: 100 } },
{ id: "side_1", name: "收集突破符", description: "收集3个突破符", progress: 0, target: 3, completed: false, reward: { cultivation: 250, stones: 150 } },
{ id: "side_2", name: "成就达人", description: "完成3个成就", progress: 0, target: 3, completed: false, reward: { cultivation: 500, stones: 300 } }
],
// 背包系统
inventory: [
{ id: "breakthrough_talisman", name: "突破符", count: 0, description: "增加20%的突破成功率" },
{ id: "heavenly_pill", name: "天灵丹", count: 0, description: "立即获得100点修为" },
{ id: "magic_artifact", name: "法宝", count: 0, description: "增加修炼速度10%" },
{ id: "root_improvement_pill", name: "灵根提升丹", count: 0, description: "提升灵根品质" },
{ id: "energy_crystal", name: "能量水晶", count: 0, description: "立即获得500点灵气" }
],
// 商店物品
shopItems: [
{ id: "breakthrough_talisman", name: "突破符", cost: 50, description: "增加20%的突破成功率" },
{ id: "heavenly_pill", name: "天灵丹", cost: 80, description: "立即获得100点修为" },
{ id: "magic_artifact", name: "法宝", cost: 150, description: "增加修炼速度10%" },
{ id: "root_improvement_pill", name: "灵根提升丹", cost: 200, description: "提升灵根品质" },
{ id: "energy_crystal", name: "能量水晶", cost: 120, description: "立即获得500点灵气" }
],
// 新手引导
tutorialStep: 0,
tutorialSteps: [
"欢迎来到修仙世界!点击中间的圆形区域进行修炼,积累修为。",
"修为达到100后可以尝试突破境界,提升自己的实力。",
"点击'采集灵气'按钮可以获取灵气,灵气可用于突破。",
"使用灵石可以在商店购买各种道具,提升修炼效率。",
"查看任务和成就面板,完成目标可以获得丰厚奖励!",
"点击背包中的物品可以直接使用,提升你的修仙之路!"
],
// 特殊事件
specialEvents: {
active: false,
eventType: null,
countdown: 0
}
};
// DOM元素
const cultivationCircle = document.getElementById('cultivationCircle');
const cultivationCore = cultivationCircle.querySelector('.cultivation-core');
const cultivationProgressText = document.getElementById('cultivationProgressText');
const spiritualStonesText = document.getElementById('spiritStone');
const spiritualEnergyText = document.getElementById('qi');
const realmText = document.getElementById('realm');
const gatherBtn = document.getElementById('gatherBtn');
const breakthroughBtn = document.getElementById('breakthroughBtn');
const autoCultivationBtn = document.getElementById('autoCultivationBtn');
const tutorialOverlay = document.getElementById('tutorialOverlay');
const tutorialMessage = document.getElementById('tutorialMessage');
const nextTutorialBtn = document.getElementById('nextTutorialBtn');
const skipTutorialBtn = document.getElementById('skipTutorialBtn');
const statsContainer = document.querySelector('.game-stats');
const achievementsContainer = document.getElementById('achievementsContainer');
const inventoryContainer = document.getElementById('inventoryContainer');
// 创建缺失的元素
const shopContainer = document.querySelector('.shop-items');
const eventLog = document.createElement('div');
eventLog.id = 'eventLog';
eventLog.className = 'event-log';
document.body.appendChild(eventLog);
const questsContainer = document.createElement('div');
questsContainer.id = 'questsContainer';
questsContainer.className = 'quests-container';
const rootTypeDisplay = document.createElement('div');
rootTypeDisplay.id = 'rootTypeDisplay';
const rootQualityDisplay = document.createElement('div');
rootQualityDisplay.id = 'rootQualityDisplay';
const cultivationSpeedDisplay = document.getElementById('cultivationSpeed');
const energyGatheringSpeedDisplay = document.getElementById('qiGatherSpeed');
const resetGameBtn = document.getElementById('resetGameBtn');
const fullscreenBtn = document.getElementById('toggleFullscreenBtn');
// 创建新的DOM元素
let tutorialElement;
let questElement;
let achievementElement;
// 初始化游戏
function initGame() {
loadGame();
// 确保lastUpdateTime正确设置
if (!gameState.lastUpdateTime) {
gameState.lastUpdateTime = Date.now();
}
createTutorialUI();
createQuestUI();
createAchievementUI();
addNewShopItems();
updateUI();
setupEventListeners();
gameLoop();
// 开始新手引导
if (gameState.tutorialStep < gameState.tutorialSteps.length) {
showTutorialStep();
}
}
// 更新UI
function updateUI() {
// 更新游戏状态显示
cultivationProgressText.textContent = `修为:${gameState.cultivation}/${gameState.maxCultivation}`;
spiritualEnergyText.textContent = `灵气:${gameState.spiritualEnergy}`;
spiritualStonesText.textContent = `灵石:${gameState.spiritualStones}`;
realmText.textContent = gameState.realm;
// 更新灵根信息
rootTypeDisplay.textContent = gameState.spiritualRoot.type;
rootQualityDisplay.textContent = gameState.spiritualRoot.quality;
// 更新修炼速度和灵气采集速度显示
const effectiveCultivationSpeed = gameState.cultivationSpeed * (1 + gameState.spiritualRoot.bonus / 100);
const effectiveEnergyGatheringSpeed = gameState.energyGatheringSpeed * (1 + gameState.spiritualRoot.bonus / 100);
cultivationSpeedDisplay.textContent = `${effectiveCultivationSpeed.toFixed(2)}x`;
energyGatheringSpeedDisplay.textContent = `${effectiveEnergyGatheringSpeed.toFixed(2)}x`;
// 更新突破按钮状态
if (gameState.cultivation >= gameState.maxCultivation) {
breakthroughBtn.disabled = false;
breakthroughBtn.textContent = `突破到下一层`;
} else {
breakthroughBtn.disabled = true;
breakthroughBtn.textContent = `需要:${gameState.maxCultivation} 修为`;
}
// 更新修炼信息面板
updateCultivationInfo();
// 更新任务UI
updateQuestUI();
// 更新成就UI
updateAchievementUI();
// 更新自动修炼按钮状态
if (gameState.autoCultivation) {
autoCultivationBtn.textContent = '停止自动修炼';
autoCultivationBtn.classList.add('active');
} else {
autoCultivationBtn.textContent = '自动修炼';
autoCultivationBtn.classList.remove('active');
}
}
// 更新修炼信息面板
function updateCultivationInfo() {
const cultivationInfoContainer = document.getElementById('cultivationInfo');
if (cultivationInfoContainer) {
cultivationInfoContainer.innerHTML = `
<div class="info-item">
<span class="info-label">当前境界:</span>
<span class="info-value">${gameState.realm}</span>
</div>
<div class="info-item">
<span class="info-label">灵根属性:</span>
<span class="info-value">${gameState.spiritualRoot.type} (${gameState.spiritualRoot.quality})</span>
</div>
<div class="info-item">
<span class="info-label">修炼速度:</span>
<span class="info-value">${(gameState.cultivationSpeed * (1 + gameState.spiritualRoot.bonus / 100)).toFixed(2)}x</span>
</div>
<div class="info-item">
<span class="info-label">灵气采集速度:</span>
<span class="info-value">${(gameState.energyGatheringSpeed * (1 + gameState.spiritualRoot.bonus / 100)).toFixed(2)}x</span>
</div>
<div class="info-item">
<span class="info-label">突破加成:</span>
<span class="info-value">${gameState.breakthroughBonus || 0}%</span>
</div>
`;
}
}
// 创建引导UI
function createTutorialUI() {
// 引导UI已经在HTML中创建
// 这里只需要初始化变量
tutorialElement = document.getElementById('tutorialOverlay');
const tutorialText = document.getElementById('tutorialMessage');
tutorialText.style.fontSize = '1.1rem';
// 使用HTML中已有的按钮
const nextBtn = document.getElementById('nextTutorialBtn');
const skipBtn = document.getElementById('skipTutorialBtn');
nextBtn.addEventListener('click', () => {
gameState.tutorialStep++;
if (gameState.tutorialStep < gameState.tutorialSteps.length) {
showTutorialStep();
} else {
tutorialElement.style.display = 'none';
addEvent('新手引导已完成!你现在可以自由探索修仙世界了。');
}
saveGame();
});
skipBtn.addEventListener('click', () => {
tutorialElement.style.display = 'none';
addEvent('你跳过了新手引导。');
saveGame();
});
}
// 显示引导步骤
function showTutorialStep() {
const step = gameState.tutorialSteps[gameState.tutorialStep];
const tutorialText = document.getElementById('tutorialMessage');
tutorialText.textContent = step;
tutorialElement.style.display = 'block';
// 高亮当前引导步骤对应的元素
highlightTutorialElement();
}
// 高亮当前引导步骤对应的元素
function highlightTutorialElement() {
const step = gameState.tutorialStep;
// 先移除所有高亮
const highlightedElements = document.querySelectorAll('.tutorial-highlight');
highlightedElements.forEach(el => el.classList.remove('tutorial-highlight'));
// 根据步骤添加高亮
switch(step) {
case 0:
cultivationCircle.classList.add('tutorial-highlight');
break;
case 1:
breakthroughBtn.classList.add('tutorial-highlight');
break;
case 2:
gatherBtn.classList.add('tutorial-highlight');
break;
case 3:
document.querySelector('.shop').classList.add('tutorial-highlight');
break;
case 4:
document.querySelector('.system-panels').classList.add('tutorial-highlight');
break;
case 5:
if (inventoryContainer) {
inventoryContainer.classList.add('tutorial-highlight');
}
break;
}
}
// 创建任务UI
function createQuestUI() {
const gameMain = document.querySelector('.game-main');
questElement = document.createElement('div');
questElement.classList.add('quests');
questElement.style.gridColumn = '1 / -1';
const questTitle = document.createElement('h3');
questTitle.textContent = '修仙任务';
questTitle.style.color = '#f9d423';
questTitle.style.marginBottom = '15px';
questElement.appendChild(questTitle);
gameMain.appendChild(questElement);
}
// 更新任务UI
function updateQuestUI() {
// 清除现有任务
while (questElement.children.length > 1) {
questElement.removeChild(questElement.lastChild);
}
// 添加任务
gameState.quests.forEach(quest => {
const questItem = document.createElement('div');
questItem.classList.add('quest-item');
questItem.style.background = 'rgba(255, 255, 255, 0.05)';
questItem.style.padding = '10px 15px';
questItem.style.borderRadius = '8px';
questItem.style.marginBottom = '10px';
if (quest.completed) {
questItem.style.opacity = '0.6';
questItem.style.textDecoration = 'line-through';
}
const questName = document.createElement('h4');
questName.textContent = quest.name;
questName.style.color = '#ffffff';
questName.style.marginBottom = '5px';
const questDescription = document.createElement('p');
questDescription.textContent = quest.description;
questDescription.style.color = '#cccccc';
questDescription.style.fontSize = '0.9rem';
questDescription.style.marginBottom = '5px';
const questProgress = document.createElement('div');
questProgress.classList.add('quest-progress');
questProgress.style.width = '100%';
questProgress.style.height = '5px';
questProgress.style.background = 'rgba(255, 255, 255, 0.1)';
questProgress.style.borderRadius = '3px';
const progressFill = document.createElement('div');
progressFill.classList.add('progress-fill');
progressFill.style.height = '100%';
progressFill.style.background = '#4CAF50';
progressFill.style.borderRadius = '3px';
progressFill.style.width = `${Math.min(100, (quest.progress / quest.target) * 100)}%`;
questProgress.appendChild(progressFill);
const questReward = document.createElement('p');
questReward.textContent = `奖励:`;
questReward.style.color = '#4CAF50';
questReward.style.fontSize = '0.85rem';
// 添加奖励详情
if (quest.reward.qi) {
questReward.textContent += `灵气 ${quest.reward.qi} `;
}
if (quest.reward.cultivation) {
questReward.textContent += `修为 ${quest.reward.cultivation} `;
}
if (quest.reward.spiritStone) {
questReward.textContent += `灵石 ${quest.reward.spiritStone} `;
}
if (quest.reward.artifact) {
questReward.textContent += `法宝 ${quest.reward.artifact} `;
}
questItem.appendChild(questName);
questItem.appendChild(questDescription);
questItem.appendChild(questProgress);
questItem.appendChild(questReward);
questElement.appendChild(questItem);
});
}
// 创建成就UI
function createAchievementUI() {
const gameMain = document.querySelector('.game-main');
achievementElement = document.createElement('div');
achievementElement.classList.add('achievements');
achievementElement.style.gridColumn = '1 / -1';
const achievementTitle = document.createElement('h3');
achievementTitle.textContent = '修仙成就';
achievementTitle.style.color = '#f9d423';
achievementTitle.style.marginBottom = '15px';
achievementElement.appendChild(achievementTitle);
gameMain.appendChild(achievementElement);
}
// 更新成就UI
function updateAchievementUI() {
// 清除现有成就
while (achievementElement.children.length > 1) {
achievementElement.removeChild(achievementElement.lastChild);
}
// 添加成就
gameState.achievements.forEach(achievement => {
const achievementItem = document.createElement('div');
achievementItem.classList.add('achievement-item');
achievementItem.style.background = 'rgba(255, 255, 255, 0.05)';
achievementItem.style.padding = '10px 15px';
achievementItem.style.borderRadius = '8px';
achievementItem.style.marginBottom = '10px';
if (achievement.completed) {
achievementItem.style.backgroundColor = 'rgba(76, 175, 80, 0.2)';
}
const achievementName = document.createElement('h4');
achievementName.textContent = achievement.name;
achievementName.style.color = achievement.completed ? '#4CAF50' : '#ffffff';
achievementName.style.marginBottom = '5px';
const achievementDescription = document.createElement('p');
achievementDescription.textContent = achievement.description;
achievementDescription.style.color = '#cccccc';
achievementDescription.style.fontSize = '0.9rem';
achievementDescription.style.marginBottom = '5px';
let achievementProgress;
if (achievement.progress !== undefined) {
achievementProgress = document.createElement('div');
achievementProgress.classList.add('achievement-progress');
achievementProgress.style.width = '100%';
achievementProgress.style.height = '5px';
achievementProgress.style.background = 'rgba(255, 255, 255, 0.1)';
achievementProgress.style.borderRadius = '3px';
const progressFill = document.createElement('div');
progressFill.classList.add('progress-fill');
progressFill.style.height = '100%';
progressFill.style.background = achievement.completed ? '#4CAF50' : '#2196F3';
progressFill.style.borderRadius = '3px';
progressFill.style.width = `${Math.min(100, (achievement.progress / achievement.target) * 100)}%`;
achievementProgress.appendChild(progressFill);
}
const achievementReward = document.createElement('p');
achievementReward.textContent = `奖励:`;
achievementReward.style.color = '#ffeb3b';
achievementReward.style.fontSize = '0.85rem';
// 添加奖励详情
if (achievement.reward.qi) {
achievementReward.textContent += `灵气 ${achievement.reward.qi} `;
}
if (achievement.reward.cultivation) {
achievementReward.textContent += `修为 ${achievement.reward.cultivation} `;
}
if (achievement.reward.spiritStone) {
achievementReward.textContent += `灵石 ${achievement.reward.spiritStone} `;
}
if (achievement.reward.artifact) {
achievementReward.textContent += `法宝 ${achievement.reward.artifact} `;
}
achievementItem.appendChild(achievementName);
achievementItem.appendChild(achievementDescription);
if (achievementProgress) {
achievementItem.appendChild(achievementProgress);
}
achievementItem.appendChild(achievementReward);
achievementElement.appendChild(achievementItem);
});
}
// 添加新的商店物品
function addNewShopItems() {
const shopItemsContainer = document.querySelector('.shop-items');
// 添加突破符
const breakthroughCharmItem = document.createElement('div');
breakthroughCharmItem.classList.add('shop-item');
breakthroughCharmItem.setAttribute('data-cost', '50');
breakthroughCharmItem.setAttribute('data-type', 'breakthroughCharm');
breakthroughCharmItem.innerHTML = `
<span>突破符 (50灵石)</span>
<button class="buy-btn">购买</button>
`;
// 添加天灵丹
const spiritPillItem = document.createElement('div');
spiritPillItem.classList.add('shop-item');
spiritPillItem.setAttribute('data-cost', '100');
spiritPillItem.setAttribute('data-type', 'spiritPill');
spiritPillItem.innerHTML = `
<span>天灵丹 (100灵石)</span>
<button class="buy-btn">购买</button>
`;
// 添加法宝
const artifactItem = document.createElement('div');
artifactItem.classList.add('shop-item');
artifactItem.setAttribute('data-cost', '200');
artifactItem.setAttribute('data-type', 'artifact');
artifactItem.innerHTML = `
<span>低级法宝 (200灵石)</span>
<button class="buy-btn">购买</button>
`;
// 添加灵根提升丹
const spiritRootItem = document.createElement('div');
spiritRootItem.classList.add('shop-item');
spiritRootItem.setAttribute('data-cost', '500');
spiritRootItem.setAttribute('data-type', 'spiritRoot');
spiritRootItem.innerHTML = `
<span>灵根提升丹 (500灵石)</span>
<button class="buy-btn">购买</button>
`;
shopItemsContainer.appendChild(breakthroughCharmItem);
shopItemsContainer.appendChild(spiritPillItem);
shopItemsContainer.appendChild(artifactItem);
shopItemsContainer.appendChild(spiritRootItem);
// 重新绑定购买事件
const newShopItems = document.querySelectorAll('.shop-item');
newShopItems.forEach(item => {
const buyBtn = item.querySelector('.buy-btn');
buyBtn.addEventListener('click', () => {
const cost = parseInt(item.dataset.cost);
const type = item.dataset.type;
if (gameState.spiritStone >= cost) {
gameState.spiritStone -= cost;
if (type === 'spiritRoot') {
upgradeSpiritRoot();
} else if (typeof gameState.itemEffects[type] === 'function') {
gameState.itemEffects[type]();
} else {
if (type === 'qi') {
gameState.qi += gameState.itemEffects[type];
addEvent(`你使用了小灵气丹,获得了${gameState.itemEffects[type]}点灵气。`);
} else if (type === 'cultivation') {
gameState.cultivation += gameState.itemEffects[type];
addEvent(`你使用了培元丹,获得了${gameState.itemEffects[type]}点修为。`);
}
}
// 更新任务进度
checkQuestProgress('shop');
updateUI();
saveGame();
}
});
});
}
// 提升灵根
function upgradeSpiritRoot() {
const currentIndex = gameState.spiritRootTypes.indexOf(gameState.spiritRoot);
if (currentIndex < gameState.spiritRootTypes.length - 1) {
const oldRoot = gameState.spiritRoot;
const oldMultiplier = gameState.spiritRootMultiplier[oldRoot];
gameState.spiritRoot = gameState.spiritRootTypes[currentIndex + 1];
const newMultiplier = gameState.spiritRootMultiplier[gameState.spiritRoot];
// 调整修炼速度和灵气采集速度
gameState.cultivationSpeed = gameState.cultivationSpeed / oldMultiplier * newMultiplier;
gameState.qiGatherSpeed = gameState.qiGatherSpeed / oldMultiplier * newMultiplier;
addEvent(`你的灵根从${oldRoot}提升到了${gameState.spiritRoot}!修炼速度大幅提升!`);
} else {
addEvent('你的灵根已经是最高级了!');
gameState.spiritStone += 500; // 退还灵石
}
}
// 检查任务进度
function checkQuestProgress(action) {
gameState.quests.forEach(quest => {
if (quest.completed) return;
switch (action) {
case 'click':
if (quest.id === 'quest_1') {
quest.progress++;
}
break;
case 'gather':
if (quest.id === 'quest_2') {
quest.progress++;
}
break;
case 'breakthrough':
if (quest.id === 'quest_3' && gameState.realm === '练气') {
quest.progress = 1;
}
break;
case 'shop':
if (quest.id === 'quest_4') {
quest.progress = 1;
}
break;
}
// 检查修为相关任务
if (quest.id === 'quest_5' && gameState.cultivation >= 100) {
quest.progress = 100;
}
// 检查是否完成
if (quest.progress >= quest.target) {
completeQuest(quest);
}
});
}
// 完成任务
function completeQuest(quest) {
if (!quest.completed) {
quest.completed = true;
// 发放奖励
if (quest.reward.qi) {
gameState.qi += quest.reward.qi;
}
if (quest.reward.cultivation) {
gameState.cultivation += quest.reward.cultivation;
}
if (quest.reward.spiritStone) {
gameState.spiritStone += quest.reward.spiritStone;
}
if (quest.reward.artifact) {
gameState.artifactCount += quest.reward.artifact;
gameState.cultivationSpeed *= Math.pow(1.1, quest.reward.artifact);
gameState.qiGatherSpeed *= Math.pow(1.1, quest.reward.artifact);
}
addEvent(`任务完成:${quest.name}!获得了丰厚的奖励!`);
updateUI();
saveGame();
}
}
// 检查成就进度
function checkAchievementProgress(action) {
gameState.achievements.forEach(achievement => {
if (achievement.completed) return;
switch (action) {
case 'first_click':
if (achievement.id === 'first_click') {
achievement.completed = true;
grantAchievementReward(achievement);
}
break;
case 'meditation':
if (achievement.id === 'meditation_master') {
achievement.progress++;
if (achievement.progress >= achievement.target) {
achievement.completed = true;
grantAchievementReward(achievement);
}
}
break;
case 'gather':
if (achievement.id === 'qi_gatherer') {
achievement.progress++;
if (achievement.progress >= achievement.target) {
achievement.completed = true;
grantAchievementReward(achievement);
}
}
break;
case 'breakthrough':
if (achievement.id === 'first_breakthrough' && gameState.realm === '练气') {
achievement.completed = true;
grantAchievementReward(achievement);
}
if (achievement.id === 'realm_master' && gameState.realm === '金丹') {
achievement.completed = true;
grantAchievementReward(achievement);
}
break;
}
// 检查灵石相关成就
if (achievement.id === 'stone_collector' && gameState.spiritStone >= 100) {
achievement.completed = true;
grantAchievementReward(achievement);
}
});
}
// 发放成就奖励
function grantAchievementReward(achievement) {
if (achievement.completed) {
// 发放奖励
if (achievement.reward.energy) {
gameState.spiritualEnergy += achievement.reward.energy;
}
if (achievement.reward.cultivation) {
gameState.cultivation += achievement.reward.cultivation;
}
if (achievement.reward.stones) {
gameState.spiritualStones += achievement.reward.stones;
}
if (achievement.reward.item) {
addItemToInventory(achievement.reward.item);
}
// 成就点数系统
gameState.achievementPoints += 1;
addEvent(`成就达成:${achievement.name}!获得了特殊奖励!`);
updateUI();
saveGame();
}
}
// 添加物品到背包
function addItemToInventory(itemId) {
const item = gameState.inventory.find(i => i.id === itemId);
if (item) {
item.count += 1;
addEvent(`获得了1个${item.name}!`);
// 更新背包UI
updateInventoryUI();
// 检查成就进度
if (itemId === "breakthrough_talisman") {
const quest = gameState.quests.find(q => q.id === "side_1");
if (quest && !quest.completed) {
quest.progress = Math.min(quest.target, item.count);
if (quest.progress >= quest.target) {
completeQuest(quest);
}
}
}
// 检查寻宝专家成就
const treasureHunter = gameState.achievements.find(a => a.id === "treasure_hunter");
if (treasureHunter && !treasureHunter.completed) {
const uniqueItems = gameState.inventory.filter(i => i.count > 0).length;
if (uniqueItems >= treasureHunter.target) {
treasureHunter.completed = true;
grantAchievementReward(treasureHunter);
}
}
}
}
// 使用背包物品
function useInventoryItem(itemId) {
const item = gameState.inventory.find(i => i.id === itemId);
if (item && item.count > 0) {
item.count -= 1;
// 应用物品效果
switch (itemId) {
case "breakthrough_talisman":
gameState.breakthroughBonus = 20;
addEvent("使用了突破符,突破成功率提升20%!");
break;
case "heavenly_pill":
gameState.cultivation += 100;
addEvent("服用了天灵丹,获得了100点修为!");
break;
case "magic_artifact":
gameState.cultivationSpeed *= 1.1;
gameState.energyGatheringSpeed *= 1.1;
addEvent("装备了法宝,修炼速度和灵气采集速度提升10%!");
gameState.equippedArtifacts += 1;
break;
case "root_improvement_pill":
upgradeSpiritRoot();
addEvent("服用了灵根提升丹!");
break;
case "energy_crystal":
gameState.spiritualEnergy += 500;
addEvent("使用了能量水晶,获得了500点灵气!");
break;
}
updateInventoryUI();
updateUI();
saveGame();
}
}
// 创建背包UI
function createInventoryUI() {
const inventoryTitle = document.createElement('h3');
inventoryTitle.textContent = '背包物品';
inventoryTitle.style.color = '#f9d423';
inventoryTitle.style.marginBottom = '15px';
inventoryContainer.appendChild(inventoryTitle);
updateInventoryUI();
}
// 更新背包UI
function updateInventoryUI() {
// 清除现有物品
while (inventoryContainer.children.length > 1) {
inventoryContainer.removeChild(inventoryContainer.lastChild);
}
// 添加物品
gameState.inventory.forEach(item => {
if (item.count > 0) {
const inventoryItem = document.createElement('div');
inventoryItem.classList.add('inventory-item');
inventoryItem.style.background = 'rgba(255, 255, 255, 0.05)';
inventoryItem.style.padding = '10px 15px';
inventoryItem.style.borderRadius = '8px';
inventoryItem.style.marginBottom = '10px';
inventoryItem.style.cursor = 'pointer';
inventoryItem.style.transition = 'all 0.3s ease';
inventoryItem.addEventListener('mouseenter', () => {
inventoryItem.style.backgroundColor = 'rgba(255, 255, 255, 0.1)';
});
inventoryItem.addEventListener('mouseleave', () => {
inventoryItem.style.backgroundColor = 'rgba(255, 255, 255, 0.05)';
});
inventoryItem.addEventListener('click', () => {
useInventoryItem(item.id);
});
const itemName = document.createElement('h4');
itemName.textContent = `${item.name} (${item.count})`;
itemName.style.color = '#ffffff';
itemName.style.marginBottom = '5px';
const itemDescription = document.createElement('p');
itemDescription.textContent = item.description;
itemDescription.style.color = '#cccccc';
itemDescription.style.fontSize = '0.9rem';
itemDescription.style.marginBottom = '5px';
inventoryItem.appendChild(itemName);
inventoryItem.appendChild(itemDescription);
inventoryContainer.appendChild(inventoryItem);
}
});
// 如果背包为空,显示提示
if (inventoryContainer.children.length === 1) {
const emptyMessage = document.createElement('p');
emptyMessage.textContent = '背包为空';
emptyMessage.style.color = '#666';
emptyMessage.style.textAlign = 'center';
emptyMessage.style.padding = '20px';
inventoryContainer.appendChild(emptyMessage);
}
}
// 提升灵根
function upgradeSpiritRoot() {
const rootTypes = ['凡根', '灵根', '地灵根', '天灵根', '混沌灵根'];
const rootQualities = ['普通', '优秀', '卓越', '完美'];
if (gameState.spiritualRoot.quality === '完美' && gameState.spiritualRoot.level < rootTypes.length) {
gameState.spiritualRoot.type = rootTypes[gameState.spiritualRoot.level];
gameState.spiritualRoot.quality = '普通';
gameState.spiritualRoot.level += 1;
gameState.spiritualRoot.bonus = gameState.spiritualRoot.level * 10;
addEvent(`你的灵根进化为${gameState.spiritualRoot.type}!修炼效率大幅提升!`);
} else if (gameState.spiritualRoot.quality !== '完美') {
const currentQualityIndex = rootQualities.indexOf(gameState.spiritualRoot.quality);
if (currentQualityIndex < rootQualities.length - 1) {
gameState.spiritualRoot.quality = rootQualities[currentQualityIndex + 1];
gameState.spiritualRoot.bonus += 5;
addEvent(`你的灵根品质提升为${gameState.spiritualRoot.quality}!修炼效率提升!`);
}
}
// 更新修炼速度
gameState.cultivationSpeed = 1 + (gameState.spiritualRoot.bonus / 100);
gameState.energyGatheringSpeed = 1 + (gameState.spiritualRoot.bonus / 100);
// 检查成就
const rootMasterAchievement = gameState.achievements.find(a => a.id === 'spiritual_master');
if (rootMasterAchievement && !rootMasterAchievement.completed) {
rootMasterAchievement.completed = true;
grantAchievementReward(rootMasterAchievement);
}
// 检查任务
const rootQuest = gameState.quests.find(q => q.id === 'main_4');
if (rootQuest && !rootQuest.completed) {
rootQuest.progress = 1;
completeQuest(rootQuest);
}
}
// 触发特殊事件
function triggerSpecialEvent() {
if (!gameState.specialEvents.active) {
const events = [
{ type: 'treasure', message: '你发现了一个神秘宝箱!', duration: 30 },
{ type: 'attack', message: '一只妖兽正在接近!准备战斗!', duration: 20 },
{ type: 'spirit_spring', message: '你发现了一处灵泉!', duration: 40 },
{ type: 'mysterious_merchant', message: '神秘商人出现了!限时出售珍稀物品!', duration: 25 }
];
const randomEvent = events[Math.floor(Math.random() * events.length)];
gameState.specialEvents.active = true;
gameState.specialEvents.eventType = randomEvent.type;
gameState.specialEvents.countdown = randomEvent.duration;
gameState.specialEvents.message = randomEvent.message;
addEvent(`【特殊事件】${randomEvent.message}`);
// 更新特殊事件UI
updateSpecialEventUI();
// 根据事件类型应用临时效果
if (randomEvent.type === 'spirit_spring') {
gameState.energyGatheringSpeed *= 2;
}
}
}
// 更新特殊事件UI
function updateSpecialEventUI() {
const specialEventContainer = document.getElementById('specialEventContainer');
if (!specialEventContainer) {
return;
}
if (gameState.specialEvents.active) {
specialEventContainer.style.display = 'block';
specialEventContainer.innerHTML = `
<div class="special-event-header">
<h4>【特殊事件】${gameState.specialEvents.message}</h4>
<span class="event-countdown">剩余 ${gameState.specialEvents.countdown} 秒</span>
</div>
`;
// 根据事件类型添加不同的操作按钮
if (gameState.specialEvents.eventType === 'treasure') {
const openButton = document.createElement('button');
openButton.textContent = '打开宝箱 (消耗20灵石)';
openButton.classList.add('special-event-btn');
openButton.addEventListener('click', () => {
if (gameState.spiritualStones >= 20) {
gameState.spiritualStones -= 20;
const rewards = [
{ type: 'stones', amount: Math.floor(Math.random() * 50) + 20 },
{ type: 'energy', amount: Math.floor(Math.random() * 300) + 100 },
{ type: 'cultivation', amount: Math.floor(Math.random() * 200) + 50 },
{ type: 'item', id: ['breakthrough_talisman', 'heavenly_pill', 'energy_crystal'][Math.floor(Math.random() * 3)] }
];
const reward = rewards[Math.floor(Math.random() * rewards.length)];
if (reward.type === 'item') {
addItemToInventory(reward.id);
} else {
gameState[reward.type === 'stones' ? 'spiritualStones' : reward.type === 'energy' ? 'spiritualEnergy' : 'cultivation'] += reward.amount;
addEvent(`打开宝箱获得了${reward.amount}${reward.type === 'stones' ? '颗灵石' : reward.type === 'energy' ? '点灵气' : '点修为'}!`);
}
gameState.specialEvents.active = false;
updateSpecialEventUI();
updateUI();
saveGame();
}
});
specialEventContainer.appendChild(openButton);
} else if (gameState.specialEvents.eventType === 'attack') {
const fightButton = document.createElement('button');
fightButton.textContent = '战斗';
fightButton.classList.add('special-event-btn');
fightButton.addEventListener('click', () => {
const successChance = 0.7 + (gameState.spiritualRoot.bonus / 100);
const isSuccess = Math.random() < successChance;
if (isSuccess) {
const reward = Math.floor(Math.random() * 100) + 50;
gameState.spiritualStones += reward;
addEvent(`成功击败妖兽,获得了${reward}颗灵石!`);
} else {
const loss = Math.floor(Math.random() * 50) + 20;
gameState.spiritualStones = Math.max(0, gameState.spiritualStones - loss);
addEvent(`战斗失败,损失了${loss}颗灵石!`);
}
gameState.specialEvents.active = false;
updateSpecialEventUI();
updateUI();
saveGame();
});
specialEventContainer.appendChild(fightButton);
} else if (gameState.specialEvents.eventType === 'mysterious_merchant') {
const merchantContainer = document.createElement('div');
merchantContainer.classList.add('merchant-items');
const specialItems = [
{ id: 'legendary_talisman', name: '传说突破符', cost: 100, description: '必定突破成功' },
{ id: 'immortal_pill', name: '仙人丹', cost: 150, description: '立即获得500点修为' },
{ id: 'ultimate_artifact', name: '终极法宝', cost: 300, description: '修炼速度提升50%' }
];
specialItems.forEach(item => {
const merchantItem = document.createElement('div');
merchantItem.classList.add('merchant-item');
merchantItem.innerHTML = `
<span>${item.name} (${item.cost}灵石) - ${item.description}</span>
<button class="buy-merchant-btn" data-id="${item.id}" data-cost="${item.cost}">购买</button>
`;
merchantContainer.appendChild(merchantItem);
});
specialEventContainer.appendChild(merchantContainer);
// 绑定购买事件
document.querySelectorAll('.buy-merchant-btn').forEach(btn => {
btn.addEventListener('click', function() {
const itemId = this.dataset.id;
const cost = parseInt(this.dataset.cost);
if (gameState.spiritualStones >= cost) {
gameState.spiritualStones -= cost;
switch (itemId) {
case 'legendary_talisman':
addItemToInventory('breakthrough_talisman');
addEvent('购买了传说突破符!');
break;
case 'immortal_pill':
gameState.cultivation += 500;
addEvent('购买并服用了仙人丹,获得了500点修为!');
break;
case 'ultimate_artifact':
gameState.cultivationSpeed *= 1.5;
addEvent('购买了终极法宝,修炼速度提升50%!');
gameState.equippedArtifacts += 1;
break;
}
updateUI();
saveGame();
}
});
});
}
} else {
specialEventContainer.style.display = 'none';
}
}
// 重置游戏
function resetGame() {
if (confirm('确定要重置游戏吗?所有进度将会丢失!')) {
// 清空本地存储
localStorage.removeItem('cultivationGameSave');
// 重新加载页面
location.reload();
}
}
// 切换全屏模式
function toggleFullscreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen().catch(err => {
addEvent(`全屏模式切换失败: ${err.message}`);
});
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
}
}
}
// 修复设置事件监听器函数
function setupEventListeners() {
// 点击修炼
cultivationCircle.addEventListener('click', () => {
if (gameState.spiritualEnergy >= 1) {
gameState.spiritualEnergy -= 1;
const cultivationGain = Math.floor(gameState.cultivationSpeed * (1 + gameState.spiritualRoot.bonus / 100));
gameState.cultivation += cultivationGain;
// 添加修炼动画
cultivationCore.classList.add('pulse');
setTimeout(() => {
cultivationCore.classList.remove('pulse');
}, 500);
addEvent(`获得了${cultivationGain}点修为!`);
// 检查成就进度
const firstCultivation = gameState.achievements.find(a => a.id === 'first_cultivation');
if (firstCultivation && !firstCultivation.completed) {
firstCultivation.completed = true;
grantAchievementReward(firstCultivation);
}
// 检查任务进度
const mainQuest1 = gameState.quests.find(q => q.id === 'main_1');
if (mainQuest1 && !mainQuest1.completed) {
mainQuest1.progress = 1;
completeQuest(mainQuest1);
}
// 检查聚气成海成就
const energyMaster = gameState.achievements.find(a => a.id === 'energy_master');
if (energyMaster && !energyMaster.completed && gameState.cultivation >= energyMaster.target) {
energyMaster.completed = true;
grantAchievementReward(energyMaster);
}
// 有几率触发特殊事件
if (Math.random() < 0.05) {
triggerSpecialEvent();
}
updateUI();
saveGame();
}
});
// 采集灵气按钮
gatherBtn.addEventListener('click', () => {
const energyGain = Math.floor(gameState.energyGatheringSpeed * (1 + gameState.spiritualRoot.bonus / 100));
gameState.spiritualEnergy += energyGain;
addEvent(`采集到了${energyGain}点灵气!`);
// 检查成就进度
const gatherAchievement = gameState.achievements.find(a => a.id === 'gather_energy');
if (gatherAchievement && !gatherAchievement.completed) {
gatherAchievement.progress += 1;
if (gatherAchievement.progress >= gatherAchievement.target) {
gatherAchievement.completed = true;
grantAchievementReward(gatherAchievement);
}
}
// 检查任务进度
const mainQuest2 = gameState.quests.find(q => q.id === 'main_2');
if (mainQuest2 && !mainQuest2.completed) {
mainQuest2.progress += 1;
if (mainQuest2.progress >= mainQuest2.target) {
completeQuest(mainQuest2);
}
}
// 更新UI
updateUI();
saveGame();
});
// 突破境界按钮
breakthroughBtn.addEventListener('click', breakthroughRealm);
// 自动修炼按钮
autoCultivationBtn.addEventListener('click', toggleAutoCultivation);
// 重置游戏按钮
resetGameBtn.addEventListener('click', resetGame);
// 全屏按钮
fullscreenBtn.addEventListener('click', toggleFullscreen);
// 商店购买按钮
document.querySelectorAll('.shop-item').forEach(item => {
const buyBtn = item.querySelector('.buy-btn');
if (buyBtn) {
buyBtn.addEventListener('click', function() {
const itemId = this.dataset.id || item.dataset.type;
const shopItem = gameState.shopItems.find(i => i.id === itemId);
if (shopItem && gameState.spiritualStones >= shopItem.cost) {
gameState.spiritualStones -= shopItem.cost;
addItemToInventory(itemId);
// 检查成就进度
const buyAchievement = gameState.achievements.find(a => a.id === 'buy_item');
if (buyAchievement && !buyAchievement.completed) {
buyAchievement.completed = true;
grantAchievementReward(buyAchievement);
}
// 检查任务进度
const mainQuest5 = gameState.quests.find(q => q.id === 'main_5');
if (mainQuest5 && !mainQuest5.completed) {
mainQuest5.progress = 1;
completeQuest(mainQuest5);
}
updateUI();
saveGame();
}
});
}
});
// 引导按钮事件
nextTutorialBtn.addEventListener('click', () => {
if (gameState.tutorialStep < gameState.tutorialSteps.length - 1) {
gameState.tutorialStep += 1;
showTutorialStep();
} else {
// 隐藏引导
tutorialOverlay.style.display = 'none';
localStorage.setItem('tutorialCompleted', 'true');
// 发放完成引导奖励
gameState.spiritualStones += 100;
gameState.spiritualEnergy += 200;
addEvent('完成新手引导,获得100灵石和200灵气奖励!');
updateUI();
saveGame();
}
});
// 跳过引导按钮事件
skipTutorialBtn.addEventListener('click', () => {
tutorialOverlay.style.display = 'none';
localStorage.setItem('tutorialCompleted', 'true');
});
// 空格键快速修炼
document.addEventListener('keydown', (e) => {
if (e.code === 'Space' && !tutorialOverlay.style.display) {
cultivationCircle.click();
}
});
// 突破境界按钮
breakthroughBtn.addEventListener('click', breakthroughRealm);
// 商店购买按钮
shopItems.forEach(item => {
const buyBtn = item.querySelector('.buy-btn');
buyBtn.addEventListener('click', () => {
const cost = parseInt(item.dataset.cost);
const type = item.dataset.type;
if (gameState.spiritualStones >= cost) {
gameState.spiritualStones -= cost;
if (typeof gameState.itemEffects[type] === 'function') {
gameState.itemEffects[type]();
} else {
if (type === 'qi') {
gameState.spiritualEnergy += gameState.itemEffects[type];
addEvent(`你使用了小灵气丹,获得了${gameState.itemEffects[type]}点灵气。`);
} else if (type === 'cultivation') {
gameState.cultivation += gameState.itemEffects[type];
addEvent(`你使用了培元丹,获得了${gameState.itemEffects[type]}点修为。`);
}
}
updateUI();
saveGame();
}
});
});
}
// 突破境界
function breakthroughRealm() {
if (gameState.cultivation >= gameState.maxCultivation) {
// 计算突破成功率
const baseChance = 0.7 - (gameState.realmLevel * 0.05); // 随着境界提升,基础成功率降低
const rootBonus = gameState.spiritualRoot.bonus / 100; // 灵根品质的加成
let breakthroughChance = Math.min(0.95, baseChance + rootBonus);
// 检查是否有突破符加成
if (gameState.breakthroughBonus > 0) {
breakthroughChance = Math.min(1, breakthroughChance + gameState.breakthroughBonus / 100);
addEvent(`突破符生效,成功率提升${gameState.breakthroughBonus}%!`);
gameState.breakthroughBonus = 0; // 消耗突破符
}
const isSuccess = Math.random() < breakthroughChance;
if (isSuccess) {
// 成功突破
gameState.realmLevel += 1;
gameState.realm = gameState.realmOrder[gameState.realmLevel];
// 提升修炼和灵气采集速度
gameState.cultivationSpeed *= 1.5;
gameState.energyGatheringSpeed *= 1.2;
// 重置修为和提升最大修为
gameState.cultivation = 0;
gameState.maxCultivation = Math.floor(gameState.maxCultivation * 1.5);
// 突破奖励
gameState.spiritualStones += Math.floor(Math.random() * 50) + 50;
// 添加突破动画效果
cultivationCircle.classList.add('breakthrough-animation');
setTimeout(() => {
cultivationCircle.classList.remove('breakthrough-animation');
}, 2000);
// 检查成就
const breakthroughAchievement = gameState.achievements.find(a => a.id === 'realm_master');
if (breakthroughAchievement && !breakthroughAchievement.completed) {
breakthroughAchievement.progress = Math.min(breakthroughAchievement.target, gameState.realmLevel);
if (breakthroughAchievement.progress >= breakthroughAchievement.target) {
breakthroughAchievement.completed = true;
grantAchievementReward(breakthroughAchievement);
}
}
// 特殊境界提示
if (gameState.realm === "合体期") {
addEvent("你进入了合体期,已经是一方大能!");
} else if (gameState.realm === "渡劫期") {
addEvent("你进入了渡劫期,即将面临九重雷劫!");
} else if (gameState.realm === "大乘期") {
addEvent("恭喜!你成功渡过雷劫,达到大乘期!距离成仙只有一步之遥!");
} else {
addEvent(`恭喜!你成功突破到${gameState.realm}!`);
}
} else {
// 突破失败
const cultivationLost = Math.floor(gameState.cultivation * 0.1);
const energyLost = Math.floor(gameState.spiritualEnergy * 0.1);
gameState.cultivation -= cultivationLost;
gameState.spiritualEnergy = Math.max(0, gameState.spiritualEnergy - energyLost);
addEvent(`突破失败!损失了${cultivationLost}点修为和${energyLost}点灵气。`);
}
updateUI();
saveGame();
}
}
// 游戏循环(自动获得资源)
function gameLoop() {
const currentTime = Date.now();
const deltaTime = (currentTime - gameState.lastUpdateTime) / 1000; // 转换为秒
gameState.lastUpdateTime = currentTime;
// 自动获得灵气
const effectiveEnergyGatheringSpeed = gameState.energyGatheringSpeed * (1 + gameState.spiritualRoot.bonus / 100);
const autoEnergyGain = effectiveEnergyGatheringSpeed * deltaTime;
gameState.spiritualEnergy += autoEnergyGain;
// 自动获得修为(如果开启了自动修炼)
if (gameState.autoCultivation && gameState.spiritualEnergy >= 0.1) {
const effectiveCultivationSpeed = gameState.cultivationSpeed * (1 + gameState.spiritualRoot.bonus / 100);
const autoCultivationGain = effectiveCultivationSpeed * deltaTime;
gameState.spiritualEnergy -= autoCultivationGain * 0.5; // 消耗灵气
gameState.cultivation += autoCultivationGain;
gameState.autoCultivationCount = (gameState.autoCultivationCount || 0) + 1;
// 每自动修炼100次检查成就
if (gameState.autoCultivationCount % 100 === 0) {
const autoCultivationAchievement = gameState.achievements.find(a => a.id === 'auto_cultivation_master');
if (autoCultivationAchievement && !autoCultivationAchievement.completed) {
autoCultivationAchievement.progress += 1;
if (autoCultivationAchievement.progress >= autoCultivationAchievement.target) {
autoCultivationAchievement.completed = true;
grantAchievementReward(autoCultivationAchievement);
}
}
}
}
// 自动获得灵石(根据境界和成就)
const stoneGainRate = (gameState.realmLevel * 0.5) + (gameState.equippedArtifacts * 0.2);
gameState.spiritualStones += stoneGainRate * deltaTime;
// 定期检查特殊事件
if (Math.random() < 0.001 * deltaTime) { // 大约每10分钟触发一次
triggerSpecialEvent();
}
// 特殊事件倒计时
if (gameState.specialEvents.active) {
gameState.specialEvents.countdown -= deltaTime;
if (gameState.specialEvents.countdown <= 0) {
// 结束特殊事件
if (gameState.specialEvents.eventType === 'spirit_spring') {
gameState.energyGatheringSpeed /= 2;
}
gameState.specialEvents.active = false;
updateSpecialEventUI();
addEvent('【特殊事件】已结束。');
}
}
// 确保数值为正数
gameState.spiritualEnergy = Math.max(0, gameState.spiritualEnergy);
gameState.spiritualStones = Math.max(0, gameState.spiritualStones);
updateUI();
// 每10秒自动保存一次
if (Math.random() < 0.1 * deltaTime) { // 大约每10秒触发一次
saveGame();
}
requestAnimationFrame(gameLoop);
}
// 保存游戏
function saveGame() {
localStorage.setItem('cultivationGameSave', JSON.stringify(gameState));
}
// 加载游戏
function loadGame() {
const savedGame = localStorage.getItem('cultivationGameSave');
if (savedGame) {
const parsedSave = JSON.parse(savedGame);
Object.assign(gameState, parsedSave);
// 确保所有系统数据都已初始化
if (!gameState.spiritualRoot) {
gameState.spiritualRoot = {
type: "凡根",
quality: "普通",
level: 1,
bonus: 0
};
}
if (!gameState.quests) {
gameState.quests = [
{ id: "main_1", name: "修仙之路", description: "完成一次修炼", progress: 0, target: 1, completed: false, reward: { cultivation: 50, stones: 50 } },
{ id: "main_2", name: "灵气积累", description: "采集5次灵气", progress: 0, target: 5, completed: false, reward: { cultivation: 100, stones: 80 } },
{ id: "main_3", name: "初入练气", description: "突破到练气一层", progress: 0, target: 1, completed: false, reward: { cultivation: 200, stones: 150, energy: 200 } },
{ id: "main_4", name: "提升灵根", description: "提升一次灵根品质", progress: 0, target: 1, completed: false, reward: { cultivation: 300, stones: 200 } },
{ id: "main_5", name: "商店购物", description: "在商店购买一个物品", progress: 0, target: 1, completed: false, reward: { cultivation: 150, stones: 100 } },
{ id: "side_1", name: "收集突破符", description: "收集3个突破符", progress: 0, target: 3, completed: false, reward: { cultivation: 250, stones: 150 } },
{ id: "side_2", name: "成就达人", description: "完成3个成就", progress: 0, target: 3, completed: false, reward: { cultivation: 500, stones: 300 } },
{ id: "side_3", name: "修仙之路", description: "达到100点修为", progress: 0, target: 100, completed: false, reward: { cultivation: 100, energy: 50 } }
];
}
if (!gameState.achievements) {
gameState.achievements = [
{id: "first_click", name: "初次修炼", description: "点击修炼第一次", completed: false, reward: {spiritStone: 5}},
{id: "first_breakthrough", name: "初次突破", description: "突破到练气期", completed: false, reward: {spiritStone: 20, qi: 50}},
{id: "meditation_master", name: "打坐大师", description: "打坐修炼100次", completed: false, progress: 0, target: 100, reward: {cultivation: 500}},
{id: "qi_gatherer", name: "灵气采集者", description: "采集灵气200次", completed: false, progress: 0, target: 200, reward: {qi: 200}},
{id: "stone_collector", name: "灵石收藏家", description: "拥有100颗灵石", completed: false, reward: {spiritStone: 50}},
{id: "realm_master", name: "境界大师", description: "突破到金丹期", completed: false, reward: {spiritStone: 100, artifact: 1}}
];
}
if (gameState.tutorialStep === undefined) {
gameState.tutorialStep = 0;
}
gameState.lastUpdateTime = Date.now(); // 更新时间戳
addEvent("游戏已加载!");
}
}
// 添加事件到日志函数
function addEvent(message) {
const eventElement = document.createElement('p');
eventElement.textContent = message;
// 根据事件类型设置颜色
if (message.includes('恭喜') || message.includes('获得') || message.includes('成功')) {
eventElement.style.color = '#4CAF50';
} else if (message.includes('失败') || message.includes('损失')) {
eventElement.style.color = '#F44336';
} else if (message.includes('【特殊事件】')) {
eventElement.style.color = '#ff9800';
eventElement.style.fontWeight = 'bold';
}
// 添加到日志开头
const eventLog = document.getElementById('eventLog');
if (eventLog) {
eventLog.insertBefore(eventElement, eventLog.firstChild);
// 限制日志数量
if (eventLog.children.length > 50) {
eventLog.removeChild(eventLog.lastChild);
}
// 滚动到顶部
eventLog.scrollTop = 0;
}
}
// 启动游戏
initGame();
index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>修仙模拟器</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="game-container">
<!-- 游戏顶部导航 -->
<header>
<div class="header-content">
<div class="logo-section">
<h1>修仙模拟器</h1>
<p>修炼成仙,逆天改命!</p>
</div>
<div class="header-actions">
<button id="resetGameBtn" class="nav-btn">重置游戏</button>
<button id="toggleFullscreenBtn" class="nav-btn">全屏</button>
</div>
</div>
</header>
<!-- 游戏状态 -->
<div class="game-stats">
<div class="stat">
<span class="stat-icon">✨</span>
<span class="stat-name">修为</span>
<span class="stat-value" id="cultivation">0</span>
</div>
<div class="stat">
<span class="stat-icon">💨</span>
<span class="stat-name">灵气</span>
<span class="stat-value" id="qi">10</span>
</div>
<div class="stat">
<span class="stat-icon">🏆</span>
<span class="stat-name">境界</span>
<span class="stat-value" id="realm">凡人</span>
</div>
<div class="stat">
<span class="stat-icon">💎</span>
<span class="stat-name">灵石</span>
<span class="stat-value" id="spiritStone">0</span>
</div>
<div class="stat">
<span class="stat-icon">🌱</span>
<span class="stat-name">灵根</span>
<span class="stat-value" id="spiritRootDisplay">普通</span>
</div>
</div>
<!-- 主要内容区域 -->
<div class="game-main">
<!-- 修炼区域 -->
<div class="left-panel">
<div class="cultivation-area">
<div class="cultivation-circle" id="cultivationCircle">
<div class="cultivation-core">
<span id="cultivationProgressText">点击开始修炼</span>
</div>
<div class="cultivation-glow"></div>
</div>
<!-- 修炼信息面板 -->
<div class="cultivation-info">
<div class="info-item">
<span>修炼速度:</span>
<span id="cultivationSpeed">1.0x</span>
</div>
<div class="info-item">
<span>灵气采集:</span>
<span id="qiGatherSpeed">1.0x</span>
</div>
</div>
</div>
<!-- 操作按钮 -->
<div class="actions">
<button class="action-btn primary" id="meditateBtn">打坐修炼 (+修为)</button>
<button class="action-btn secondary" id="gatherBtn">采集灵气 (+灵气)</button>
<button class="action-btn breakthrough" id="breakthroughBtn" disabled>突破境界</button>
<button class="action-btn auto" id="autoCultivationBtn">开启自动修炼</button>
</div>
</div>
<!-- 右侧面板 -->
<div class="right-panel">
<!-- 修仙商店 -->
<div class="shop panel">
<div class="panel-header">
<h3>修仙商店</h3>
<div class="panel-icon">🛒</div>
</div>
<div class="shop-items">
<div class="shop-item" data-cost="5" data-type="qi">
<div class="item-info">
<span class="item-name">小灵气丹</span>
<span class="item-cost">5 💎</span>
</div>
<button class="buy-btn">购买</button>
</div>
<div class="shop-item" data-cost="10" data-type="cultivation">
<div class="item-info">
<span class="item-name">培元丹</span>
<span class="item-cost">10 💎</span>
</div>
<button class="buy-btn">购买</button>
</div>
<div class="shop-item" data-cost="20" data-type="speed">
<div class="item-info">
<span class="item-name">加速符</span>
<span class="item-cost">20 💎</span>
</div>
<button class="buy-btn">购买</button>
</div>
</div>
</div>
<!-- 修仙事件 -->
<div class="events panel">
<div class="panel-header">
<h3>修仙事件</h3>
<div class="panel-icon">📜</div>
</div>
<div id="eventLog" class="event-log">
<p class="welcome-message">欢迎来到修仙世界!开始你的修仙之旅吧。</p>
</div>
</div>
</div>
</div>
<!-- 额外系统面板 -->
<div class="system-panels">
<!-- 任务面板 -->
<div class="quests panel">
<div class="panel-header">
<h3>修仙任务</h3>
<div class="panel-icon">📋</div>
</div>
<div id="questsContainer" class="quests-container">
<!-- 任务列表将由JavaScript动态生成 -->
</div>
</div>
<!-- 成就面板 -->
<div class="achievements panel">
<div class="panel-header">
<h3>修仙成就</h3>
<div class="panel-icon">🏆</div>
</div>
<div id="achievementsContainer" class="achievements-container">
<!-- 成就列表将由JavaScript动态生成 -->
</div>
</div>
<!-- 背包面板 -->
<div class="inventory panel">
<div class="panel-header">
<h3>修仙背包</h3>
<div class="panel-icon">🎒</div>
</div>
<div id="inventoryContainer" class="inventory-container">
<!-- 背包内容将由JavaScript动态生成 -->
</div>
</div>
</div>
<!-- 新手引导遮罩层 -->
<div id="tutorialOverlay" class="tutorial-overlay" style="display: none;">
<div class="tutorial-content">
<div id="tutorialMessage"></div>
<button id="nextTutorialBtn" class="tutorial-btn">下一步</button>
<button id="skipTutorialBtn" class="tutorial-btn skip">跳过</button>
</div>
</div>
<!-- 页脚 -->
<footer>
<p>修仙模拟器 © - 创意小游戏</p>
</footer>
</div>
<script src="game.js"></script>
</body>
</html>
style.css
/* 基础样式 */
:root {
--primary-gradient: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
--secondary-gradient: linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%);
--success-gradient: linear-gradient(135deg, #1dd1a1 0%, #10ac84 100%);
--warning-gradient: linear-gradient(135deg, #feca57 0%, #ff9ff3 100%);
--panel-bg: rgba(255, 255, 255, 0.05);
--panel-border: rgba(255, 255, 255, 0.1);
--highlight-color: #f9d423;
--text-primary: #ffffff;
--text-secondary: #cccccc;
--shadow-lg: 0 10px 30px rgba(0, 0, 0, 0.5);
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', Arial, sans-serif;
background: linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%);
color: var(--text-primary);
min-height: 100vh;
padding: 10px;
overflow-x: hidden;
}
/* 游戏容器 */
.game-container {
max-width: 1400px;
margin: 0 auto;
background: rgba(255, 255, 255, 0.03);
border-radius: 24px;
padding: 20px;
box-shadow: var(--shadow-lg);
backdrop-filter: blur(15px);
border: 1px solid var(--panel-border);
}
/* 页头样式 */
header {
margin-bottom: 30px;
padding-bottom: 20px;
border-bottom: 2px solid var(--panel-border);
}
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 20px;
}
.logo-section h1 {
font-size: 2.8rem;
background: linear-gradient(45deg, #f9d423, #ff4e50);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
margin-bottom: 8px;
font-weight: 900;
}
.logo-section p {
font-size: 1.1rem;
color: var(--text-secondary);
font-weight: 500;
}
.header-actions {
display: flex;
gap: 12px;
}
.nav-btn {
padding: 10px 20px;
background: rgba(255, 255, 255, 0.1);
color: var(--text-primary);
border: 1px solid var(--panel-border);
border-radius: 10px;
cursor: pointer;
transition: var(--transition);
font-size: 0.95rem;
backdrop-filter: blur(5px);
}
.nav-btn:hover {
background: rgba(255, 255, 255, 0.15);
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
/* 游戏状态统计 */
.game-stats {
display: flex;
justify-content: space-around;
margin-bottom: 30px;
flex-wrap: wrap;
gap: 15px;
}
.stat {
background: var(--panel-bg);
padding: 15px 25px;
border-radius: 12px;
text-align: center;
min-width: 140px;
transition: var(--transition);
border: 1px solid var(--panel-border);
backdrop-filter: blur(5px);
position: relative;
overflow: hidden;
}
.stat::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: var(--primary-gradient);
transform: scaleX(0);
transition: var(--transition);
}
.stat:hover {
background: rgba(255, 255, 255, 0.08);
transform: translateY(-5px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4);
}
.stat:hover::before {
transform: scaleX(1);
}
.stat-icon {
display: block;
font-size: 1.8rem;
margin-bottom: 5px;
}
.stat-name {
display: block;
font-size: 0.9rem;
color: var(--text-secondary);
margin-bottom: 5px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.stat-value {
display: block;
font-size: 1.6rem;
font-weight: bold;
color: var(--highlight-color);
text-shadow: 0 2px 10px rgba(249, 212, 35, 0.3);
}
/* 主要内容区域 */
.game-main {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 30px;
margin-bottom: 30px;
}
.left-panel, .right-panel {
display: flex;
flex-direction: column;
gap: 25px;
}
/* 修炼区域 */
.cultivation-area {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.cultivation-circle {
width: 320px;
height: 320px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.05);
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: var(--transition);
position: relative;
overflow: hidden;
border: 2px solid var(--panel-border);
}
.cultivation-core {
width: 280px;
height: 280px;
border-radius: 50%;
background: var(--primary-gradient);
display: flex;
justify-content: center;
align-items: center;
position: relative;
z-index: 2;
transition: var(--transition);
}
.cultivation-glow {
position: absolute;
top: 50%;
left: 50%;
width: 100%;
height: 100%;
transform: translate(-50%, -50%);
background: radial-gradient(circle, rgba(79, 172, 254, 0.4) 0%, rgba(0, 242, 254, 0) 70%);
animation: pulse 3s ease-in-out infinite;
z-index: 1;
}
@keyframes pulse {
0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.6; }
50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.8; }
}
.cultivation-circle:hover .cultivation-core {
transform: scale(1.05);
box-shadow: 0 0 50px rgba(79, 172, 254, 0.6);
}
.cultivation-circle::before {
content: '';
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
background: linear-gradient(45deg, #ff4e50, #f9d423, #4facfe, #00f2fe, #ff4e50);
z-index: -1;
animation: glowing 20s linear infinite;
background-size: 400%;
border-radius: 50%;
opacity: 0.3;
}
@keyframes glowing {
0% { background-position: 0 0; }
50% { background-position: 400% 0; }
100% { background-position: 0 0; }
}
#cultivationProgressText {
font-size: 1.6rem;
font-weight: bold;
text-align: center;
padding: 20px;
color: var(--text-primary);
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
animation: textGlow 2s ease-in-out infinite alternate;
}
@keyframes textGlow {
from { text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); }
to { text-shadow: 0 2px 20px rgba(255, 255, 255, 0.5); }
}
/* 修炼信息面板 */
.cultivation-info {
display: flex;
gap: 20px;
background: var(--panel-bg);
padding: 15px 25px;
border-radius: 12px;
border: 1px solid var(--panel-border);
backdrop-filter: blur(5px);
}
.info-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
}
.info-item span:first-child {
font-size: 0.9rem;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
}
.info-item span:last-child {
font-size: 1.2rem;
font-weight: bold;
color: var(--highlight-color);
}
/* 操作按钮 */
.actions {
display: flex;
flex-direction: column;
gap: 12px;
}
.action-btn {
padding: 16px 25px;
font-size: 1.1rem;
font-weight: bold;
color: white;
border: none;
border-radius: 12px;
cursor: pointer;
transition: var(--transition);
text-transform: uppercase;
letter-spacing: 0.5px;
position: relative;
overflow: hidden;
}
.action-btn::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: var(--transition);
}
.action-btn:hover::before {
left: 100%;
}
.action-btn.primary {
background: var(--primary-gradient);
}
.action-btn.secondary {
background: var(--secondary-gradient);
}
.action-btn.breakthrough {
background: var(--warning-gradient);
}
.action-btn.auto {
background: var(--success-gradient);
}
.action-btn:hover:not(:disabled) {
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
}
.action-btn:active:not(:disabled) {
transform: translateY(0);
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
}
.action-btn:disabled {
background: #444;
cursor: not-allowed;
opacity: 0.6;
transform: none;
}
/* 通用面板样式 */
.panel {
background: var(--panel-bg);
padding: 20px;
border-radius: 16px;
border: 1px solid var(--panel-border);
backdrop-filter: blur(10px);
transition: var(--transition);
}
.panel:hover {
transform: translateY(-5px);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
}
.panel-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid var(--panel-border);
}
.panel-header h3 {
font-size: 1.3rem;
color: var(--highlight-color);
margin: 0;
}
.panel-icon {
font-size: 1.5rem;
}
/* 修仙商店 */
.shop-items {
display: flex;
flex-direction: column;
gap: 10px;
}
.shop-item {
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(255, 255, 255, 0.05);
padding: 12px 15px;
border-radius: 10px;
transition: var(--transition);
border: 1px solid var(--panel-border);
}
.shop-item:hover {
background: rgba(255, 255, 255, 0.1);
transform: translateX(5px);
}
.item-info {
display: flex;
flex-direction: column;
gap: 3px;
}
.item-name {
font-weight: 600;
color: var(--text-primary);
}
.item-cost {
font-size: 0.9rem;
color: var(--highlight-color);
}
.buy-btn {
padding: 8px 20px;
background: var(--success-gradient);
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
transition: var(--transition);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
font-size: 0.9rem;
}
.buy-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(29, 209, 161, 0.3);
}
/* 修仙事件 */
.event-log {
max-height: 250px;
overflow-y: auto;
font-size: 0.95rem;
line-height: 1.6;
}
.event-log p {
margin-bottom: 10px;
padding: 10px 12px;
background: rgba(255, 255, 255, 0.03);
border-radius: 8px;
border-left: 3px solid transparent;
animation: slideIn 0.3s ease-out;
}
@keyframes slideIn {
from { opacity: 0; transform: translateX(-20px); }
to { opacity: 1; transform: translateX(0); }
}
.event-log p.welcome-message {
border-left-color: var(--highlight-color);
background: rgba(249, 212, 35, 0.1);
}
.event-log p[data-type="success"] {
border-left-color: #1dd1a1;
background: rgba(29, 209, 161, 0.1);
}
.event-log p[data-type="error"] {
border-left-color: #ff6b6b;
background: rgba(255, 107, 107, 0.1);
}
.event-log p[data-type="info"] {
border-left-color: #4facfe;
background: rgba(79, 172, 254, 0.1);
}
/* 系统面板区域 */
.system-panels {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 25px;
margin-bottom: 30px;
}
/* 任务面板 */
.quests-container {
max-height: 300px;
overflow-y: auto;
}
.quest-item {
padding: 15px;
margin-bottom: 10px;
background: rgba(255, 255, 255, 0.05);
border-radius: 10px;
border: 1px solid var(--panel-border);
transition: var(--transition);
}
.quest-item:hover {
background: rgba(255, 255, 255, 0.08);
}
.quest-item.completed {
opacity: 0.7;
background: rgba(29, 209, 161, 0.1);
border-color: #1dd1a1;
}
.quest-name {
font-weight: 600;
color: var(--highlight-color);
margin-bottom: 5px;
}
.quest-description {
font-size: 0.9rem;
color: var(--text-secondary);
margin-bottom: 10px;
}
.quest-progress {
height: 6px;
background: rgba(255, 255, 255, 0.1);
border-radius: 3px;
overflow: hidden;
margin-bottom: 5px;
}
.quest-progress-bar {
height: 100%;
background: var(--primary-gradient);
transition: width 0.3s ease;
border-radius: 3px;
}
.quest-reward {
font-size: 0.85rem;
color: #1dd1a1;
}
/* 成就面板 */
.achievements-container {
max-height: 300px;
overflow-y: auto;
}
.achievement-item {
padding: 15px;
margin-bottom: 10px;
background: rgba(255, 255, 255, 0.05);
border-radius: 10px;
border: 1px solid var(--panel-border);
transition: var(--transition);
position: relative;
}
.achievement-item:hover {
background: rgba(255, 255, 255, 0.08);
}
.achievement-item.completed {
background: rgba(249, 212, 35, 0.1);
border-color: var(--highlight-color);
animation: achievementGlow 2s ease-in-out infinite alternate;
}
@keyframes achievementGlow {
from { box-shadow: 0 0 0 rgba(249, 212, 35, 0.3); }
to { box-shadow: 0 0 20px rgba(249, 212, 35, 0.6); }
}
.achievement-name {
font-weight: 600;
color: var(--text-primary);
margin-bottom: 5px;
}
.achievement-description {
font-size: 0.9rem;
color: var(--text-secondary);
margin-bottom: 10px;
}
.achievement-progress {
height: 6px;
background: rgba(255, 255, 255, 0.1);
border-radius: 3px;
overflow: hidden;
margin-bottom: 5px;
}
.achievement-progress-bar {
height: 100%;
background: var(--warning-gradient);
transition: width 0.3s ease;
border-radius: 3px;
}
.achievement-reward {
font-size: 0.85rem;
color: var(--highlight-color);
}
/* 背包面板 */
.inventory-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
gap: 10px;
max-height: 300px;
overflow-y: auto;
padding-right: 5px;
}
.inventory-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 10px;
background: rgba(255, 255, 255, 0.05);
border-radius: 10px;
border: 1px solid var(--panel-border);
transition: var(--transition);
text-align: center;
cursor: pointer;
}
.inventory-item:hover {
background: rgba(255, 255, 255, 0.1);
transform: translateY(-3px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.inventory-item-icon {
font-size: 2rem;
margin-bottom: 5px;
}
.inventory-item-name {
font-size: 0.85rem;
font-weight: 600;
margin-bottom: 3px;
}
.inventory-item-count {
font-size: 0.8rem;
color: var(--highlight-color);
background: rgba(0, 0, 0, 0.3);
padding: 2px 8px;
border-radius: 10px;
min-width: 30px;
}
/* 新手引导 */
.tutorial-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.8);
backdrop-filter: blur(5px);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
animation: fadeIn 0.3s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.tutorial-content {
background: rgba(255, 255, 255, 0.1);
padding: 30px;
border-radius: 20px;
max-width: 600px;
text-align: center;
backdrop-filter: blur(10px);
border: 1px solid var(--panel-border);
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
}
#tutorialMessage {
font-size: 1.2rem;
margin-bottom: 20px;
line-height: 1.6;
}
.tutorial-btn {
padding: 12px 30px;
font-size: 1rem;
font-weight: bold;
background: var(--primary-gradient);
color: white;
border: none;
border-radius: 10px;
cursor: pointer;
transition: var(--transition);
margin: 0 10px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.tutorial-btn:hover {
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
}
.tutorial-btn.skip {
background: rgba(255, 255, 255, 0.2);
}
/* 页脚 */
footer {
text-align: center;
margin-top: 40px;
padding-top: 20px;
border-top: 2px solid var(--panel-border);
color: var(--text-secondary);
font-size: 0.9rem;
}
/* 滚动条样式 */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.05);
border-radius: 4px;
}
::-webkit-scrollbar-thumb {
background: linear-gradient(180deg, #4facfe, #00f2fe);
border-radius: 4px;
transition: var(--transition);
}
::-webkit-scrollbar-thumb:hover {
background: linear-gradient(180deg, #00f2fe, #4facfe);
}
/* 响应式设计 */
@media (max-width: 1200px) {
.system-panels {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 992px) {
.game-main {
grid-template-columns: 1fr;
}
.system-panels {
grid-template-columns: 1fr;
}
.cultivation-circle {
width: 280px;
height: 280px;
}
.cultivation-core {
width: 240px;
height: 240px;
}
}
@media (max-width: 768px) {
.header-content {
flex-direction: column;
text-align: center;
}
.logo-section h1 {
font-size: 2.2rem;
}
.game-stats {
justify-content: center;
}
.stat {
min-width: 120px;
}
.cultivation-circle {
width: 250px;
height: 250px;
}
.cultivation-core {
width: 210px;
height: 210px;
}
#cultivationProgressText {
font-size: 1.3rem;
}
.action-btn {
padding: 14px 20px;
font-size: 1rem;
}
.tutorial-content {
margin: 20px;
padding: 20px;
}
}
@media (max-width: 480px) {
.game-container {
padding: 15px;
border-radius: 16px;
}
.logo-section h1 {
font-size: 1.8rem;
}
.stat {
min-width: 100px;
padding: 12px 15px;
}
.cultivation-circle {
width: 200px;
height: 200px;
}
.cultivation-core {
width: 160px;
height: 160px;
}
#cultivationProgressText {
font-size: 1.1rem;
}
.inventory-container {
grid-template-columns: repeat(3, 1fr);
}
}
一、项目整体架构设计
在开始编码前,我们需要先规划项目的整体结构。一个完整的小游戏通常包含三个核心部分:
- 数据层:管理游戏所有状态(修为、灵气、境界等)
- 视图层:负责 UI 渲染和用户交互
- 逻辑层:处理游戏核心逻辑(修炼、突破、任务系统等)
我们的修仙模拟器将采用以下文件结构:
index.html:页面结构和 DOM 元素定义style.css:游戏样式和动画效果game.js:游戏核心逻辑和状态管理
二、第一步:搭建 HTML 基础结构
首先,我们需要创建游戏的页面骨架。HTML 部分主要负责定义 DOM 元素,为后续的样式和交互做准备。
核心思路
- 划分功能区域:顶部导航、游戏状态统计、修炼核心区、系统面板(商店 / 任务 / 成就)
- 预留交互元素:按钮、面板容器、提示区域
- 确保结构语义化,便于后续 JS 操作和样式控制
关键代码解析
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>修仙模拟器 - 2025重制版</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="game-container">
<!-- 1. 顶部导航:游戏标题和操作按钮 -->
<header>
<div class="header-content">
<div class="logo-section">
<h1>修仙模拟器</h1>
<p>2025重制版 · 修炼成仙,逆天改命!</p>
</div>
<div class="header-actions">
<button id="resetGameBtn" class="nav-btn">重置游戏</button>
<button id="toggleFullscreenBtn" class="nav-btn">全屏</button>
</div>
</div>
</header>
<!-- 2. 游戏状态统计:实时显示核心数据 -->
<div class="game-stats">
<div class="stat">
<span class="stat-icon">✨</span>
<span class="stat-name">修为</span>
<span class="stat-value" id="cultivation">0</span>
</div>
<!-- 其他状态:灵气、境界、灵石、灵根 -->
</div>
<!-- 3. 核心内容区:修炼操作和信息展示 -->
<div class="game-main">
<!-- 左侧:修炼核心区 -->
<div class="left-panel">
<div class="cultivation-area">
<!-- 修炼圆形按钮(核心交互元素) -->
<div class="cultivation-circle" id="cultivationCircle">
<div class="cultivation-core">
<span id="cultivationProgressText">点击开始修炼</span>
</div>
</div>
<!-- 修炼信息面板 -->
<div class="cultivation-info">
<!-- 修炼速度、灵气采集速度 -->
</div>
</div>
<!-- 操作按钮区 -->
<div class="actions">
<button class="action-btn primary" id="meditateBtn">打坐修炼 (+修为)</button>
<button class="action-btn secondary" id="gatherBtn">采集灵气 (+灵气)</button>
<button class="action-btn breakthrough" id="breakthroughBtn" disabled>突破境界</button>
<button class="action-btn auto" id="autoCultivationBtn">开启自动修炼</button>
</div>
</div>
<!-- 右侧:商店和事件日志 -->
<div class="right-panel">
<!-- 修仙商店 -->
<div class="shop panel">
<div class="panel-header">
<h3>修仙商店</h3>
<div class="panel-icon">🛒</div>
</div>
<div class="shop-items">
<!-- 商店物品由JS动态生成 -->
</div>
</div>
<!-- 事件日志 -->
<div class="events panel">
<div class="panel-header">
<h3>修仙事件</h3>
<div class="panel-icon">📜</div>
</div>
<div id="eventLog" class="event-log">
<p class="welcome-message">欢迎来到修仙世界!</p>
</div>
</div>
</div>
</div>
<!-- 4. 系统面板区:任务、成就、背包 -->
<div class="system-panels">
<!-- 任务面板 -->
<div class="quests panel">
<div class="panel-header">
<h3>修仙任务</h3>
<div class="panel-icon">📋</div>
</div>
<div id="questsContainer" class="quests-container"></div>
</div>
<!-- 成就面板 -->
<div class="achievements panel">
<!-- 结构类似任务面板 -->
</div>
<!-- 背包面板 -->
<div class="inventory panel">
<!-- 结构类似任务面板 -->
</div>
</div>
<!-- 5. 新手引导遮罩层 -->
<div id="tutorialOverlay" class="tutorial-overlay" style="display: none;">
<div class="tutorial-content">
<div id="tutorialMessage"></div>
<button id="nextTutorialBtn" class="tutorial-btn">下一步</button>
<button id="skipTutorialBtn" class="tutorial-btn skip">跳过</button>
</div>
</div>
<!-- 6. 页脚 -->
<footer>
<p>修仙模拟器 © 2025 - 创意小游戏重制版</p>
</footer>
</div>
<!-- 引入JS逻辑文件 -->
<script src="game.js"></script>
</body>
</html>
为什么这样设计?
- 区域划分清晰:将游戏分为多个功能模块,便于后续维护和扩展
- 预留 ID 和类名:所有需要 JS 操作的元素都设置了唯一 ID,方便获取 DOM 节点
- 响应式基础:使用弹性布局和网格布局,为后续响应式设计打下基础
- 用户体验优先:核心交互元素(修炼按钮)放在显眼位置,辅助功能(任务 / 成就)集中展示
三、第二步:设计 CSS 样式与动画
好的 UI 设计能极大提升游戏体验。本项目采用修仙主题的深色渐变风格,配合灵动的动画效果,营造沉浸式修仙氛围。
核心设计思路
- 色彩系统:以深蓝、紫色为主色调(修仙神秘感),金色 / 黄色为强调色(修为、奖励)
- 动画效果:为核心交互添加脉冲、发光等动画,增强操作反馈
- 响应式适配:确保在手机、平板、电脑上都有良好的显示效果
- 分层设计:通过阴影、渐变、遮罩实现视觉层次感
关键样式解析
1. 基础样式与变量定义
/* 定义全局变量,便于统一管理 */
:root {
--primary-gradient: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
--secondary-gradient: linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%);
--success-gradient: linear-gradient(135deg, #1dd1a1 0%, #10ac84 100%);
--warning-gradient: linear-gradient(135deg, #feca57 0%, #ff9ff3 100%);
--panel-bg: rgba(255, 255, 255, 0.05);
--panel-border: rgba(255, 255, 255, 0.1);
--highlight-color: #f9d423; /* 金色,用于强调重要信息 */
--text-primary: #ffffff;
--text-secondary: #cccccc;
--shadow-lg: 0 10px 30px rgba(0, 0, 0, 0.5);
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); /* 统一过渡效果 */
}
/* 重置默认样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 页面基础样式 */
body {
font-family: 'Microsoft YaHei', 'PingFang SC', sans-serif;
background: linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%);
color: var(--text-primary);
min-height: 100vh;
padding: 10px;
overflow-x: hidden;
}
2. 核心交互元素样式(修炼圆形按钮)
/* 修炼核心区域 */
.cultivation-circle {
width: 320px;
height: 320px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.05);
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: var(--transition);
position: relative;
overflow: hidden;
border: 2px solid var(--panel-border);
}
/* 修炼核心内部 */
.cultivation-core {
width: 280px;
height: 280px;
border-radius: 50%;
background: var(--primary-gradient);
display: flex;
justify-content: center;
align-items: center;
position: relative;
z-index: 2;
transition: var(--transition);
}
/* 发光效果 */
.cultivation-glow {
position: absolute;
top: 50%;
left: 50%;
width: 100%;
height: 100%;
transform: translate(-50%, -50%);
background: radial-gradient(circle, rgba(79, 172, 254, 0.4) 0%, rgba(0, 242, 254, 0) 70%);
animation: pulse 3s ease-in-out infinite; /* 脉冲动画 */
z-index: 1;
}
/* 脉冲动画关键帧 */
@keyframes pulse {
0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.6; }
50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.8; }
}
/* 鼠标悬浮效果 */
.cultivation-circle:hover .cultivation-core {
transform: scale(1.05);
box-shadow: 0 0 50px rgba(79, 172, 254, 0.6); /* 增强发光效果 */
}
3. 面板与按钮样式
/* 通用面板样式 */
.panel {
background: var(--panel-bg);
padding: 20px;
border-radius: 16px;
border: 1px solid var(--panel-border);
backdrop-filter: blur(10px); /* 毛玻璃效果,增强现代感 */
transition: var(--transition);
}
.panel:hover {
transform: translateY(-5px);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4); /* 悬浮提升效果 */
}
/* 按钮样式 */
.action-btn {
padding: 16px 25px;
font-size: 1.1rem;
font-weight: bold;
color: white;
border: none;
border-radius: 12px;
cursor: pointer;
transition: var(--transition);
text-transform: uppercase;
letter-spacing: 0.5px;
position: relative;
overflow: hidden;
}
/* 按钮渐变样式(不同功能按钮不同颜色) */
.action-btn.primary { background: var(--primary-gradient); }
.action-btn.secondary { background: var(--secondary-gradient); }
.action-btn.breakthrough { background: var(--warning-gradient); }
.action-btn.auto { background: var(--success-gradient); }
/* 按钮hover效果 */
.action-btn:hover:not(:disabled) {
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
}
4. 响应式适配
/* 平板设备适配 */
@media (max-width: 992px) {
.game-main {
grid-template-columns: 1fr; /* 单列布局 */
}
.cultivation-circle {
width: 280px;
height: 280px;
}
}
/* 手机设备适配 */
@media (max-width: 480px) {
.game-container {
padding: 15px;
border-radius: 16px;
}
.cultivation-circle {
width: 200px;
height: 200px;
}
.inventory-container {
grid-template-columns: repeat(3, 1fr); /* 背包3列布局 */
}
}
设计亮点
- 毛玻璃效果:通过
backdrop-filter: blur(10px)实现,增强现代感 - 渐变与动画:核心元素使用渐变背景和脉冲动画,提升视觉吸引力
- 交互反馈:所有可点击元素都有 hover 和 active 效果,增强用户体验
- 响应式设计:适配不同屏幕尺寸,确保移动端体验
四、第三步:实现 JS 核心逻辑
JS 部分是游戏的灵魂,负责管理游戏状态、处理用户交互、实现核心玩法。我们将采用模块化的方式编写代码,确保逻辑清晰、易于维护。
核心逻辑模块划分
- 游戏状态管理:定义和维护所有游戏数据
- DOM 操作:获取元素、更新 UI、创建动态内容
- 核心玩法:修炼、突破、采集、自动修炼
- 系统功能:任务、成就、背包、商店
- 数据持久化:本地存储保存游戏进度
- 辅助功能:新手引导、事件日志、全屏模式
模块一:游戏状态对象(数据核心)
游戏状态对象是整个游戏的数据中心,存储了所有可变化的游戏数据。我们采用对象字面量的方式定义,便于访问和修改。
// 游戏状态对象 - 2025重制版
let gameState = {
// 核心属性
cultivation: 0, // 修为(升级境界的核心资源)
maxCultivation: 100, // 最大修为(达到后可突破)
spiritualEnergy: 0, // 灵气(修炼消耗的资源)
spiritualStones: 100, // 灵石(商店购物货币)
realm: "凡人", // 当前境界
realmLevel: 0, // 当前境界等级(对应realmOrder的索引)
realmOrder: ["凡人", "练气期", "筑基期", "金丹期", "元婴期", "化神期", "合体期", "渡劫期", "大乘期", "成仙"], // 境界顺序
// 突破相关
breakthroughChance: 30, // 突破成功率(百分比)
breakthroughBonus: 0, // 突破加成(百分比)
// 速度属性
cultivationSpeed: 1, // 修炼速度(每点击获得的修为倍数)
energyGatheringSpeed: 1, // 灵气采集速度(每点击获得的灵气倍数)
// 自动修炼
autoCultivation: false, // 自动修炼状态
autoCultivationInterval: null, // 自动修炼定时器
// 灵根系统(影响修炼效率)
spiritualRoot: {
type: "凡根",
quality: "普通",
level: 1,
bonus: 0 // 修炼效率加成(百分比)
},
// 成就系统
achievements: [
{ id: "first_cultivation", name: "初入修仙", description: "完成第一次修炼", completed: false, progress: 0, target: 1, reward: 50 },
// 其他成就...
],
// 任务系统
quests: [
{ id: "main_1", name: "修仙之路", description: "完成一次修炼", progress: 0, target: 1, completed: false, reward: { cultivation: 50, stones: 50 } },
// 其他任务...
],
// 背包系统
inventory: [
{ id: "breakthrough_talisman", name: "突破符", count: 0, description: "增加20%的突破成功率" },
// 其他物品...
],
// 商店物品
shopItems: [
{ id: "breakthrough_talisman", name: "突破符", cost: 50, description: "增加20%的突破成功率" },
// 其他商品...
],
// 新手引导
tutorialStep: 0,
tutorialSteps: [
"欢迎来到修仙世界!点击中间的圆形区域进行修炼,积累修为。",
// 其他引导步骤...
],
// 特殊事件系统(2025新增)
specialEvents: {
active: false,
eventType: null,
countdown: 0
},
// 时间戳(用于离线收益计算)
lastUpdateTime: Date.now()
};
为什么这样设计?
- 集中管理:所有游戏数据放在一个对象中,便于统一管理和访问
- 层次清晰:按功能模块划分属性(核心属性、突破相关、系统功能),逻辑清晰
- 易于扩展:新增功能时只需在对应模块下添加属性,无需修改整体结构
- 数据持久化友好:整对象可直接序列化为 JSON,便于本地存储
模块二:DOM 元素获取与初始化
在操作 DOM 之前,我们需要先获取所有需要交互的元素,并进行初始化设置。
// DOM元素获取(按功能分类)
// 1. 修炼核心区域元素
const cultivationCircle = document.getElementById('cultivationCircle');
const cultivationCore = cultivationCircle.querySelector('.cultivation-core');
const cultivationProgressText = document.getElementById('cultivationProgressText');
// 2. 状态显示元素
const spiritualStonesText = document.getElementById('spiritStone');
const spiritualEnergyText = document.getElementById('qi');
const realmText = document.getElementById('realm');
// 3. 按钮元素
const gatherBtn = document.getElementById('gatherBtn');
const breakthroughBtn = document.getElementById('breakthroughBtn');
const autoCultivationBtn = document.getElementById('autoCultivationBtn');
const resetGameBtn = document.getElementById('resetGameBtn');
const fullscreenBtn = document.getElementById('toggleFullscreenBtn');
// 4. 系统面板元素
const achievementsContainer = document.getElementById('achievementsContainer');
const inventoryContainer = document.getElementById('inventoryContainer');
const questsContainer = document.getElementById('questsContainer');
// 5. 新手引导元素
const tutorialOverlay = document.getElementById('tutorialOverlay');
const tutorialMessage = document.getElementById('tutorialMessage');
const nextTutorialBtn = document.getElementById('nextTutorialBtn');
const skipTutorialBtn = document.getElementById('skipTutorialBtn');
// 6. 动态创建缺失元素(如果HTML中未定义)
const eventLog = document.createElement('div');
eventLog.id = 'eventLog';
eventLog.className = 'event-log';
document.body.appendChild(eventLog);
// 初始化函数(游戏入口)
function initGame() {
loadGame(); // 加载本地存储的游戏进度
// 确保时间戳正确设置
if (!gameState.lastUpdateTime) {
gameState.lastUpdateTime = Date.now();
}
// 创建UI组件
createTutorialUI();
createQuestUI();
createAchievementUI();
createInventoryUI();
addNewShopItems();
// 更新UI显示
updateUI();
// 绑定事件监听器
setupEventListeners();
// 启动游戏循环
gameLoop();
// 开始新手引导(如果未完成)
if (gameState.tutorialStep < gameState.tutorialSteps.length) {
showTutorialStep();
}
}
// 页面加载完成后初始化游戏
window.addEventListener('load', initGame);
关键知识点
- DOM 元素获取方式:
getElementById(高效获取单个元素)、querySelector(灵活选择器)、createElement(动态创建元素) - 初始化顺序:先加载数据 → 再创建 UI → 最后绑定事件,确保逻辑正确
- 兼容性处理:动态创建缺失元素,避免 HTML 结构变化导致的错误
模块三:核心玩法实现(修炼与突破)
修炼和突破是游戏的核心玩法,我们需要实现点击修炼、自动修炼、突破境界等核心功能。
1. 点击修炼功能
// 点击修炼逻辑(绑定到修炼圆形按钮)
function handleCultivationClick() {
// 检查是否有足够灵气(修炼需要消耗灵气)
if (gameState.spiritualEnergy >= 1) {
// 消耗灵气
gameState.spiritualEnergy -= 1;
// 计算获得的修为(受灵根加成影响)
const effectiveCultivationSpeed = gameState.cultivationSpeed * (1 + gameState.spiritualRoot.bonus / 100);
const cultivationGain = Math.floor(effectiveCultivationSpeed);
gameState.cultivation += cultivationGain;
// 添加修炼动画效果(提升视觉反馈)
cultivationCore.classList.add('pulse');
setTimeout(() => {
cultivationCore.classList.remove('pulse');
}, 500);
// 添加事件日志
addEvent(`获得了${cultivationGain}点修为!`);
// 检查成就进度(初入修仙成就)
const firstCultivation = gameState.achievements.find(a => a.id === 'first_cultivation');
if (firstCultivation && !firstCultivation.completed) {
firstCultivation.completed = true;
grantAchievementReward(firstCultivation);
}
// 检查任务进度(修仙之路任务)
const mainQuest1 = gameState.quests.find(q => q.id === 'main_1');
if (mainQuest1 && !mainQuest1.completed) {
mainQuest1.progress = 1;
completeQuest(mainQuest1);
}
// 有几率触发特殊事件(增加游戏随机性)
if (Math.random() < 0.05) { // 5%几率
triggerSpecialEvent();
}
// 更新UI和保存游戏
updateUI();
saveGame();
}
}
2. 突破境界功能
// 突破境界逻辑
function breakthroughRealm() {
// 检查是否达到突破条件(修为满值)
if (gameState.cultivation >= gameState.maxCultivation) {
// 计算突破成功率(基础成功率 + 灵根加成 + 突破符加成)
const baseChance = 0.7 - (gameState.realmLevel * 0.05); // 境界越高,基础成功率越低
const rootBonus = gameState.spiritualRoot.bonus / 100; // 灵根品质加成
let breakthroughChance = Math.min(0.95, baseChance + rootBonus); // 最高95%成功率
// 检查是否使用了突破符
if (gameState.breakthroughBonus > 0) {
breakthroughChance = Math.min(1, breakthroughChance + gameState.breakthroughBonus / 100);
addEvent(`突破符生效,成功率提升${gameState.breakthroughBonus}%!`);
gameState.breakthroughBonus = 0; // 消耗突破符
}
// 随机判断是否突破成功
const isSuccess = Math.random() < breakthroughChance;
if (isSuccess) {
// 突破成功处理
gameState.realmLevel += 1;
gameState.realm = gameState.realmOrder[gameState.realmLevel]; // 更新境界
// 提升修炼和灵气采集速度(境界奖励)
gameState.cultivationSpeed *= 1.5;
gameState.energyGatheringSpeed *= 1.2;
// 重置修为并提升最大修为(为下一境界做准备)
gameState.cultivation = 0;
gameState.maxCultivation = Math.floor(gameState.maxCultivation * 1.5);
// 奖励灵石
gameState.spiritualStones += Math.floor(Math.random() * 50) + 50;
// 突破动画效果
cultivationCircle.classList.add('breakthrough-animation');
setTimeout(() => {
cultivationCircle.classList.remove('breakthrough-animation');
}, 2000);
// 特殊境界提示(增强游戏体验)
if (gameState.realm === "渡劫期") {
addEvent("你进入了渡劫期,即将面临九重雷劫!");
} else if (gameState.realm === "大乘期") {
addEvent("恭喜!你成功渡过雷劫,达到大乘期!距离成仙只有一步之遥!");
} else {
addEvent(`恭喜!你成功突破到${gameState.realm}!`);
}
} else {
// 突破失败处理(损失部分修为和灵气)
const cultivationLost = Math.floor(gameState.cultivation * 0.1);
const energyLost = Math.floor(gameState.spiritualEnergy * 0.1);
gameState.cultivation -= cultivationLost;
gameState.spiritualEnergy = Math.max(0, gameState.spiritualEnergy - energyLost);
addEvent(`突破失败!损失了${cultivationLost}点修为和${energyLost}点灵气。`);
}
// 更新UI和保存游戏
updateUI();
saveGame();
}
}
3. 自动修炼功能
// 切换自动修炼状态
function toggleAutoCultivation() {
if (gameState.autoCultivation) {
// 停止自动修炼
clearInterval(gameState.autoCultivationInterval);
gameState.autoCultivation = false;
addEvent("自动修炼已停止!");
} else {
// 开启自动修炼(每1秒自动修炼一次)
gameState.autoCultivation = true;
gameState.autoCultivationInterval = setInterval(() => {
// 自动修炼逻辑(类似点击修炼,但无需手动操作)
if (gameState.spiritualEnergy >= 0.5) { // 自动修炼消耗更少灵气
gameState.spiritualEnergy -= 0.5;
const effectiveCultivationSpeed = gameState.cultivationSpeed * (1 + gameState.spiritualRoot.bonus / 100);
const cultivationGain = Math.floor(effectiveCultivationSpeed * 0.5);
gameState.cultivation += cultivationGain;
// 每10次自动修炼添加一次日志(避免日志刷屏)
if (gameState.autoCultivationCount % 10 === 0) {
addEvent(`自动修炼获得了${cultivationGain}点修为!`);
}
gameState.autoCultivationCount = (gameState.autoCultivationCount || 0) + 1;
updateUI();
saveGame();
} else {
// 灵气不足时停止自动修炼
clearInterval(gameState.autoCultivationInterval);
gameState.autoCultivation = false;
addEvent("灵气不足,自动修炼已停止!");
updateUI();
}
}, 1000);
addEvent("自动修炼已开启!");
}
// 更新按钮状态
updateUI();
}
模块四:系统功能实现(任务、成就、背包)
任务和成就系统是提升游戏可玩性的关键,能引导用户探索游戏功能、提供持续的目标感。
1. 任务系统
// 检查任务进度
function checkQuestProgress(actionType, params = {}) {
gameState.quests.forEach(quest => {
if (quest.completed) return; // 已完成的任务跳过
// 根据不同操作类型更新任务进度
switch (actionType) {
case 'cultivate': // 修炼操作
if (quest.id === 'main_1') { // 修仙之路任务
quest.progress = 1;
}
break;
case 'gather_energy': // 采集灵气操作
if (quest.id === 'main_2') { // 灵气积累任务
quest.progress = Math.min(quest.target, quest.progress + 1);
}
break;
case 'breakthrough': // 突破操作
if (quest.id === 'main_3' && params.realm === '练气期') { // 初入练气任务
quest.progress = 1;
}
break;
case 'buy_item': // 商店购买操作
if (quest.id === 'main_5') { // 商店购物任务
quest.progress = 1;
}
break;
}
// 检查是否完成任务
if (quest.progress >= quest.target) {
completeQuest(quest);
}
});
}
// 完成任务并发放奖励
function completeQuest(quest) {
if (!quest.completed) {
quest.completed = true;
// 发放奖励
if (quest.reward.cultivation) {
gameState.cultivation += quest.reward.cultivation;
}
if (quest.reward.stones) {
gameState.spiritualStones += quest.reward.stones;
}
if (quest.reward.energy) {
gameState.spiritualEnergy += quest.reward.energy;
}
// 添加任务完成日志
addEvent(`任务完成:${quest.name}!获得了丰厚的奖励!`);
// 检查成就进度(成就达人任务)
const achievementQuest = gameState.quests.find(q => q.id === 'side_2');
if (achievementQuest && !achievementQuest.completed) {
const completedAchievements = gameState.achievements.filter(a => a.completed).length;
achievementQuest.progress = Math.min(achievementQuest.target, completedAchievements);
if (achievementQuest.progress >= achievementQuest.target) {
completeQuest(achievementQuest);
}
}
// 更新UI和保存游戏
updateUI();
saveGame();
}
}
// 更新任务UI
function updateQuestUI() {
// 清空现有任务
questsContainer.innerHTML = '';
// 动态生成任务列表
gameState.quests.forEach(quest => {
const questElement = document.createElement('div');
questElement.className = `quest-item ${quest.completed ? 'completed' : ''}`;
// 设置任务内容
questElement.innerHTML = `
<h4>${quest.name}</h4>
<p>${quest.description}</p>
<div class="quest-progress">
<div class="progress-fill" style="width: ${Math.min(100, (quest.progress / quest.target) * 100)}%"></div>
</div>
<p class="quest-reward">奖励:${formatReward(quest.reward)}</p>
`;
questsContainer.appendChild(questElement);
});
}
// 格式化奖励显示
function formatReward(reward) {
let rewardText = '';
if (reward.cultivation) rewardText += `修为 ${reward.cultivation} `;
if (reward.stones) rewardText += `灵石 ${reward.stones} `;
if (reward.energy) rewardText += `灵气 ${reward.energy} `;
return rewardText || '无';
}
2. 成就系统
// 检查成就进度
function checkAchievementProgress(actionType, params = {}) {
gameState.achievements.forEach(achievement => {
if (achievement.completed) return;
switch (actionType) {
case 'first_cultivate': // 第一次修炼
if (achievement.id === 'first_cultivation') {
achievement.completed = true;
grantAchievementReward(achievement);
}
break;
case 'gather_energy': // 采集灵气
if (achievement.id === 'gather_energy') {
achievement.progress = Math.min(achievement.target, achievement.progress + 1);
if (achievement.progress >= achievement.target) {
achievement.completed = true;
grantAchievementReward(achievement);
}
}
break;
case 'breakthrough': // 突破境界
if (achievement.id === 'first_breakthrough' && params.realm === '练气期') {
achievement.completed = true;
grantAchievementReward(achievement);
}
break;
case 'buy_item': // 购买物品
if (achievement.id === 'buy_item') {
achievement.completed = true;
grantAchievementReward(achievement);
}
break;
}
});
}
// 发放成就奖励
function grantAchievementReward(achievement) {
if (achievement.completed) {
// 发放奖励
if (achievement.reward) {
gameState.spiritualStones += achievement.reward; // 成就奖励默认是灵石
addEvent(`成就达成:${achievement.name}!获得${achievement.reward}颗灵石!`);
}
// 更新UI和保存游戏
updateUI();
saveGame();
}
}
// 更新成就UI(类似任务UI,略)
function updateAchievementUI() {
// 实现逻辑与任务UI类似,动态生成成就列表
}
3. 背包系统
// 添加物品到背包
function addItemToInventory(itemId) {
const item = gameState.inventory.find(i => i.id === itemId);
if (item) {
item.count += 1;
addEvent(`获得了1个${item.name}!`);
// 检查相关任务进度(如收集突破符任务)
if (itemId === "breakthrough_talisman") {
const quest = gameState.quests.find(q => q.id === "side_1");
if (quest && !quest.completed) {
quest.progress = Math.min(quest.target, item.count);
if (quest.progress >= quest.target) {
completeQuest(quest);
}
}
}
// 更新背包UI
updateInventoryUI();
saveGame();
}
}
// 使用背包物品
function useInventoryItem(itemId) {
const item = gameState.inventory.find(i => i.id === itemId);
if (item && item.count > 0) {
item.count -= 1;
// 根据物品类型应用效果
switch (itemId) {
case "breakthrough_talisman": // 突破符
gameState.breakthroughBonus = 20;
addEvent("使用了突破符,突破成功率提升20%!");
break;
case "heavenly_pill": // 天灵丹
gameState.cultivation += 100;
addEvent("服用了天灵丹,获得了100点修为!");
break;
case "magic_artifact": // 法宝
gameState.cultivationSpeed *= 1.1;
gameState.energyGatheringSpeed *= 1.1;
addEvent("装备了法宝,修炼速度和灵气采集速度提升10%!");
break;
case "root_improvement_pill": // 灵根提升丹
upgradeSpiritRoot();
addEvent("服用了灵根提升丹,灵根品质提升!");
break;
}
// 更新UI和保存游戏
updateInventoryUI();
updateUI();
saveGame();
}
}
// 更新背包UI
function updateInventoryUI() {
// 清空现有物品
inventoryContainer.innerHTML = '';
// 动态生成背包物品列表
gameState.inventory.forEach(item => {
if (item.count > 0) {
const itemElement = document.createElement('div');
itemElement.className = 'inventory-item';
itemElement.innerHTML = `
<h4>${item.name} (${item.count})</h4>
<p>${item.description}</p>
`;
// 绑定使用物品事件
itemElement.addEventListener('click', () => {
useInventoryItem(item.id);
});
inventoryContainer.appendChild(itemElement);
}
});
// 背包为空时显示提示
if (gameState.inventory.filter(i => i.count > 0).length === 0) {
const emptyMessage = document.createElement('p');
emptyMessage.textContent = '背包为空';
emptyMessage.style.color = '#666';
emptyMessage.style.textAlign = 'center';
emptyMessage.style.padding = '20px';
inventoryContainer.appendChild(emptyMessage);
}
}
模块五:数据持久化与辅助功能
1. 本地存储(保存游戏进度)
// 保存游戏进度到本地存储
function saveGame() {
try {
// 将游戏状态对象序列化为JSON字符串
const savedData = JSON.stringify(gameState);
// 保存到localStorage
localStorage.setItem('cultivationGameSave', savedData);
// 可选:添加保存提示
// addEvent("游戏已自动保存!");
} catch (e) {
console.error('保存游戏失败:', e);
addEvent("保存游戏失败,请检查浏览器存储权限!");
}
}
// 从本地存储加载游戏进度
function loadGame() {
try {
// 从localStorage获取保存的游戏数据
const savedData = localStorage.getItem('cultivationGameSave');
if (savedData) {
// 将JSON字符串解析为对象
const parsedData = JSON.parse(savedData);
// 合并到当前游戏状态(保留默认值,避免数据缺失)
Object.assign(gameState, parsedData);
// 数据兼容性处理(如果旧版本数据缺少新属性)
if (!gameState.specialEvents) {
gameState.specialEvents = {
active: false,
eventType: null,
countdown: 0
};
}
addEvent("游戏进度已加载!");
} else {
addEvent("未找到保存的游戏进度,开始新游戏!");
}
} catch (e) {
console.error('加载游戏失败:', e);
addEvent("加载游戏失败,将开始新游戏!");
// 清除损坏的保存数据
localStorage.removeItem('cultivationGameSave');
}
}
// 重置游戏(清除本地存储并刷新页面)
function resetGame() {
if (confirm('确定要重置游戏吗?所有进度将会丢失!')) {
localStorage.removeItem('cultivationGameSave');
location.reload();
}
}
2. 游戏循环(处理自动收益)
// 游戏循环(使用requestAnimationFrame实现平滑更新)
function gameLoop() {
const currentTime = Date.now();
const deltaTime = (currentTime - gameState.lastUpdateTime) / 1000; // 时间差(秒)
gameState.lastUpdateTime = currentTime;
// 1. 自动获得灵气(即使玩家不操作)
const effectiveEnergySpeed = gameState.energyGatheringSpeed * (1 + gameState.spiritualRoot.bonus / 100);
const autoEnergyGain = effectiveEnergySpeed * deltaTime;
gameState.spiritualEnergy += autoEnergyGain;
// 2. 自动获得灵石(根据境界和装备)
const stoneGainRate = (gameState.realmLevel * 0.5) + (gameState.equippedArtifacts * 0.2);
gameState.spiritualStones += stoneGainRate * deltaTime;
// 3. 处理特殊事件倒计时
if (gameState.specialEvents.active) {
gameState.specialEvents.countdown -= deltaTime;
if (gameState.specialEvents.countdown <= 0) {
// 结束特殊事件
if (gameState.specialEvents.eventType === 'spirit_spring') {
gameState.energyGatheringSpeed /= 2; // 取消灵泉加成
}
gameState.specialEvents.active = false;
addEvent('【特殊事件】已结束!');
updateSpecialEventUI();
}
}
// 4. 定期触发特殊事件(大约每10分钟一次)
if (Math.random() < 0.001 * deltaTime) {
triggerSpecialEvent();
}
// 确保数值不为负
gameState.spiritualEnergy = Math.max(0, gameState.spiritualEnergy);
gameState.spiritualStones = Math.max(0, gameState.spiritualStones);
// 更新UI
updateUI();
// 每10秒自动保存一次
if (Math.random() < 0.1 * deltaTime) {
saveGame();
}
// 继续下一次循环
requestAnimationFrame(gameLoop);
}
3. 新手引导功能
// 显示新手引导步骤
function showTutorialStep() {
const step = gameState.tutorialSteps[gameState.tutorialStep];
tutorialMessage.textContent = step;
tutorialOverlay.style.display = 'block';
// 高亮当前引导对应的元素(提升引导效果)
highlightTutorialElement();
}
// 高亮引导元素
function highlightTutorialElement() {
// 先移除所有高亮
document.querySelectorAll('.tutorial-highlight').forEach(el => {
el.classList.remove('tutorial-highlight');
});
// 根据当前引导步骤高亮对应元素
switch (gameState.tutorialStep) {
case 0: // 引导点击修炼
cultivationCircle.classList.add('tutorial-highlight');
break;
case 1: // 引导突破境界
breakthroughBtn.classList.add('tutorial-highlight');
break;
case 2: // 引导采集灵气
gatherBtn.classList.add('tutorial-highlight');
break;
case 3: // 引导商店购物
document.querySelector('.shop').classList.add('tutorial-highlight');
break;
}
}
// 绑定引导按钮事件
function bindTutorialEvents() {
// 下一步按钮
nextTutorialBtn.addEventListener('click', () => {
gameState.tutorialStep++;
if (gameState.tutorialStep < gameState.tutorialSteps.length) {
showTutorialStep();
} else {
// 引导完成
tutorialOverlay.style.display = 'none';
addEvent('新手引导已完成!你现在可以自由探索修仙世界了。');
}
saveGame();
});
// 跳过按钮
skipTutorialBtn.addEventListener('click', () => {
tutorialOverlay.style.display = 'none';
gameState.tutorialStep = gameState.tutorialSteps.length; // 标记为已完成
addEvent('你跳过了新手引导。');
saveGame();
});
}
五、第四步:测试与优化
完成代码编写后,我们需要进行全面测试,确保游戏功能正常、体验流畅。
测试重点
-
功能测试:
- 修炼、突破、采集等核心功能是否正常
- 任务和成就是否能正确触发和完成
- 物品购买和使用是否正常
- 本地存储是否能正确保存和加载
-
边界测试:
- 灵气不足时是否能正常提示
- 突破失败时是否正确损失资源
- 背包为空时是否显示正确提示
- 特殊事件倒计时结束是否正确处理
-
性能测试:
- 游戏循环是否流畅(无卡顿)
- 大量事件日志是否影响性能
- 自动修炼长时间运行是否稳定
优化方向
-
性能优化:
- 减少 DOM 操作频率(批量更新 UI)
- 优化事件绑定(使用事件委托)
- 限制日志数量(避免 DOM 元素过多)
-
体验优化:
- 增加更多动画效果(如物品使用动画)
- 优化响应式布局(确保移动端体验)
- 增加离线收益计算(玩家关闭页面后也能获得收益)
-
功能扩展:
- 增加更多境界和物品
- 添加 PVP 或排行榜功能
- 实现多存档功能
六、总结与扩展
通过本文的学习,我们成功构建了一个功能完整的修仙模拟器,涵盖了前端开发的多个核心知识点:
- HTML 结构设计:语义化布局、功能区域划分
- CSS 样式与动画:渐变、阴影、过渡、关键帧动画
- JavaScript 逻辑:DOM 操作、事件绑定、状态管理、本地存储
- 游戏开发思想:状态机、游戏循环、随机事件、进度系统
扩展建议
-
增加社交功能:
- 实现玩家之间的互动(如赠送物品)
- 添加排行榜系统(展示修为最高的玩家)
-
丰富游戏内容:
- 增加更多境界和修炼体系
- 设计复杂的任务链和隐藏成就
- 添加 BOSS 挑战和副本系统
-
商业化探索(肯定是不能商业的,哈哈哈):
- 实现广告激励(观看广告获得额外奖励)
- 设计内购系统(可选,需遵守相关规定)
-
技术升级:
- 使用框架重构(如 Vue、React),便于维护和扩展
- 实现后端存储(使用 Node.js + MongoDB),支持多设备同步
- 开发移动端版本(使用 PWA 技术)
希望本文能帮助大家掌握前端游戏开发的基本思路和方法,如果你有任何问题或建议,欢迎在评论区交流!






