balance: 全面提升游戏难度——怪物HP/速度/KPI扣减上调,精力消耗加快,初始HC降至150,波次加量缩间隔,Boss技能冷却12s,自动下一波等待2s
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 // 每秒恢复量
|
||||
|
||||
@@ -33,9 +33,9 @@ export const DIFFICULTY_MULTIPLIER: Record<DifficultyLevel, {
|
||||
bossHp: number
|
||||
hcReward: number
|
||||
}> = {
|
||||
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 }] },
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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') }
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -93,7 +93,7 @@ export class MapTransitionModal {
|
||||
|
||||
// KPI & 说明
|
||||
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 = `
|
||||
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(() => {
|
||||
|
||||
Reference in New Issue
Block a user