tower-defense / src /config /gameConfig.js
victor's picture
victor HF Staff
Refactor tower system and UI improvements
9e6ef9c
import * as THREE from "three";
// Game settings
export const INITIAL_MONEY = 200;
export const INITIAL_LIVES = 10;
// Audio settings
export const AUDIO_CONFIG = {
musicVolume: 0.4, // Background music volume (0-1)
effectsVolume: 0.3, // Sound effects volume (0-1)
musicEnabled: true, // Enable/disable background music
effectsEnabled: true, // Enable/disable sound effects
};
// Tower settings
// Define multiple tower types, keeping the original as "basic"
export const TOWER_TYPES = {
basic: {
key: "basic",
name: "Basic Tower",
type: "basic",
cost: 50,
range: 9,
fireRate: 1.0, // shots per second
damage: 6,
},
slow: {
key: "slow",
name: "Slow Tower",
type: "slow",
cost: 60,
range: 8.5,
fireRate: 0.9,
damage: 4,
// On-hit slow: 40% slow (mult 0.6) for 2.5s, refresh on re-hit
projectileEffect: {
type: "slow",
mult: 0.6,
duration: 2.5,
color: 0x80d8ff,
emissive: 0x104a70,
},
},
sniper: {
key: "sniper",
name: "Sniper Tower",
type: "sniper",
cost: 130,
// 2x the range of basic
range: 18,
// slow fire rate
fireRate: 0.7, // shots per second (reload ≈ 3.33s)
damage: 32, // high damage per shot
// Sniper specific parameters
aimTime: 0.8, // seconds to aim before firing
projectileSpeed: 40, // high-speed dart
// Targeting priority identifier
targetPriority: "closestToExit",
// If target moves out of this threshold (>= range) during aiming, cancel
cancelThreshold: 18,
// Optional chance to pierce; behavior can be extended later
pierceChance: 0.0,
},
electric: {
key: "electric",
name: "Electric Tower",
type: "electric",
cost: 200,
// Set to the smallest tower range (slow tower = 8.5)
range: 8.5, // world units (scene uses world units; 1 cell = 2 units, so ~4.25 cells)
fireRate: 1.0, // shots per second
damage: 25, // per target
maxTargets: 3,
// Persist electric arc visuals for 2 seconds
arcDurationMs: 2000,
// Visual tuning for arcs (can be read by Tower)
arc: {
color: 0x9ad6ff, // light electric blue
coreColor: 0xe6fbff,
thickness: 2,
jitter: 0.25,
segments: 10,
},
// Targeting priority
targetPriority: "closestToExit",
},
};
// Back-compat alias for existing code that expects TOWER_CONFIG
export const TOWER_CONFIG = TOWER_TYPES.basic;
// Projectile settings
export const PROJECTILE_SPEED = 18;
// Upgrade settings
export const UPGRADE_MAX_LEVEL = 5;
export const UPGRADE_START_COST = 40;
export const UPGRADE_COST_SCALE = 1.6;
export const UPGRADE_RANGE_SCALE = 1.1; // +10% per level
export const UPGRADE_RATE_SCALE = 1.15; // +15% per level
export const UPGRADE_DAMAGE_SCALE = 1.12; // +12% per level
export const SELL_REFUND_RATE = 0.7;
// Infinite wave scaling configuration (replaces static WAVES array)
export const WAVE_SCALING = {
// base values (wave 1)
baseCount: 8,
baseHP: 12,
baseSpeed: 3.0,
baseReward: 5,
baseSpawnInterval: 0.8,
// per-wave growth (applied from wave 2 onward)
countPerWave: 3, // +3 enemies each wave
hpMultiplierPerWave: 1.15, // HP *= 1.18 each wave
speedIncrementPerWave: 0.025, // +0.05 speed per wave
rewardMultiplierPerWave: 1.03, // reward *= 1.03 each wave
spawnIntervalDecayPerWave: 0.01, // -0.02s per wave
// safeguards/limits
minSpawnInterval: 0.3,
maxSpeed: 5.5,
roundCountToInt: true,
};
// Compute wave parameters for a given wave number (1-based)
export function getWaveParams(n) {
const w = WAVE_SCALING;
const waveNum = Math.max(1, Math.floor(n));
const countBase = w.baseCount + (waveNum - 1) * w.countPerWave;
const count = w.roundCountToInt
? Math.max(1, Math.round(countBase))
: Math.max(1, countBase);
const hp = Math.max(
1,
Math.round(w.baseHP * Math.pow(w.hpMultiplierPerWave, waveNum - 1))
);
const speed = Math.min(
w.maxSpeed,
w.baseSpeed + (waveNum - 1) * w.speedIncrementPerWave
);
const reward = Math.max(
1,
Math.round(w.baseReward * Math.pow(w.rewardMultiplierPerWave, waveNum - 1))
);
const spawnInterval = Math.max(
w.minSpawnInterval,
w.baseSpawnInterval - (waveNum - 1) * w.spawnIntervalDecayPerWave
);
return { count, hp, speed, reward, spawnInterval };
}
// Path waypoints
export const PATH_POINTS = [
new THREE.Vector3(-24, 0, -24),
new THREE.Vector3(-24, 0, 0),
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(0, 0, 16),
new THREE.Vector3(20, 0, 16),
new THREE.Vector3(26, 0, 26),
];
// Grid settings
export const GROUND_SIZE = 60;
export const GRID_CELL_SIZE = 2;
// Visual settings
export const SCENE_BACKGROUND = 0x202432;
// Road settings
export const ROAD_HALF_WIDTH = 1.5;
export const ROAD_BEVEL_SIZE = 1.2;
export const ROAD_ARC_SEGMENTS = 16;