From 4fec1ebe9d750a88b03d14e57bea812b03d8c821 Mon Sep 17 00:00:00 2001 From: Cloud Bot Date: Tue, 24 Mar 2026 08:56:14 +0000 Subject: [PATCH] =?UTF-8?q?balance:=20=E5=85=A8=E9=9D=A2=E6=8F=90=E5=8D=87?= =?UTF-8?q?=E6=B8=B8=E6=88=8F=E9=9A=BE=E5=BA=A6=E2=80=94=E2=80=94=E6=80=AA?= =?UTF-8?q?=E7=89=A9HP/=E9=80=9F=E5=BA=A6/KPI=E6=89=A3=E5=87=8F=E4=B8=8A?= =?UTF-8?q?=E8=B0=83=EF=BC=8C=E7=B2=BE=E5=8A=9B=E6=B6=88=E8=80=97=E5=8A=A0?= =?UTF-8?q?=E5=BF=AB=EF=BC=8C=E5=88=9D=E5=A7=8BHC=E9=99=8D=E8=87=B3150?= =?UTF-8?q?=EF=BC=8C=E6=B3=A2=E6=AC=A1=E5=8A=A0=E9=87=8F=E7=BC=A9=E9=97=B4?= =?UTF-8?q?=E9=9A=94=EF=BC=8CBoss=E6=8A=80=E8=83=BD=E5=86=B7=E5=8D=B412s?= =?UTF-8?q?=EF=BC=8C=E8=87=AA=E5=8A=A8=E4=B8=8B=E4=B8=80=E6=B3=A2=E7=AD=89?= =?UTF-8?q?=E5=BE=852s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/game/page.tsx | 2 +- game/GameScene.ts | 2 +- game/constants.ts | 2 +- game/data/mapConfigs.ts | 36 +++++++++++++++++------------------ game/enemies/BossVP.ts | 7 ++++--- game/enemies/FreshGraduate.ts | 3 ++- game/enemies/OldEmployee.ts | 5 +++-- game/enemies/TroubleMaker.ts | 3 ++- game/mapRenderer.ts | 3 ++- game/towers/TowerBase.ts | 2 +- game/ui/MapTransitionModal.ts | 6 +++--- 11 files changed, 38 insertions(+), 33 deletions(-) diff --git a/app/game/page.tsx b/app/game/page.tsx index a74865c..cc57ef9 100644 --- a/app/game/page.tsx +++ b/app/game/page.tsx @@ -470,7 +470,7 @@ function PuaPanel({ gameReady, hc, waveStarted }: { gameReady: boolean; hc: numb // ── 主游戏页面 ──────────────────────────────────────────────────────────────── export default function GamePage() { const gameRef = useRef<{ destroy: (removeCanvas: boolean) => void } | null>(null) - const [hc, setHc] = useState(200) + const [hc, setHc] = useState(150) const [selectedTower, setSelectedTower] = useState(null) const [gameReady, setGameReady] = useState(false) const [waveStarted, setWaveStarted] = useState(false) diff --git a/game/GameScene.ts b/game/GameScene.ts index f4181ba..05f64ff 100644 --- a/game/GameScene.ts +++ b/game/GameScene.ts @@ -321,7 +321,7 @@ export function createGameScene(PhaserLib: typeof Phaser): typeof Phaser.Scene { // 自动下一波倒计时(ms),-1 表示未激活 private autoNextWaveTimer: number = -1 - private readonly AUTO_WAVE_DELAY = 3000 // 3 秒后自动开始 + private readonly AUTO_WAVE_DELAY = 2000 // 自动开始等待:3s→2s,缩短喘息时间 update(_time: number, delta: number): void { if (this.manager.gameState !== 'playing' && this.manager.gameState !== 'idle') return diff --git a/game/constants.ts b/game/constants.ts index bb2a8f9..7547106 100644 --- a/game/constants.ts +++ b/game/constants.ts @@ -12,7 +12,7 @@ export const HUD_HEIGHT = 60 export const WAVES_PER_MAP = 5 // 游戏初始数值 -export const INITIAL_HC = 200 +export const INITIAL_HC = 150 // 降低初始HC:200→150,提高前期资源压力 export const INITIAL_KPI = 100 export const STAMINA_MAX = 100 export const STAMINA_REGEN = 5 // 每秒恢复量 diff --git a/game/data/mapConfigs.ts b/game/data/mapConfigs.ts index ccdc911..3aa991a 100644 --- a/game/data/mapConfigs.ts +++ b/game/data/mapConfigs.ts @@ -33,9 +33,9 @@ export const DIFFICULTY_MULTIPLIER: Record = { - easy: { enemyCount: 0.7, enemySpeed: 0.8, bossHp: 0.7, hcReward: 1.2 }, - normal: { enemyCount: 1.0, enemySpeed: 1.0, bossHp: 1.0, hcReward: 1.0 }, - hard: { enemyCount: 1.4, enemySpeed: 1.3, bossHp: 1.5, hcReward: 0.8 }, + easy: { enemyCount: 0.7, enemySpeed: 0.85, bossHp: 0.7, hcReward: 1.1 }, + normal: { enemyCount: 1.0, enemySpeed: 1.0, bossHp: 1.0, hcReward: 1.0 }, + hard: { enemyCount: 1.5, enemySpeed: 1.35, bossHp: 1.8, hcReward: 0.75 }, } // 地图1:人力资源部(S型路径) @@ -68,11 +68,11 @@ const MAP1: MapConfig = { ], waveCount: 5, waves: [ - { enemies: [{ type: 'FreshGraduate', count: 10, interval: 800 }] }, - { enemies: [{ type: 'FreshGraduate', count: 8, interval: 700 }, { type: 'OldEmployee', count: 2, interval: 2000 }] }, - { enemies: [{ type: 'OldEmployee', count: 4, interval: 1800 }, { type: 'TroubleMaker', count: 3, interval: 1500 }] }, - { enemies: [{ type: 'FreshGraduate', count: 12, interval: 600 }, { type: 'TroubleMaker', count: 3, interval: 1200 }] }, - { enemies: [{ type: 'BossVP', count: 1, interval: 0 }, { type: 'OldEmployee', count: 3, interval: 2000 }, { type: 'FreshGraduate', count: 5, interval: 800 }] }, + { enemies: [{ type: 'FreshGraduate', count: 14, interval: 650 }] }, + { enemies: [{ type: 'FreshGraduate', count: 10, interval: 600 }, { type: 'OldEmployee', count: 3, interval: 1800 }] }, + { enemies: [{ type: 'OldEmployee', count: 5, interval: 1500 }, { type: 'TroubleMaker', count: 4, interval: 1200 }] }, + { enemies: [{ type: 'FreshGraduate', count: 16, interval: 500 }, { type: 'TroubleMaker', count: 4, interval: 1000 }] }, + { enemies: [{ type: 'BossVP', count: 1, interval: 0 }, { type: 'OldEmployee', count: 4, interval: 1800 }, { type: 'FreshGraduate', count: 8, interval: 700 }] }, ], } @@ -111,11 +111,11 @@ const MAP2: MapConfig = { ], waveCount: 5, waves: [ - { enemies: [{ type: 'FreshGraduate', count: 12, interval: 700 }, { type: 'OldEmployee', count: 2, interval: 2000 }] }, - { enemies: [{ type: 'OldEmployee', count: 5, interval: 1500 }, { type: 'TroubleMaker', count: 3, interval: 1200 }] }, - { enemies: [{ type: 'FreshGraduate', count: 15, interval: 500 }, { type: 'TroubleMaker', count: 4, interval: 1000 }] }, - { enemies: [{ type: 'BossVP', count: 1, interval: 0 }, { type: 'OldEmployee', count: 4, interval: 1500 }] }, - { enemies: [{ type: 'BossVP', count: 1, interval: 0 }, { type: 'FreshGraduate', count: 10, interval: 600 }, { type: 'TroubleMaker', count: 5, interval: 1000 }] }, + { enemies: [{ type: 'FreshGraduate', count: 15, interval: 600 }, { type: 'OldEmployee', count: 3, interval: 1800 }] }, + { enemies: [{ type: 'OldEmployee', count: 6, interval: 1300 }, { type: 'TroubleMaker', count: 4, interval: 1000 }] }, + { enemies: [{ type: 'FreshGraduate', count: 18, interval: 450 }, { type: 'TroubleMaker', count: 5, interval: 900 }] }, + { enemies: [{ type: 'BossVP', count: 1, interval: 0 }, { type: 'OldEmployee', count: 5, interval: 1300 }, { type: 'TroubleMaker', count: 3, interval: 1000 }] }, + { enemies: [{ type: 'BossVP', count: 1, interval: 0 }, { type: 'FreshGraduate', count: 14, interval: 500 }, { type: 'TroubleMaker', count: 6, interval: 850 }] }, ], } @@ -154,11 +154,11 @@ const MAP3: MapConfig = { ], waveCount: 5, waves: [ - { enemies: [{ type: 'OldEmployee', count: 6, interval: 1500 }, { type: 'TroubleMaker', count: 4, interval: 1000 }] }, - { enemies: [{ type: 'BossVP', count: 1, interval: 0 }, { type: 'FreshGraduate', count: 12, interval: 600 }, { type: 'OldEmployee', count: 3, interval: 1500 }] }, - { enemies: [{ type: 'BossVP', count: 1, interval: 0 }, { type: 'TroubleMaker', count: 6, interval: 800 }, { type: 'OldEmployee', count: 4, interval: 1500 }] }, - { enemies: [{ type: 'BossVP', count: 2, interval: 5000 }, { type: 'OldEmployee', count: 5, interval: 1200 }, { type: 'FreshGraduate', count: 8, interval: 600 }] }, - { enemies: [{ type: 'BossVP', count: 2, interval: 3000 }, { type: 'TroubleMaker', count: 8, interval: 600 }, { type: 'OldEmployee', count: 6, interval: 1000 }] }, + { enemies: [{ type: 'OldEmployee', count: 7, interval: 1300 }, { type: 'TroubleMaker', count: 5, interval: 900 }] }, + { enemies: [{ type: 'BossVP', count: 1, interval: 0 }, { type: 'FreshGraduate', count: 16, interval: 500 }, { type: 'OldEmployee', count: 4, interval: 1300 }] }, + { enemies: [{ type: 'BossVP', count: 1, interval: 0 }, { type: 'TroubleMaker', count: 8, interval: 700 }, { type: 'OldEmployee', count: 5, interval: 1200 }] }, + { enemies: [{ type: 'BossVP', count: 2, interval: 4000 }, { type: 'OldEmployee', count: 6, interval: 1100 }, { type: 'FreshGraduate', count: 12, interval: 500 }] }, + { enemies: [{ type: 'BossVP', count: 2, interval: 2500 }, { type: 'TroubleMaker', count: 10, interval: 550 }, { type: 'OldEmployee', count: 7, interval: 900 }] }, ], } diff --git a/game/enemies/BossVP.ts b/game/enemies/BossVP.ts index f3156c4..01265a6 100644 --- a/game/enemies/BossVP.ts +++ b/game/enemies/BossVP.ts @@ -4,7 +4,7 @@ import { getRandomQuote } from '../data/quotes' import { AudioEngine } from '../AudioEngine' export class BossVP extends EnemyBase { - private skillTimer: number = 20000 + private skillTimer: number = 12000 // 技能间隔从20s压缩到12s private onDestroyTower?: () => void private bossLabel!: Phaser.GameObjects.Text @@ -15,7 +15,8 @@ export class BossVP extends EnemyBase { speedMultiplier: number = 1.0, hpMultiplier: number = 1.0 ) { - super(scene, pathPoints, 800, 40, 30, 150, 'enemy-boss', speedMultiplier, hpMultiplier) + // HP: 800→1200, speed: 40→55, kpiDamage: 30→40, hcReward: 150→100 + super(scene, pathPoints, 1200, 55, 40, 100, 'enemy-boss', speedMultiplier, hpMultiplier) this.onDestroyTower = onDestroyTower const bossSize = this.cellW * 1.3 this.imageSprite.setDisplaySize(bossSize, bossSize) @@ -47,7 +48,7 @@ export class BossVP extends EnemyBase { super.update(delta) this.skillTimer -= delta if (this.skillTimer <= 0) { - this.skillTimer = 20000 + this.skillTimer = 12000 // 重置技能冷却 this.triggerOrgRestructure() } if (this.bossLabel) { diff --git a/game/enemies/FreshGraduate.ts b/game/enemies/FreshGraduate.ts index a741a95..245327a 100644 --- a/game/enemies/FreshGraduate.ts +++ b/game/enemies/FreshGraduate.ts @@ -9,7 +9,8 @@ export class FreshGraduate extends EnemyBase { speedMultiplier: number = 1.0, hpMultiplier: number = 1.0 ) { - super(scene, pathPoints, 30, 120, 2, 10, 'enemy-fresh', speedMultiplier, hpMultiplier) + // HP: 30→50, speed: 120→145, kpiDamage: 2→3, hcReward: 10→8 + super(scene, pathPoints, 50, 145, 3, 8, 'enemy-fresh', speedMultiplier, hpMultiplier) } getQuote(): string { return getRandomQuote('FreshGraduate') } } diff --git a/game/enemies/OldEmployee.ts b/game/enemies/OldEmployee.ts index d88db60..32f6cad 100644 --- a/game/enemies/OldEmployee.ts +++ b/game/enemies/OldEmployee.ts @@ -9,8 +9,9 @@ export class OldEmployee extends EnemyBase { speedMultiplier: number = 1.0, hpMultiplier: number = 1.0 ) { - super(scene, pathPoints, 150, 50, 8, 30, 'enemy-old', speedMultiplier, hpMultiplier) - this.shieldCount = 3 + // HP: 150→240, speed: 50→65, kpiDamage: 8→12, hcReward: 30→22, shield: 3→4 + super(scene, pathPoints, 240, 65, 12, 22, 'enemy-old', speedMultiplier, hpMultiplier) + this.shieldCount = 4 this.imageSprite.setDisplaySize(this.cellW * 0.85, this.cellW * 0.85) } diff --git a/game/enemies/TroubleMaker.ts b/game/enemies/TroubleMaker.ts index 1835b23..2ef03e7 100644 --- a/game/enemies/TroubleMaker.ts +++ b/game/enemies/TroubleMaker.ts @@ -10,7 +10,8 @@ export class TroubleMaker extends EnemyBase { speedMultiplier: number = 1.0, hpMultiplier: number = 1.0 ) { - super(scene, pathPoints, 80, 80, 5, 20, 'enemy-trouble', speedMultiplier, hpMultiplier) + // HP: 80→130, speed: 80→100, kpiDamage: 5→7, hcReward: 20→15 + super(scene, pathPoints, 130, 100, 7, 15, 'enemy-trouble', speedMultiplier, hpMultiplier) } protected override onDeath(): void { diff --git a/game/mapRenderer.ts b/game/mapRenderer.ts index d7ff1b2..0a042bd 100644 --- a/game/mapRenderer.ts +++ b/game/mapRenderer.ts @@ -5,6 +5,7 @@ import { GAME_WIDTH, GAME_HEIGHT, HUD_HEIGHT, + INITIAL_HC, INITIAL_KPI, } from './constants' import type { MapConfig } from './data/mapConfigs' @@ -222,7 +223,7 @@ export function renderHUD(scene: Phaser.Scene): { const hcText = scene.add.text( GAME_WIDTH - 16, HUD_HEIGHT / 2, - `HC: 200`, + `HC: ${INITIAL_HC}`, { fontFamily: "'Press Start 2P', monospace", fontSize: '10px', diff --git a/game/towers/TowerBase.ts b/game/towers/TowerBase.ts index 87c5460..965ab05 100644 --- a/game/towers/TowerBase.ts +++ b/game/towers/TowerBase.ts @@ -98,7 +98,7 @@ export abstract class TowerBase { const target = this.findTarget(enemies) if (target && this.attackCooldown <= 0) { this.attack(target) - this.stamina -= 5 + this.stamina -= 8 // 精力消耗:5→8,更快进入摸鱼状态 // 应用 PUA 攻速倍率(倍率越高冷却越短) this.attackCooldown = 1000 / (this.attackSpeed * this._puaSpeedMult) this.updateStaminaBar() diff --git a/game/ui/MapTransitionModal.ts b/game/ui/MapTransitionModal.ts index 8a50dd7..76f0588 100644 --- a/game/ui/MapTransitionModal.ts +++ b/game/ui/MapTransitionModal.ts @@ -93,7 +93,7 @@ export class MapTransitionModal { // KPI & 说明 const statsEl = document.createElement('div') - statsEl.innerHTML = `最终KPI: ${kpi}%  |  HC 将重置为 200` + statsEl.innerHTML = `最终KPI: ${kpi}%  |  HC 将重置为 150` statsEl.style.cssText = ` font-size: 20px; color: #e2e8f0; @@ -131,7 +131,7 @@ export class MapTransitionModal { // 倒计时提示(HC 重置提醒) const countdownEl = document.createElement('div') countdownEl.id = 'mt-countdown' - countdownEl.textContent = isFinalMap ? '3秒后返回主菜单...' : '3秒后进入下一关,HC重置为200...' + countdownEl.textContent = isFinalMap ? '3秒后返回主菜单...' : '3秒后进入下一关,HC重置为150...' countdownEl.style.cssText = ` font-size: 16px; color: #6b7280; @@ -157,7 +157,7 @@ export class MapTransitionModal { const el = document.getElementById('mt-countdown') if (el) el.textContent = isFinalMap ? `${remaining}秒后返回主菜单...` - : `${remaining}秒后进入下一关,HC重置为200...` + : `${remaining}秒后进入下一关,HC重置为150...` } const interval = setInterval(tick, 1000) this.autoCloseTimer = setTimeout(() => {