User prompt
Los obstáculos más pequeños aparecerán de 80x80
User prompt
Los obstáculos más pequeños serán de 30x30
User prompt
Cuando tienes inmunidad al colisionar con un obstáculo desaparece el obstáculo y sumas 10 puntos, además la inmunidad dura 10 segundos
User prompt
Crea Power-up de inmunidad ,crea su assets ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
El número de vida sube cuando se coge una, sin máximo
User prompt
El rango para la regla de colisión es de un 25% más pequeño que el obstáculo
User prompt
El rango para la regla de colisión es de un 10% más pequeño que el obstáculo
User prompt
Las balas atraviesan la luna no afecta esa colisión entre luna y bala
User prompt
Revisa los obstáculos que solo desaparezcan en la colisión con : el jugador, el disparo o la luna
User prompt
Crea un assets para el contador de vida
User prompt
Crea un assets para el power-up de vida
User prompt
Borra el menú
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'documentElement')' in or related to this line: 'if (storage.fullscreen && document.documentElement.requestFullscreen) {' Line Number: 393 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'orientation')' in or related to this line: 'if (screen.orientation && screen.orientation.lock) {' Line Number: 404 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Por defecto empieza vertical ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'orientation')' in or related to this line: 'if (storage.orientation && screen.orientation && screen.orientation.lock) {' Line Number: 753 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Agrega un menú donde se pueda elegir pantalla completa, y jugar en horizontal o vertical ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Preparalo para jugar con la pantalla girada 90 grados
User prompt
Coloca el juego para jugar apaisado
User prompt
Crea el assets para la imagen del botón de disparo
User prompt
Los destellos de la luna pueden ser blancos, amarillos, naranjas o rojos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Los destellos de la luna solamente cada vez que le impacte un obstáculo y en la zona del impacto ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Los obstáculos no se reducen el tamaño hasta pasar la órbita del jugador ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
El botón más despegado de los bordes
User prompt
El botón más grande como x4
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
lives: 3,
maxLives: 3
});
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3,
tint: 0xffff00
});
self.speed = 12;
self.velocityX = 0;
self.velocityY = 0;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
// Remove bullet if it goes off screen
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
self.destroy();
}
};
return self;
});
var FireParticle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6,
tint: 0xff4500
});
self.life = 1.0;
self.velocityX = 0;
self.velocityY = 0;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.life -= 0.05;
particleGraphics.alpha = self.life;
particleGraphics.scaleX = self.life * 0.6;
particleGraphics.scaleY = self.life * 0.6;
if (self.life <= 0) {
self.destroy();
}
};
return self;
});
var LifePowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('heart', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2,
tint: 0xff1493
});
// Rotation and pulsing effect
self.rotationSpeed = 0.05;
self.pulsePhase = 0;
self.pulseSpeed = 0.1;
self.baseScale = 0.8;
self.lifetime = 600; // 10 seconds at 60fps
self.age = 0;
self.update = function () {
// Rotate the power-up
powerUpGraphics.rotation += self.rotationSpeed;
// Pulsing scale effect
self.pulsePhase += self.pulseSpeed;
var pulseFactor = 1 + Math.sin(self.pulsePhase) * 0.2;
powerUpGraphics.scaleX = self.baseScale * pulseFactor;
powerUpGraphics.scaleY = self.baseScale * pulseFactor;
// Age and fade out near end of lifetime
self.age++;
if (self.age > self.lifetime * 0.7) {
var fadeProgress = (self.age - self.lifetime * 0.7) / (self.lifetime * 0.3);
powerUpGraphics.alpha = 1 - fadeProgress;
}
// Remove when lifetime expires
if (self.age >= self.lifetime) {
self.destroy();
}
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
self.speed = 2;
self.targetX = 2048 / 2;
self.targetY = 2732 / 2;
self.update = function () {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Calculate scale based on distance from center, but only start scaling after passing player orbit
var playerOrbitDistance = 400; // Player orbit distance from center
var maxDistance = Math.sqrt(2048 / 2 * (2048 / 2) + 2732 / 2 * (2732 / 2)); // Max distance from center to corner
var minDistance = 80; // Stop before touching the moon (moon radius ~60px)
var scale;
if (distance > playerOrbitDistance) {
// Maintain original size until reaching player orbit
scale = 4.0; // Original obstacle scale
} else {
// Start scaling only after passing player orbit
var normalizedDistance = Math.max(0, Math.min(1, (distance - minDistance) / (playerOrbitDistance - minDistance)));
scale = 0.3 + normalizedDistance * 3.7; // Scale from 0.3 to 4.0 within player orbit
}
// Apply scale with tween for smooth transition
tween(obstacleGraphics, {
scaleX: scale,
scaleY: scale
}, {
duration: 100,
easing: tween.easeOut
});
// Always move toward center - obstacles will disappear before reaching moon
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
// Rotate obstacle continuously as it moves
obstacleGraphics.rotation += 0.1;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
// Make it look more like a spaceship by rotating it to point upward
playerGraphics.rotation = -Math.PI * 1.5; // Rotated an additional 90 degrees
self.speed = 8;
self.targetX = self.x;
self.targetY = self.y;
self.lastX = self.x;
self.lastY = self.y;
self.fireParticles = [];
self.bullets = [];
self.shootCooldown = 0;
self.engineSoundPlaying = false;
self.update = function () {
// Store last position for movement detection
self.lastX = self.x;
self.lastY = self.y;
// Smooth movement toward target position
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var isMoving = Math.abs(dx) > 1 || Math.abs(dy) > 1;
if (isMoving) {
self.x += dx * 0.15;
self.y += dy * 0.15;
// Play engine sound when moving
if (!self.engineSoundPlaying) {
self.engineSound = LK.getSound('engine');
self.engineSound.play();
self.engineSoundPlaying = true;
}
} else {
// Stop engine sound when not moving
if (self.engineSoundPlaying) {
if (self.engineSound) {
self.engineSound.stop();
}
self.engineSoundPlaying = false;
}
}
// Calculate angle to center and rotate spaceship to point toward it
var centerX = 2048 / 2;
var centerY = 2732 / 2;
var angleToCenter = Math.atan2(centerY - self.y, centerX - self.x);
var targetRotation = angleToCenter - Math.PI / 2; // Point toward center
// Smooth rotation toward target angle using tween
tween(playerGraphics, {
rotation: targetRotation
}, {
duration: 100,
easing: tween.easeOut
});
// Create fire particles when moving
if (isMoving) {
var particle = new FireParticle();
// Always position particle from the left side of player (consistent side)
var leftSideOffsetX = -35; // Fixed offset to the left
var leftSideOffsetY = 0;
particle.x = self.x + leftSideOffsetX;
particle.y = self.y + leftSideOffsetY;
// Add velocity toward the left side (consistent direction)
particle.velocityX = -2 - Math.random() * 2;
particle.velocityY = 0;
// Add some random spread
particle.velocityX += (Math.random() - 0.5) * 2;
particle.velocityY += (Math.random() - 0.5) * 2;
self.fireParticles.push(particle);
game.addChild(particle);
}
// Clean up dead particles
for (var i = self.fireParticles.length - 1; i >= 0; i--) {
if (self.fireParticles[i].life <= 0) {
self.fireParticles.splice(i, 1);
}
}
// Update shooting cooldown
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
// Clean up bullets that are destroyed
for (var i = self.bullets.length - 1; i >= 0; i--) {
var bullet = self.bullets[i];
if (bullet.destroyed || bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) {
self.bullets.splice(i, 1);
}
}
};
self.moveTo = function (x, y) {
// Keep player within central area bounds
var centerX = 2048 / 2;
var centerY = 2732 / 2;
var maxDistance = 400;
// Always constrain player to move only on the circular path at maxDistance
var angle = Math.atan2(y - centerY, x - centerX);
self.targetX = centerX + Math.cos(angle) * maxDistance;
self.targetY = centerY + Math.sin(angle) * maxDistance;
};
self.shoot = function () {
if (self.shootCooldown <= 0) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
// Always shoot toward center (moon)
var centerX = 2048 / 2;
var centerY = 2732 / 2;
var dx = centerX - self.x;
var dy = centerY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
bullet.velocityX = dx / distance * bullet.speed;
bullet.velocityY = dy / distance * bullet.speed;
self.bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
self.shootCooldown = 15; // Cooldown between shots
}
};
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
// Random star properties
self.twinkleSpeed = 0.02 + Math.random() * 0.03;
self.twinklePhase = Math.random() * Math.PI * 2;
self.baseAlpha = 0.5 + Math.random() * 0.5;
self.isFlashing = false;
self.flashTimer = 0;
self.nextFlashTime = Math.random() * 300 + 120; // Random time between 2-7 seconds
self.updateScale = function () {
// Calculate distance from center of screen
var centerX = 2048 / 2;
var centerY = 2732 / 2;
var dx = self.x - centerX;
var dy = self.y - centerY;
var distanceFromCenter = Math.sqrt(dx * dx + dy * dy);
// Maximum possible distance from center to corner
var maxDistance = Math.sqrt(centerX * centerX + centerY * centerY);
// Scale factor: 3.0 at center, 8.0 at edges (much larger stars)
var normalizedDistance = distanceFromCenter / maxDistance;
var scale = 3.0 + normalizedDistance * 5.0;
starGraphics.scaleX = scale;
starGraphics.scaleY = scale;
};
self.update = function () {
// Normal twinkling effect
if (!self.isFlashing) {
self.twinklePhase += self.twinkleSpeed;
starGraphics.alpha = self.baseAlpha + Math.sin(self.twinklePhase) * 0.3;
starGraphics.tint = 0xffffff;
// Check if it's time for a colored flash
self.flashTimer++;
if (self.flashTimer >= self.nextFlashTime) {
self.isFlashing = true;
self.flashTimer = 0;
// Randomly choose between yellow and blue flash
var flashColor = Math.random() < 0.5 ? 0xffff00 : 0x00aaff;
// Start colored flash tween
tween(starGraphics, {
tint: flashColor
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
// Fade back to white
tween(starGraphics, {
tint: 0xffffff
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
self.isFlashing = false;
self.nextFlashTime = Math.random() * 300 + 120; // Next flash in 2-7 seconds
}
});
}
});
}
} else {
// During flash, maintain bright alpha
starGraphics.alpha = 1.0;
}
// Update scale based on distance from center
self.updateScale();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
var player;
var obstacles = [];
var bullets = [];
var stars = [];
var powerUps = [];
var gameStarted = false;
var spawnTimer = 0;
var spawnRate = 120; // Initial spawn rate (ticks between spawns)
var difficultyTimer = 0;
var baseObstacleSpeed = 2;
var currentLives = storage.lives || 3;
var maxLives = storage.maxLives || 3;
var invulnerabilityTimer = 0;
var invulnerabilityDuration = 120; // 2 seconds at 60fps
var powerUpSpawnTimer = 0;
var powerUpSpawnRate = 1800; // Spawn power-up every 30 seconds at 60fps
var timeScoreTimer = 0;
var timeScoreRate = 60; // Award points every second (60 ticks)
// Create starfield background
function createStarfield() {
for (var i = 0; i < 150; i++) {
var star = new Star();
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
// Apply initial scaling based on position
star.updateScale();
stars.push(star);
game.addChild(star);
}
}
// Initialize starfield
createStarfield();
// Create center moon indicator
var centerIndicator = LK.getAsset('moon', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
alpha: 0.8
});
centerIndicator.x = 2048 / 2;
centerIndicator.y = 2732 / 2;
game.addChild(centerIndicator);
// Start continuous moon rotation
tween(centerIndicator, {
rotation: Math.PI * 2
}, {
duration: 8000,
easing: tween.linear,
onFinish: function onFinish() {
// Reset rotation and start again for infinite loop
centerIndicator.rotation = 0;
tween(centerIndicator, {
rotation: Math.PI * 2
}, {
duration: 8000,
easing: tween.linear,
onFinish: arguments.callee // Reference to this same function for infinite loop
});
}
});
// Create sparkle effects container for moon impact glimmers
var moonSparkles = [];
function createMoonSparkle(impactX, impactY) {
// Random initial size for sparkles - vary between small, medium and large
var initialSize = 4 + Math.random() * 12; // Range from 4 to 16
// Random sparkle color - white, yellow, orange, or red
var sparkleColors = [0xffffff, 0xffff00, 0xff8800, 0xff0000];
var randomColor = sparkleColors[Math.floor(Math.random() * sparkleColors.length)];
var sparkle = LK.getAsset('star', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: initialSize,
scaleY: initialSize,
alpha: 0,
tint: randomColor
});
// Position sparkle at the impact location on moon's surface
sparkle.x = impactX;
sparkle.y = impactY;
game.addChild(sparkle);
moonSparkles.push(sparkle);
// Calculate target sizes - make them grow to 1.5-2x their initial size
var maxSize = initialSize * (1.5 + Math.random() * 0.5);
var endSize = initialSize * 0.3;
// Sparkle animation - fade in, scale up, then fade out (much faster)
tween(sparkle, {
alpha: 1,
scaleX: maxSize,
scaleY: maxSize
}, {
duration: 120,
// Much faster - was 300ms, now 120ms
easing: tween.easeOut,
onFinish: function onFinish() {
tween(sparkle, {
alpha: 0,
scaleX: endSize,
scaleY: endSize
}, {
duration: 180,
// Much faster - was 400ms, now 180ms
easing: tween.easeIn,
onFinish: function onFinish() {
sparkle.destroy();
// Remove from array
for (var i = moonSparkles.length - 1; i >= 0; i--) {
if (moonSparkles[i] === sparkle) {
moonSparkles.splice(i, 1);
break;
}
}
}
});
}
});
}
// Create player
player = new Player();
player.x = 2048 / 2;
player.y = 2732 / 2;
game.addChild(player);
// Score display
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// High score display
var highScore = storage.highScore || 0;
var highScoreTxt = new Text2('Best: ' + highScore, {
size: 60,
fill: 0xFFD700
});
highScoreTxt.anchor.set(1, 0);
highScoreTxt.y = 0;
LK.gui.topRight.addChild(highScoreTxt);
// Lives display with player icons
var livesContainer = new Container();
var lifeIcons = [];
function updateLivesDisplay() {
// Clear existing icons and text
for (var i = 0; i < lifeIcons.length; i++) {
lifeIcons[i].destroy();
}
lifeIcons = [];
if (livesContainer.livesText) {
livesContainer.livesText.destroy();
}
// Create single life icon using heart asset
var lifeIcon = LK.getAsset('heartIcon', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2,
tint: 0xff4444
});
lifeIcon.x = 40; // Position icon from left edge
lifeIcon.y = 0;
lifeIcons.push(lifeIcon);
livesContainer.addChild(lifeIcon);
// Create lives number text
var livesText = new Text2('x' + currentLives, {
size: 60,
fill: 0xFFFFFF
});
livesText.anchor.set(0, 0.5);
livesText.x = 80; // Position text next to icon
livesText.y = 0;
livesContainer.livesText = livesText;
livesContainer.addChild(livesText);
}
livesContainer.x = 0;
livesContainer.y = 0;
LK.gui.bottomLeft.addChild(livesContainer);
updateLivesDisplay();
// Create shoot button in bottom right
var shootButtonContainer = new Container();
var shootButton = LK.getAsset('shootButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4,
alpha: 0.8
});
shootButtonContainer.addChild(shootButton);
shootButtonContainer.x = -120;
shootButtonContainer.y = -120;
LK.gui.bottomRight.addChild(shootButtonContainer);
// Add shoot button touch handler
shootButtonContainer.down = function (x, y, obj) {
if (gameStarted) {
player.shoot();
// Visual feedback - briefly scale and flash the button
tween(shootButton, {
scaleX: 5,
scaleY: 5,
alpha: 1.0
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(shootButton, {
scaleX: 4,
scaleY: 4,
alpha: 0.8
}, {
duration: 100,
easing: tween.easeIn
});
}
});
}
};
// Game instructions
var instructionTxt = new Text2('Touch to move around the center', {
size: 60,
fill: 0xCCCCCC
});
instructionTxt.anchor.set(0.5, 0.5);
instructionTxt.x = 2048 / 2;
instructionTxt.y = 2732 / 2 + 80;
game.addChild(instructionTxt);
function updateLives(newLives) {
currentLives = Math.max(0, Math.min(maxLives, newLives));
storage.lives = currentLives;
updateLivesDisplay();
if (currentLives <= 0) {
LK.showGameOver();
}
}
function spawnObstacle() {
var obstacle = new Obstacle();
// Random spawn position along screen edges
var edge = Math.floor(Math.random() * 4);
switch (edge) {
case 0:
// Top edge
obstacle.x = Math.random() * 2048;
obstacle.y = -50;
break;
case 1:
// Right edge
obstacle.x = 2048 + 50;
obstacle.y = Math.random() * 2732;
break;
case 2:
// Bottom edge
obstacle.x = Math.random() * 2048;
obstacle.y = 2732 + 50;
break;
case 3:
// Left edge
obstacle.x = -50;
obstacle.y = Math.random() * 2732;
break;
}
// Add random size variation to obstacles
var randomScale = 0.5 + Math.random() * 1.5; // Random scale between 0.5x and 2x
obstacle.scaleX = randomScale;
obstacle.scaleY = randomScale;
// Set speed based on current difficulty
obstacle.speed = baseObstacleSpeed + difficultyTimer / 3600 * 2; // Increase speed over time
obstacles.push(obstacle);
game.addChild(obstacle);
}
function spawnPowerUp() {
if (currentLives >= maxLives) return; // Don't spawn if already at max lives
var powerUp = new LifePowerUp();
// Spawn in a safe area around the player's orbit
var centerX = 2048 / 2;
var centerY = 2732 / 2;
var angle = Math.random() * Math.PI * 2;
var distance = 300 + Math.random() * 200; // Between player orbit and center
powerUp.x = centerX + Math.cos(angle) * distance;
powerUp.y = centerY + Math.sin(angle) * distance;
powerUps.push(powerUp);
game.addChild(powerUp);
}
function checkCollisions() {
// Check power-up collisions
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
// Initialize collision tracking if not present
if (powerUp.lastIntersecting === undefined) {
powerUp.lastIntersecting = false;
}
var currentIntersecting = player.intersects(powerUp);
// Check if collection just started (transition from false to true)
if (!powerUp.lastIntersecting && currentIntersecting) {
// Add life if not at maximum
if (currentLives < maxLives) {
// Play power-up sound when gaining a life
LK.getSound('lifeup').play();
updateLives(currentLives + 1);
LK.effects.flashScreen(0x00ff00, 300); // Green flash for power-up
// Create collection effect with tween
tween(powerUp, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
powerUp.destroy();
}
});
powerUps.splice(i, 1);
continue; // Skip further checks for this power-up
} else {
// Still destroy if at max lives
powerUp.destroy();
powerUps.splice(i, 1);
continue;
}
}
// Update last intersecting state
powerUp.lastIntersecting = currentIntersecting;
}
// Clean up expired power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (powerUp.age >= powerUp.lifetime) {
powerUps.splice(i, 1);
}
}
// Only check collisions if not invulnerable
if (invulnerabilityTimer <= 0) {
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
// Initialize collision tracking if not present
if (obstacle.lastIntersecting === undefined) {
obstacle.lastIntersecting = false;
}
// Create smaller collision area (75% of obstacle size) for more forgiving gameplay
var collisionScale = 0.75;
var originalScaleX = obstacle.scaleX;
var originalScaleY = obstacle.scaleY;
// Temporarily reduce obstacle scale for collision detection
obstacle.scaleX = originalScaleX * collisionScale;
obstacle.scaleY = originalScaleY * collisionScale;
var currentIntersecting = player.intersects(obstacle);
// Restore original scale
obstacle.scaleX = originalScaleX;
obstacle.scaleY = originalScaleY;
// Check if collision just started (transition from false to true)
if (!obstacle.lastIntersecting && currentIntersecting) {
// Play collision sound immediately when collision starts
LK.getSound('collision').play();
LK.effects.flashScreen(0xff0000, 500);
// Reduce life instead of immediate game over
updateLives(currentLives - 1);
// Set invulnerability period
invulnerabilityTimer = invulnerabilityDuration;
// Remove the obstacle that hit the player
obstacle.destroy();
obstacles.splice(i, 1);
break; // Exit loop after first collision
}
// Update last intersecting state
obstacle.lastIntersecting = currentIntersecting;
}
}
// Check bullet-obstacle collisions
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
var hitByBullet = false;
for (var j = player.bullets.length - 1; j >= 0; j--) {
var bullet = player.bullets[j];
// Create smaller collision area (75% of obstacle size) for bullet collisions
var collisionScale = 0.75;
var originalScaleX = obstacle.scaleX;
var originalScaleY = obstacle.scaleY;
// Temporarily reduce obstacle scale for collision detection
obstacle.scaleX = originalScaleX * collisionScale;
obstacle.scaleY = originalScaleY * collisionScale;
var bulletHit = bullet.intersects(obstacle);
// Restore original scale
obstacle.scaleX = originalScaleX;
obstacle.scaleY = originalScaleY;
if (bulletHit) {
// Add 10 points for destroying obstacle
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
// Update high score if current score is higher
if (LK.getScore() > highScore) {
highScore = LK.getScore();
storage.highScore = highScore;
highScoreTxt.setText('Best: ' + highScore);
}
// Create destruction effect
tween(obstacle, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 150,
easing: tween.easeIn,
onFinish: function onFinish() {
obstacle.destroy();
}
});
// Remove bullet
bullet.destroy();
player.bullets.splice(j, 1);
// Remove obstacle
obstacles.splice(i, 1);
hitByBullet = true;
break;
}
}
if (hitByBullet) continue;
}
// Bullets now pass through the moon without collision detection
// Clean up obstacles that reach close to the moon - make them disappear with effect
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
var distanceToCenter = Math.sqrt((obstacle.x - 2048 / 2) * (obstacle.x - 2048 / 2) + (obstacle.y - 2732 / 2) * (obstacle.y - 2732 / 2));
if (distanceToCenter < 80) {
// Moon collision radius
// Create impact sparkle at obstacle's current position
createMoonSparkle(obstacle.x, obstacle.y);
// Make obstacle disappear with fade effect when touching the moon
tween(obstacle, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
obstacle.destroy();
}
});
obstacles.splice(i, 1);
}
}
}
function updateDifficulty() {
difficultyTimer++;
// Increase spawn rate every 5 seconds
if (difficultyTimer % 300 === 0 && spawnRate > 30) {
spawnRate -= 5;
}
}
game.down = function (x, y, obj) {
if (!gameStarted) {
gameStarted = true;
instructionTxt.destroy();
}
player.moveTo(x, y);
};
game.move = function (x, y, obj) {
if (gameStarted) {
player.moveTo(x, y);
}
};
game.update = function () {
if (!gameStarted) return;
// Update invulnerability timer
if (invulnerabilityTimer > 0) {
invulnerabilityTimer--;
// Make player flash during invulnerability
player.alpha = invulnerabilityTimer % 10 < 5 ? 0.5 : 1.0;
} else {
player.alpha = 1.0;
}
// Update score display (score is now updated in collision detection)
scoreTxt.setText(LK.getScore());
// Update high score if current score is higher
if (currentScore > highScore) {
highScore = currentScore;
storage.highScore = highScore;
highScoreTxt.setText('Best: ' + highScore);
}
// Spawn obstacles
spawnTimer++;
if (spawnTimer >= spawnRate) {
spawnObstacle();
spawnTimer = 0;
}
// Spawn power-ups
powerUpSpawnTimer++;
if (powerUpSpawnTimer >= powerUpSpawnRate) {
spawnPowerUp();
powerUpSpawnTimer = 0;
}
// Update difficulty
updateDifficulty();
// Time-based scoring - award points for staying alive
timeScoreTimer++;
if (timeScoreTimer >= timeScoreRate) {
LK.setScore(LK.getScore() + 1);
timeScoreTimer = 0;
}
// Manual shooting only - removed auto-shoot
// Check for collisions
checkCollisions();
}; ===================================================================
--- original.js
+++ change.js
@@ -678,10 +678,10 @@
// Initialize collision tracking if not present
if (obstacle.lastIntersecting === undefined) {
obstacle.lastIntersecting = false;
}
- // Create smaller collision area (90% of obstacle size) for more forgiving gameplay
- var collisionScale = 0.9;
+ // Create smaller collision area (75% of obstacle size) for more forgiving gameplay
+ var collisionScale = 0.75;
var originalScaleX = obstacle.scaleX;
var originalScaleY = obstacle.scaleY;
// Temporarily reduce obstacle scale for collision detection
obstacle.scaleX = originalScaleX * collisionScale;
@@ -713,10 +713,10 @@
var obstacle = obstacles[i];
var hitByBullet = false;
for (var j = player.bullets.length - 1; j >= 0; j--) {
var bullet = player.bullets[j];
- // Create smaller collision area (90% of obstacle size) for bullet collisions
- var collisionScale = 0.9;
+ // Create smaller collision area (75% of obstacle size) for bullet collisions
+ var collisionScale = 0.75;
var originalScaleX = obstacle.scaleX;
var originalScaleY = obstacle.scaleY;
// Temporarily reduce obstacle scale for collision detection
obstacle.scaleX = originalScaleX * collisionScale;
Botón rojo con dibujo de bala en el interior. In-Game asset. 2d. High contrast. No shadows
Planeta tierra. In-Game asset. 2d. High contrast. No shadows
Rodeado de un corazón rosa
Escudo azul. In-Game asset. 2d. High contrast. No shadows
Boss espacial. In-Game asset. 2d. High contrast. No shadows
Bala azul. In-Game asset. 2d. High contrast. No shadows
Amarillo