Spaces:
Running
Running
File size: 4,870 Bytes
b29710c 9e6ef9c b29710c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
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;
|