This commit is contained in:
Bluwww 2025-12-16 08:41:46 +07:00
parent 1cbd757ddb
commit dbeb74692d

View File

@ -51,7 +51,7 @@ var game = {
surge: 1.0,
surgePhase: 0,
surgeTimer: 0,
surgeCooldown: 2400, // Start with 40s cooldown
surgeCooldown: 2400,
};
var keys = {
@ -75,7 +75,6 @@ laserPickupImg.src = "img/Skills/double-missile.png";
// *** GAMBAR BARU UNTUK PICKUP BOMB ***
var bombPickupImg = new Image();
// Pastikan file gambar bom clay Anda disimpan di sini
bombPickupImg.src = "img/Skills/bomb.png";
var livesImg = new Image();
@ -138,8 +137,6 @@ let currentPlanet = null;
let laserSprite, enemyBulletSprite, missileSprite;
function preRenderAssets() {
// 1. CACHE LASER BULLET
// Padding for shadowBlur (15px)
const lPad = 20;
const lW = 13 + lPad * 2;
const lH = 4 + lPad * 2;
@ -159,7 +156,6 @@ function preRenderAssets() {
lCtx.fillRect(lPad, lPad, 13, 4);
// 2. CACHE ENEMY BULLET
const ePad = 15;
const eW = 10 + ePad * 2;
const eH = 4 + ePad * 2;
@ -168,7 +164,7 @@ function preRenderAssets() {
enemyBulletSprite.height = eH;
const eCtx = enemyBulletSprite.getContext("2d");
let eg = eCtx.createLinearGradient(ePad + 10, ePad, ePad, ePad); // Right to Left
let eg = eCtx.createLinearGradient(ePad + 10, ePad, ePad, ePad);
eg.addColorStop(0, "#ff9900");
eg.addColorStop(0.5, "#ffffff");
eg.addColorStop(1, "#ff3300");
@ -179,7 +175,6 @@ function preRenderAssets() {
eCtx.fillRect(ePad, ePad, 10, 4);
// 3. CACHE PLAYER MISSILE (Body Only)
const mPad = 5;
const mW = 30 + mPad * 2;
const mH = 12 + mPad * 2;
@ -196,8 +191,8 @@ function preRenderAssets() {
mCtx.fillStyle = mg;
mCtx.beginPath();
mCtx.moveTo(mPad, mPad);
mCtx.lineTo(mPad + 30, mPad + 6); // height/2
mCtx.lineTo(mPad, mPad + 12); // height
mCtx.lineTo(mPad + 30, mPad + 6);
mCtx.lineTo(mPad, mPad + 12);
mCtx.fill();
}
@ -206,7 +201,7 @@ window.onload = function () {
};
function init() {
preRenderAssets(); // Generate sprites before game starts
preRenderAssets();
c = document.getElementById("canvas");
ctx = c.getContext("2d", { alpha: false });
@ -311,7 +306,6 @@ function fireBullet() {
}
laser.currentTime = 0;
// IMPORTANT!! EXPERIMENT WITH THIS VALUE
laser.volume = 0.2;
laser.play();
createParticles(
@ -639,7 +633,7 @@ function drawUI() {
drawNewText(game.level, canvasWidth - 140, 50, "#00ff00", "30px");
// Lives (Stacked Icons)
const lifeSize = 40; // Scaled down from 104px source
const lifeSize = 40;
const lifePadding = 5;
if (livesImg.complete) {
@ -843,7 +837,7 @@ class backgroundObj {
this.height = 900;
this.img = img;
this.img = img;
this.factor = speed; // Rename speed to factor for parallax
this.factor = speed;
}
draw() {
ctx.save();
@ -938,11 +932,9 @@ class PlayerMissile {
draw() {
ctx.save();
// Draw Cached Missile Body
const padding = 5;
ctx.drawImage(missileSprite, this.x - padding, this.y - padding);
// TRAIL BIRU LANGIT
if (Math.random() < 0.5) {
createParticles(this.x, this.y + this.height / 2, 2, "#00bfff");
}
@ -1101,7 +1093,6 @@ function addShips() {
if (currentWave.spawnTimer <= 0) {
spawnEnemyFromWave(currentWave);
currentWave.spawned++;
// --- RANDOM SPACING ---
let randomSpacing =
currentWave.spacing + Math.floor(Math.random() * 30);
currentWave.spawnTimer = randomSpacing;
@ -1129,7 +1120,7 @@ function startNewWave() {
let baseCount = 3;
let scalingCount = Math.floor(game.level / 2);
let count = Math.min(
20, // Max musuh ditingkatkan sedikit untuk kompensasi sebaran
20,
baseCount + scalingCount + Math.floor(Math.random() * 5)
);
@ -1145,15 +1136,12 @@ function startNewWave() {
}
function spawnEnemyFromWave(wave) {
// --- POSISI BENAR-BENAR ACAK ---
// Tentukan Y sembarang di area layar
// Area aman: 60px dari atas, 100px dari bawah
// --- POSISI MUSUH ACAK ---
const minY = 60;
const maxY = canvasHeight - 120;
const y = Math.random() * (maxY - minY) + minY;
// Random X Offset biar tidak muncul dalam satu garis lurus sempurna
const xOffset = Math.random() * 200;
const randomShip = Math.floor(Math.random() * enemyImgArray.length);
@ -1162,20 +1150,18 @@ function spawnEnemyFromWave(wave) {
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 + xOffset, // X position + random offset
canvasWidth + 50 + xOffset,
y,
speed,
enemyImgArray[randomShip],
movementType
);
// BALANCING HEALTH
// ENEMY HEALTH
enemy.health = 60 + game.level * 10;
enemyShipArray.push(enemy);
@ -1186,10 +1172,9 @@ class AbilityToken {
constructor(x, y) {
this.x = x;
this.y = y;
this.width = 40; // Ukuran sedikit diperbesar untuk gambar
this.width = 40;
this.height = 40;
this.speed = 4;
// RAND: 0-0.33=Bomb, 0.33-0.66=Double, 0.66-1.0=Missile
let r = Math.random();
if (r < 0.33) this.type = "bomb";
else if (r < 0.66) this.type = "double";
@ -1199,7 +1184,6 @@ class AbilityToken {
draw() {
ctx.save();
// --- GAYA METAL SLUG (KOTAK PUTIH TEBAL) UNTUK SEMUA TIPE PICKUP ---
ctx.strokeStyle = "#ffffff";
ctx.lineWidth = 3;
ctx.strokeRect(this.x, this.y, this.width, this.height);
@ -1212,7 +1196,6 @@ class AbilityToken {
} else if (this.type === "double") {
imgToDraw = laserPickupImg;
} else if (this.type === "bomb") {
// GUNAKAN GAMBAR BOM PICKUP YANG BARU
imgToDraw = bombPickupImg;
}
@ -1436,14 +1419,12 @@ function drawScreenShading() {
}
// --- BRIGHTNESS SURGE OVERLAY ---
// Use 'hard-light' or 'screen' to make dark backgrounds brighter
if (game.surge > 1.0) {
let intensity = (game.surge - 1.0) / (7.0 - 1.0); // Normalized 0 to 1
let intensity = (game.surge - 1.0) / (7.0 - 1.0);
if (intensity > 0) {
ctx.save();
ctx.globalCompositeOperation = "hard-light"; // Better for space haze
ctx.globalCompositeOperation = "hard-light";
ctx.fillStyle = "white";
// Intensity 0.0 to 1.0 -> Alpha 0.0 to 0.4
ctx.globalAlpha = intensity * 0.4;
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
ctx.restore();
@ -1452,9 +1433,9 @@ function drawScreenShading() {
}
function updateSurge() {
const RAMP_UP_FRAMES = 240; // 4 seconds
const HOLD_FRAMES = 780; // 13 seconds
const RAMP_DOWN_FRAMES = 300;// 5 seconds
const RAMP_UP_FRAMES = 240;
const HOLD_FRAMES = 780;
const RAMP_DOWN_FRAMES = 300;
const MAX_SURGE_SPEED = 7.0;
// Phase 0: Cooldown
@ -1726,16 +1707,12 @@ musicBtns.forEach(btn => {
btn.addEventListener('click', () => {
playSound(menuClickSound);
// Remove active from all
musicBtns.forEach(b => b.classList.remove('active'));
// Add active to clicked
btn.classList.add('active');
// Update setting
gameSettings.musicEnabled = btn.dataset.music === 'on';
// Apply immediately if in game
if (typeof currentBGM !== 'undefined') {
if (gameSettings.musicEnabled) {
currentBGM.volume = 1;
@ -1755,13 +1732,10 @@ sfxBtns.forEach(btn => {
btn.addEventListener('click', () => {
playSound(menuClickSound);
// Remove active from all
sfxBtns.forEach(b => b.classList.remove('active'));
// Add active to clicked
btn.classList.add('active');
// Update setting
gameSettings.sfxEnabled = btn.dataset.sfx === 'on';
});
});
@ -1824,7 +1798,6 @@ document.addEventListener('keydown', (e) => {
// === MODIFY EXISTING GAME FUNCTIONS ===
// Override window.onload
window.onload = function () {
console.log('Game Ready - Waiting for menu start...');
};