balance: 全面提升游戏难度——怪物HP/速度/KPI扣减上调,精力消耗加快,初始HC降至150,波次加量缩间隔,Boss技能冷却12s,自动下一波等待2s
This commit is contained in:
@@ -470,7 +470,7 @@ function PuaPanel({ gameReady, hc, waveStarted }: { gameReady: boolean; hc: numb
|
|||||||
// ── 主游戏页面 ────────────────────────────────────────────────────────────────
|
// ── 主游戏页面 ────────────────────────────────────────────────────────────────
|
||||||
export default function GamePage() {
|
export default function GamePage() {
|
||||||
const gameRef = useRef<{ destroy: (removeCanvas: boolean) => void } | null>(null)
|
const gameRef = useRef<{ destroy: (removeCanvas: boolean) => void } | null>(null)
|
||||||
const [hc, setHc] = useState(200)
|
const [hc, setHc] = useState(150)
|
||||||
const [selectedTower, setSelectedTower] = useState<TowerType | null>(null)
|
const [selectedTower, setSelectedTower] = useState<TowerType | null>(null)
|
||||||
const [gameReady, setGameReady] = useState(false)
|
const [gameReady, setGameReady] = useState(false)
|
||||||
const [waveStarted, setWaveStarted] = useState(false)
|
const [waveStarted, setWaveStarted] = useState(false)
|
||||||
|
|||||||
@@ -321,7 +321,7 @@ export function createGameScene(PhaserLib: typeof Phaser): typeof Phaser.Scene {
|
|||||||
|
|
||||||
// 自动下一波倒计时(ms),-1 表示未激活
|
// 自动下一波倒计时(ms),-1 表示未激活
|
||||||
private autoNextWaveTimer: number = -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 {
|
update(_time: number, delta: number): void {
|
||||||
if (this.manager.gameState !== 'playing' && this.manager.gameState !== 'idle') return
|
if (this.manager.gameState !== 'playing' && this.manager.gameState !== 'idle') return
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export const HUD_HEIGHT = 60
|
|||||||
export const WAVES_PER_MAP = 5
|
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 INITIAL_KPI = 100
|
||||||
export const STAMINA_MAX = 100
|
export const STAMINA_MAX = 100
|
||||||
export const STAMINA_REGEN = 5 // 每秒恢复量
|
export const STAMINA_REGEN = 5 // 每秒恢复量
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ export const DIFFICULTY_MULTIPLIER: Record<DifficultyLevel, {
|
|||||||
bossHp: number
|
bossHp: number
|
||||||
hcReward: number
|
hcReward: number
|
||||||
}> = {
|
}> = {
|
||||||
easy: { enemyCount: 0.7, enemySpeed: 0.8, bossHp: 0.7, hcReward: 1.2 },
|
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 },
|
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 },
|
hard: { enemyCount: 1.5, enemySpeed: 1.35, bossHp: 1.8, hcReward: 0.75 },
|
||||||
}
|
}
|
||||||
|
|
||||||
// 地图1:人力资源部(S型路径)
|
// 地图1:人力资源部(S型路径)
|
||||||
@@ -68,11 +68,11 @@ const MAP1: MapConfig = {
|
|||||||
],
|
],
|
||||||
waveCount: 5,
|
waveCount: 5,
|
||||||
waves: [
|
waves: [
|
||||||
{ enemies: [{ type: 'FreshGraduate', count: 10, interval: 800 }] },
|
{ enemies: [{ type: 'FreshGraduate', count: 14, interval: 650 }] },
|
||||||
{ enemies: [{ type: 'FreshGraduate', count: 8, interval: 700 }, { type: 'OldEmployee', count: 2, interval: 2000 }] },
|
{ enemies: [{ type: 'FreshGraduate', count: 10, interval: 600 }, { type: 'OldEmployee', count: 3, interval: 1800 }] },
|
||||||
{ enemies: [{ type: 'OldEmployee', count: 4, interval: 1800 }, { type: 'TroubleMaker', count: 3, interval: 1500 }] },
|
{ enemies: [{ type: 'OldEmployee', count: 5, interval: 1500 }, { type: 'TroubleMaker', count: 4, interval: 1200 }] },
|
||||||
{ enemies: [{ type: 'FreshGraduate', count: 12, interval: 600 }, { type: 'TroubleMaker', count: 3, 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: 3, interval: 2000 }, { type: 'FreshGraduate', count: 5, interval: 800 }] },
|
{ 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,
|
waveCount: 5,
|
||||||
waves: [
|
waves: [
|
||||||
{ enemies: [{ type: 'FreshGraduate', count: 12, interval: 700 }, { type: 'OldEmployee', count: 2, interval: 2000 }] },
|
{ enemies: [{ type: 'FreshGraduate', count: 15, interval: 600 }, { type: 'OldEmployee', count: 3, interval: 1800 }] },
|
||||||
{ enemies: [{ type: 'OldEmployee', count: 5, interval: 1500 }, { type: 'TroubleMaker', count: 3, interval: 1200 }] },
|
{ enemies: [{ type: 'OldEmployee', count: 6, interval: 1300 }, { type: 'TroubleMaker', count: 4, interval: 1000 }] },
|
||||||
{ enemies: [{ type: 'FreshGraduate', count: 15, interval: 500 }, { 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: 4, interval: 1500 }] },
|
{ 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: 10, interval: 600 }, { type: 'TroubleMaker', count: 5, 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,
|
waveCount: 5,
|
||||||
waves: [
|
waves: [
|
||||||
{ enemies: [{ type: 'OldEmployee', count: 6, interval: 1500 }, { type: 'TroubleMaker', count: 4, 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: 12, interval: 600 }, { type: 'OldEmployee', count: 3, interval: 1500 }] },
|
{ 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: 6, interval: 800 }, { type: 'OldEmployee', count: 4, interval: 1500 }] },
|
{ 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: 5000 }, { type: 'OldEmployee', count: 5, interval: 1200 }, { type: 'FreshGraduate', count: 8, interval: 600 }] },
|
{ 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: 3000 }, { type: 'TroubleMaker', count: 8, interval: 600 }, { type: 'OldEmployee', count: 6, interval: 1000 }] },
|
{ enemies: [{ type: 'BossVP', count: 2, interval: 2500 }, { type: 'TroubleMaker', count: 10, interval: 550 }, { type: 'OldEmployee', count: 7, interval: 900 }] },
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { getRandomQuote } from '../data/quotes'
|
|||||||
import { AudioEngine } from '../AudioEngine'
|
import { AudioEngine } from '../AudioEngine'
|
||||||
|
|
||||||
export class BossVP extends EnemyBase {
|
export class BossVP extends EnemyBase {
|
||||||
private skillTimer: number = 20000
|
private skillTimer: number = 12000 // 技能间隔从20s压缩到12s
|
||||||
private onDestroyTower?: () => void
|
private onDestroyTower?: () => void
|
||||||
private bossLabel!: Phaser.GameObjects.Text
|
private bossLabel!: Phaser.GameObjects.Text
|
||||||
|
|
||||||
@@ -15,7 +15,8 @@ export class BossVP extends EnemyBase {
|
|||||||
speedMultiplier: number = 1.0,
|
speedMultiplier: number = 1.0,
|
||||||
hpMultiplier: 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
|
this.onDestroyTower = onDestroyTower
|
||||||
const bossSize = this.cellW * 1.3
|
const bossSize = this.cellW * 1.3
|
||||||
this.imageSprite.setDisplaySize(bossSize, bossSize)
|
this.imageSprite.setDisplaySize(bossSize, bossSize)
|
||||||
@@ -47,7 +48,7 @@ export class BossVP extends EnemyBase {
|
|||||||
super.update(delta)
|
super.update(delta)
|
||||||
this.skillTimer -= delta
|
this.skillTimer -= delta
|
||||||
if (this.skillTimer <= 0) {
|
if (this.skillTimer <= 0) {
|
||||||
this.skillTimer = 20000
|
this.skillTimer = 12000 // 重置技能冷却
|
||||||
this.triggerOrgRestructure()
|
this.triggerOrgRestructure()
|
||||||
}
|
}
|
||||||
if (this.bossLabel) {
|
if (this.bossLabel) {
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ export class FreshGraduate extends EnemyBase {
|
|||||||
speedMultiplier: number = 1.0,
|
speedMultiplier: number = 1.0,
|
||||||
hpMultiplier: 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') }
|
getQuote(): string { return getRandomQuote('FreshGraduate') }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,9 @@ export class OldEmployee extends EnemyBase {
|
|||||||
speedMultiplier: number = 1.0,
|
speedMultiplier: number = 1.0,
|
||||||
hpMultiplier: number = 1.0
|
hpMultiplier: number = 1.0
|
||||||
) {
|
) {
|
||||||
super(scene, pathPoints, 150, 50, 8, 30, 'enemy-old', speedMultiplier, hpMultiplier)
|
// HP: 150→240, speed: 50→65, kpiDamage: 8→12, hcReward: 30→22, shield: 3→4
|
||||||
this.shieldCount = 3
|
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)
|
this.imageSprite.setDisplaySize(this.cellW * 0.85, this.cellW * 0.85)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ export class TroubleMaker extends EnemyBase {
|
|||||||
speedMultiplier: number = 1.0,
|
speedMultiplier: number = 1.0,
|
||||||
hpMultiplier: 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 {
|
protected override onDeath(): void {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
GAME_WIDTH,
|
GAME_WIDTH,
|
||||||
GAME_HEIGHT,
|
GAME_HEIGHT,
|
||||||
HUD_HEIGHT,
|
HUD_HEIGHT,
|
||||||
|
INITIAL_HC,
|
||||||
INITIAL_KPI,
|
INITIAL_KPI,
|
||||||
} from './constants'
|
} from './constants'
|
||||||
import type { MapConfig } from './data/mapConfigs'
|
import type { MapConfig } from './data/mapConfigs'
|
||||||
@@ -222,7 +223,7 @@ export function renderHUD(scene: Phaser.Scene): {
|
|||||||
|
|
||||||
const hcText = scene.add.text(
|
const hcText = scene.add.text(
|
||||||
GAME_WIDTH - 16, HUD_HEIGHT / 2,
|
GAME_WIDTH - 16, HUD_HEIGHT / 2,
|
||||||
`HC: 200`,
|
`HC: ${INITIAL_HC}`,
|
||||||
{
|
{
|
||||||
fontFamily: "'Press Start 2P', monospace",
|
fontFamily: "'Press Start 2P', monospace",
|
||||||
fontSize: '10px',
|
fontSize: '10px',
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ export abstract class TowerBase {
|
|||||||
const target = this.findTarget(enemies)
|
const target = this.findTarget(enemies)
|
||||||
if (target && this.attackCooldown <= 0) {
|
if (target && this.attackCooldown <= 0) {
|
||||||
this.attack(target)
|
this.attack(target)
|
||||||
this.stamina -= 5
|
this.stamina -= 8 // 精力消耗:5→8,更快进入摸鱼状态
|
||||||
// 应用 PUA 攻速倍率(倍率越高冷却越短)
|
// 应用 PUA 攻速倍率(倍率越高冷却越短)
|
||||||
this.attackCooldown = 1000 / (this.attackSpeed * this._puaSpeedMult)
|
this.attackCooldown = 1000 / (this.attackSpeed * this._puaSpeedMult)
|
||||||
this.updateStaminaBar()
|
this.updateStaminaBar()
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ export class MapTransitionModal {
|
|||||||
|
|
||||||
// KPI & 说明
|
// KPI & 说明
|
||||||
const statsEl = document.createElement('div')
|
const statsEl = document.createElement('div')
|
||||||
statsEl.innerHTML = `最终KPI: <span style="color:#34d399">${kpi}%</span> | <span style="color:#94a3b8">HC 将重置为 200</span>`
|
statsEl.innerHTML = `最终KPI: <span style="color:#34d399">${kpi}%</span> | <span style="color:#94a3b8">HC 将重置为 150</span>`
|
||||||
statsEl.style.cssText = `
|
statsEl.style.cssText = `
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
color: #e2e8f0;
|
color: #e2e8f0;
|
||||||
@@ -131,7 +131,7 @@ export class MapTransitionModal {
|
|||||||
// 倒计时提示(HC 重置提醒)
|
// 倒计时提示(HC 重置提醒)
|
||||||
const countdownEl = document.createElement('div')
|
const countdownEl = document.createElement('div')
|
||||||
countdownEl.id = 'mt-countdown'
|
countdownEl.id = 'mt-countdown'
|
||||||
countdownEl.textContent = isFinalMap ? '3秒后返回主菜单...' : '3秒后进入下一关,HC重置为200...'
|
countdownEl.textContent = isFinalMap ? '3秒后返回主菜单...' : '3秒后进入下一关,HC重置为150...'
|
||||||
countdownEl.style.cssText = `
|
countdownEl.style.cssText = `
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: #6b7280;
|
color: #6b7280;
|
||||||
@@ -157,7 +157,7 @@ export class MapTransitionModal {
|
|||||||
const el = document.getElementById('mt-countdown')
|
const el = document.getElementById('mt-countdown')
|
||||||
if (el) el.textContent = isFinalMap
|
if (el) el.textContent = isFinalMap
|
||||||
? `${remaining}秒后返回主菜单...`
|
? `${remaining}秒后返回主菜单...`
|
||||||
: `${remaining}秒后进入下一关,HC重置为200...`
|
: `${remaining}秒后进入下一关,HC重置为150...`
|
||||||
}
|
}
|
||||||
const interval = setInterval(tick, 1000)
|
const interval = setInterval(tick, 1000)
|
||||||
this.autoCloseTimer = setTimeout(() => {
|
this.autoCloseTimer = setTimeout(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user