User prompt
El botón un poco más separado de los bordes y más grande
User prompt
Se puntúa también por segundo con vida, y agregar un botón para los disparos abajo en la derecha
User prompt
El disparo siempre se realiza hacia delante
User prompt
Agrega disparo y cada vez que se destruya un obstáculo suma 10 puntos
User prompt
Los obstáculos tienen q llegar en un tamaño más grande a la circunferencia que se desplaza el jugador
User prompt
Los destellos en distintos tamaños y más rápido ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
La Luna gira sobre si misma y tiene destellos desde distintos punto de la misma ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
No suena nada
User prompt
Sonido al conseguir una vida
User prompt
Los obstáculos desaparantes de impactar con la Luna
User prompt
Los obstáculos aparecen el doble de tamaño
User prompt
Los obstáculos van reduciendo su tamaño hacia el centro sin llegar a tocar la luna ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
En el centro en vez de un obstáculo una luna
User prompt
Con la regla de tamaño que puse para las estrellas todas más grande
User prompt
Los destellos de las estrellas aparte de amarillo también azul ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Coloca arriba a la derecha el récord ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Que salga solo un icono de vida y el número restante de vida. Abajo en la izquierda
User prompt
En vez de poner live, a las vidas colócale el icono del jugador
User prompt
El contador de vida aparece abajo
User prompt
Crea power-up de vida ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
Las estrellas giran ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Los tamaños de las estrellas más grandes y emiten destellos amarillos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Las estrellas deben de ser de distintos tamaños más grande cuando se encuentren cerca del bode de la pantalla y más pequeñas cuando se encuentren más al centro
User prompt
Agrega un fondo estrellado
User prompt
Agrega sistema de vida ↪💡 Consider importing and using the following plugins: @upit/storage.v1
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
lives: 3,
maxLives: 3
});
/****
* Classes
****/
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('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
tint: 0x00ff00
});
// 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: 2,
scaleY: 2
});
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);
if (distance > 5) {
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.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);
}
}
};
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;
};
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 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
// 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);
// 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);
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
var lifeIcon = LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
lifeIcon.x = 40; // Position icon from left edge
lifeIcon.y = 0;
lifeIcon.rotation = -Math.PI * 1.5; // Same rotation as main player
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();
// 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) {
// Play power-up sound
LK.getSound('powerup').play();
// Add life if not at maximum
if (currentLives < maxLives) {
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;
}
var currentIntersecting = player.intersects(obstacle);
// 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;
}
}
// Clean up obstacles that reach center
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 < 30) {
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 based on survival time
var currentScore = Math.floor(LK.ticks / 60); // Score increases every second
LK.setScore(currentScore);
scoreTxt.setText(currentScore);
// 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();
// Check for collisions
checkCollisions();
}; ===================================================================
--- original.js
+++ change.js
@@ -297,15 +297,15 @@
}
}
// Initialize starfield
createStarfield();
-// Create center circle indicator
-var centerIndicator = LK.getAsset('obstacle', {
+// Create center moon indicator
+var centerIndicator = LK.getAsset('moon', {
anchorX: 0.5,
anchorY: 0.5,
- scaleX: 3,
- scaleY: 3,
- alpha: 0.1
+ scaleX: 2,
+ scaleY: 2,
+ alpha: 0.8
});
centerIndicator.x = 2048 / 2;
centerIndicator.y = 2732 / 2;
game.addChild(centerIndicator);
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