User prompt
Has que la nave esté un poco más alante y has que cada 15 segundos los obstáculos caigan 5% más rápido y cada 50 puntos has q la nave aumente un poco más su velocidad
Code edit (1 edits merged)
Please save this source code
User prompt
Space Dodger
Initial prompt
Quiero hacer un juego el cual cuyo propósito sea q una nave espacial viaje en linea recta sin detenerse mientras van apareciendo meteoritos y basura espacial que debe ir esquivando has una barra en la parte inferior de la pantalla donde de manera táctil se pueda mover de izquierda a derecha para dirigir la nave
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var BackButton = Container.expand(function () {
var self = Container.call(this);
var buttonBg = self.attachAsset('backButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
tween(self.scale, {
x: 0.9,
y: 0.9
}, {
duration: 200
});
};
self.up = function (x, y, obj) {
tween(self.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.lastY = undefined;
self.update = function () {
self.y += self.speed;
// Add floating animation
self.x += Math.sin(LK.ticks * 0.1 + self.y * 0.01) * 0.5;
// Add rotation
graphics.rotation += 0.05;
};
return self;
});
var Debris = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('debris', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.lastY = undefined;
self.update = function () {
self.y += self.speed;
};
return self;
});
var ImmunityPower = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('immunityPower', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.lastY = undefined;
self.update = function () {
self.y += self.speed;
// Add pulsing animation
graphics.scaleX = 1 + Math.sin(LK.ticks * 0.1) * 0.2;
graphics.scaleY = 1 + Math.sin(LK.ticks * 0.1) * 0.2;
// Add rotation
graphics.rotation += 0.03;
};
return self;
});
var MenuButton = Container.expand(function (color) {
var self = Container.call(this);
var buttonBg = self.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5
});
if (color) buttonBg.tint = color;
self.down = function (x, y, obj) {
tween(self.scale, {
x: 0.9,
y: 0.9
}, {
duration: 200
});
};
self.up = function (x, y, obj) {
tween(self.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
};
return self;
});
var Meteorite = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('meteorite', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.lastY = undefined;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Projectile = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('boostButton', {
anchorX: 0.5,
anchorY: 0.5
});
graphics.scaleX = 0.3;
graphics.scaleY = 0.3;
self.speed = -8;
self.lastY = undefined;
self.update = function () {
self.y += self.speed;
};
return self;
});
var SensitivitySlider = Container.expand(function () {
var self = Container.call(this);
var sliderBar = self.attachAsset('sensSlider', {
anchorX: 0.5,
anchorY: 0.5
});
var sliderHandle = self.addChild(LK.getAsset('sensHandle', {
anchorX: 0.5,
anchorY: 0.5
}));
self.minX = -280;
self.maxX = 280;
self.isDragging = false;
self.down = function (x, y, obj) {
self.isDragging = true;
self.updateHandle(x);
};
self.up = function (x, y, obj) {
self.isDragging = false;
};
self.updateHandle = function (x) {
var localX = x - self.x;
localX = Math.max(self.minX, Math.min(self.maxX, localX));
sliderHandle.x = localX;
};
self.getSensitivity = function () {
return (sliderHandle.x + 280) / 560; // 0 to 1
};
self.setSensitivity = function (value) {
sliderHandle.x = value * 560 - 280;
};
return self;
});
var SettingsButton = Container.expand(function () {
var self = Container.call(this);
var buttonBg = self.attachAsset('settingsButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
tween(self.scale, {
x: 0.9,
y: 0.9
}, {
duration: 200
});
};
self.up = function (x, y, obj) {
tween(self.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
};
return self;
});
var Spaceship = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('spaceship', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var StartButton = Container.expand(function () {
var self = Container.call(this);
var buttonBg = self.attachAsset('startButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
tween(self.scale, {
x: 0.9,
y: 0.9
}, {
duration: 200
});
};
self.up = function (x, y, obj) {
tween(self.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
};
return self;
});
var TouchSlider = Container.expand(function () {
var self = Container.call(this);
var sliderBar = self.attachAsset('sliderBar', {
anchorX: 0.5,
anchorY: 0.5
});
var sliderHandle = self.addChild(LK.getAsset('sliderHandle', {
anchorX: 0.5,
anchorY: 0.5
}));
self.minX = -380;
self.maxX = 380;
self.isDragging = false;
self.down = function (x, y, obj) {
self.isDragging = true;
self.updateHandle(x);
};
self.up = function (x, y, obj) {
self.isDragging = false;
};
self.updateHandle = function (x) {
var localX = x - self.x;
localX = Math.max(self.minX, Math.min(self.maxX, localX));
sliderHandle.x = localX;
};
self.getSliderValue = function () {
return sliderHandle.x / 380;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000011
});
/****
* Game Code
****/
// Game state management
var gameState = 'menu'; // 'menu', 'settings', 'playing', 'airplanes'
var sensitivity = storage.sensitivity || 1.0;
var selectedAirplane = storage.selectedAirplane || 'classic';
// Menu elements
var titleText = new Text2('Hasta el infinito y más allá', {
size: 110,
fill: 0xFFD700,
font: "'Press Start 2P', 'VT323', 'Pixel Emulator', 'Courier New', monospace"
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 600;
game.addChild(titleText);
var startButton = game.addChild(new StartButton());
startButton.x = 2048 / 2;
startButton.y = 1200;
var settingsButton = game.addChild(new SettingsButton());
settingsButton.x = 2048 / 2;
settingsButton.y = 1400;
var airplaneButton = game.addChild(new MenuButton(0x44aa44));
airplaneButton.x = 2048 / 2;
airplaneButton.y = 1600;
// Settings menu elements (initially hidden)
var settingsTitle = new Text2('AJUSTAR SENSIBILIDAD', {
size: 80,
fill: 0xFFFFFF
});
settingsTitle.anchor.set(0.5, 0.5);
settingsTitle.x = 2048 / 2;
settingsTitle.y = 800;
settingsTitle.visible = false;
game.addChild(settingsTitle);
var sensitivitySlider = game.addChild(new SensitivitySlider());
sensitivitySlider.x = 2048 / 2;
sensitivitySlider.y = 1200;
sensitivitySlider.visible = false;
sensitivitySlider.setSensitivity(sensitivity);
var sensValueText = new Text2('Sensibilidad: ' + Math.round(sensitivity * 100) + '%', {
size: 60,
fill: 0xFFFFFF
});
sensValueText.anchor.set(0.5, 0.5);
sensValueText.x = 2048 / 2;
sensValueText.y = 1350;
sensValueText.visible = false;
game.addChild(sensValueText);
var backButton = game.addChild(new BackButton());
backButton.x = 2048 / 2;
backButton.y = 1500;
backButton.visible = false;
// Airplane selection menu elements (initially hidden)
var airplaneTitle = new Text2('ELEGIR AVIÓN', {
size: 80,
fill: 0xFFFFFF
});
airplaneTitle.anchor.set(0.5, 0.5);
airplaneTitle.x = 2048 / 2;
airplaneTitle.y = 600;
airplaneTitle.visible = false;
game.addChild(airplaneTitle);
var airplane1Button = game.addChild(new MenuButton(0x4444aa));
airplane1Button.x = 2048 / 2;
airplane1Button.y = 1000;
airplane1Button.visible = false;
var airplane2Button = game.addChild(new MenuButton(0xaa4444));
airplane2Button.x = 2048 / 2;
airplane2Button.y = 1200;
airplane2Button.visible = false;
var airplane3Button = game.addChild(new MenuButton(0x44aa44));
airplane3Button.x = 2048 / 2;
airplane3Button.y = 1400;
airplane3Button.visible = false;
var airplaneBackButton = game.addChild(new BackButton());
airplaneBackButton.x = 2048 / 2;
airplaneBackButton.y = 1600;
airplaneBackButton.visible = false;
// Decorative elements
var stars = [];
for (var i = 0; i < 50; i++) {
var star = game.addChild(LK.getAsset('star', {
anchorX: 0.5,
anchorY: 0.5
}));
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
star.alpha = Math.random() * 0.8 + 0.2;
stars.push(star);
}
var planet1 = game.addChild(LK.getAsset('planet', {
anchorX: 0.5,
anchorY: 0.5
}));
planet1.x = 200;
planet1.y = 300;
planet1.alpha = 0.6;
planet1.tint = 0x8888ff;
var planet2 = game.addChild(LK.getAsset('planet', {
anchorX: 0.5,
anchorY: 0.5
}));
planet2.x = 1800;
planet2.y = 2400;
planet2.alpha = 0.4;
planet2.tint = 0xff8888;
planet2.scaleX = 0.7;
planet2.scaleY = 0.7;
// Game elements (initially hidden)
var spaceship;
var obstacles = [];
var coins = [];
var coinSpawnTimer = 0;
var coinSpawnRate = 180;
var totalCoins = storage.totalCoins || 0;
var obstacleSpawnTimer = 0;
var obstacleSpawnRate = 90;
var gameSpeed = 1;
var spaceshipSpeed = 1;
var survivalTime = 0;
var difficultyTimer = 0;
var lastScoreCheck = 0;
var speedIncreaseTimer = 0;
var slider;
// Heart system variables
var hearts = 3;
var heartElements = [];
// Immunity power variables
var immunityPowers = [];
var immunitySpawnTimer = 0;
var immunitySpawnRate = 1500; // 25 seconds at 60 FPS
var isImmune = false;
var immunityDuration = 0;
var immunityMaxDuration = 600; // 10 seconds at 60 FPS
// Boost power variables
var isBoostActive = false;
var boostDuration = 0;
var boostMaxDuration = 1200; // 20 seconds at 60 FPS
var boostMultiplier = 2.5;
var boostCooldown = 0;
var boostMaxCooldown = 1800; // 30 seconds cooldown
// Shooting system variables
var projectiles = [];
var shootCooldown = 0;
var shootMaxCooldown = 900; // 15 seconds at 60 FPS
var canShoot = true;
// GUI elements (created but initially hidden)
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.visible = false;
LK.gui.top.addChild(scoreTxt);
var timeTxt = new Text2('Time: 0s', {
size: 60,
fill: 0xFFFFFF
});
timeTxt.anchor.set(1, 0);
timeTxt.visible = false;
LK.gui.topRight.addChild(timeTxt);
timeTxt.x = -20;
timeTxt.y = 100;
var coinsTxt = new Text2('Coins: ' + totalCoins, {
size: 50,
fill: 0xffd700
});
coinsTxt.anchor.set(0, 0);
coinsTxt.visible = false;
LK.gui.topLeft.addChild(coinsTxt);
coinsTxt.x = 120;
coinsTxt.y = 20;
var shootButton = LK.getAsset('boostButton', {
anchorX: 0.5,
anchorY: 0.5
});
shootButton.visible = false;
LK.gui.bottomRight.addChild(shootButton);
shootButton.x = -120;
shootButton.y = -120;
var shootStatusText = new Text2('SHOOT READY', {
size: 40,
fill: 0xff6600
});
shootStatusText.anchor.set(0.5, 0.5);
shootStatusText.visible = false;
LK.gui.bottom.addChild(shootStatusText);
shootStatusText.y = -180;
// Add cooldown indicator circle
var cooldownIndicator = LK.getAsset('boostButton', {
anchorX: 0.5,
anchorY: 0.5
});
cooldownIndicator.visible = false;
cooldownIndicator.alpha = 0.3;
cooldownIndicator.tint = 0x000000;
LK.gui.bottomRight.addChild(cooldownIndicator);
cooldownIndicator.x = -120;
cooldownIndicator.y = -120;
// Create heart GUI elements
for (var h = 0; h < 3; h++) {
var heartGui = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
heartGui.visible = false;
LK.gui.topRight.addChild(heartGui);
heartGui.x = -280 + h * 90;
heartGui.y = 40;
heartElements.push(heartGui);
}
var immunityStatusText = new Text2('', {
size: 50,
fill: 0x00ff88
});
immunityStatusText.anchor.set(0.5, 0.5);
immunityStatusText.visible = false;
LK.gui.center.addChild(immunityStatusText);
immunityStatusText.y = -200;
game.move = function (x, y, obj) {
if (gameState === 'playing' && slider && slider.isDragging) {
slider.updateHandle(x);
var sliderValue = slider.getSliderValue();
var currentSpeed = spaceshipSpeed * (isBoostActive ? boostMultiplier : 1);
spaceship.x = 2048 / 2 + sliderValue * 800 * currentSpeed * sensitivity;
spaceship.x = Math.max(100, Math.min(1948, spaceship.x));
} else if (gameState === 'settings' && sensitivitySlider.isDragging) {
sensitivitySlider.updateHandle(x);
sensitivity = sensitivitySlider.getSensitivity();
sensValueText.setText('Sensibilidad: ' + Math.round(sensitivity * 100) + '%');
storage.sensitivity = sensitivity;
}
};
// Add shoot button click handler
shootButton.down = function (x, y, obj) {
if (gameState === 'playing' && canShoot && shootCooldown <= 0) {
// Fire projectile
var projectile = new Projectile();
projectile.x = spaceship.x;
projectile.y = spaceship.y - 50;
projectile.lastY = projectile.y;
projectiles.push(projectile);
game.addChild(projectile);
// Play shooting sound
LK.getSound('shoot').play();
// Start cooldown
canShoot = false;
shootCooldown = shootMaxCooldown;
shootStatusText.setText('RELOADING...');
shootStatusText.fill = 0xff0000;
shootButton.tint = 0x666666;
// Button press animation
tween(shootButton.scale, {
x: 0.9,
y: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(shootButton.scale, {
x: 1.0,
y: 1.0
}, {
duration: 100,
easing: tween.easeIn
});
}
});
}
};
shootButton.up = function (x, y, obj) {
// Reset button scale on release
tween(shootButton.scale, {
x: 1.0,
y: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
};
game.down = function (x, y, obj) {
// Game down handler for other interactions
};
// Button handlers
startButton.up = function (x, y, obj) {
tween(startButton.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
startGame();
};
settingsButton.up = function (x, y, obj) {
tween(settingsButton.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
showSettings();
};
backButton.up = function (x, y, obj) {
tween(backButton.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
showMenu();
};
airplaneButton.up = function (x, y, obj) {
tween(airplaneButton.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
showAirplaneSelection();
};
airplane1Button.up = function (x, y, obj) {
tween(airplane1Button.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
selectedAirplane = 'classic';
storage.selectedAirplane = selectedAirplane;
showMenu();
};
airplane2Button.up = function (x, y, obj) {
tween(airplane2Button.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
selectedAirplane = 'fast';
storage.selectedAirplane = selectedAirplane;
showMenu();
};
airplane3Button.up = function (x, y, obj) {
tween(airplane3Button.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
selectedAirplane = 'robust';
storage.selectedAirplane = selectedAirplane;
showMenu();
};
airplaneBackButton.up = function (x, y, obj) {
tween(airplaneBackButton.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
showMenu();
};
function startGame() {
gameState = 'playing';
// Hide menu elements
titleText.visible = false;
startButton.visible = false;
settingsButton.visible = false;
airplaneButton.visible = false;
// Show game elements
spaceship = game.addChild(new Spaceship());
spaceship.x = 2048 / 2;
spaceship.y = 2000;
slider = game.addChild(new TouchSlider());
slider.x = 2048 / 2;
slider.y = 2600;
scoreTxt.visible = true;
timeTxt.visible = true;
// Reset game variables
obstacles = [];
coins = [];
coinSpawnTimer = 0;
obstacleSpawnTimer = 0;
obstacleSpawnRate = 90;
coinSpawnRate = 180;
gameSpeed = 1;
spaceshipSpeed = 1;
survivalTime = 0;
difficultyTimer = 0;
speedIncreaseTimer = 0;
lastScoreCheck = 0;
LK.setScore(0);
scoreTxt.setText('0');
timeTxt.setText('Time: 0s');
coinsTxt.visible = true;
coinsTxt.setText('Coins: ' + totalCoins);
// Reset heart system
hearts = 3;
for (var h = 0; h < heartElements.length; h++) {
heartElements[h].visible = true;
heartElements[h].alpha = 1;
}
// Reset immunity power system
immunityPowers = [];
immunitySpawnTimer = 0;
isImmune = false;
immunityDuration = 0;
immunityStatusText.visible = false;
// Show shooting elements
shootButton.visible = true;
shootStatusText.visible = true;
cooldownIndicator.visible = true;
projectiles = [];
canShoot = true;
shootCooldown = 0;
shootStatusText.setText('SHOOT READY');
shootStatusText.fill = 0xff6600;
shootButton.tint = 0xff6600;
cooldownIndicator.scaleX = 0;
cooldownIndicator.scaleY = 0;
// Start background music
LK.playMusic('bgMusic');
}
function showSettings() {
gameState = 'settings';
// Hide menu elements
titleText.visible = false;
startButton.visible = false;
settingsButton.visible = false;
airplaneButton.visible = false;
coinsTxt.visible = false;
shootButton.visible = false;
shootStatusText.visible = false;
cooldownIndicator.visible = false;
// Hide heart elements
for (var h = 0; h < heartElements.length; h++) {
heartElements[h].visible = false;
}
immunityStatusText.visible = false;
// Hide heart elements
for (var h = 0; h < heartElements.length; h++) {
heartElements[h].visible = false;
}
immunityStatusText.visible = false;
// Hide heart elements
for (var h = 0; h < heartElements.length; h++) {
heartElements[h].visible = false;
}
immunityStatusText.visible = false;
// Show settings elements
settingsTitle.visible = true;
sensitivitySlider.visible = true;
sensValueText.visible = true;
backButton.visible = true;
}
function showAirplaneSelection() {
gameState = 'airplanes';
// Hide menu elements
titleText.visible = false;
startButton.visible = false;
settingsButton.visible = false;
airplaneButton.visible = false;
coinsTxt.visible = false;
shootButton.visible = false;
shootStatusText.visible = false;
cooldownIndicator.visible = false;
// Show airplane selection elements
airplaneTitle.visible = true;
airplane1Button.visible = true;
airplane2Button.visible = true;
airplane3Button.visible = true;
airplaneBackButton.visible = true;
}
function showMenu() {
gameState = 'menu';
// Hide settings elements
settingsTitle.visible = false;
sensitivitySlider.visible = false;
sensValueText.visible = false;
backButton.visible = false;
// Hide airplane selection elements
airplaneTitle.visible = false;
airplane1Button.visible = false;
airplane2Button.visible = false;
airplane3Button.visible = false;
airplaneBackButton.visible = false;
// Hide game elements if they exist
if (spaceship) {
spaceship.destroy();
spaceship = null;
}
if (slider) {
slider.destroy();
slider = null;
}
scoreTxt.visible = false;
timeTxt.visible = false;
coinsTxt.visible = false;
shootButton.visible = false;
shootStatusText.visible = false;
cooldownIndicator.visible = false;
// Clear obstacles
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].destroy();
}
obstacles = [];
// Clear coins
for (var i = 0; i < coins.length; i++) {
coins[i].destroy();
}
coins = [];
// Clear immunity powers
for (var i = 0; i < immunityPowers.length; i++) {
immunityPowers[i].destroy();
}
immunityPowers = [];
// Clear projectiles
for (var i = 0; i < projectiles.length; i++) {
projectiles[i].destroy();
}
projectiles = [];
// Show menu elements
titleText.visible = true;
startButton.visible = true;
settingsButton.visible = true;
airplaneButton.visible = true;
// Stop background music
LK.stopMusic();
}
game.update = function () {
// Animate stars
for (var s = 0; s < stars.length; s++) {
stars[s].alpha = Math.sin(LK.ticks * 0.02 + s) * 0.3 + 0.5;
}
// Rotate planets slowly
planet1.rotation += 0.005;
planet2.rotation -= 0.003;
// Only run game logic during gameplay
if (gameState !== 'playing' || !spaceship) {
return;
}
// Handle shooting system cooldown
if (shootCooldown > 0) {
shootCooldown--;
var cooldownProgress = 1 - shootCooldown / shootMaxCooldown;
// Update cooldown indicator with growing circle animation
cooldownIndicator.scaleX = cooldownProgress;
cooldownIndicator.scaleY = cooldownProgress;
// Update status text with remaining time
var timeLeft = Math.ceil(shootCooldown / 60);
shootStatusText.setText('RELOAD: ' + timeLeft + 's');
if (shootCooldown <= 0) {
canShoot = true;
shootStatusText.setText('SHOOT READY');
shootStatusText.fill = 0xff6600;
shootButton.tint = 0xff6600;
cooldownIndicator.scaleX = 0;
cooldownIndicator.scaleY = 0;
}
}
// Update projectiles
for (var p = projectiles.length - 1; p >= 0; p--) {
var projectile = projectiles[p];
// Remove projectiles that go off screen
if (projectile.y < -100) {
projectile.destroy();
projectiles.splice(p, 1);
continue;
}
// Check projectile collision with obstacles
for (var o = obstacles.length - 1; o >= 0; o--) {
var obstacle = obstacles[o];
var dx = projectile.x - obstacle.x;
var dy = projectile.y - obstacle.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 100) {
// Explosion effect
tween(obstacle, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
obstacle.destroy();
}
});
// Remove projectile
projectile.destroy();
projectiles.splice(p, 1);
// Remove obstacle
obstacles.splice(o, 1);
// Add score bonus
LK.setScore(LK.getScore() + 50);
scoreTxt.setText(LK.getScore());
// Play destroy sound
LK.getSound('destroy').play();
// Screen flash effect
LK.effects.flashScreen(0xffff00, 200);
break;
}
}
if (projectile.parent) {
projectile.lastY = projectile.y;
}
}
survivalTime++;
difficultyTimer++;
speedIncreaseTimer++;
if (survivalTime % 60 === 0) {
var seconds = Math.floor(survivalTime / 60);
timeTxt.setText('Time: ' + seconds + 's');
}
// Every 10 seconds (600 ticks), increase both airplane and obstacle speeds
if (speedIncreaseTimer >= 600) {
speedIncreaseTimer = 0;
gameSpeed *= 1.1; // Increase falling object speed by 10%
spaceshipSpeed *= 1.1; // Increase airplane speed by 10%
}
// Every 15 seconds (900 ticks), increase obstacle speed by 5%
if (difficultyTimer >= 900) {
difficultyTimer = 0;
gameSpeed *= 1.05;
obstacleSpawnRate = Math.max(30, obstacleSpawnRate - 5);
}
// Every 50 points, increase spaceship speed slightly
var currentScore = LK.getScore();
if (Math.floor(currentScore / 50) > Math.floor(lastScoreCheck / 50)) {
spaceshipSpeed += 0.1;
}
lastScoreCheck = currentScore;
obstacleSpawnTimer++;
if (obstacleSpawnTimer >= obstacleSpawnRate) {
obstacleSpawnTimer = 0;
var obstacle;
if (Math.random() < 0.7) {
obstacle = new Meteorite();
} else {
obstacle = new Debris();
}
obstacle.x = Math.random() * 1800 + 124;
obstacle.y = -100;
obstacle.speed *= gameSpeed;
obstacle.lastY = obstacle.y;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Spawn coins
coinSpawnTimer++;
if (coinSpawnTimer >= coinSpawnRate) {
coinSpawnTimer = 0;
var coin = new Coin();
coin.x = Math.random() * 1800 + 124;
coin.y = -100;
coin.speed *= gameSpeed;
coin.lastY = coin.y;
coins.push(coin);
game.addChild(coin);
}
// Spawn immunity powers every 25 seconds
immunitySpawnTimer++;
if (immunitySpawnTimer >= immunitySpawnRate) {
immunitySpawnTimer = 0;
var immunityPower = new ImmunityPower();
immunityPower.x = Math.random() * 1800 + 124;
immunityPower.y = -100;
immunityPower.speed *= gameSpeed;
immunityPower.lastY = immunityPower.y;
immunityPowers.push(immunityPower);
game.addChild(immunityPower);
}
// Update and check coin collection
for (var c = coins.length - 1; c >= 0; c--) {
var coin = coins[c];
// Remove coins that go off screen
if (coin.y > 2800) {
coin.destroy();
coins.splice(c, 1);
continue;
}
// Check coin collection with spaceship
var dx = spaceship.x - coin.x;
var dy = spaceship.y - coin.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var collectionDistance = 80; // Generous collection radius
if (distance < collectionDistance) {
// Collect coin
totalCoins++;
storage.totalCoins = totalCoins;
coinsTxt.setText('Coins: ' + totalCoins);
// Play coin collection sound
LK.getSound('coinCollect').play();
// Add coin collection animation
tween(coin, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
coin.destroy();
}
});
coins.splice(c, 1);
continue;
}
coin.lastY = coin.y;
}
// Handle immunity system
if (isImmune) {
immunityDuration--;
// Update immunity status text
var timeLeft = Math.ceil(immunityDuration / 60);
immunityStatusText.setText('IMMUNE: ' + timeLeft + 's');
immunityStatusText.visible = true;
// Add immunity visual effects to spaceship
if (LK.ticks % 20 === 0) {
tween(spaceship, {
alpha: 0.3
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(spaceship, {
alpha: 1.0
}, {
duration: 200,
easing: tween.easeInOut
});
}
});
}
if (immunityDuration <= 0) {
isImmune = false;
immunityStatusText.visible = false;
spaceship.alpha = 1.0;
}
}
// Update and check immunity power collection
for (var ip = immunityPowers.length - 1; ip >= 0; ip--) {
var immunityPower = immunityPowers[ip];
// Remove immunity powers that go off screen
if (immunityPower.y > 2800) {
immunityPower.destroy();
immunityPowers.splice(ip, 1);
continue;
}
// Check immunity power collection with spaceship
var dx = spaceship.x - immunityPower.x;
var dy = spaceship.y - immunityPower.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var collectionDistance = 100;
if (distance < collectionDistance) {
// Collect immunity power
isImmune = true;
immunityDuration = immunityMaxDuration;
// Play powerup sound
LK.getSound('powerup').play();
// Add collection animation
tween(immunityPower, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
immunityPower.destroy();
}
});
immunityPowers.splice(ip, 1);
continue;
}
immunityPower.lastY = immunityPower.y;
}
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (obstacle.lastY < 2800 && obstacle.y >= 2800) {
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
}
if (obstacle.y > 2800) {
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
// Only lose if spaceship intersects with meteorites or debris with more precise collision
if (obstacle instanceof Meteorite || obstacle instanceof Debris) {
// Calculate distance between centers
var dx = spaceship.x - obstacle.x;
var dy = spaceship.y - obstacle.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Use smaller collision radius for more precise collision (about 60% of original size)
var spaceshipRadius = spaceship.width * 0.6 / 2;
var obstacleRadius = obstacle.width * 0.6 / 2;
var collisionDistance = spaceshipRadius + obstacleRadius;
if (distance < collisionDistance && !isImmune) {
// Lose a heart instead of immediate game over
hearts--;
// Update heart display
if (hearts >= 0 && hearts < heartElements.length) {
heartElements[hearts].alpha = 0.3;
tween(heartElements[hearts], {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 500,
easing: tween.easeOut
});
}
// Flash effect when hit
LK.effects.flashScreen(0xff0000, 500);
// Play hit sound
LK.getSound('hit').play();
// Remove the obstacle that hit the player
obstacle.destroy();
obstacles.splice(i, 1);
// Check if game over (no hearts left)
if (hearts <= 0) {
LK.getSound('destroy').play();
LK.showGameOver();
showMenu();
return;
}
// Temporary immunity after getting hit (1 second)
if (!isImmune) {
isImmune = true;
immunityDuration = 60; // 1 second
}
continue;
}
}
obstacle.lastY = obstacle.y;
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var BackButton = Container.expand(function () {
var self = Container.call(this);
var buttonBg = self.attachAsset('backButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
tween(self.scale, {
x: 0.9,
y: 0.9
}, {
duration: 200
});
};
self.up = function (x, y, obj) {
tween(self.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.lastY = undefined;
self.update = function () {
self.y += self.speed;
// Add floating animation
self.x += Math.sin(LK.ticks * 0.1 + self.y * 0.01) * 0.5;
// Add rotation
graphics.rotation += 0.05;
};
return self;
});
var Debris = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('debris', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.lastY = undefined;
self.update = function () {
self.y += self.speed;
};
return self;
});
var ImmunityPower = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('immunityPower', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.lastY = undefined;
self.update = function () {
self.y += self.speed;
// Add pulsing animation
graphics.scaleX = 1 + Math.sin(LK.ticks * 0.1) * 0.2;
graphics.scaleY = 1 + Math.sin(LK.ticks * 0.1) * 0.2;
// Add rotation
graphics.rotation += 0.03;
};
return self;
});
var MenuButton = Container.expand(function (color) {
var self = Container.call(this);
var buttonBg = self.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5
});
if (color) buttonBg.tint = color;
self.down = function (x, y, obj) {
tween(self.scale, {
x: 0.9,
y: 0.9
}, {
duration: 200
});
};
self.up = function (x, y, obj) {
tween(self.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
};
return self;
});
var Meteorite = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('meteorite', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.lastY = undefined;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Projectile = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('boostButton', {
anchorX: 0.5,
anchorY: 0.5
});
graphics.scaleX = 0.3;
graphics.scaleY = 0.3;
self.speed = -8;
self.lastY = undefined;
self.update = function () {
self.y += self.speed;
};
return self;
});
var SensitivitySlider = Container.expand(function () {
var self = Container.call(this);
var sliderBar = self.attachAsset('sensSlider', {
anchorX: 0.5,
anchorY: 0.5
});
var sliderHandle = self.addChild(LK.getAsset('sensHandle', {
anchorX: 0.5,
anchorY: 0.5
}));
self.minX = -280;
self.maxX = 280;
self.isDragging = false;
self.down = function (x, y, obj) {
self.isDragging = true;
self.updateHandle(x);
};
self.up = function (x, y, obj) {
self.isDragging = false;
};
self.updateHandle = function (x) {
var localX = x - self.x;
localX = Math.max(self.minX, Math.min(self.maxX, localX));
sliderHandle.x = localX;
};
self.getSensitivity = function () {
return (sliderHandle.x + 280) / 560; // 0 to 1
};
self.setSensitivity = function (value) {
sliderHandle.x = value * 560 - 280;
};
return self;
});
var SettingsButton = Container.expand(function () {
var self = Container.call(this);
var buttonBg = self.attachAsset('settingsButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
tween(self.scale, {
x: 0.9,
y: 0.9
}, {
duration: 200
});
};
self.up = function (x, y, obj) {
tween(self.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
};
return self;
});
var Spaceship = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('spaceship', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var StartButton = Container.expand(function () {
var self = Container.call(this);
var buttonBg = self.attachAsset('startButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
tween(self.scale, {
x: 0.9,
y: 0.9
}, {
duration: 200
});
};
self.up = function (x, y, obj) {
tween(self.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
};
return self;
});
var TouchSlider = Container.expand(function () {
var self = Container.call(this);
var sliderBar = self.attachAsset('sliderBar', {
anchorX: 0.5,
anchorY: 0.5
});
var sliderHandle = self.addChild(LK.getAsset('sliderHandle', {
anchorX: 0.5,
anchorY: 0.5
}));
self.minX = -380;
self.maxX = 380;
self.isDragging = false;
self.down = function (x, y, obj) {
self.isDragging = true;
self.updateHandle(x);
};
self.up = function (x, y, obj) {
self.isDragging = false;
};
self.updateHandle = function (x) {
var localX = x - self.x;
localX = Math.max(self.minX, Math.min(self.maxX, localX));
sliderHandle.x = localX;
};
self.getSliderValue = function () {
return sliderHandle.x / 380;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000011
});
/****
* Game Code
****/
// Game state management
var gameState = 'menu'; // 'menu', 'settings', 'playing', 'airplanes'
var sensitivity = storage.sensitivity || 1.0;
var selectedAirplane = storage.selectedAirplane || 'classic';
// Menu elements
var titleText = new Text2('Hasta el infinito y más allá', {
size: 110,
fill: 0xFFD700,
font: "'Press Start 2P', 'VT323', 'Pixel Emulator', 'Courier New', monospace"
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 600;
game.addChild(titleText);
var startButton = game.addChild(new StartButton());
startButton.x = 2048 / 2;
startButton.y = 1200;
var settingsButton = game.addChild(new SettingsButton());
settingsButton.x = 2048 / 2;
settingsButton.y = 1400;
var airplaneButton = game.addChild(new MenuButton(0x44aa44));
airplaneButton.x = 2048 / 2;
airplaneButton.y = 1600;
// Settings menu elements (initially hidden)
var settingsTitle = new Text2('AJUSTAR SENSIBILIDAD', {
size: 80,
fill: 0xFFFFFF
});
settingsTitle.anchor.set(0.5, 0.5);
settingsTitle.x = 2048 / 2;
settingsTitle.y = 800;
settingsTitle.visible = false;
game.addChild(settingsTitle);
var sensitivitySlider = game.addChild(new SensitivitySlider());
sensitivitySlider.x = 2048 / 2;
sensitivitySlider.y = 1200;
sensitivitySlider.visible = false;
sensitivitySlider.setSensitivity(sensitivity);
var sensValueText = new Text2('Sensibilidad: ' + Math.round(sensitivity * 100) + '%', {
size: 60,
fill: 0xFFFFFF
});
sensValueText.anchor.set(0.5, 0.5);
sensValueText.x = 2048 / 2;
sensValueText.y = 1350;
sensValueText.visible = false;
game.addChild(sensValueText);
var backButton = game.addChild(new BackButton());
backButton.x = 2048 / 2;
backButton.y = 1500;
backButton.visible = false;
// Airplane selection menu elements (initially hidden)
var airplaneTitle = new Text2('ELEGIR AVIÓN', {
size: 80,
fill: 0xFFFFFF
});
airplaneTitle.anchor.set(0.5, 0.5);
airplaneTitle.x = 2048 / 2;
airplaneTitle.y = 600;
airplaneTitle.visible = false;
game.addChild(airplaneTitle);
var airplane1Button = game.addChild(new MenuButton(0x4444aa));
airplane1Button.x = 2048 / 2;
airplane1Button.y = 1000;
airplane1Button.visible = false;
var airplane2Button = game.addChild(new MenuButton(0xaa4444));
airplane2Button.x = 2048 / 2;
airplane2Button.y = 1200;
airplane2Button.visible = false;
var airplane3Button = game.addChild(new MenuButton(0x44aa44));
airplane3Button.x = 2048 / 2;
airplane3Button.y = 1400;
airplane3Button.visible = false;
var airplaneBackButton = game.addChild(new BackButton());
airplaneBackButton.x = 2048 / 2;
airplaneBackButton.y = 1600;
airplaneBackButton.visible = false;
// Decorative elements
var stars = [];
for (var i = 0; i < 50; i++) {
var star = game.addChild(LK.getAsset('star', {
anchorX: 0.5,
anchorY: 0.5
}));
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
star.alpha = Math.random() * 0.8 + 0.2;
stars.push(star);
}
var planet1 = game.addChild(LK.getAsset('planet', {
anchorX: 0.5,
anchorY: 0.5
}));
planet1.x = 200;
planet1.y = 300;
planet1.alpha = 0.6;
planet1.tint = 0x8888ff;
var planet2 = game.addChild(LK.getAsset('planet', {
anchorX: 0.5,
anchorY: 0.5
}));
planet2.x = 1800;
planet2.y = 2400;
planet2.alpha = 0.4;
planet2.tint = 0xff8888;
planet2.scaleX = 0.7;
planet2.scaleY = 0.7;
// Game elements (initially hidden)
var spaceship;
var obstacles = [];
var coins = [];
var coinSpawnTimer = 0;
var coinSpawnRate = 180;
var totalCoins = storage.totalCoins || 0;
var obstacleSpawnTimer = 0;
var obstacleSpawnRate = 90;
var gameSpeed = 1;
var spaceshipSpeed = 1;
var survivalTime = 0;
var difficultyTimer = 0;
var lastScoreCheck = 0;
var speedIncreaseTimer = 0;
var slider;
// Heart system variables
var hearts = 3;
var heartElements = [];
// Immunity power variables
var immunityPowers = [];
var immunitySpawnTimer = 0;
var immunitySpawnRate = 1500; // 25 seconds at 60 FPS
var isImmune = false;
var immunityDuration = 0;
var immunityMaxDuration = 600; // 10 seconds at 60 FPS
// Boost power variables
var isBoostActive = false;
var boostDuration = 0;
var boostMaxDuration = 1200; // 20 seconds at 60 FPS
var boostMultiplier = 2.5;
var boostCooldown = 0;
var boostMaxCooldown = 1800; // 30 seconds cooldown
// Shooting system variables
var projectiles = [];
var shootCooldown = 0;
var shootMaxCooldown = 900; // 15 seconds at 60 FPS
var canShoot = true;
// GUI elements (created but initially hidden)
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.visible = false;
LK.gui.top.addChild(scoreTxt);
var timeTxt = new Text2('Time: 0s', {
size: 60,
fill: 0xFFFFFF
});
timeTxt.anchor.set(1, 0);
timeTxt.visible = false;
LK.gui.topRight.addChild(timeTxt);
timeTxt.x = -20;
timeTxt.y = 100;
var coinsTxt = new Text2('Coins: ' + totalCoins, {
size: 50,
fill: 0xffd700
});
coinsTxt.anchor.set(0, 0);
coinsTxt.visible = false;
LK.gui.topLeft.addChild(coinsTxt);
coinsTxt.x = 120;
coinsTxt.y = 20;
var shootButton = LK.getAsset('boostButton', {
anchorX: 0.5,
anchorY: 0.5
});
shootButton.visible = false;
LK.gui.bottomRight.addChild(shootButton);
shootButton.x = -120;
shootButton.y = -120;
var shootStatusText = new Text2('SHOOT READY', {
size: 40,
fill: 0xff6600
});
shootStatusText.anchor.set(0.5, 0.5);
shootStatusText.visible = false;
LK.gui.bottom.addChild(shootStatusText);
shootStatusText.y = -180;
// Add cooldown indicator circle
var cooldownIndicator = LK.getAsset('boostButton', {
anchorX: 0.5,
anchorY: 0.5
});
cooldownIndicator.visible = false;
cooldownIndicator.alpha = 0.3;
cooldownIndicator.tint = 0x000000;
LK.gui.bottomRight.addChild(cooldownIndicator);
cooldownIndicator.x = -120;
cooldownIndicator.y = -120;
// Create heart GUI elements
for (var h = 0; h < 3; h++) {
var heartGui = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
heartGui.visible = false;
LK.gui.topRight.addChild(heartGui);
heartGui.x = -280 + h * 90;
heartGui.y = 40;
heartElements.push(heartGui);
}
var immunityStatusText = new Text2('', {
size: 50,
fill: 0x00ff88
});
immunityStatusText.anchor.set(0.5, 0.5);
immunityStatusText.visible = false;
LK.gui.center.addChild(immunityStatusText);
immunityStatusText.y = -200;
game.move = function (x, y, obj) {
if (gameState === 'playing' && slider && slider.isDragging) {
slider.updateHandle(x);
var sliderValue = slider.getSliderValue();
var currentSpeed = spaceshipSpeed * (isBoostActive ? boostMultiplier : 1);
spaceship.x = 2048 / 2 + sliderValue * 800 * currentSpeed * sensitivity;
spaceship.x = Math.max(100, Math.min(1948, spaceship.x));
} else if (gameState === 'settings' && sensitivitySlider.isDragging) {
sensitivitySlider.updateHandle(x);
sensitivity = sensitivitySlider.getSensitivity();
sensValueText.setText('Sensibilidad: ' + Math.round(sensitivity * 100) + '%');
storage.sensitivity = sensitivity;
}
};
// Add shoot button click handler
shootButton.down = function (x, y, obj) {
if (gameState === 'playing' && canShoot && shootCooldown <= 0) {
// Fire projectile
var projectile = new Projectile();
projectile.x = spaceship.x;
projectile.y = spaceship.y - 50;
projectile.lastY = projectile.y;
projectiles.push(projectile);
game.addChild(projectile);
// Play shooting sound
LK.getSound('shoot').play();
// Start cooldown
canShoot = false;
shootCooldown = shootMaxCooldown;
shootStatusText.setText('RELOADING...');
shootStatusText.fill = 0xff0000;
shootButton.tint = 0x666666;
// Button press animation
tween(shootButton.scale, {
x: 0.9,
y: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(shootButton.scale, {
x: 1.0,
y: 1.0
}, {
duration: 100,
easing: tween.easeIn
});
}
});
}
};
shootButton.up = function (x, y, obj) {
// Reset button scale on release
tween(shootButton.scale, {
x: 1.0,
y: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
};
game.down = function (x, y, obj) {
// Game down handler for other interactions
};
// Button handlers
startButton.up = function (x, y, obj) {
tween(startButton.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
startGame();
};
settingsButton.up = function (x, y, obj) {
tween(settingsButton.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
showSettings();
};
backButton.up = function (x, y, obj) {
tween(backButton.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
showMenu();
};
airplaneButton.up = function (x, y, obj) {
tween(airplaneButton.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
showAirplaneSelection();
};
airplane1Button.up = function (x, y, obj) {
tween(airplane1Button.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
selectedAirplane = 'classic';
storage.selectedAirplane = selectedAirplane;
showMenu();
};
airplane2Button.up = function (x, y, obj) {
tween(airplane2Button.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
selectedAirplane = 'fast';
storage.selectedAirplane = selectedAirplane;
showMenu();
};
airplane3Button.up = function (x, y, obj) {
tween(airplane3Button.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
selectedAirplane = 'robust';
storage.selectedAirplane = selectedAirplane;
showMenu();
};
airplaneBackButton.up = function (x, y, obj) {
tween(airplaneBackButton.scale, {
x: 1.0,
y: 1.0
}, {
duration: 200
});
showMenu();
};
function startGame() {
gameState = 'playing';
// Hide menu elements
titleText.visible = false;
startButton.visible = false;
settingsButton.visible = false;
airplaneButton.visible = false;
// Show game elements
spaceship = game.addChild(new Spaceship());
spaceship.x = 2048 / 2;
spaceship.y = 2000;
slider = game.addChild(new TouchSlider());
slider.x = 2048 / 2;
slider.y = 2600;
scoreTxt.visible = true;
timeTxt.visible = true;
// Reset game variables
obstacles = [];
coins = [];
coinSpawnTimer = 0;
obstacleSpawnTimer = 0;
obstacleSpawnRate = 90;
coinSpawnRate = 180;
gameSpeed = 1;
spaceshipSpeed = 1;
survivalTime = 0;
difficultyTimer = 0;
speedIncreaseTimer = 0;
lastScoreCheck = 0;
LK.setScore(0);
scoreTxt.setText('0');
timeTxt.setText('Time: 0s');
coinsTxt.visible = true;
coinsTxt.setText('Coins: ' + totalCoins);
// Reset heart system
hearts = 3;
for (var h = 0; h < heartElements.length; h++) {
heartElements[h].visible = true;
heartElements[h].alpha = 1;
}
// Reset immunity power system
immunityPowers = [];
immunitySpawnTimer = 0;
isImmune = false;
immunityDuration = 0;
immunityStatusText.visible = false;
// Show shooting elements
shootButton.visible = true;
shootStatusText.visible = true;
cooldownIndicator.visible = true;
projectiles = [];
canShoot = true;
shootCooldown = 0;
shootStatusText.setText('SHOOT READY');
shootStatusText.fill = 0xff6600;
shootButton.tint = 0xff6600;
cooldownIndicator.scaleX = 0;
cooldownIndicator.scaleY = 0;
// Start background music
LK.playMusic('bgMusic');
}
function showSettings() {
gameState = 'settings';
// Hide menu elements
titleText.visible = false;
startButton.visible = false;
settingsButton.visible = false;
airplaneButton.visible = false;
coinsTxt.visible = false;
shootButton.visible = false;
shootStatusText.visible = false;
cooldownIndicator.visible = false;
// Hide heart elements
for (var h = 0; h < heartElements.length; h++) {
heartElements[h].visible = false;
}
immunityStatusText.visible = false;
// Hide heart elements
for (var h = 0; h < heartElements.length; h++) {
heartElements[h].visible = false;
}
immunityStatusText.visible = false;
// Hide heart elements
for (var h = 0; h < heartElements.length; h++) {
heartElements[h].visible = false;
}
immunityStatusText.visible = false;
// Show settings elements
settingsTitle.visible = true;
sensitivitySlider.visible = true;
sensValueText.visible = true;
backButton.visible = true;
}
function showAirplaneSelection() {
gameState = 'airplanes';
// Hide menu elements
titleText.visible = false;
startButton.visible = false;
settingsButton.visible = false;
airplaneButton.visible = false;
coinsTxt.visible = false;
shootButton.visible = false;
shootStatusText.visible = false;
cooldownIndicator.visible = false;
// Show airplane selection elements
airplaneTitle.visible = true;
airplane1Button.visible = true;
airplane2Button.visible = true;
airplane3Button.visible = true;
airplaneBackButton.visible = true;
}
function showMenu() {
gameState = 'menu';
// Hide settings elements
settingsTitle.visible = false;
sensitivitySlider.visible = false;
sensValueText.visible = false;
backButton.visible = false;
// Hide airplane selection elements
airplaneTitle.visible = false;
airplane1Button.visible = false;
airplane2Button.visible = false;
airplane3Button.visible = false;
airplaneBackButton.visible = false;
// Hide game elements if they exist
if (spaceship) {
spaceship.destroy();
spaceship = null;
}
if (slider) {
slider.destroy();
slider = null;
}
scoreTxt.visible = false;
timeTxt.visible = false;
coinsTxt.visible = false;
shootButton.visible = false;
shootStatusText.visible = false;
cooldownIndicator.visible = false;
// Clear obstacles
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].destroy();
}
obstacles = [];
// Clear coins
for (var i = 0; i < coins.length; i++) {
coins[i].destroy();
}
coins = [];
// Clear immunity powers
for (var i = 0; i < immunityPowers.length; i++) {
immunityPowers[i].destroy();
}
immunityPowers = [];
// Clear projectiles
for (var i = 0; i < projectiles.length; i++) {
projectiles[i].destroy();
}
projectiles = [];
// Show menu elements
titleText.visible = true;
startButton.visible = true;
settingsButton.visible = true;
airplaneButton.visible = true;
// Stop background music
LK.stopMusic();
}
game.update = function () {
// Animate stars
for (var s = 0; s < stars.length; s++) {
stars[s].alpha = Math.sin(LK.ticks * 0.02 + s) * 0.3 + 0.5;
}
// Rotate planets slowly
planet1.rotation += 0.005;
planet2.rotation -= 0.003;
// Only run game logic during gameplay
if (gameState !== 'playing' || !spaceship) {
return;
}
// Handle shooting system cooldown
if (shootCooldown > 0) {
shootCooldown--;
var cooldownProgress = 1 - shootCooldown / shootMaxCooldown;
// Update cooldown indicator with growing circle animation
cooldownIndicator.scaleX = cooldownProgress;
cooldownIndicator.scaleY = cooldownProgress;
// Update status text with remaining time
var timeLeft = Math.ceil(shootCooldown / 60);
shootStatusText.setText('RELOAD: ' + timeLeft + 's');
if (shootCooldown <= 0) {
canShoot = true;
shootStatusText.setText('SHOOT READY');
shootStatusText.fill = 0xff6600;
shootButton.tint = 0xff6600;
cooldownIndicator.scaleX = 0;
cooldownIndicator.scaleY = 0;
}
}
// Update projectiles
for (var p = projectiles.length - 1; p >= 0; p--) {
var projectile = projectiles[p];
// Remove projectiles that go off screen
if (projectile.y < -100) {
projectile.destroy();
projectiles.splice(p, 1);
continue;
}
// Check projectile collision with obstacles
for (var o = obstacles.length - 1; o >= 0; o--) {
var obstacle = obstacles[o];
var dx = projectile.x - obstacle.x;
var dy = projectile.y - obstacle.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 100) {
// Explosion effect
tween(obstacle, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
obstacle.destroy();
}
});
// Remove projectile
projectile.destroy();
projectiles.splice(p, 1);
// Remove obstacle
obstacles.splice(o, 1);
// Add score bonus
LK.setScore(LK.getScore() + 50);
scoreTxt.setText(LK.getScore());
// Play destroy sound
LK.getSound('destroy').play();
// Screen flash effect
LK.effects.flashScreen(0xffff00, 200);
break;
}
}
if (projectile.parent) {
projectile.lastY = projectile.y;
}
}
survivalTime++;
difficultyTimer++;
speedIncreaseTimer++;
if (survivalTime % 60 === 0) {
var seconds = Math.floor(survivalTime / 60);
timeTxt.setText('Time: ' + seconds + 's');
}
// Every 10 seconds (600 ticks), increase both airplane and obstacle speeds
if (speedIncreaseTimer >= 600) {
speedIncreaseTimer = 0;
gameSpeed *= 1.1; // Increase falling object speed by 10%
spaceshipSpeed *= 1.1; // Increase airplane speed by 10%
}
// Every 15 seconds (900 ticks), increase obstacle speed by 5%
if (difficultyTimer >= 900) {
difficultyTimer = 0;
gameSpeed *= 1.05;
obstacleSpawnRate = Math.max(30, obstacleSpawnRate - 5);
}
// Every 50 points, increase spaceship speed slightly
var currentScore = LK.getScore();
if (Math.floor(currentScore / 50) > Math.floor(lastScoreCheck / 50)) {
spaceshipSpeed += 0.1;
}
lastScoreCheck = currentScore;
obstacleSpawnTimer++;
if (obstacleSpawnTimer >= obstacleSpawnRate) {
obstacleSpawnTimer = 0;
var obstacle;
if (Math.random() < 0.7) {
obstacle = new Meteorite();
} else {
obstacle = new Debris();
}
obstacle.x = Math.random() * 1800 + 124;
obstacle.y = -100;
obstacle.speed *= gameSpeed;
obstacle.lastY = obstacle.y;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Spawn coins
coinSpawnTimer++;
if (coinSpawnTimer >= coinSpawnRate) {
coinSpawnTimer = 0;
var coin = new Coin();
coin.x = Math.random() * 1800 + 124;
coin.y = -100;
coin.speed *= gameSpeed;
coin.lastY = coin.y;
coins.push(coin);
game.addChild(coin);
}
// Spawn immunity powers every 25 seconds
immunitySpawnTimer++;
if (immunitySpawnTimer >= immunitySpawnRate) {
immunitySpawnTimer = 0;
var immunityPower = new ImmunityPower();
immunityPower.x = Math.random() * 1800 + 124;
immunityPower.y = -100;
immunityPower.speed *= gameSpeed;
immunityPower.lastY = immunityPower.y;
immunityPowers.push(immunityPower);
game.addChild(immunityPower);
}
// Update and check coin collection
for (var c = coins.length - 1; c >= 0; c--) {
var coin = coins[c];
// Remove coins that go off screen
if (coin.y > 2800) {
coin.destroy();
coins.splice(c, 1);
continue;
}
// Check coin collection with spaceship
var dx = spaceship.x - coin.x;
var dy = spaceship.y - coin.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var collectionDistance = 80; // Generous collection radius
if (distance < collectionDistance) {
// Collect coin
totalCoins++;
storage.totalCoins = totalCoins;
coinsTxt.setText('Coins: ' + totalCoins);
// Play coin collection sound
LK.getSound('coinCollect').play();
// Add coin collection animation
tween(coin, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
coin.destroy();
}
});
coins.splice(c, 1);
continue;
}
coin.lastY = coin.y;
}
// Handle immunity system
if (isImmune) {
immunityDuration--;
// Update immunity status text
var timeLeft = Math.ceil(immunityDuration / 60);
immunityStatusText.setText('IMMUNE: ' + timeLeft + 's');
immunityStatusText.visible = true;
// Add immunity visual effects to spaceship
if (LK.ticks % 20 === 0) {
tween(spaceship, {
alpha: 0.3
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(spaceship, {
alpha: 1.0
}, {
duration: 200,
easing: tween.easeInOut
});
}
});
}
if (immunityDuration <= 0) {
isImmune = false;
immunityStatusText.visible = false;
spaceship.alpha = 1.0;
}
}
// Update and check immunity power collection
for (var ip = immunityPowers.length - 1; ip >= 0; ip--) {
var immunityPower = immunityPowers[ip];
// Remove immunity powers that go off screen
if (immunityPower.y > 2800) {
immunityPower.destroy();
immunityPowers.splice(ip, 1);
continue;
}
// Check immunity power collection with spaceship
var dx = spaceship.x - immunityPower.x;
var dy = spaceship.y - immunityPower.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var collectionDistance = 100;
if (distance < collectionDistance) {
// Collect immunity power
isImmune = true;
immunityDuration = immunityMaxDuration;
// Play powerup sound
LK.getSound('powerup').play();
// Add collection animation
tween(immunityPower, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
immunityPower.destroy();
}
});
immunityPowers.splice(ip, 1);
continue;
}
immunityPower.lastY = immunityPower.y;
}
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (obstacle.lastY < 2800 && obstacle.y >= 2800) {
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
}
if (obstacle.y > 2800) {
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
// Only lose if spaceship intersects with meteorites or debris with more precise collision
if (obstacle instanceof Meteorite || obstacle instanceof Debris) {
// Calculate distance between centers
var dx = spaceship.x - obstacle.x;
var dy = spaceship.y - obstacle.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Use smaller collision radius for more precise collision (about 60% of original size)
var spaceshipRadius = spaceship.width * 0.6 / 2;
var obstacleRadius = obstacle.width * 0.6 / 2;
var collisionDistance = spaceshipRadius + obstacleRadius;
if (distance < collisionDistance && !isImmune) {
// Lose a heart instead of immediate game over
hearts--;
// Update heart display
if (hearts >= 0 && hearts < heartElements.length) {
heartElements[hearts].alpha = 0.3;
tween(heartElements[hearts], {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 500,
easing: tween.easeOut
});
}
// Flash effect when hit
LK.effects.flashScreen(0xff0000, 500);
// Play hit sound
LK.getSound('hit').play();
// Remove the obstacle that hit the player
obstacle.destroy();
obstacles.splice(i, 1);
// Check if game over (no hearts left)
if (hearts <= 0) {
LK.getSound('destroy').play();
LK.showGameOver();
showMenu();
return;
}
// Temporary immunity after getting hit (1 second)
if (!isImmune) {
isImmune = true;
immunityDuration = 60; // 1 second
}
continue;
}
}
obstacle.lastY = obstacle.y;
}
};