User prompt
reducir la cantidada de disparos de los enemigos
User prompt
reduce un 50% la cantidad de disparos de los enemigos, son demasiados los disparon que hacen los enemigos
User prompt
ahora deseo que los numeros de disparos de lso enemigos se reduzcan un 50%
Code edit (1 edits merged)
Please save this source code
User prompt
Musical Space Invaders
Initial prompt
quiero crear un juego al estilo space invaders con tematicas de naves espaciales musicales
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Drop = Container.expand(function (dropType) { var self = Container.call(this); self.dropType = dropType; var dropGraphics = self.attachAsset(dropType, { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.update = function () { self.y += self.speed; }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.health = 1; self.shootTimer = 0; var waveReduction = (currentWave - 1) * 60; // Reduce by 1 second (60 frames) per wave var minInterval = Math.max(60, 360 - waveReduction); // Minimum 1 second interval var maxInterval = Math.max(120, 600 - waveReduction); // Minimum 2 second max interval self.shootInterval = minInterval + Math.random() * (maxInterval - minInterval); // Dynamic interval based on wave level self.moveSpeed = 2; self.note = 0; // Musical note value self.update = function () { self.shootTimer++; if (self.shootTimer >= self.shootInterval) { self.shoot(); self.shootTimer = 0; var waveReduction = (currentWave - 1) * 60; // Reduce by 1 second (60 frames) per wave var minInterval = Math.max(60, 360 - waveReduction); // Minimum 1 second interval var maxInterval = Math.max(120, 600 - waveReduction); // Minimum 2 second max interval self.shootInterval = minInterval + Math.random() * (maxInterval - minInterval); // Dynamic interval based on wave level } // Add subtle horizontal sway movement for more fluid feel if (LK.ticks % 180 === 0) { var sideMovement = (Math.random() - 0.5) * 60; var targetX = Math.max(50, Math.min(1998, self.x + sideMovement)); tween(self, { x: targetX }, { duration: 1500 + Math.random() * 1000, easing: tween.easeInOut }); } }; self.shoot = function () { var bullet = new EnemyBullet(); bullet.x = self.x; bullet.y = self.y + 20; enemyBullets.push(bullet); game.addChild(bullet); }; self.takeDamage = function (damage) { self.health -= damage * rhythmMultiplier; if (self.health <= 0) { // Drop system - chance to drop items var dropChance = Math.random() * 100; if (dropChance < 2) { // 2% chance for powerup1 var drop = new Drop('powerup1'); drop.x = self.x; drop.y = self.y; drops.push(drop); game.addChild(drop); } else if (dropChance < 3) { // 1% chance for powerup2 var drop = new Drop('powerup2'); drop.x = self.x; drop.y = self.y; drops.push(drop); game.addChild(drop); } else if (dropChance < 4) { // 1% chance for lifeup var drop = new Drop('lifeup'); drop.x = self.x; drop.y = self.y; drops.push(drop); game.addChild(drop); } self.destroy(); return true; } return false; }; return self; }); var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 4; self.update = function () { self.y += self.speed; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 1.0 }); self.speed = 8; self.lives = 3; self.canShoot = true; self.shootCooldown = 0; self.update = function () { if (self.shootCooldown > 0) { self.shootCooldown--; if (self.shootCooldown <= 0) { self.canShoot = true; } } // Keep player within screen bounds if (self.x < 60) self.x = 60; if (self.x > 2048 - 60) self.x = 2048 - 60; }; self.shoot = function () { if (!self.canShoot) return false; self.canShoot = false; self.shootCooldown = 15; // Determine number of bullets based on powerup var bulletCount = 1; if (currentPowerup === 'powerup1') { bulletCount = 3; } // Create bullets for (var i = 0; i < bulletCount; i++) { var bullet = new PlayerBullet(currentPowerup); if (bulletCount === 1) { bullet.x = self.x; } else { bullet.x = self.x + (i - 1) * 30; // Spread bullets } bullet.y = self.y - 40; playerBullets.push(bullet); game.addChild(bullet); } LK.getSound('shoot').play(); // 1 in 20 chance to play rhythmBonus sound if (Math.random() < 0.05) { LK.getSound('rhythmBonus').play(); } // Check if shooting in rhythm var timeSinceLastBeat = LK.ticks * 16.67 % beatInterval; var rhythmWindow = beatInterval * 0.15; if (timeSinceLastBeat < rhythmWindow || timeSinceLastBeat > beatInterval - rhythmWindow) { rhythmMultiplier = Math.min(rhythmMultiplier + 0.1, 2.0); } else { rhythmMultiplier = Math.max(rhythmMultiplier - 0.05, 1.0); } return true; }; return self; }); var PlayerBullet = Container.expand(function (bulletType) { var self = Container.call(this); self.bulletType = bulletType || 'normal'; var assetName = 'playerBullet'; if (self.bulletType === 'powerup1') { assetName = 'powebullet1'; } else if (self.bulletType === 'powerup2') { assetName = 'powerbullet2'; } var bulletGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); self.speed = -12; self.damage = 1; self.piercing = self.bulletType === 'powerup2'; self.update = function () { self.y += self.speed; }; return self; }); var SuperBoss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('superboss', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3, tint: 0xff0000 }); self.health = 100; self.maxHealth = 100; self.shootTimer = 0; var waveReduction = (currentWave - 1) * 60; // Reduce by 1 second (60 frames) per wave var minInterval = Math.max(60, 180 - waveReduction); // Minimum 1 second interval var maxInterval = Math.max(120, 480 - waveReduction); // Minimum 2 second max interval self.shootInterval = minInterval + Math.random() * (maxInterval - minInterval); // Dynamic interval based on wave level self.moveSpeed = 1; self.moveDirection = 1; self.update = function () { // Boss movement - side to side self.x += self.moveSpeed * self.moveDirection; if (self.x <= 200 || self.x >= 1848) { self.moveDirection *= -1; } // Boss shooting self.shootTimer++; if (self.shootTimer >= self.shootInterval) { self.shoot(); self.shootTimer = 0; var waveReduction = (currentWave - 1) * 60; // Reduce by 1 second (60 frames) per wave var minInterval = Math.max(60, 180 - waveReduction); // Minimum 1 second interval var maxInterval = Math.max(120, 480 - waveReduction); // Minimum 2 second max interval self.shootInterval = minInterval + Math.random() * (maxInterval - minInterval); // Dynamic interval based on wave level } // Update boss color based on health var healthPercent = self.health / self.maxHealth; if (healthPercent > 0.6) { bossGraphics.tint = 0xff0000; // Red } else if (healthPercent > 0.3) { bossGraphics.tint = 0xff8800; // Orange } else { bossGraphics.tint = 0xffff00; // Yellow } }; self.shoot = function () { // Shoot multiple bullets in different directions for (var i = -2; i <= 2; i++) { var bullet = new EnemyBullet(); bullet.x = self.x + i * 50; bullet.y = self.y + 50; bullet.speed = 3 + Math.abs(i) * 0.5; enemyBullets.push(bullet); game.addChild(bullet); } }; self.takeDamage = function (damage) { self.health -= damage * rhythmMultiplier; LK.effects.flashObject(self, 0xffffff, 100); if (self.health <= 0) { self.destroy(); return true; } return false; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000011 }); /**** * Game Code ****/ var gameStarted = false; var startButton = game.addChild(LK.getAsset('start', { anchorX: 0.5, anchorY: 0.5, scaleX: 4, scaleY: 4 })); startButton.x = 1024; // Center horizontally startButton.y = 1366; // Center vertically var player = game.addChild(new Player()); player.x = 1024; player.y = 2600; player.visible = false; // Hide player until game starts var playerBullets = []; var enemyBullets = []; var enemies = []; var currentWave = 1; var enemiesKilled = 0; var totalEnemiesInWave = 0; var waveStarted = false; var waveDelay = 0; var rhythmMultiplier = 1.0; var beatInterval = 500; // milliseconds var lastBeatTime = 0; var enemyFormationX = 0; var enemyFormationDirection = 1; var enemyDropDistance = 60; var shouldDropEnemies = false; var superBoss = null; var bossActive = false; var bossDefeated = false; var drops = []; var currentPowerup = null; // Sound management for bonus sounds var currentBonusSoundName = null; var currentBonusSoundTimeout = null; var bonusSounds = ['bonusmusic', 'bonusmusic2', 'bonusmusic3', 'bonusmusic4', 'bonusmusic5']; function playRandomBonusSound() { // Only play if no bonus sound is currently playing if (currentBonusSoundName === null) { var randomSoundName = bonusSounds[Math.floor(Math.random() * bonusSounds.length)]; var randomSound = LK.getSound(randomSoundName); currentBonusSoundName = randomSoundName; randomSound.play(); // Clear any existing timeout if (currentBonusSoundTimeout !== null) { LK.clearTimeout(currentBonusSoundTimeout); } // Set a longer timeout to ensure sound finishes before allowing new ones // Using 2500ms to be safe that the sound completes currentBonusSoundTimeout = LK.setTimeout(function () { currentBonusSoundName = null; currentBonusSoundTimeout = null; }, 2500); } } // UI Elements var scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); scoreTxt.x = 20; scoreTxt.y = 20; LK.gui.topLeft.addChild(scoreTxt); var livesTxt = new Text2('Lives: 3', { size: 60, fill: 0xFFFFFF }); livesTxt.anchor.set(1, 0); livesTxt.x = -20; livesTxt.y = 20; LK.gui.topRight.addChild(livesTxt); var waveTxt = new Text2('Wave: 1', { size: 60, fill: 0xFFFFFF }); waveTxt.anchor.set(0.5, 0); waveTxt.x = 0; waveTxt.y = 20; LK.gui.top.addChild(waveTxt); var rhythmTxt = new Text2('Rhythm: 1.0x', { size: 50, fill: 0xFFFF00 }); rhythmTxt.anchor.set(0.5, 0); rhythmTxt.x = 0; rhythmTxt.y = 100; LK.gui.top.addChild(rhythmTxt); function createWave(waveNumber) { enemies = []; enemiesKilled = 0; var rows = 3 + Math.floor(waveNumber / 3); var cols = 8 + Math.floor(waveNumber / 2); totalEnemiesInWave = rows * cols; var startX = (2048 - cols * 100) / 2; var startY = 200; for (var row = 0; row < rows; row++) { for (var col = 0; col < cols; col++) { var enemy = new Enemy(); enemy.x = startX + col * 100; enemy.y = startY + row * 80; enemy.note = (row * cols + col) % 12; // Assign musical notes enemies.push(enemy); game.addChild(enemy); } } enemyFormationX = 0; enemyFormationDirection = 1; waveStarted = true; // Increase tempo with each wave beatInterval = Math.max(300, 500 - waveNumber * 20); } function updateEnemyFormation() { if (enemies.length === 0) return; var moveDistance = 4 + Math.floor(currentWave / 2); var shouldMove = LK.ticks % Math.max(1, 20 - currentWave * 1.5) === 0; if (shouldMove) { if (shouldDropEnemies) { // Drop enemies down for (var i = 0; i < enemies.length; i++) { enemies[i].y += enemyDropDistance; } shouldDropEnemies = false; } else { // Move all enemies horizontally in synchronized formation using tween var hitEdge = false; var targetDirection = moveDistance * enemyFormationDirection; // Check if any enemy would hit the edge for (var i = 0; i < enemies.length; i++) { var newX = enemies[i].x + targetDirection; if (newX <= 50 || newX >= 1998) { hitEdge = true; break; } } // Move all enemies together with synchronized tween animation for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; tween(enemy, { x: enemy.x + targetDirection }, { duration: 300, easing: tween.easeInOut }); } if (hitEdge) { enemyFormationDirection *= -1; shouldDropEnemies = true; } } } } function checkCollisions() { // Player bullets vs enemies for (var i = playerBullets.length - 1; i >= 0; i--) { var bullet = playerBullets[i]; var bulletHit = false; for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (bullet.intersects(enemy)) { if (enemy.takeDamage(bullet.damage)) { enemies.splice(j, 1); enemiesKilled++; var baseScore = 100 * Math.floor(rhythmMultiplier); LK.setScore(LK.getScore() + baseScore); LK.getSound('enemyHit').play(); // Play random bonus sound effect with 15% chance if (Math.random() < 0.15) { playRandomBonusSound(); } LK.effects.flashObject(enemy, 0xffffff, 200); } if (!bullet.piercing) { bullet.destroy(); playerBullets.splice(i, 1); bulletHit = true; break; } else { bulletHit = false; // Allow piercing bullets to continue } } } // Player bullets vs super boss if (!bulletHit && superBoss && bullet.intersects(superBoss)) { if (superBoss.takeDamage(bullet.damage)) { superBoss = null; bossActive = false; bossDefeated = true; var bossScore = 5000 * Math.floor(rhythmMultiplier); LK.setScore(LK.getScore() + bossScore); LK.getSound('enemyHit').play(); // Play random bonus sound effect with 15% chance if (Math.random() < 0.15) { playRandomBonusSound(); } } if (!bullet.piercing) { bullet.destroy(); playerBullets.splice(i, 1); bulletHit = true; } } if (!bulletHit && bullet.y < -20) { bullet.destroy(); playerBullets.splice(i, 1); } } // Player vs drops for (var i = drops.length - 1; i >= 0; i--) { var drop = drops[i]; if (drop.intersects(player)) { if (drop.dropType === 'lifeup') { player.lives = Math.min(player.lives + 1, 5); } else { currentPowerup = drop.dropType; } drop.destroy(); drops.splice(i, 1); } else if (drop.y > 2732) { drop.destroy(); drops.splice(i, 1); } } // Enemy bullets vs player for (var i = enemyBullets.length - 1; i >= 0; i--) { var bullet = enemyBullets[i]; if (bullet.intersects(player)) { player.lives--; currentPowerup = null; // Reset powerup when player loses a life bullet.destroy(); enemyBullets.splice(i, 1); LK.getSound('playerHit').play(); LK.effects.flashObject(player, 0xff0000, 500); if (player.lives <= 0) { LK.showGameOver(); return; } } else if (bullet.y > 2732) { bullet.destroy(); enemyBullets.splice(i, 1); } } // Check if enemies reached player for (var i = 0; i < enemies.length; i++) { if (enemies[i].y > 2500) { LK.showGameOver(); return; } } // Check if super boss reached player if (superBoss && superBoss.y > 2500) { LK.showGameOver(); return; } } function updateUI() { scoreTxt.setText('Score: ' + LK.getScore()); livesTxt.setText('Lives: ' + player.lives); waveTxt.setText('Wave: ' + currentWave); rhythmTxt.setText('Rhythm: ' + rhythmMultiplier.toFixed(1) + 'x'); // Color rhythm multiplier text based on value if (rhythmMultiplier > 1.5) { rhythmTxt.tint = 0x00ff00; } else if (rhythmMultiplier > 1.2) { rhythmTxt.tint = 0xffff00; } else { rhythmTxt.tint = 0xffffff; } } // Touch controls var dragStartX = 0; var isDragging = false; var lastTouchTime = 0; game.down = function (x, y, obj) { if (!gameStarted) { gameStarted = true; startButton.visible = false; // Hide start button player.visible = true; // Show player when game starts // Start background music LK.playMusic('bgmusic'); // Initialize first wave createWave(currentWave); return; } isDragging = true; // Stop any existing tween for immediate response tween.stop(player, { x: true }); // Quick tween to clicked position for responsive feel tween(player, { x: x }, { duration: 100, easing: tween.easeOut }); var currentTime = Date.now(); if (currentTime - lastTouchTime < 300) { // Double tap to shoot player.shoot(); } lastTouchTime = currentTime; }; game.move = function (x, y, obj) { if (!gameStarted) return; // Stop any existing tween to prevent conflicts tween.stop(player, { x: true }); // Calculate distance for dynamic duration var distance = Math.abs(x - player.x); // Dynamic duration based on distance - closer targets move faster var duration = Math.min(Math.max(distance * 0.8, 50), 200); // Use smooth easing for natural movement tween(player, { x: x }, { duration: duration, easing: tween.easeOut }); }; game.up = function (x, y, obj) { if (!gameStarted) return; isDragging = false; // Shoot on mouse up for better control player.shoot(); }; game.update = function () { if (!gameStarted) return; updateEnemyFormation(); checkCollisions(); updateUI(); // Gradually decay rhythm multiplier rhythmMultiplier = Math.max(rhythmMultiplier - 0.001, 1.0); // Check if wave is complete if (enemies.length === 0 && waveStarted && !bossActive) { waveStarted = false; bossActive = true; bossDefeated = false; // Spawn super boss superBoss = new SuperBoss(); superBoss.x = 1024; superBoss.y = 300; game.addChild(superBoss); } // Check if boss is defeated if (bossDefeated && !waveStarted) { waveDelay = 120; // 2 second delay currentWave++; bossDefeated = false; if (currentWave > 10) { LK.showYouWin(); return; } } // Start next wave after delay if (!waveStarted && waveDelay > 0) { waveDelay--; if (waveDelay <= 0) { createWave(currentWave); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Drop = Container.expand(function (dropType) {
var self = Container.call(this);
self.dropType = dropType;
var dropGraphics = self.attachAsset(dropType, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 1;
self.shootTimer = 0;
var waveReduction = (currentWave - 1) * 60; // Reduce by 1 second (60 frames) per wave
var minInterval = Math.max(60, 360 - waveReduction); // Minimum 1 second interval
var maxInterval = Math.max(120, 600 - waveReduction); // Minimum 2 second max interval
self.shootInterval = minInterval + Math.random() * (maxInterval - minInterval); // Dynamic interval based on wave level
self.moveSpeed = 2;
self.note = 0; // Musical note value
self.update = function () {
self.shootTimer++;
if (self.shootTimer >= self.shootInterval) {
self.shoot();
self.shootTimer = 0;
var waveReduction = (currentWave - 1) * 60; // Reduce by 1 second (60 frames) per wave
var minInterval = Math.max(60, 360 - waveReduction); // Minimum 1 second interval
var maxInterval = Math.max(120, 600 - waveReduction); // Minimum 2 second max interval
self.shootInterval = minInterval + Math.random() * (maxInterval - minInterval); // Dynamic interval based on wave level
}
// Add subtle horizontal sway movement for more fluid feel
if (LK.ticks % 180 === 0) {
var sideMovement = (Math.random() - 0.5) * 60;
var targetX = Math.max(50, Math.min(1998, self.x + sideMovement));
tween(self, {
x: targetX
}, {
duration: 1500 + Math.random() * 1000,
easing: tween.easeInOut
});
}
};
self.shoot = function () {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + 20;
enemyBullets.push(bullet);
game.addChild(bullet);
};
self.takeDamage = function (damage) {
self.health -= damage * rhythmMultiplier;
if (self.health <= 0) {
// Drop system - chance to drop items
var dropChance = Math.random() * 100;
if (dropChance < 2) {
// 2% chance for powerup1
var drop = new Drop('powerup1');
drop.x = self.x;
drop.y = self.y;
drops.push(drop);
game.addChild(drop);
} else if (dropChance < 3) {
// 1% chance for powerup2
var drop = new Drop('powerup2');
drop.x = self.x;
drop.y = self.y;
drops.push(drop);
game.addChild(drop);
} else if (dropChance < 4) {
// 1% chance for lifeup
var drop = new Drop('lifeup');
drop.x = self.x;
drop.y = self.y;
drops.push(drop);
game.addChild(drop);
}
self.destroy();
return true;
}
return false;
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = 8;
self.lives = 3;
self.canShoot = true;
self.shootCooldown = 0;
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
if (self.shootCooldown <= 0) {
self.canShoot = true;
}
}
// Keep player within screen bounds
if (self.x < 60) self.x = 60;
if (self.x > 2048 - 60) self.x = 2048 - 60;
};
self.shoot = function () {
if (!self.canShoot) return false;
self.canShoot = false;
self.shootCooldown = 15;
// Determine number of bullets based on powerup
var bulletCount = 1;
if (currentPowerup === 'powerup1') {
bulletCount = 3;
}
// Create bullets
for (var i = 0; i < bulletCount; i++) {
var bullet = new PlayerBullet(currentPowerup);
if (bulletCount === 1) {
bullet.x = self.x;
} else {
bullet.x = self.x + (i - 1) * 30; // Spread bullets
}
bullet.y = self.y - 40;
playerBullets.push(bullet);
game.addChild(bullet);
}
LK.getSound('shoot').play();
// 1 in 20 chance to play rhythmBonus sound
if (Math.random() < 0.05) {
LK.getSound('rhythmBonus').play();
}
// Check if shooting in rhythm
var timeSinceLastBeat = LK.ticks * 16.67 % beatInterval;
var rhythmWindow = beatInterval * 0.15;
if (timeSinceLastBeat < rhythmWindow || timeSinceLastBeat > beatInterval - rhythmWindow) {
rhythmMultiplier = Math.min(rhythmMultiplier + 0.1, 2.0);
} else {
rhythmMultiplier = Math.max(rhythmMultiplier - 0.05, 1.0);
}
return true;
};
return self;
});
var PlayerBullet = Container.expand(function (bulletType) {
var self = Container.call(this);
self.bulletType = bulletType || 'normal';
var assetName = 'playerBullet';
if (self.bulletType === 'powerup1') {
assetName = 'powebullet1';
} else if (self.bulletType === 'powerup2') {
assetName = 'powerbullet2';
}
var bulletGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -12;
self.damage = 1;
self.piercing = self.bulletType === 'powerup2';
self.update = function () {
self.y += self.speed;
};
return self;
});
var SuperBoss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('superboss', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3,
tint: 0xff0000
});
self.health = 100;
self.maxHealth = 100;
self.shootTimer = 0;
var waveReduction = (currentWave - 1) * 60; // Reduce by 1 second (60 frames) per wave
var minInterval = Math.max(60, 180 - waveReduction); // Minimum 1 second interval
var maxInterval = Math.max(120, 480 - waveReduction); // Minimum 2 second max interval
self.shootInterval = minInterval + Math.random() * (maxInterval - minInterval); // Dynamic interval based on wave level
self.moveSpeed = 1;
self.moveDirection = 1;
self.update = function () {
// Boss movement - side to side
self.x += self.moveSpeed * self.moveDirection;
if (self.x <= 200 || self.x >= 1848) {
self.moveDirection *= -1;
}
// Boss shooting
self.shootTimer++;
if (self.shootTimer >= self.shootInterval) {
self.shoot();
self.shootTimer = 0;
var waveReduction = (currentWave - 1) * 60; // Reduce by 1 second (60 frames) per wave
var minInterval = Math.max(60, 180 - waveReduction); // Minimum 1 second interval
var maxInterval = Math.max(120, 480 - waveReduction); // Minimum 2 second max interval
self.shootInterval = minInterval + Math.random() * (maxInterval - minInterval); // Dynamic interval based on wave level
}
// Update boss color based on health
var healthPercent = self.health / self.maxHealth;
if (healthPercent > 0.6) {
bossGraphics.tint = 0xff0000; // Red
} else if (healthPercent > 0.3) {
bossGraphics.tint = 0xff8800; // Orange
} else {
bossGraphics.tint = 0xffff00; // Yellow
}
};
self.shoot = function () {
// Shoot multiple bullets in different directions
for (var i = -2; i <= 2; i++) {
var bullet = new EnemyBullet();
bullet.x = self.x + i * 50;
bullet.y = self.y + 50;
bullet.speed = 3 + Math.abs(i) * 0.5;
enemyBullets.push(bullet);
game.addChild(bullet);
}
};
self.takeDamage = function (damage) {
self.health -= damage * rhythmMultiplier;
LK.effects.flashObject(self, 0xffffff, 100);
if (self.health <= 0) {
self.destroy();
return true;
}
return false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000011
});
/****
* Game Code
****/
var gameStarted = false;
var startButton = game.addChild(LK.getAsset('start', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
}));
startButton.x = 1024; // Center horizontally
startButton.y = 1366; // Center vertically
var player = game.addChild(new Player());
player.x = 1024;
player.y = 2600;
player.visible = false; // Hide player until game starts
var playerBullets = [];
var enemyBullets = [];
var enemies = [];
var currentWave = 1;
var enemiesKilled = 0;
var totalEnemiesInWave = 0;
var waveStarted = false;
var waveDelay = 0;
var rhythmMultiplier = 1.0;
var beatInterval = 500; // milliseconds
var lastBeatTime = 0;
var enemyFormationX = 0;
var enemyFormationDirection = 1;
var enemyDropDistance = 60;
var shouldDropEnemies = false;
var superBoss = null;
var bossActive = false;
var bossDefeated = false;
var drops = [];
var currentPowerup = null;
// Sound management for bonus sounds
var currentBonusSoundName = null;
var currentBonusSoundTimeout = null;
var bonusSounds = ['bonusmusic', 'bonusmusic2', 'bonusmusic3', 'bonusmusic4', 'bonusmusic5'];
function playRandomBonusSound() {
// Only play if no bonus sound is currently playing
if (currentBonusSoundName === null) {
var randomSoundName = bonusSounds[Math.floor(Math.random() * bonusSounds.length)];
var randomSound = LK.getSound(randomSoundName);
currentBonusSoundName = randomSoundName;
randomSound.play();
// Clear any existing timeout
if (currentBonusSoundTimeout !== null) {
LK.clearTimeout(currentBonusSoundTimeout);
}
// Set a longer timeout to ensure sound finishes before allowing new ones
// Using 2500ms to be safe that the sound completes
currentBonusSoundTimeout = LK.setTimeout(function () {
currentBonusSoundName = null;
currentBonusSoundTimeout = null;
}, 2500);
}
}
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
scoreTxt.x = 20;
scoreTxt.y = 20;
LK.gui.topLeft.addChild(scoreTxt);
var livesTxt = new Text2('Lives: 3', {
size: 60,
fill: 0xFFFFFF
});
livesTxt.anchor.set(1, 0);
livesTxt.x = -20;
livesTxt.y = 20;
LK.gui.topRight.addChild(livesTxt);
var waveTxt = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFFFF
});
waveTxt.anchor.set(0.5, 0);
waveTxt.x = 0;
waveTxt.y = 20;
LK.gui.top.addChild(waveTxt);
var rhythmTxt = new Text2('Rhythm: 1.0x', {
size: 50,
fill: 0xFFFF00
});
rhythmTxt.anchor.set(0.5, 0);
rhythmTxt.x = 0;
rhythmTxt.y = 100;
LK.gui.top.addChild(rhythmTxt);
function createWave(waveNumber) {
enemies = [];
enemiesKilled = 0;
var rows = 3 + Math.floor(waveNumber / 3);
var cols = 8 + Math.floor(waveNumber / 2);
totalEnemiesInWave = rows * cols;
var startX = (2048 - cols * 100) / 2;
var startY = 200;
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
var enemy = new Enemy();
enemy.x = startX + col * 100;
enemy.y = startY + row * 80;
enemy.note = (row * cols + col) % 12; // Assign musical notes
enemies.push(enemy);
game.addChild(enemy);
}
}
enemyFormationX = 0;
enemyFormationDirection = 1;
waveStarted = true;
// Increase tempo with each wave
beatInterval = Math.max(300, 500 - waveNumber * 20);
}
function updateEnemyFormation() {
if (enemies.length === 0) return;
var moveDistance = 4 + Math.floor(currentWave / 2);
var shouldMove = LK.ticks % Math.max(1, 20 - currentWave * 1.5) === 0;
if (shouldMove) {
if (shouldDropEnemies) {
// Drop enemies down
for (var i = 0; i < enemies.length; i++) {
enemies[i].y += enemyDropDistance;
}
shouldDropEnemies = false;
} else {
// Move all enemies horizontally in synchronized formation using tween
var hitEdge = false;
var targetDirection = moveDistance * enemyFormationDirection;
// Check if any enemy would hit the edge
for (var i = 0; i < enemies.length; i++) {
var newX = enemies[i].x + targetDirection;
if (newX <= 50 || newX >= 1998) {
hitEdge = true;
break;
}
}
// Move all enemies together with synchronized tween animation
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
tween(enemy, {
x: enemy.x + targetDirection
}, {
duration: 300,
easing: tween.easeInOut
});
}
if (hitEdge) {
enemyFormationDirection *= -1;
shouldDropEnemies = true;
}
}
}
}
function checkCollisions() {
// Player bullets vs enemies
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
var bulletHit = false;
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
if (enemy.takeDamage(bullet.damage)) {
enemies.splice(j, 1);
enemiesKilled++;
var baseScore = 100 * Math.floor(rhythmMultiplier);
LK.setScore(LK.getScore() + baseScore);
LK.getSound('enemyHit').play();
// Play random bonus sound effect with 15% chance
if (Math.random() < 0.15) {
playRandomBonusSound();
}
LK.effects.flashObject(enemy, 0xffffff, 200);
}
if (!bullet.piercing) {
bullet.destroy();
playerBullets.splice(i, 1);
bulletHit = true;
break;
} else {
bulletHit = false; // Allow piercing bullets to continue
}
}
}
// Player bullets vs super boss
if (!bulletHit && superBoss && bullet.intersects(superBoss)) {
if (superBoss.takeDamage(bullet.damage)) {
superBoss = null;
bossActive = false;
bossDefeated = true;
var bossScore = 5000 * Math.floor(rhythmMultiplier);
LK.setScore(LK.getScore() + bossScore);
LK.getSound('enemyHit').play();
// Play random bonus sound effect with 15% chance
if (Math.random() < 0.15) {
playRandomBonusSound();
}
}
if (!bullet.piercing) {
bullet.destroy();
playerBullets.splice(i, 1);
bulletHit = true;
}
}
if (!bulletHit && bullet.y < -20) {
bullet.destroy();
playerBullets.splice(i, 1);
}
}
// Player vs drops
for (var i = drops.length - 1; i >= 0; i--) {
var drop = drops[i];
if (drop.intersects(player)) {
if (drop.dropType === 'lifeup') {
player.lives = Math.min(player.lives + 1, 5);
} else {
currentPowerup = drop.dropType;
}
drop.destroy();
drops.splice(i, 1);
} else if (drop.y > 2732) {
drop.destroy();
drops.splice(i, 1);
}
}
// Enemy bullets vs player
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
if (bullet.intersects(player)) {
player.lives--;
currentPowerup = null; // Reset powerup when player loses a life
bullet.destroy();
enemyBullets.splice(i, 1);
LK.getSound('playerHit').play();
LK.effects.flashObject(player, 0xff0000, 500);
if (player.lives <= 0) {
LK.showGameOver();
return;
}
} else if (bullet.y > 2732) {
bullet.destroy();
enemyBullets.splice(i, 1);
}
}
// Check if enemies reached player
for (var i = 0; i < enemies.length; i++) {
if (enemies[i].y > 2500) {
LK.showGameOver();
return;
}
}
// Check if super boss reached player
if (superBoss && superBoss.y > 2500) {
LK.showGameOver();
return;
}
}
function updateUI() {
scoreTxt.setText('Score: ' + LK.getScore());
livesTxt.setText('Lives: ' + player.lives);
waveTxt.setText('Wave: ' + currentWave);
rhythmTxt.setText('Rhythm: ' + rhythmMultiplier.toFixed(1) + 'x');
// Color rhythm multiplier text based on value
if (rhythmMultiplier > 1.5) {
rhythmTxt.tint = 0x00ff00;
} else if (rhythmMultiplier > 1.2) {
rhythmTxt.tint = 0xffff00;
} else {
rhythmTxt.tint = 0xffffff;
}
}
// Touch controls
var dragStartX = 0;
var isDragging = false;
var lastTouchTime = 0;
game.down = function (x, y, obj) {
if (!gameStarted) {
gameStarted = true;
startButton.visible = false; // Hide start button
player.visible = true; // Show player when game starts
// Start background music
LK.playMusic('bgmusic');
// Initialize first wave
createWave(currentWave);
return;
}
isDragging = true;
// Stop any existing tween for immediate response
tween.stop(player, {
x: true
});
// Quick tween to clicked position for responsive feel
tween(player, {
x: x
}, {
duration: 100,
easing: tween.easeOut
});
var currentTime = Date.now();
if (currentTime - lastTouchTime < 300) {
// Double tap to shoot
player.shoot();
}
lastTouchTime = currentTime;
};
game.move = function (x, y, obj) {
if (!gameStarted) return;
// Stop any existing tween to prevent conflicts
tween.stop(player, {
x: true
});
// Calculate distance for dynamic duration
var distance = Math.abs(x - player.x);
// Dynamic duration based on distance - closer targets move faster
var duration = Math.min(Math.max(distance * 0.8, 50), 200);
// Use smooth easing for natural movement
tween(player, {
x: x
}, {
duration: duration,
easing: tween.easeOut
});
};
game.up = function (x, y, obj) {
if (!gameStarted) return;
isDragging = false;
// Shoot on mouse up for better control
player.shoot();
};
game.update = function () {
if (!gameStarted) return;
updateEnemyFormation();
checkCollisions();
updateUI();
// Gradually decay rhythm multiplier
rhythmMultiplier = Math.max(rhythmMultiplier - 0.001, 1.0);
// Check if wave is complete
if (enemies.length === 0 && waveStarted && !bossActive) {
waveStarted = false;
bossActive = true;
bossDefeated = false;
// Spawn super boss
superBoss = new SuperBoss();
superBoss.x = 1024;
superBoss.y = 300;
game.addChild(superBoss);
}
// Check if boss is defeated
if (bossDefeated && !waveStarted) {
waveDelay = 120; // 2 second delay
currentWave++;
bossDefeated = false;
if (currentWave > 10) {
LK.showYouWin();
return;
}
}
// Start next wave after delay
if (!waveStarted && waveDelay > 0) {
waveDelay--;
if (waveDelay <= 0) {
createWave(currentWave);
}
}
};
nave espacial extraterrestre. In-Game asset. 2d. High contrast. No shadows
un bala lazer de nergia. In-Game asset. 2d. High contrast. No shadows
monster space ship. In-Game asset. 2d. High contrast. No shadows
una espada roja con destellos. In-Game asset. 2d. High contrast. No shadows
espada azul con destellos. In-Game asset. 2d. High contrast. No shadows
un rayo lazer con destellos de fuego alrededor. In-Game asset. 2d. High contrast. No shadows
rayo láser azul con fuego azul alrededor. In-Game asset. 2d. High contrast. No shadows
una esfera blanca con destellos con alas de angel a los lados. In-Game asset. 2d. High contrast. No shadows
una imagen que diga "start" en letras grandes con una fuente alusiva a lso que se usan en video juegos de color metal brillante. In-Game asset. 2d. High contrast. No shadows