diff --git a/Script.js b/Script.js index b26d6e6..10be2b1 100644 --- a/Script.js +++ b/Script.js @@ -830,7 +830,12 @@ function addShips() { if (currentWave.spawnTimer <= 0) { spawnEnemyFromWave(currentWave); currentWave.spawned++; - currentWave.spawnTimer = currentWave.spacing; + // --- RANDOM SPACING --- + // Membuat jarak muncul antar musuh bervariasi + // Kadang cepat, kadang ada jeda. + let randomSpacing = + currentWave.spacing + Math.floor(Math.random() * 30); + currentWave.spawnTimer = randomSpacing; } else { currentWave.spawnTimer--; } @@ -850,19 +855,21 @@ function addShips() { } function startNewWave() { - const patterns = ["line", "v", "sine", "scatter"]; - const pattern = patterns[Math.floor(Math.random() * patterns.length)]; + // --- CHAOS WAVE MODE --- + // Tidak ada pattern 'line', 'v', 'zigzag'. + // Kita hanya menentukan jumlah musuh yang akan muncul di wave ini. let baseCount = 3; let scalingCount = Math.floor(game.level / 2); let count = Math.min( - 15, - baseCount + scalingCount + Math.floor(Math.random() * 3) + 20, // Max musuh ditingkatkan sedikit untuk kompensasi sebaran + baseCount + scalingCount + Math.floor(Math.random() * 5) ); - let spacing = Math.max(20, 50 - game.level); + + // Spacing dasar (nanti diacak lagi per musuh) + let spacing = Math.max(15, 40 - game.level); currentWave = { - pattern: pattern, count: count, spacing: spacing, spawned: 0, @@ -871,41 +878,34 @@ function startNewWave() { } function spawnEnemyFromWave(wave) { - const baseY = canvasHeight / 2; - const spread = 250; - const index = wave.spawned; - let y = Math.random() * (canvasHeight - 120) + 60; + // --- POSISI BENAR-BENAR ACAK --- + // Tentukan Y sembarang di area layar + // Area aman: 60px dari atas, 100px dari bawah + const minY = 60; + const maxY = canvasHeight - 120; - if (wave.pattern === "line") { - const step = (spread * 2) / Math.max(1, wave.count - 1); - y = baseY - spread + step * index; - } else if (wave.pattern === "v") { - const centerIndex = (wave.count - 1) / 2; - const offset = (index - centerIndex) * 50; - y = baseY + Math.abs(offset) * 1.2; - } else if (wave.pattern === "sine") { - const angle = (index / wave.count) * Math.PI * 2; - y = baseY + Math.sin(angle) * spread; - } else if (wave.pattern === "scatter") { - y = Math.random() * (canvasHeight - 150) + 75; - } + const y = Math.random() * (maxY - minY) + minY; - y = Math.max(60, Math.min(canvasHeight - 100, y)); + // Random X Offset biar tidak muncul dalam satu garis lurus sempurna + const xOffset = Math.random() * 200; const randomShip = Math.floor(Math.random() * enemyImgArray.length); - // --- KECEPATAN MUSUH DIPERLAMBAT --- - // Lama: 4 + Math.random()*3 + game.level*0.25 (Cepat) - // Baru: 3.5 + Math.random()*2 + game.level*0.1 (Lambat & Scaling Halus) - // Max Speed: 8 (Agar tidak teleportasi) + + // Scaling Speed per 5 Level (0.2 factor) let rawSpeed = 3.5 + Math.random() * 2 + game.level * 0.2; const speed = Math.min(rawSpeed, 8); + // --- RANDOM MOVEMENT TYPE --- + // Setiap musuh melempar dadu sendiri untuk menentukan tipe gerakannya + // 30% kemungkinan gerak gelombang (sine), sisanya lurus. + let movementType = Math.random() < 0.3 ? "sine" : "straight"; + let enemy = new EnemyObj( - canvasWidth + 50, + canvasWidth + 50 + xOffset, // X position + random offset y, speed, enemyImgArray[randomShip], - wave.pattern === "sine" ? "sine" : "straight" + movementType ); // BALANCING HEALTH