User prompt
As que cada 10 segundos el jugador se tenga que mover obligar obligatoriamente
User prompt
Ahora as que el tiempo solo funcione cuando el jugador se mueva por ejemplo:si el jugador no se mueve todo se va a quedar quieto los enemigos las balas y más pero cuando el jugador de mueve todo se empieza a mover los enemigos las balas se vuelven a mover
User prompt
Sabes que elimina la cámara lenta
User prompt
As el botón más grande
User prompt
As que el muro se rompa después de aguantar 15 balazos
User prompt
El botón de poner paredes no funciona
User prompt
Elimina la opción de escudo del juego
User prompt
As el botón más grande y separalo más del botón de camara lenta
User prompt
As que con un botón el jugador pueda poner paredes para que las balas reboten en ellas
User prompt
As que en una esquina en la pantalla allá un botón que si el jugador lo preciona todo se pone en cámara lenta durante 5 segundos y después el jugador tiene que esperar 30 segundos para volver a usar ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
As que en una esquina en la pantalla allá un botón que si el jugador lo preciona todo se pone en cámara lenta durante 5 segundos y después el jugador tiene que esperar 30 minutos para volvelo a usar ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
En una esquina pon un texto que diga "solo puedes disparar cuando escuches un chasquido de dedos"
User prompt
Quita el texto que dice whait for beat
User prompt
Quita el texto que dice next beat
User prompt
As que se pueda dispara cada 2 segundos
User prompt
As que el rayo baje asta salir de la pantalla ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
A medida que cada rato aparece un "!" Y donde aparece el ! salga un rayo Que mata al jugador (el rayo va bajando) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
A medida que cada rato aparece un "!" Y donde aparece el ! salga un rayoQue mata al jugador ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
En una esquina de la pantalla pon cuáles son los botones
User prompt
As botones para que el jugador pueda moverse
User prompt
As que el jugador pueda presionar un botón para pone un escudo anti balas
User prompt
Y as que sus balas reboten en las paredes 3 veces antes de desaparecer
User prompt
As que los enemigos disparen a lugares aleatorios
User prompt
Pon la 3 música del "musica bg"
User prompt
Pon la 3 música del álbum musica bg
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var BeatIndicator = Container.expand(function () {
var self = Container.call(this);
var indicatorGraphics = self.attachAsset('beatIndicator', {
anchorX: 0.5,
anchorY: 0.5
});
indicatorGraphics.alpha = 0.3;
self.pulse = function () {
indicatorGraphics.alpha = 0.8;
tween(indicatorGraphics, {
alpha: 0.3,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
indicatorGraphics.scaleX = 1;
indicatorGraphics.scaleY = 1;
}
});
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 25;
self.directionX = 0;
self.directionY = -1;
self.enemiesKilled = 0;
self.maxKills = 2;
self.bounceCount = 0;
self.maxBounces = 3;
self.update = function () {
// Store previous position for collision detection
if (self.lastX === undefined) self.lastX = self.x;
if (self.lastY === undefined) self.lastY = self.y;
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
// Check wall collisions and bounce
if (self.x <= 10 && self.directionX < 0) {
self.directionX = -self.directionX; // Bounce off left wall
self.x = 10;
self.bounceCount++;
}
if (self.x >= 2038 && self.directionX > 0) {
self.directionX = -self.directionX; // Bounce off right wall
self.x = 2038;
self.bounceCount++;
}
if (self.y <= 10 && self.directionY < 0) {
self.directionY = -self.directionY; // Bounce off top wall
self.y = 10;
self.bounceCount++;
}
if (self.y >= 2722 && self.directionY > 0) {
self.directionY = -self.directionY; // Bounce off bottom wall
self.y = 2722;
self.bounceCount++;
}
// Update last positions
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.targetX = self.x;
self.targetY = self.y;
self.moveSpeed = 0.1;
self.isMoving = false;
self.shootTimer = 0;
self.shootInterval = 120 + Math.random() * 180; // Random interval between 2-5 seconds
self.setTarget = function (x, y) {
self.targetX = x;
self.targetY = y;
self.isMoving = true;
tween(self, {
x: x,
y: y
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isMoving = false;
}
});
};
self.update = function () {
self.shootTimer++;
if (self.shootTimer >= self.shootInterval) {
// Shoot at random location
var randomX = Math.random() * 2048;
var randomY = Math.random() * 2732;
// Create enemy bullet
var enemyBullet = game.addChild(new EnemyBullet());
var dx = randomX - self.x;
var dy = randomY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
enemyBullet.directionX = dx / distance;
enemyBullet.directionY = dy / distance;
}
enemyBullet.x = self.x;
enemyBullet.y = self.y;
enemyBullets.push(enemyBullet);
// Reset timer with new random interval
self.shootTimer = 0;
self.shootInterval = 120 + Math.random() * 180;
}
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
bulletGraphics.tint = 0xff5722; // Orange/red tint to differentiate from player bullets
self.speed = 15;
self.directionX = 0;
self.directionY = 1;
self.bounceCount = 0;
self.maxBounces = 3;
self.update = function () {
// Store previous position for collision detection
if (self.lastX === undefined) self.lastX = self.x;
if (self.lastY === undefined) self.lastY = self.y;
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
// Check wall collisions and bounce
if (self.x <= 10 && self.directionX < 0) {
self.directionX = -self.directionX; // Bounce off left wall
self.x = 10;
self.bounceCount++;
}
if (self.x >= 2038 && self.directionX > 0) {
self.directionX = -self.directionX; // Bounce off right wall
self.x = 2038;
self.bounceCount++;
}
if (self.y <= 10 && self.directionY < 0) {
self.directionY = -self.directionY; // Bounce off top wall
self.y = 10;
self.bounceCount++;
}
if (self.y >= 2722 && self.directionY > 0) {
self.directionY = -self.directionY; // Bounce off bottom wall
self.y = 2722;
self.bounceCount++;
}
// Remove if bounced too many times
if (self.bounceCount >= self.maxBounces) {
self.shouldDestroy = true;
}
// Remove if off-screen (fallback)
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
// Mark for removal
self.shouldDestroy = true;
}
// Update last positions
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
var GiantEnemy = Container.expand(function () {
var self = Container.call(this);
var giantGraphics = self.attachAsset('giantEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 5;
self.speed = 2;
self.update = function () {
// Move toward player
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
return self;
});
var Lightning = Container.expand(function () {
var self = Container.call(this);
var lightningGraphics = self.attachAsset('lightning', {
anchorX: 0.5,
anchorY: 0.5
});
self.duration = 30; // Lightning lasts 0.5 seconds
self.timer = 0;
self.speedY = 15; // Speed of downward movement
self.update = function () {
self.timer++;
self.y += self.speedY; // Move lightning downwards
// Flash effect
if (self.timer % 5 === 0) {
lightningGraphics.alpha = lightningGraphics.alpha === 1 ? 0.7 : 1;
}
// Mark for destruction if it moves off-screen (bottom)
if (self.y > 2732 + lightningGraphics.height / 2) {
self.shouldDestroy = true;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.canShoot = true;
self.shootCooldown = 0;
return self;
});
var PredictionCircle = Container.expand(function () {
var self = Container.call(this);
var circleGraphics = self.attachAsset('predictionCircle', {
anchorX: 0.5,
anchorY: 0.5
});
circleGraphics.alpha = 0.7;
self.show = function () {
// Make circle visible and animate it
circleGraphics.alpha = 0.7;
circleGraphics.scaleX = 0.5;
circleGraphics.scaleY = 0.5;
// Animate appearance
tween(circleGraphics, {
scaleX: 1,
scaleY: 1,
alpha: 0.9
}, {
duration: 200,
easing: tween.easeOut
});
// Auto-hide after 2 seconds
tween(circleGraphics, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var Shield = Container.expand(function () {
var self = Container.call(this);
var shieldGraphics = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5
});
shieldGraphics.alpha = 0.6;
self.isActive = false;
self.duration = 300; // 5 seconds at 60fps
self.timer = 0;
self.cooldown = 600; // 10 seconds cooldown at 60fps
self.cooldownTimer = 0;
self.activate = function () {
if (self.cooldownTimer <= 0 && !self.isActive) {
self.isActive = true;
self.timer = self.duration;
self.visible = true;
shieldGraphics.alpha = 0.6;
// Pulse effect when activated
tween(shieldGraphics, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0.8
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
shieldGraphics.scaleX = 1;
shieldGraphics.scaleY = 1;
}
});
}
};
self.update = function () {
// Update cooldown
if (self.cooldownTimer > 0) {
self.cooldownTimer--;
}
// Update active shield
if (self.isActive) {
self.timer--;
// Flash effect when shield is about to expire
if (self.timer <= 60 && self.timer % 10 === 0) {
shieldGraphics.alpha = shieldGraphics.alpha === 0.6 ? 0.2 : 0.6;
}
if (self.timer <= 0) {
self.isActive = false;
self.visible = false;
self.cooldownTimer = self.cooldown;
}
}
};
self.visible = false;
return self;
});
var Warning = Container.expand(function () {
var self = Container.call(this);
var warningGraphics = self.attachAsset('warning', {
anchorX: 0.5,
anchorY: 0.5
});
self.timer = 120; // 2 seconds warning time
self.flashTimer = 0;
self.update = function () {
self.timer--;
self.flashTimer++;
// Flash warning every 10 frames
if (self.flashTimer % 10 === 0) {
warningGraphics.alpha = warningGraphics.alpha === 1 ? 0.3 : 1;
}
// Mark for destruction when timer expires
if (self.timer <= 0) {
self.shouldSpawnLightning = true;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Game variables
var player;
var enemies = [];
var bullets = [];
var enemyBullets = [];
var predictionCircles = [];
var beatIndicator;
var beatTimer = 0;
var beatInterval = 300; // 5 seconds at 60fps
var nextBeatTime = 0;
var canShootWindow = false;
var shootWindow = 60; // 1 second window after beat
var shootWindowTimer = 0;
var totalKills = 0;
var bulletsPerShot = 1;
var enemyPositions = [{
x: 400,
y: 300
}, {
x: 1648,
y: 300
}, {
x: 1024,
y: 200
}, {
x: 600,
y: 500
}, {
x: 1448,
y: 500
}];
var currentWave = 0;
var enemyPredictionTimer = 0;
var enemyPredictionInterval = 180; // 3 seconds at 60fps
var giantEnemies = [];
var giantEnemyTimer = 0;
var giantEnemyInterval = 3600; // 60 seconds at 60fps (1 minute)
var warnings = [];
var lightnings = [];
var warningSpawnTimer = 0;
var warningSpawnInterval = 180; // 3 seconds at 60fps
// UI elements
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var shootStatusTxt = new Text2('', {
size: 45,
fill: 0xFFFF00
});
shootStatusTxt.anchor.set(0.5, 0);
shootStatusTxt.y = 140;
LK.gui.top.addChild(shootStatusTxt);
var enemyPredictionTxt = new Text2('', {
size: 40,
fill: 0xff9800
});
enemyPredictionTxt.anchor.set(0.5, 0);
enemyPredictionTxt.y = 190;
LK.gui.top.addChild(enemyPredictionTxt);
var bossCountdownTxt = new Text2('Next Boss: 60.0s', {
size: 45,
fill: 0xff0000
});
bossCountdownTxt.anchor.set(0.5, 0);
bossCountdownTxt.y = 240;
LK.gui.top.addChild(bossCountdownTxt);
// Player health system
var playerHealth = 3;
var maxPlayerHealth = 3;
// Shooting cooldown system (2 seconds = 120 frames at 60fps)
var shootCooldown = 0;
var shootCooldownMax = 120;
var canShoot = true;
var playerHealthTxt = new Text2('Lives: 3/3', {
size: 45,
fill: 0x00ff00
});
playerHealthTxt.anchor.set(0.5, 0);
playerHealthTxt.y = 290;
LK.gui.top.addChild(playerHealthTxt);
// Shield system
var playerShield;
var shieldStatusTxt = new Text2('Shield: Ready', {
size: 45,
fill: 0x00bcd4
});
shieldStatusTxt.anchor.set(0.5, 0);
shieldStatusTxt.y = 340;
LK.gui.top.addChild(shieldStatusTxt);
var shootCooldownTxt = new Text2('Shoot: Ready', {
size: 45,
fill: 0x00ff00
});
shootCooldownTxt.anchor.set(0.5, 0);
shootCooldownTxt.y = 390;
LK.gui.top.addChild(shootCooldownTxt);
// Movement buttons
var leftButton = new Text2('◀', {
size: 80,
fill: 0xffffff
});
leftButton.anchor.set(0.5, 0.5);
leftButton.x = 200;
leftButton.y = 200;
LK.gui.bottomLeft.addChild(leftButton);
var rightButton = new Text2('▶', {
size: 80,
fill: 0xffffff
});
rightButton.anchor.set(0.5, 0.5);
rightButton.x = -200;
rightButton.y = 200;
LK.gui.bottomRight.addChild(rightButton);
var upButton = new Text2('▲', {
size: 80,
fill: 0xffffff
});
upButton.anchor.set(0.5, 0.5);
upButton.x = 0;
upButton.y = 300;
LK.gui.bottom.addChild(upButton);
var downButton = new Text2('▼', {
size: 80,
fill: 0xffffff
});
downButton.anchor.set(0.5, 0.5);
upButton.x = 0;
upButton.y = 100;
LK.gui.bottom.addChild(downButton);
var shieldButtonTxt = new Text2('SHIELD', {
size: 50,
fill: 0x00bcd4
});
shieldButtonTxt.anchor.set(0.5, 0.5);
shieldButtonTxt.x = 0;
shieldButtonTxt.y = 150;
LK.gui.bottom.addChild(shieldButtonTxt);
// Controls instructions in corner
var controlsTxt = new Text2('Controls:\n◀▶ Move\n▲▼ Up/Down\nSHIELD: Block\nTouch: Shoot', {
size: 30,
fill: 0xffffff
});
controlsTxt.anchor.set(1, 1);
controlsTxt.x = -20;
controlsTxt.y = -20;
LK.gui.bottomRight.addChild(controlsTxt);
// Shooting instruction text in corner
var shootInstructionTxt = new Text2('Solo puedes disparar cuando\nescuches un chasquido de dedos', {
size: 25,
fill: 0xffff00
});
shootInstructionTxt.anchor.set(0, 1);
shootInstructionTxt.x = 20;
shootInstructionTxt.y = -20;
LK.gui.bottomLeft.addChild(shootInstructionTxt);
// Slow motion system
var slowMotionActive = false;
var slowMotionTimer = 0;
var slowMotionDuration = 300; // 5 seconds at 60fps
var slowMotionCooldown = 108000000; // 30 minutes in milliseconds
var slowMotionLastUsed = storage.slowMotionLastUsed || 0;
var gameSpeed = 1.0;
// Slow motion button
var slowMotionButton = new Text2('SLOW\nMOTION', {
size: 30,
fill: 0x9c27b0
});
slowMotionButton.anchor.set(0, 0);
slowMotionButton.x = 20;
slowMotionButton.y = 20;
LK.gui.topRight.addChild(slowMotionButton);
// Initialize player
player = game.addChild(new Player());
player.x = 1024;
player.y = 2400;
player.speed = 8;
// Movement state
var moveLeft = false;
var moveRight = false;
var moveUp = false;
var moveDown = false;
// Initialize shield
playerShield = game.addChild(new Shield());
playerShield.x = player.x;
playerShield.y = player.y;
// Initialize beat indicator
beatIndicator = game.addChild(new BeatIndicator());
beatIndicator.x = 1024;
beatIndicator.y = 1366;
// Initialize enemies
function spawnEnemies() {
// Clear existing enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].destroy();
enemies.splice(i, 1);
}
// Clear any remaining prediction circles
for (var c = predictionCircles.length - 1; c >= 0; c--) {
predictionCircles[c].destroy();
predictionCircles.splice(c, 1);
}
// Spawn new enemies - base amount plus bonus based on total kills
var baseEnemies = 3 + Math.floor(currentWave / 2);
var bonusEnemies = Math.floor(totalKills / 5); // 1 extra enemy per 5 kills
var numEnemies = Math.min(baseEnemies + bonusEnemies, 5);
for (var i = 0; i < numEnemies; i++) {
var enemy = game.addChild(new Enemy());
var pos = enemyPositions[i % enemyPositions.length];
enemy.x = pos.x;
enemy.y = pos.y;
enemies.push(enemy);
}
}
function moveEnemies() {
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var newPos = enemyPositions[(enemies.indexOf(enemy) + currentWave + 1) % enemyPositions.length];
enemy.setTarget(newPos.x, newPos.y);
}
}
function createBullet(targetX, targetY) {
// Update bullets per shot based on total kills
bulletsPerShot = 1 + Math.floor(totalKills / 3); // 1 extra bullet per 3 kills
bulletsPerShot = Math.min(bulletsPerShot, 5); // Cap at 5 bullets
// Create multiple bullets
for (var b = 0; b < bulletsPerShot; b++) {
var bullet = game.addChild(new Bullet());
// Calculate direction to target first
var dx = targetX - player.x;
var dy = targetY - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Add spread for multiple bullets
var spreadAngle = 0;
if (bulletsPerShot > 1) {
var maxSpread = Math.PI / 6; // 30 degrees total spread
spreadAngle = (b - (bulletsPerShot - 1) / 2) * (maxSpread / (bulletsPerShot - 1));
}
if (distance > 0) {
var baseDirectionX = dx / distance;
var baseDirectionY = dy / distance;
// Apply spread rotation
bullet.directionX = baseDirectionX * Math.cos(spreadAngle) - baseDirectionY * Math.sin(spreadAngle);
bullet.directionY = baseDirectionX * Math.sin(spreadAngle) + baseDirectionY * Math.cos(spreadAngle);
}
// Position bullet in front of player (offset by player size + bullet size to avoid collision)
var offsetDistance = 80; // Player size (70) + bullet height (40) + small buffer
bullet.x = player.x + bullet.directionX * offsetDistance;
bullet.y = player.y + bullet.directionY * offsetDistance;
bullets.push(bullet);
}
LK.getSound('shoot').play();
}
function damagePlayer() {
playerHealth--;
playerHealthTxt.setText('Lives: ' + playerHealth + '/' + maxPlayerHealth);
// Flash player red when damaged
LK.effects.flashObject(player, 0xff0000, 500);
// Update health text color based on remaining health
if (playerHealth <= 1) {
playerHealthTxt.fill = 0xff0000; // Red when critical
} else if (playerHealth <= 2) {
playerHealthTxt.fill = 0xffa500; // Orange when low
}
// Check if player is dead
if (playerHealth <= 0) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return true; // Player is dead
}
return false; // Player is still alive
}
// Touch/click handling
game.down = function (x, y, obj) {
// Convert to GUI coordinates to check button presses
var guiPos = LK.gui.toLocal({
x: x,
y: y
});
// Check slow motion button (top right corner)
if (guiPos.x > LK.gui.width - 150 && guiPos.x < LK.gui.width - 20 && guiPos.y > 20 && guiPos.y < 100) {
// Slow motion button pressed
var currentTime = Date.now();
var timeSinceLastUse = currentTime - slowMotionLastUsed;
if (timeSinceLastUse >= slowMotionCooldown && !slowMotionActive) {
// Activate slow motion
slowMotionActive = true;
slowMotionTimer = slowMotionDuration;
gameSpeed = 0.3; // Slow down to 30% speed
slowMotionLastUsed = currentTime;
storage.slowMotionLastUsed = currentTime;
LK.effects.flashScreen(0x9c27b0, 300);
}
} else if (guiPos.x < 400 && guiPos.y > LK.gui.height - 400) {
// Left button area
moveLeft = true;
} else if (guiPos.x > LK.gui.width - 400 && guiPos.y > LK.gui.height - 400) {
// Right button area
moveRight = true;
} else if (guiPos.x > LK.gui.width / 2 - 100 && guiPos.x < LK.gui.width / 2 + 100 && guiPos.y > LK.gui.height - 500 && guiPos.y < LK.gui.height - 300) {
// Up button area
moveUp = true;
} else if (guiPos.x > LK.gui.width / 2 - 100 && guiPos.x < LK.gui.width / 2 + 100 && guiPos.y > LK.gui.height - 200) {
// Down button area
moveDown = true;
} else if (guiPos.x > LK.gui.width / 2 - 100 && guiPos.x < LK.gui.width / 2 + 100 && guiPos.y > LK.gui.height - 300 && guiPos.y < LK.gui.height - 200) {
// Shield button area
playerShield.activate();
} else {
// Check if player can shoot (2-second cooldown)
if (canShoot) {
createBullet(x, y);
// Start cooldown
canShoot = false;
shootCooldown = shootCooldownMax;
} else {
// If can't shoot, try to activate shield
playerShield.activate();
}
}
};
// Touch release handling
game.up = function (x, y, obj) {
// Stop all movement when touch is released
moveLeft = false;
moveRight = false;
moveUp = false;
moveDown = false;
};
// Initialize game
spawnEnemies();
nextBeatTime = beatInterval;
// Start background music
LK.playMusic('musicabg3');
// Main game update loop
game.update = function () {
// Update slow motion system
if (slowMotionActive) {
slowMotionTimer--;
if (slowMotionTimer <= 0) {
slowMotionActive = false;
gameSpeed = 1.0; // Return to normal speed
}
}
// Update slow motion button status
var currentTime = Date.now();
var timeSinceLastUse = currentTime - slowMotionLastUsed;
var cooldownRemaining = slowMotionCooldown - timeSinceLastUse;
if (slowMotionActive) {
var timeLeft = slowMotionTimer / 60.0;
slowMotionButton.setText('SLOW\nMOTION\n' + timeLeft.toFixed(1) + 's');
slowMotionButton.fill = 0x4caf50; // Green when active
} else if (cooldownRemaining > 0) {
var minutesLeft = Math.ceil(cooldownRemaining / 60000);
slowMotionButton.setText('SLOW\nMOTION\n' + minutesLeft + 'm');
slowMotionButton.fill = 0xff5722; // Red when on cooldown
} else {
slowMotionButton.setText('SLOW\nMOTION\nREADY');
slowMotionButton.fill = 0x9c27b0; // Purple when ready
}
// Apply game speed to timers (when in slow motion, game runs slower)
var speedMultiplier = slowMotionActive ? gameSpeed : 1.0;
beatTimer += speedMultiplier;
giantEnemyTimer += speedMultiplier;
warningSpawnTimer += speedMultiplier;
// Warning spawn system
if (warningSpawnTimer >= warningSpawnInterval) {
// Spawn warning at random position
var warning = game.addChild(new Warning());
warning.x = 100 + Math.random() * 1848; // Keep within screen bounds
warning.y = 100 + Math.random() * 2532;
warnings.push(warning);
warningSpawnTimer = 0;
// Decrease interval slightly over time to increase difficulty
warningSpawnInterval = Math.max(120, warningSpawnInterval - 2);
}
// Giant enemy spawn system
if (giantEnemyTimer >= giantEnemyInterval) {
// Spawn giant enemy at random edge of screen
var giantEnemy = game.addChild(new GiantEnemy());
var side = Math.floor(Math.random() * 4); // 0=top, 1=right, 2=bottom, 3=left
if (side === 0) {
// top
giantEnemy.x = Math.random() * 2048;
giantEnemy.y = 0;
} else if (side === 1) {
// right
giantEnemy.x = 2048;
giantEnemy.y = Math.random() * 2732;
} else if (side === 2) {
// bottom
giantEnemy.x = Math.random() * 2048;
giantEnemy.y = 2732;
} else {
// left
giantEnemy.x = 0;
giantEnemy.y = Math.random() * 2732;
}
giantEnemies.push(giantEnemy);
giantEnemyTimer = 0;
}
// Beat system
if (beatTimer >= nextBeatTime) {
// Beat occurred
beatIndicator.pulse();
LK.getSound('beat').play();
// Move enemies
moveEnemies();
currentWave++;
// Enable shooting window
canShootWindow = true;
shootWindowTimer = 0;
// Reset beat timer
beatTimer = 0;
nextBeatTime = beatInterval;
}
// Shooting window management
if (canShootWindow) {
shootWindowTimer++;
if (shootWindowTimer >= shootWindow) {
canShootWindow = false;
}
}
// Update player movement (affected by slow motion)
var effectivePlayerSpeed = player.speed * gameSpeed;
if (moveLeft && player.x > 35) {
player.x -= effectivePlayerSpeed;
}
if (moveRight && player.x < 2048 - 35) {
player.x += effectivePlayerSpeed;
}
if (moveUp && player.y > 35) {
player.y -= effectivePlayerSpeed;
}
if (moveDown && player.y < 2732 - 35) {
player.y += effectivePlayerSpeed;
}
// Update shooting cooldown (affected by slow motion)
if (shootCooldown > 0) {
shootCooldown -= gameSpeed;
if (shootCooldown <= 0) {
canShoot = true;
}
}
// Update shield position and status
playerShield.x = player.x;
playerShield.y = player.y;
// Update UI
var timeToNextBeat = (nextBeatTime - beatTimer) / 60.0;
if (canShootWindow) {
var windowTimeLeft = (shootWindow - shootWindowTimer) / 60.0;
shootStatusTxt.setText('SHOOT NOW! (' + windowTimeLeft.toFixed(1) + 's)');
} else {
shootStatusTxt.setText('');
}
// Update shield status text
if (playerShield.isActive) {
var shieldTimeLeft = playerShield.timer / 60.0;
shieldStatusTxt.setText('Shield: ' + shieldTimeLeft.toFixed(1) + 's');
} else if (playerShield.cooldownTimer > 0) {
var cooldownLeft = playerShield.cooldownTimer / 60.0;
shieldStatusTxt.setText('Shield: ' + cooldownLeft.toFixed(1) + 's');
} else {
shieldStatusTxt.setText('Shield: Ready');
}
// Update shooting cooldown status text
if (canShoot) {
shootCooldownTxt.setText('Shoot: Ready');
shootCooldownTxt.fill = 0x00ff00;
} else {
var shootTimeLeft = shootCooldown / 60.0;
shootCooldownTxt.setText('Shoot: ' + shootTimeLeft.toFixed(1) + 's');
shootCooldownTxt.fill = 0xff0000;
}
// Update boss countdown
var timeToNextBoss = (giantEnemyInterval - giantEnemyTimer) / 60.0;
bossCountdownTxt.setText('Next Boss: ' + timeToNextBoss.toFixed(1) + 's');
// Enemy movement prediction system
enemyPredictionTimer++;
if (enemyPredictionTimer >= enemyPredictionInterval) {
// Clear existing prediction circles
for (var c = predictionCircles.length - 1; c >= 0; c--) {
predictionCircles[c].destroy();
predictionCircles.splice(c, 1);
}
// Announce where enemies will move
var nextPositions = [];
for (var k = 0; k < enemies.length; k++) {
var enemy = enemies[k];
var nextPosIndex = (enemies.indexOf(enemy) + currentWave + 1) % enemyPositions.length;
var nextPos = enemyPositions[nextPosIndex];
nextPositions.push('(' + Math.floor(nextPos.x) + ',' + Math.floor(nextPos.y) + ')');
// Create prediction circle at the target position
var predictionCircle = game.addChild(new PredictionCircle());
predictionCircle.x = nextPos.x;
predictionCircle.y = nextPos.y;
predictionCircles.push(predictionCircle);
predictionCircle.show();
}
if (nextPositions.length > 0) {
enemyPredictionTxt.setText('Enemies moving to: ' + nextPositions.join(', '));
}
enemyPredictionTimer = 0;
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Check if bullet has bounced too many times
if (bullet.bounceCount >= bullet.maxBounces) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet-player collision (player loses if hit by own bullet)
if (bullet.intersects(player)) {
// Damage player and remove bullet
if (damagePlayer()) {
return; // Player died, exit update loop
}
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Remove off-screen check since bullets now bounce
// Check bullet-enemy collisions
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
// Hit!
totalKills++;
bullet.enemiesKilled++;
LK.setScore(LK.getScore() + 100);
scoreTxt.setText('Score: ' + LK.getScore() + ' | Kills: ' + totalKills + ' | Bullets: ' + bulletsPerShot);
LK.getSound('hit').play();
LK.effects.flashObject(enemy, 0xffffff, 200);
// Remove enemy
enemy.destroy();
enemies.splice(j, 1);
// Only remove bullet if it has killed maximum enemies
if (bullet.enemiesKilled >= bullet.maxKills) {
bullet.destroy();
bullets.splice(i, 1);
}
break;
}
}
// Check bullet-giant enemy collisions
for (var g = giantEnemies.length - 1; g >= 0; g--) {
var giantEnemy = giantEnemies[g];
if (bullet.intersects(giantEnemy)) {
// Hit giant enemy
giantEnemy.health--;
bullet.enemiesKilled++;
LK.setScore(LK.getScore() + 50);
scoreTxt.setText('Score: ' + LK.getScore() + ' | Kills: ' + totalKills + ' | Bullets: ' + bulletsPerShot);
LK.getSound('hit').play();
LK.effects.flashObject(giantEnemy, 0xffffff, 200);
// Check if giant enemy is defeated
if (giantEnemy.health <= 0) {
totalKills++;
giantEnemy.destroy();
giantEnemies.splice(g, 1);
}
// Only remove bullet if it has killed maximum enemies
if (bullet.enemiesKilled >= bullet.maxKills) {
bullet.destroy();
bullets.splice(i, 1);
}
break;
}
}
}
// Check giant enemy-player collisions
for (var g = 0; g < giantEnemies.length; g++) {
var giantEnemy = giantEnemies[g];
// Check shield collision first
if (playerShield.isActive && giantEnemy.intersects(playerShield)) {
// Shield blocks giant enemy contact
if (giantEnemy.lastShieldHit === undefined) giantEnemy.lastShieldHit = false;
if (!giantEnemy.lastShieldHit) {
giantEnemy.lastShieldHit = true;
LK.effects.flashObject(playerShield, 0xffffff, 200);
// Push giant enemy back slightly
var dx = giantEnemy.x - player.x;
var dy = giantEnemy.y - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
giantEnemy.x += dx / distance * 20;
giantEnemy.y += dy / distance * 20;
}
}
} else {
giantEnemy.lastShieldHit = false;
}
if (giantEnemy.intersects(player) && (!playerShield.isActive || !giantEnemy.intersects(playerShield))) {
// Add collision tracking to prevent multiple hits per frame
if (giantEnemy.lastPlayerHit === undefined) giantEnemy.lastPlayerHit = false;
if (!giantEnemy.lastPlayerHit) {
giantEnemy.lastPlayerHit = true;
if (damagePlayer()) {
return; // Player died, exit update loop
}
}
} else {
giantEnemy.lastPlayerHit = false;
}
}
// Update enemy bullets
for (var eb = enemyBullets.length - 1; eb >= 0; eb--) {
var enemyBullet = enemyBullets[eb];
// Remove off-screen enemy bullets
if (enemyBullet.shouldDestroy) {
enemyBullet.destroy();
enemyBullets.splice(eb, 1);
continue;
}
// Check enemy bullet-shield collision first
if (playerShield.isActive && enemyBullet.intersects(playerShield)) {
// Shield blocks the bullet
LK.effects.flashObject(playerShield, 0xffffff, 200);
enemyBullet.destroy();
enemyBullets.splice(eb, 1);
continue;
}
// Check enemy bullet-player collision
if (enemyBullet.intersects(player)) {
if (damagePlayer()) {
return; // Player died, exit update loop
}
enemyBullet.destroy();
enemyBullets.splice(eb, 1);
continue;
}
}
// Update warnings
for (var w = warnings.length - 1; w >= 0; w--) {
var warning = warnings[w];
if (warning.shouldSpawnLightning) {
// Create lightning at warning position
var lightning = game.addChild(new Lightning());
lightning.x = warning.x;
lightning.y = warning.y;
lightnings.push(lightning);
// Remove warning
warning.destroy();
warnings.splice(w, 1);
}
}
// Update lightnings
for (var l = lightnings.length - 1; l >= 0; l--) {
var lightning = lightnings[l];
// Check lightning-player collision
if (lightning.intersects(player)) {
// Lightning kills player instantly
if (damagePlayer()) {
return; // Player died, exit update loop
}
}
// Check lightning-shield collision
if (playerShield.isActive && lightning.intersects(playerShield)) {
// Shield blocks lightning but gets destroyed
LK.effects.flashObject(playerShield, 0xffffff, 300);
playerShield.isActive = false;
playerShield.visible = false;
playerShield.cooldownTimer = playerShield.cooldown;
}
// Remove lightning when timer expires
if (lightning.shouldDestroy) {
lightning.destroy();
lightnings.splice(l, 1);
}
}
// Check win condition - player wins at 10,000 points
if (LK.getScore() >= 10000) {
LK.showYouWin();
}
// Spawn new enemies if all are destroyed
if (enemies.length === 0) {
spawnEnemies();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -1,8 +1,9 @@
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
@@ -516,8 +517,24 @@
shootInstructionTxt.anchor.set(0, 1);
shootInstructionTxt.x = 20;
shootInstructionTxt.y = -20;
LK.gui.bottomLeft.addChild(shootInstructionTxt);
+// Slow motion system
+var slowMotionActive = false;
+var slowMotionTimer = 0;
+var slowMotionDuration = 300; // 5 seconds at 60fps
+var slowMotionCooldown = 108000000; // 30 minutes in milliseconds
+var slowMotionLastUsed = storage.slowMotionLastUsed || 0;
+var gameSpeed = 1.0;
+// Slow motion button
+var slowMotionButton = new Text2('SLOW\nMOTION', {
+ size: 30,
+ fill: 0x9c27b0
+});
+slowMotionButton.anchor.set(0, 0);
+slowMotionButton.x = 20;
+slowMotionButton.y = 20;
+LK.gui.topRight.addChild(slowMotionButton);
// Initialize player
player = game.addChild(new Player());
player.x = 1024;
player.y = 2400;
@@ -623,14 +640,27 @@
var guiPos = LK.gui.toLocal({
x: x,
y: y
});
- // Check movement buttons (approximate button areas)
- if (guiPos.x < 400 && guiPos.y > LK.gui.height - 400) {
+ // Check slow motion button (top right corner)
+ if (guiPos.x > LK.gui.width - 150 && guiPos.x < LK.gui.width - 20 && guiPos.y > 20 && guiPos.y < 100) {
+ // Slow motion button pressed
+ var currentTime = Date.now();
+ var timeSinceLastUse = currentTime - slowMotionLastUsed;
+ if (timeSinceLastUse >= slowMotionCooldown && !slowMotionActive) {
+ // Activate slow motion
+ slowMotionActive = true;
+ slowMotionTimer = slowMotionDuration;
+ gameSpeed = 0.3; // Slow down to 30% speed
+ slowMotionLastUsed = currentTime;
+ storage.slowMotionLastUsed = currentTime;
+ LK.effects.flashScreen(0x9c27b0, 300);
+ }
+ } else if (guiPos.x < 400 && guiPos.y > LK.gui.height - 400) {
// Left button area
moveLeft = true;
} else if (guiPos.x > LK.gui.width - 400 && guiPos.y > LK.gui.height - 400) {
- // Right button area
+ // Right button area
moveRight = true;
} else if (guiPos.x > LK.gui.width / 2 - 100 && guiPos.x < LK.gui.width / 2 + 100 && guiPos.y > LK.gui.height - 500 && guiPos.y < LK.gui.height - 300) {
// Up button area
moveUp = true;
@@ -667,11 +697,37 @@
// Start background music
LK.playMusic('musicabg3');
// Main game update loop
game.update = function () {
- beatTimer++;
- giantEnemyTimer++;
- warningSpawnTimer++;
+ // Update slow motion system
+ if (slowMotionActive) {
+ slowMotionTimer--;
+ if (slowMotionTimer <= 0) {
+ slowMotionActive = false;
+ gameSpeed = 1.0; // Return to normal speed
+ }
+ }
+ // Update slow motion button status
+ var currentTime = Date.now();
+ var timeSinceLastUse = currentTime - slowMotionLastUsed;
+ var cooldownRemaining = slowMotionCooldown - timeSinceLastUse;
+ if (slowMotionActive) {
+ var timeLeft = slowMotionTimer / 60.0;
+ slowMotionButton.setText('SLOW\nMOTION\n' + timeLeft.toFixed(1) + 's');
+ slowMotionButton.fill = 0x4caf50; // Green when active
+ } else if (cooldownRemaining > 0) {
+ var minutesLeft = Math.ceil(cooldownRemaining / 60000);
+ slowMotionButton.setText('SLOW\nMOTION\n' + minutesLeft + 'm');
+ slowMotionButton.fill = 0xff5722; // Red when on cooldown
+ } else {
+ slowMotionButton.setText('SLOW\nMOTION\nREADY');
+ slowMotionButton.fill = 0x9c27b0; // Purple when ready
+ }
+ // Apply game speed to timers (when in slow motion, game runs slower)
+ var speedMultiplier = slowMotionActive ? gameSpeed : 1.0;
+ beatTimer += speedMultiplier;
+ giantEnemyTimer += speedMultiplier;
+ warningSpawnTimer += speedMultiplier;
// Warning spawn system
if (warningSpawnTimer >= warningSpawnInterval) {
// Spawn warning at random position
var warning = game.addChild(new Warning());
@@ -728,24 +784,25 @@
if (shootWindowTimer >= shootWindow) {
canShootWindow = false;
}
}
- // Update player movement
+ // Update player movement (affected by slow motion)
+ var effectivePlayerSpeed = player.speed * gameSpeed;
if (moveLeft && player.x > 35) {
- player.x -= player.speed;
+ player.x -= effectivePlayerSpeed;
}
if (moveRight && player.x < 2048 - 35) {
- player.x += player.speed;
+ player.x += effectivePlayerSpeed;
}
if (moveUp && player.y > 35) {
- player.y -= player.speed;
+ player.y -= effectivePlayerSpeed;
}
if (moveDown && player.y < 2732 - 35) {
- player.y += player.speed;
+ player.y += effectivePlayerSpeed;
}
- // Update shooting cooldown
+ // Update shooting cooldown (affected by slow motion)
if (shootCooldown > 0) {
- shootCooldown--;
+ shootCooldown -= gameSpeed;
if (shootCooldown <= 0) {
canShoot = true;
}
}