Spaces:
Running
Running
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; | |