[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>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', 'SimHei', sans-serif;
background: linear-gradient(135deg, #0f0c29, #302b63, #24243e);
color: #e6e6e6;
line-height: 1.6;
padding: 20px;
min-height: 100vh;
overflow-x: hidden;
}
.container {
max-width: 800px;
margin: 0 auto;
background: rgba(25, 20, 45, 0.92);
border-radius: 18px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8), 0 0 30px rgba(106, 76, 147, 0.3);
padding: 30px;
border: 2px solid #8a5cf5;
position: relative;
overflow: hidden;
backdrop-filter: blur(10px);
}
.container::before {
content: "";
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(138, 92, 245, 0.12) 0%, rgba(25, 20, 45, 0) 70%);
z-index: -1;
}
.container::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background:
radial-gradient(circle at 10% 20%, rgba(255, 255, 255, 0.05) 0%, transparent 20%),
radial-gradient(circle at 90% 80%, rgba(138, 92, 245, 0.1) 0%, transparent 25%);
z-index: -1;
pointer-events: none;
}
header {
text-align: center;
margin-bottom: 25px;
padding-bottom: 20px;
border-bottom: 1px solid #8a5cf5;
position: relative;
}
header::after {
content: "";
position: absolute;
bottom: -1px;
left: 50%;
transform: translateX(-50%);
width: 85%;
height: 3px;
background: linear-gradient(90deg, transparent, #ff6b6b, #ffa502, #4ade80, #4dabf7, transparent);
border-radius: 3px;
box-shadow: 0 0 10px rgba(138, 92, 245, 0.7);
}
h1 {
font-size: 3.2rem;
margin-bottom: 12px;
background: linear-gradient(45deg, #ff6b6b, #ffa502, #4ade80, #4dabf7, #9775fa);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
text-shadow: 0 0 20px rgba(138, 92, 245, 0.5);
letter-spacing: 4px;
position: relative;
font-weight: 800;
}
h1::before, h1::after {
content: "☯";
position: absolute;
font-size: 1.8em;
top: -8px;
animation: float 3.5s ease-in-out infinite;
}
h1::before {
left: -25px;
animation-delay: 0s;
}
h1::after {
right: -25px;
animation-delay: -1.75s;
}
@keyframes float {
0%, 100% { transform: translateY(0) rotate(0deg); }
25% { transform: translateY(-12px) rotate(5deg); }
50% { transform: translateY(0) rotate(0deg); }
75% { transform: translateY(-8px) rotate(-5deg); }
}
.subtitle {
color: #c5aefb;
font-size: 1.2rem;
margin-top: 8px;
letter-spacing: 2px;
text-shadow: 0 0 10px rgba(151, 117, 250, 0.6);
}
.game-info {
background: rgba(35, 30, 65, 0.85);
border-radius: 16px;
padding: 25px;
margin-bottom: 25px;
border: 1px solid #7a4cf0;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.6), inset 0 0 15px rgba(138, 92, 245, 0.2);
position: relative;
overflow: hidden;
}
.game-info::before {
content: "";
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(138, 92, 245, 0.08) 0%, transparent 70%);
z-index: -1;
}
.info-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 18px;
margin-top: 12px;
}
.info-item {
background: rgba(45, 40, 80, 0.75);
padding: 16px 12px;
border-radius: 12px;
text-align: center;
border-left: 3px solid #8a5cf5;
transition: all 0.4s ease;
position: relative;
overflow: hidden;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.info-item::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(180deg, transparent 50%, rgba(0, 0, 0, 0.3) 100%);
z-index: -1;
}
.info-item:hover {
transform: translateY(-3px) scale(1.03);
box-shadow: 0 6px 18px rgba(138, 92, 245, 0.4), 0 0 15px rgba(106, 76, 147, 0.3);
border-left: 3px solid #4ade80;
z-index: 10;
}
.info-label {
font-size: 0.95rem;
color: #b8a9d4;
margin-bottom: 6px;
display: block;
letter-spacing: 1px;
}
.info-value {
font-size: 1.6rem;
font-weight: bold;
color: #ffffff;
text-shadow: 0 0 10px rgba(255, 255, 255, 0.4);
position: relative;
z-index: 2;
}
.level-up {
color: #ffcc00 !important;
animation: pulse-glow 1.8s infinite;
text-shadow: 0 0 15px rgba(255, 204, 0, 0.8);
}
@keyframes pulse-glow {
0% { text-shadow: 0 0 8px rgba(255, 204, 0, 0.6); }
50% { text-shadow: 0 0 25px rgba(255, 204, 0, 1), 0 0 35px rgba(255, 204, 0, 0.8); }
100% { text-shadow: 0 0 8px rgba(255, 204, 0, 0.6); }
}
.max-level {
color: #ff6b6b !important;
animation: max-level-glow 2s infinite;
text-shadow: 0 0 15px rgba(255, 107, 107, 0.8);
}
@keyframes max-level-glow {
0% { text-shadow: 0 0 10px rgba(255, 107, 107, 0.7); }
50% { text-shadow: 0 0 25px rgba(255, 107, 107, 1), 0 0 35px rgba(255, 215, 0, 0.8); }
100% { text-shadow: 0 0 10px rgba(255, 107, 107, 0.7); }
}
.game-log {
background: rgba(20, 15, 40, 0.9);
border-radius: 16px;
padding: 25px;
height: 240px;
overflow-y: auto;
margin-bottom: 25px;
border: 1px solid #5a3cbf;
font-family: 'Microsoft YaHei', 'SimHei', monospace;
line-height: 1.7;
box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.7), 0 5px 15px rgba(0, 0, 0, 0.5);
position: relative;
scrollbar-width: thin;
scrollbar-color: #8a5cf5 #2d254d;
}
.game-log::-webkit-scrollbar {
width: 8px;
}
.game-log::-webkit-scrollbar-track {
background: rgba(40, 35, 70, 0.7);
border-radius: 10px;
}
.game-log::-webkit-scrollbar-thumb {
background: #8a5cf5;
border-radius: 10px;
border: 2px solid rgba(40, 35, 70, 0.7);
}
.log-entry {
padding: 6px 0;
border-bottom: 1px dashed rgba(106, 76, 147, 0.25);
animation: log-fade 0.6s ease-out;
position: relative;
padding-left: 15px;
}
.log-entry::before {
content: "";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 8px;
height: 8px;
border-radius: 50%;
background: currentColor;
opacity: 0.7;
}
@keyframes log-fade {
from {
opacity: 0;
transform: translateX(-10px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.log-entry.combat { color: #ff6b6b; }
.log-entry.gain { color: #4ade80; font-weight: 500; }
.log-entry.event { color: #4dabf7; }
.log-entry.system {
color: #ffcc00;
font-weight: bold;
background: rgba(100, 80, 150, 0.15);
border-radius: 8px;
padding: 8px;
margin: 5px 0;
border-left: 3px solid #ffcc00;
}
.log-entry.warning { color: #ffa502; font-weight: 500; }
.log-entry.heal { color: #5cdb95; }
.btn-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(145px, 1fr));
gap: 18px;
margin-top: 15px;
position: relative;
z-index: 10;
}
.game-btn {
background: linear-gradient(45deg, #5a3cbf, #4a2c9f);
color: white;
border: none;
padding: 18px 12px;
border-radius: 60px;
font-size: 1.25rem;
font-weight: bold;
cursor: pointer;
transition: all 0.35s ease;
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.5), 0 0 20px rgba(90, 60, 191, 0.4);
position: relative;
overflow: hidden;
letter-spacing: 1.5px;
text-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
z-index: 1;
}
.game-btn::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(45deg, #6a4cf0, #5a3cbf, #4a2c9f);
z-index: -1;
transition: transform 0.5s ease;
transform: scaleX(0);
transform-origin: left;
}
.game-btn:hover::before {
transform: scaleX(1);
}
.game-btn:hover {
transform: translateY(-3px) scale(1.05);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.7), 0 0 30px rgba(106, 76, 147, 0.6);
color: #fff;
}
.game-btn:active {
transform: translateY(1px) scale(0.98);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
}
.game-btn:disabled {
opacity: 0.65;
cursor: not-allowed;
transform: none;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4);
}
.game-btn:disabled:hover {
transform: none;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4);
}
.practice-btn {
background: linear-gradient(45deg, #4a2c9f, #3a1c7f);
box-shadow: 0 0 20px rgba(74, 44, 159, 0.5);
}
.practice-btn:hover {
box-shadow: 0 0 25px rgba(90, 60, 191, 0.7), 0 8px 25px rgba(0, 0, 0, 0.6);
}
.fight-btn {
background: linear-gradient(45deg, #c9184a, #800e29);
box-shadow: 0 0 20px rgba(201, 24, 74, 0.55);
}
.fight-btn:hover {
box-shadow: 0 0 30px rgba(255, 107, 107, 0.7), 0 8px 25px rgba(0, 0, 0, 0.6);
}
.item-btn {
background: linear-gradient(45deg, #0d9488, #0a5e56);
box-shadow: 0 0 20px rgba(13, 148, 136, 0.5);
}
.item-btn:hover {
box-shadow: 0 0 25px rgba(74, 222, 128, 0.6), 0 8px 25px rgba(0, 0, 0, 0.6);
}
.reset-btn {
background: linear-gradient(45deg, #64748b, #334155);
grid-column: span 2;
box-shadow: 0 0 15px rgba(100, 116, 139, 0.4);
}
.reset-btn:hover {
box-shadow: 0 0 20px rgba(156, 163, 175, 0.6), 0 8px 25px rgba(0, 0, 0, 0.6);
}
.stop-auto-btn {
background: linear-gradient(45deg, #b91c1c, #7f1d1d);
display: none;
grid-column: span 2;
box-shadow: 0 0 20px rgba(185, 28, 28, 0.5);
}
.stop-auto-btn:hover {
box-shadow: 0 0 25px rgba(248, 113, 113, 0.7), 0 8px 25px rgba(0, 0, 0, 0.6);
}
.auto-fight-active .fight-btn {
animation: pulse-border 2s infinite;
box-shadow: 0 0 25px rgba(255, 107, 107, 0.8), 0 0 40px rgba(255, 215, 0, 0.5);
position: relative;
z-index: 20;
}
@keyframes pulse-border {
0% { box-shadow: 0 0 15px rgba(255, 107, 107, 0.6), 0 0 25px rgba(255, 215, 0, 0.3); }
50% { box-shadow: 0 0 30px rgba(255, 107, 107, 0.9), 0 0 45px rgba(255, 215, 0, 0.7); }
100% { box-shadow: 0 0 15px rgba(255, 107, 107, 0.6), 0 0 25px rgba(255, 215, 0, 0.3); }
}
.notification {
position: fixed;
top: 25px;
right: 25px;
padding: 18px 30px;
background: rgba(40, 35, 70, 0.95);
border-left: 4px solid #4ade80;
border-radius: 12px;
box-shadow: 0 5px 25px rgba(0, 0, 0, 0.6), 0 0 20px rgba(74, 222, 128, 0.3);
transform: translateX(450px);
transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
z-index: 2000;
font-weight: bold;
font-size: 1.1rem;
display: flex;
align-items: center;
gap: 12px;
min-width: 300px;
text-align: center;
}
.notification.show {
transform: translateX(0);
}
.notification.error {
border-left-color: #ef4444;
box-shadow: 0 5px 25px rgba(0, 0, 0, 0.6), 0 0 20px rgba(239, 68, 68, 0.3);
}
.notification.success {
border-left-color: #4ade80;
box-shadow: 0 5px 25px rgba(0, 0, 0, 0.6), 0 0 20px rgba(74, 222, 128, 0.4);
}
.notification.warning {
border-left-color: #f59e0b;
box-shadow: 0 5px 25px rgba(0, 0, 0, 0.6), 0 0 20px rgba(245, 158, 11, 0.35);
}
.notification::before {
content: "•";
font-size: 2.5rem;
position: absolute;
left: 10px;
opacity: 0.3;
font-weight: bold;
}
.save-indicator {
position: fixed;
bottom: 25px;
right: 25px;
background: rgba(30, 25, 55, 0.92);
color: #4ade80;
padding: 12px 25px;
border-radius: 50px;
font-size: 1.1rem;
font-weight: bold;
opacity: 0;
transition: opacity 0.4s ease, transform 0.4s ease;
display: flex;
align-items: center;
gap: 12px;
z-index: 2000;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5), 0 0 15px rgba(74, 222, 128, 0.3);
transform: translateX(200px) scale(0.9);
}
.save-indicator.show {
opacity: 1;
transform: translateX(0) scale(1);
}
.save-indicator::before {
content: "✓";
font-weight: bold;
font-size: 1.5rem;
animation: pop 0.5s ease-out;
}
@keyframes pop {
0% { transform: scale(0.5); opacity: 0.7; }
50% { transform: scale(1.2); opacity: 1; }
100% { transform: scale(1); opacity: 1; }
}
footer {
text-align: center;
margin-top: 25px;
padding-top: 20px;
border-top: 1px solid #6a4cf0;
color: #c5b4e3;
font-size: 1.05rem;
line-height: 1.5;
position: relative;
}
footer::before {
content: "✨";
position: absolute;
top: -10px;
left: 50%;
transform: translateX(-50%);
font-size: 1.5rem;
animation: float 3s ease-in-out infinite;
}
.version-info {
font-size: 0.95rem;
color: #a78bfa;
margin-top: 8px;
font-weight: 500;
}
.tip {
background: rgba(70, 60, 110, 0.6);
display: inline-block;
padding: 3px 10px;
border-radius: 20px;
margin-top: 5px;
font-size: 0.95rem;
}
.cloud {
position: absolute;
background: rgba(255, 255, 255, 0.07);
border-radius: 50%;
filter: blur(8px);
z-index: -2;
opacity: 0.8;
animation: drift 45s linear infinite;
}
@keyframes drift {
0% { transform: translate(0, 0) scale(1); opacity: 0.4; }
50% { opacity: 0.8; }
100% { transform: translate(100vw, 50px) scale(1.2); opacity: 0.3; }
}
.health-bar {
height: 8px;
background: rgba(100, 100, 150, 0.3);
border-radius: 4px;
margin-top: 6px;
overflow: hidden;
position: relative;
}
.health-fill {
height: 100%;
background: linear-gradient(90deg, #ff6b6b, #ffa502);
border-radius: 4px;
width: 100%;
transition: width 0.5s ease;
}
@media (max-width: 650px) {
.container {
padding: 20px 15px;
margin: 10px;
}
h1 {
font-size: 2.5rem;
}
.subtitle {
font-size: 1rem;
}
.btn-container {
grid-template-columns: 1fr;
}
.info-grid {
grid-template-columns: repeat(2, 1fr);
gap: 12px;
}
.game-info, .game-log {
padding: 18px;
}
.game-log {
height: 200px;
}
.game-btn {
padding: 16px 10px;
font-size: 1.15rem;
}
.notification {
min-width: 250px;
padding: 15px 20px;
font-size: 1rem;
}
footer::before {
font-size: 1.2rem;
}
}
@media (max-width: 400px) {
.info-grid {
grid-template-columns: 1fr;
}
h1 {
font-size: 2.2rem;
}
.container {
padding: 15px;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>修仙模拟器</h1>
<p class="subtitle">踏上修仙之路,追求长生大道</p>
</header>
<div class="game-info">
<div class="info-grid">
<div class="info-item">
<span class="info-label">当前境界</span>
<span class="info-value" id="cultivation">炼气期</span>
</div>
<div class="info-item">
<span class="info-label">修为</span>
<span class="info-value" id="cultivation-points">0</span>
<div class="health-bar">
<div class="health-fill" id="cultivation-progress"></div>
</div>
</div>
<div class="info-item">
<span class="info-label">生命值</span>
<span class="info-value" id="hp">100/100</span>
<div class="health-bar">
<div class="health-fill" id="hp-bar"></div>
</div>
</div>
<div class="info-item">
<span class="info-label">灵石</span>
<span class="info-value" id="spirit-stones">0</span>
</div>
<div class="info-item">
<span class="info-label">历练值</span>
<span class="info-value" id="exp">0</span>
</div>
<div class="info-item">
<span class="info-label">回春丹</span>
<span class="info-value" id="healing-pills">3</span>
</div>
</div>
</div>
<div class="game-log" id="game-log">
<div class="log-entry system">☯ 欢迎来到修仙世界!开始你的修仙之旅吧~</div>
<div class="log-entry event">☁ 云雾缭绕的山门前,你深吸一口气,踏入修仙之路...</div>
<div class="log-entry tip">💡 游戏提示:生命值低于30%时无法修炼,战斗失败会损失大量资源</div>
</div>
<div class="btn-container">
<button class="game-btn practice-btn">闭关修炼</button>
<button class="game-btn fight-btn">下山历练</button>
<button class="game-btn item-btn">使用灵药</button>
<button class="game-btn reset-btn">重置游戏</button>
<button class="game-btn stop-auto-btn" id="stop-auto">■ 停止自动战斗</button>
</div>
<footer>
<p>修仙模拟器 v3.0 | 终极修复版</p>
<p class="version-info">✓ 战斗平衡优化 ✓ 生命恢复机制修复 ✓ 境界上限修复 ✓ 自动存档</p>
<p class="tip">键盘快捷键:1=修炼 2=历练 3=灵药 R=重置</p>
</footer>
</div>
<div class="notification" id="notification">
<span id="notification-text"></span>
</div>
<div class="save-indicator" id="save-indicator">
<span>游戏已自动保存</span>
</div>
<script>
// 创建动态云朵背景
function createClouds() {
const container = document.querySelector('.container');
for (let i = 0; i < 8; i++) {
const cloud = document.createElement('div');
cloud.className = 'cloud';
const size = Math.random() * 120 + 60;
cloud.style.width = `${size}px`;
cloud.style.height = `${size * 0.6}px`;
cloud.style.top = `${Math.random() * 100}%`;
cloud.style.left = `${Math.random() * 100 - 100}%`;
cloud.style.opacity = `${Math.random() * 0.3 + 0.1}`;
cloud.style.animationDuration = `${Math.random() * 30 + 30}s`;
cloud.style.animationDelay = `${Math.random() * 10}s`;
container.appendChild(cloud);
}
}
// 修仙者类 - 终极修复版
class Immortal {
constructor() {
// 基础属性
this.cultivationLevel = 0; // 0:炼气, 1:筑基, 2:金丹, 3:元婴, 4:化神, 5:渡劫, 6:大乘, 7:真仙
this.cultivationPoints = 0; // 修为
this.maxCultivationPoints = 100; // 当前境界所需修为
this.hp = 100; // 生命值
this.maxHp = 100;
this.spiritStones = 0; // 灵石
this.exp = 0; // 历练值
this.autoFight = false; // 自动战斗标志
this.items = {
healingPills: 3 // 回复药数量
};
// 境界名称(增加真仙之上境界)
this.cultivationStages = [
"炼气期", "筑基期", "金丹期", "元婴期",
"化神期", "渡劫期", "大乘期", "真仙境",
"金仙境", "太乙境", "大罗境", "道祖境"
];
// 怪物库(调整数值平衡)
this.monsters = [
{ name: "野猪", baseHp: 30, baseDamage: 5, baseExp: 10, baseStones: 5, basePoints: 15, levelReq: 0 },
{ name: "山贼", baseHp: 45, baseDamage: 8, baseExp: 18, baseStones: 9, basePoints: 22, levelReq: 0 },
{ name: "狼王", baseHp: 70, baseDamage: 12, baseExp: 30, baseStones: 14, basePoints: 35, levelReq: 1 },
{ name: "妖狐", baseHp: 100, baseDamage: 16, baseExp: 45, baseStones: 22, basePoints: 55, levelReq: 2 },
{ name: "黑风怪", baseHp: 160, baseDamage: 22, baseExp: 70, baseStones: 35, basePoints: 90, levelReq: 3 },
{ name: "火云邪神", baseHp: 250, baseDamage: 30, baseExp: 120, baseStones: 60, basePoints: 160, levelReq: 4 },
{ name: "千年树妖", baseHp: 380, baseDamage: 40, baseExp: 200, baseStones: 100, basePoints: 280, levelReq: 5 },
{ name: "魔龙", baseHp: 550, baseDamage: 55, baseExp: 320, baseStones: 160, basePoints: 450, levelReq: 6 },
{ name: "九尾天狐", baseHp: 750, baseDamage: 70, baseExp: 480, baseStones: 240, basePoints: 650, levelReq: 7 },
{ name: "混沌魔神", baseHp: 1000, baseDamage: 90, baseExp: 700, baseStones: 350, basePoints: 950, levelReq: 8 },
{ name: "太古龙皇", baseHp: 1400, baseDamage: 115, baseExp: 1000, baseStones: 500, basePoints: 1350, levelReq: 9 },
{ name: "天道化身", baseHp: 2000, baseDamage: 150, baseExp: 1500, baseStones: 750, basePoints: 2000, levelReq: 10 }
];
// 初始化界面
this.updateUI();
}
// 从存档加载
loadFromSave(saveData) {
if (saveData) {
this.cultivationLevel = Math.min(saveData.cultivationLevel || 0, this.cultivationStages.length - 1);
this.cultivationPoints = saveData.cultivationPoints || 0;
this.maxCultivationPoints = saveData.maxCultivationPoints || 100;
this.hp = Math.min(saveData.hp || 100, this.maxHp || 100);
this.maxHp = saveData.maxHp || 100;
this.spiritStones = saveData.spiritStones || 0;
this.exp = saveData.exp || 0;
this.items = saveData.items || { healingPills: 3 };
this.autoFight = false; // 加载时重置自动战斗状态
// 兼容旧存档
if (!this.items.healingPills) {
this.items.healingPills = 3;
}
// 修复可能的境界越界问题
if (this.cultivationLevel >= this.cultivationStages.length) {
this.cultivationLevel = this.cultivationStages.length - 1;
this.log("system", "⚠ 检测到境界数据异常,已修正为最高境界");
}
this.log("system", "☯ 游戏进度已加载!");
this.updateUI();
}
}
// 保存游戏
saveGame() {
const saveData = {
cultivationLevel: this.cultivationLevel,
cultivationPoints: this.cultivationPoints,
maxCultivationPoints: this.maxCultivationPoints,
hp: this.hp,
maxHp: this.maxHp,
spiritStones: this.spiritStones,
exp: this.exp,
items: this.items,
timestamp: new Date().toISOString(),
version: "3.0"
};
try {
localStorage.setItem('immortalGameSave', JSON.stringify(saveData));
this.showSaveIndicator();
} catch (e) {
console.error("保存游戏失败:", e);
this.log("warning", "⚠ 游戏保存失败,请清理浏览器存储空间");
}
}
// 显示保存指示器
showSaveIndicator() {
const indicator = document.getElementById('save-indicator');
indicator.classList.add('show');
setTimeout(() => {
indicator.classList.remove('show');
}, 2500);
}
// 更新界面
updateUI() {
// 境界显示(处理最高境界)
const cultivationEl = document.getElementById('cultivation');
if (this.cultivationLevel >= this.cultivationStages.length - 1) {
cultivationEl.textContent = "道祖境(圆满)";
cultivationEl.className = "info-value max-level";
} else {
cultivationEl.textContent = this.cultivationStages[this.cultivationLevel] || "凡人";
cultivationEl.className = "info-value";
}
// 修为显示
document.getElementById('cultivation-points').textContent = this.cultivationPoints;
// 生命值显示
document.getElementById('hp').textContent = `${this.hp}/${this.maxHp}`;
// 更新生命条
const hpPercent = Math.max(0, Math.min(100, Math.floor((this.hp / this.maxHp) * 100)));
document.getElementById('hp-bar').style.width = `${hpPercent}%`;
// 更新修为进度条
const progressPercent = Math.min(100, Math.floor((this.cultivationPoints / this.maxCultivationPoints) * 100));
document.getElementById('cultivation-progress').style.width = `${progressPercent}%`;
// 其他资源
document.getElementById('spirit-stones').textContent = this.spiritStones;
document.getElementById('exp').textContent = this.exp;
document.getElementById('healing-pills').textContent = this.items.healingPills;
// 更新按钮状态
const practiceBtn = document.querySelector('.practice-btn');
practiceBtn.disabled = (this.hp < this.maxHp * 0.35 || this.autoFight);
if (this.hp < this.maxHp * 0.35) {
practiceBtn.title = "生命值过低,无法修炼";
} else if (this.autoFight) {
practiceBtn.title = "自动战斗中,无法修炼";
} else {
practiceBtn.title = "";
}
}
// 添加日志
log(type, message) {
const logElement = document.getElementById('game-log');
const entry = document.createElement('div');
entry.className = `log-entry ${type}`;
entry.textContent = `• ${message}`;
logElement.appendChild(entry);
logElement.scrollTop = logElement.scrollHeight;
// 限制日志数量,防止内存泄漏
const entries = logElement.querySelectorAll('.log-entry');
if (entries.length > 100) {
logElement.removeChild(entries[0]);
}
}
// 闭关修炼
practice() {
// 严格检查生命值(修复bug:生命过低无法修炼)
if (this.hp < this.maxHp * 0.35) {
this.log("warning", "⚠ 你伤势过重,心神不宁,无法静心修炼!");
this.showNotification("生命值低于35%,无法修炼!", "error");
return;
}
if (this.autoFight) {
this.showNotification("请先停止自动战斗!", "warning");
return;
}
// 根据境界计算修炼收益(调整平衡)
const basePoints = 8 + Math.floor(this.cultivationLevel * 3);
const cultivationGain = Math.floor(basePoints * (1 + this.cultivationLevel * 0.25));
const spiritStonesGain = Math.floor(Math.random() * 4) + 2;
const hpCost = Math.floor(12 * (1 + this.cultivationLevel * 0.18));
// 扣除生命值
this.hp = Math.max(1, this.hp - hpCost);
// 获得修为和灵石
this.cultivationPoints += cultivationGain;
this.spiritStones += spiritStonesGain;
// 记录日志
this.log("gain", `✨ 闭关修炼:获得 ${cultivationGain} 修为,${spiritStonesGain} 灵石`);
this.log("event", `💔 修炼消耗:损失 ${hpCost} 点生命值(当前生命: ${this.hp}/${this.maxHp})`);
// 检查升级
this.checkLevelUp();
// 更新界面和保存
this.updateUI();
this.saveGame();
}
// 检查是否升级
checkLevelUp() {
// 修复bug:真仙期后变凡人(境界越界)
if (this.cultivationLevel >= this.cultivationStages.length - 1) {
// 已达到最高境界,将多余修为转换为灵石
if (this.cultivationPoints >= this.maxCultivationPoints) {
const extraPoints = this.cultivationPoints - this.maxCultivationPoints;
const stoneConversion = Math.floor(extraPoints * 0.8);
this.cultivationPoints = this.maxCultivationPoints;
this.spiritStones += stoneConversion;
this.log("gain", `💫 修为圆满:将多余修为转换为 ${stoneConversion} 灵石`);
this.log("system", "🌟 你已达天道巅峰,修为已臻至化境!");
}
return;
}
// 正常升级流程
if (this.cultivationPoints >= this.maxCultivationPoints) {
const oldLevel = this.cultivationLevel;
this.cultivationLevel++;
this.log("system", `🎉 恭喜!突破至 ${this.cultivationStages[this.cultivationLevel] || "更高境界"}!`);
// 重置修为,设置新的上限(调整增长倍数,避免后期数值爆炸)
const oldMax = this.maxCultivationPoints;
this.cultivationPoints -= oldMax;
this.maxCultivationPoints = Math.floor(oldMax * 2.2); // 降低增长倍数
// 恢复并提升生命值(调整提升幅度)
const oldMaxHp = this.maxHp;
this.maxHp = Math.floor(oldMaxHp * 1.65); // 降低提升倍数
this.hp = this.maxHp;
// 奖励灵石(调整奖励)
const stoneReward = Math.floor(40 * Math.pow(1.45, this.cultivationLevel));
this.spiritStones += stoneReward;
this.log("gain", `🎁 境界突破奖励:${stoneReward} 灵石,生命上限提升至 ${this.maxHp}!`);
// 50%几率获得灵药
if (Math.random() > 0.5) {
const pills = Math.floor(Math.random() * 2) + 1;
this.items.healingPills += pills;
this.log("gain", `🌿 突破时感悟天道:获得 ${pills} 颗回春丹!`);
}
// 偶尔获得大量灵石(高等级时)
if (this.cultivationLevel > 4 && Math.random() > 0.75) {
const bigReward = Math.floor(100 * Math.pow(1.3, this.cultivationLevel));
this.spiritStones += bigReward;
this.log("gain", `💰 天道馈赠:获得 ${bigReward} 灵石!`);
}
// 更新UI,添加升级特效
const cultivationEl = document.getElementById('cultivation');
cultivationEl.classList.add('level-up');
setTimeout(() => {
cultivationEl.classList.remove('level-up');
}, 3000);
this.updateUI();
}
}
// 下山历练(战斗)- 修复战斗平衡
fightMonster() {
// 检查生命值
if (this.hp <= 0) {
this.log("warning", "❌ 你已重伤濒死,无法继续战斗!");
this.showNotification("生命值为0,无法战斗!", "error");
this.autoFight = false;
document.getElementById('stop-auto').style.display = 'none';
document.querySelector('.container').classList.remove('auto-fight-active');
return;
}
// 禁用按钮防止重复点击
const fightBtn = document.querySelector('.fight-btn');
const stopBtn = document.getElementById('stop-auto');
fightBtn.disabled = true;
// 显示停止按钮
if (this.autoFight) {
stopBtn.style.display = 'block';
}
// 选择合适的怪物(修复:根据境界选择,避免越级太多)
const availableMonsters = this.monsters.filter(m =>
m.levelReq <= this.cultivationLevel &&
m.levelReq >= Math.max(0, this.cultivationLevel - 3)
);
const monsterIndex = Math.floor(Math.random() * availableMonsters.length);
const baseMonster = availableMonsters[monsterIndex];
const monster = {...baseMonster};
// 根据玩家境界调整怪物强度(修复:更平滑的难度曲线)
if (this.cultivationLevel > 0) {
const levelDiff = this.cultivationLevel - monster.levelReq;
const multiplier = 1 + (levelDiff * 0.35); // 降低增长倍数
monster.hp = Math.floor(monster.baseHp * multiplier);
monster.damage = Math.floor(monster.baseDamage * (0.6 + levelDiff * 0.15)); // 大幅降低伤害增长
monster.exp = Math.floor(monster.baseExp * multiplier * 0.9);
monster.spiritStones = Math.floor(monster.baseStones * multiplier * 0.85);
monster.cultivationPoints = Math.floor(monster.basePoints * multiplier * 1.1);
} else {
monster.hp = monster.baseHp;
monster.damage = monster.baseDamage;
monster.exp = monster.baseExp;
monster.spiritStones = monster.baseStones;
monster.cultivationPoints = monster.basePoints;
}
this.log("combat", `⚔ 遭遇 ${monster.name}!(HP: ${monster.hp}, 伤害: ${monster.damage})`);
// 战斗动画延迟
setTimeout(() => {
// 计算玩家伤害(修复:大幅提高玩家伤害,特别是高等级)
const baseDamage = 25 + this.cultivationLevel * 18; // 提高基础伤害和增长
const randomFactor = Math.random() * 15;
const playerDamage = Math.floor(baseDamage + randomFactor);
// 怪物实际伤害(增加玩家境界减免)
const damageReduction = Math.min(0.7, this.cultivationLevel * 0.08); // 最高70%减伤
const actualMonsterDamage = Math.floor(monster.damage * (1 - damageReduction) * (0.7 + Math.random() * 0.4));
// 玩家攻击
let monsterHp = monster.hp - playerDamage;
this.log("combat", `💥 你施展神通:对 ${monster.name} 造成 ${playerDamage} 点伤害!`);
// 怪物反击
if (monsterHp > 0) {
this.hp = Math.max(0, this.hp - actualMonsterDamage);
this.log("combat", `💔 ${monster.name} 反击:造成 ${actualMonsterDamage} 点伤害!(当前生命: ${this.hp}/${this.maxHp})`);
}
// 战斗结果
if (monsterHp <= 0 || playerDamage > monster.hp * 0.85) {
// 胜利
this.log("combat", `✅ 战斗胜利!成功击败 ${monster.name}`);
// 奖励
this.exp += monster.exp;
this.spiritStones += monster.spiritStones;
this.cultivationPoints += monster.cultivationPoints;
this.log("gain", `🏆 战利品:${monster.exp} 历练,${monster.spiritStones} 灵石,${monster.cultivationPoints} 修为`);
// 60%几率获得灵药(提高几率)
if (Math.random() > 0.4) {
const pills = Math.floor(Math.random() * 2) + 1;
this.items.healingPills += pills;
this.log("gain", `🌿 战场搜寻:获得 ${pills} 颗回春丹!`);
}
// 检查升级
this.checkLevelUp();
// 胜利后恢复(修复bug:大幅降低恢复量,避免被利用)
const victoryHeal = Math.floor(this.maxHp * 0.06); // 仅恢复6%
const actualHeal = Math.min(victoryHeal, this.maxHp - this.hp);
if (actualHeal > 0) {
this.hp += actualHeal;
this.log("heal", `✨ 调息恢复:生命值恢复 ${actualHeal} 点`);
}
} else {
// 失败
this.log("combat", `❌ 战斗失败!被 ${monster.name} 击退`);
this.log("event", "🛡 你身受重伤,勉强逃回山门...");
// 失败惩罚:重置生命为25%(修复bug:不再额外恢复)
this.hp = Math.max(1, Math.floor(this.maxHp * 0.25));
// 损失资源(增加惩罚)
const lostStones = Math.floor(this.spiritStones * 0.35); // 35%灵石
const lostExp = Math.floor(this.exp * 0.25); // 25%历练
this.spiritStones = Math.max(0, this.spiritStones - lostStones);
this.exp = Math.max(0, this.exp - lostExp);
if (lostStones > 0 || lostExp > 0) {
this.log("event", `💸 逃亡损失:${lostStones} 灵石,${lostExp} 历练值`);
}
// 15%几率丢失灵药
if (this.items.healingPills > 0 && Math.random() > 0.85) {
const lostPills = Math.min(2, Math.floor(this.items.healingPills * 0.5) + 1);
this.items.healingPills = Math.max(0, this.items.healingPills - lostPills);
this.log("event", `💊 逃亡中丢失:${lostPills} 颗回春丹`);
}
}
// 更新界面
this.updateUI();
this.saveGame();
// 重新启用按钮
setTimeout(() => {
fightBtn.disabled = false;
}, 300);
// 如果开启自动战斗且玩家还活着,继续下一场战斗
if (this.autoFight && this.hp > 0) {
setTimeout(() => {
if (this.autoFight) {
this.fightMonster();
}
}, 1800);
} else {
// 停止自动战斗
this.autoFight = false;
stopBtn.style.display = 'none';
document.querySelector('.container').classList.remove('auto-fight-active');
}
}, 900);
}
// 使用灵药
useItem() {
if (this.autoFight) {
this.showNotification("请先停止自动战斗!", "warning");
return;
}
if (this.items.healingPills <= 0) {
this.log("warning", "❌ 背包中没有回春丹了!");
this.showNotification("没有可用的灵药!", "error");
return;
}
if (this.hp >= this.maxHp) {
this.log("event", "😊 你的状态极佳,无需使用灵药");
this.showNotification("生命值已满!", "warning");
return;
}
// 使用灵药
this.items.healingPills--;
const healAmount = Math.floor(this.maxHp * 0.65); // 65%恢复
const actualHeal = Math.min(healAmount, this.maxHp - this.hp);
this.hp += actualHeal;
this.log("heal", `🌿 使用回春丹:生命值恢复 ${actualHeal} 点(当前: ${this.hp}/${this.maxHp})`);
this.updateUI();
this.saveGame();
// 小几率额外恢复
if (Math.random() > 0.85) {
const extraHeal = Math.floor(this.maxHp * 0.1);
this.hp = Math.min(this.maxHp, this.hp + extraHeal);
this.log("heal", `✨ 灵药效果超常:额外恢复 ${extraHeal} 点生命!`);
this.updateUI();
}
}
// 显示通知
showNotification(message, type = "success") {
const notification = document.getElementById('notification');
const textElement = document.getElementById('notification-text');
textElement.textContent = message;
notification.className = `notification ${type}`;
notification.classList.add('show');
// 自动隐藏
setTimeout(() => {
notification.classList.remove('show');
}, 3500);
}
// 重置游戏
resetGame() {
if (confirm("确定要重置游戏吗?所有进度将会永久丢失!")) {
localStorage.removeItem('immortalGameSave');
// 重置所有属性
this.cultivationLevel = 0;
this.cultivationPoints = 0;
this.maxCultivationPoints = 100;
this.hp = 100;
this.maxHp = 100;
this.spiritStones = 0;
this.exp = 0;
this.items = { healingPills: 3 };
this.autoFight = false;
// 清空日志
const logElement = document.getElementById('game-log');
logElement.innerHTML = `
<div class="log-entry system">☯ 欢迎来到修仙世界!开始你的修仙之旅吧~</div>
<div class="log-entry event">☁ 云雾缭绕的山门前,你深吸一口气,踏入修仙之路...</div>
<div class="log-entry tip">💡 游戏提示:生命值低于30%时无法修炼,战斗失败会损失大量资源</div>
`;
this.log("system", "☯ 游戏已重置,踏上新的修仙征程!");
this.updateUI();
this.showNotification("游戏已重置!", "success");
}
}
// 开始自动战斗
startAutoFight() {
if (this.hp < this.maxHp * 0.4) {
this.showNotification("生命值过低,无法开始自动战斗!", "error");
return;
}
this.autoFight = true;
document.querySelector('.container').classList.add('auto-fight-active');
document.getElementById('stop-auto').style.display = 'block';
this.log("system", "⚡ 已开启自动历练模式!每场战斗间隔1.8秒");
this.log("warning", "⚠ 战斗中请勿关闭页面,生命值过低会自动停止");
this.fightMonster();
}
// 停止自动战斗
stopAutoFight() {
this.autoFight = false;
document.querySelector('.container').classList.remove('auto-fight-active');
document.getElementById('stop-auto').style.display = 'none';
this.log("system", "⏸ 已停止自动历练模式");
this.updateUI(); // 确保按钮状态更新
}
}
// 初始化游戏
function initGame() {
createClouds();
// 创建游戏角色
const player = new Immortal();
window.player = player; // 使player全局可访问(用于调试)
// 尝试加载存档
const savedGame = localStorage.getItem('immortalGameSave');
if (savedGame) {
try {
const saveData = JSON.parse(savedGame);
player.loadFromSave(saveData);
// 显示加载信息
setTimeout(() => {
player.showNotification(`进度已加载!当前境界:${player.cultivationStages[Math.min(player.cultivationLevel, player.cultivationStages.length-1)]}`, "success");
}, 800);
} catch (e) {
console.error("加载存档失败", e);
player.log("warning", "⚠ 存档损坏,已开始新游戏");
player.showNotification("存档损坏,已开始新游戏", "error");
}
} else {
player.log("event", "🌟 你站在青云山脚下,前方是漫漫修仙路...");
player.log("event", "📚 闭关修炼可提升修为,下山历练可获取资源,灵药可恢复生命");
player.log("tip", "💡 提示:生命值低于35%时无法修炼,战斗失败会损失资源");
}
// 设置按钮事件监听
document.querySelector('.practice-btn').addEventListener('click', () => {
player.practice();
});
document.querySelector('.fight-btn').addEventListener('click', () => {
if (player.autoFight) {
player.showNotification("自动战斗进行中...", "warning");
return;
}
player.startAutoFight();
});
document.querySelector('.item-btn').addEventListener('click', () => {
player.useItem();
});
document.querySelector('.reset-btn').addEventListener('click', () => {
player.resetGame();
});
document.getElementById('stop-auto').addEventListener('click', () => {
player.stopAutoFight();
});
// 添加键盘快捷键
document.addEventListener('keydown', (e) => {
// 阻止默认行为,避免页面滚动等
if (['1', '2', '3', 'r', 'R'].includes(e.key)) {
e.preventDefault();
}
if (e.key === '1') player.practice();
if (e.key === '2') {
if (player.autoFight) {
player.stopAutoFight();
} else {
player.startAutoFight();
}
}
if (e.key === '3') player.useItem();
if (e.key === 'r' || e.key === 'R') player.resetGame();
});
// 页面可见性改变时保存游戏
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
player.saveGame();
player.log("system", "💾 页面隐藏,游戏已自动保存");
}
});
// 离开页面前保存
window.addEventListener('beforeunload', () => {
player.saveGame();
});
// 初始提示
setTimeout(() => {
player.showNotification("游戏加载完成!按1/2/3使用快捷键", "success");
}, 1200);
// 每5分钟自动保存一次
setInterval(() => {
if (!player.autoFight) {
player.saveGame();
}
}, 300000);
}
// 页面加载完成后初始化
window.addEventListener('DOMContentLoaded', initGame);
// 防止页面刷新丢失数据
window.addEventListener('unload', () => {
if (window.player) {
window.player.saveGame();
}
});
</script>
</body>
</html>