/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Cannon = Container.expand(function () {
var self = Container.call(this);
var cannonGraphics = self.attachAsset('cannon', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Debris = Container.expand(function () {
var self = Container.call(this);
var debrisGraphics = self.attachAsset('debris', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = (Math.random() * 6 + 8) * 0.85; // Reduced by 15%
self.horizontalSpeed = (Math.random() - 0.5) * 12; // Random horizontal movement between -6 and +6
self.rotationSpeed = (Math.random() - 0.5) * 0.2;
self.update = function () {
self.y += self.speed;
self.x += self.horizontalSpeed; // Add horizontal movement
// Keep debris within screen bounds
if (self.x < 40) {
self.x = 40;
self.horizontalSpeed = Math.abs(self.horizontalSpeed); // Bounce off left edge
}
if (self.x > 2048 - 40) {
self.x = 2048 - 40;
self.horizontalSpeed = -Math.abs(self.horizontalSpeed); // Bounce off right edge
}
self.rotation += self.rotationSpeed;
};
return self;
});
var Explosion = Container.expand(function (explosionSize) {
var self = Container.call(this);
self.explosionSize = explosionSize || 200; // Default size
self.particles = [];
// Create explosion particles
for (var i = 0; i < 15; i++) {
var particle = self.attachAsset('debris', {
anchorX: 0.5,
anchorY: 0.5
});
particle.alpha = 0.8;
particle.scaleX = 0.3;
particle.scaleY = 0.3;
particle.tint = Math.random() > 0.5 ? 0xff6600 : 0xff0000;
var angle = i / 15 * Math.PI * 2;
var speed = Math.random() * self.explosionSize + 50;
particle.velocityX = Math.cos(angle) * speed;
particle.velocityY = Math.sin(angle) * speed;
particle.rotationSpeed = (Math.random() - 0.5) * 0.3;
self.particles.push(particle);
// Animate particle
tween(particle, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 1500,
easing: tween.easeOut
});
}
self.lifeTime = 0;
self.update = function () {
self.lifeTime++;
// Move particles
for (var p = 0; p < self.particles.length; p++) {
var particle = self.particles[p];
particle.x += particle.velocityX * 0.016;
particle.y += particle.velocityY * 0.016;
particle.velocityY += 5; // Gravity
particle.rotation += particle.rotationSpeed;
}
// Remove explosion after animation
if (self.lifeTime > 90) {
// 1.5 seconds at 60fps
self.destroy();
}
};
return self;
});
var Laser = Container.expand(function () {
var self = Container.call(this);
var laserGraphics = self.attachAsset('laser', {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = -12;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Meteor = Container.expand(function () {
var self = Container.call(this);
var meteorGraphics = self.attachAsset('meteor', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 10;
self.maxHealth = 10;
self.speed = 0.5;
self.lastHitTime = 0;
self.update = function () {
self.y += self.speed;
};
self.takeDamage = function () {
self.health--;
self.lastHitTime = LK.ticks;
LK.effects.flashObject(self, 0xff0000, 200);
};
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starType = Math.floor(Math.random() * 3) + 1;
var starGraphics = self.attachAsset('star' + starType, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 2 + 1;
self.twinkleSpeed = Math.random() * 0.05 + 0.02;
self.twinklePhase = Math.random() * Math.PI * 2;
self.update = function () {
self.y += self.speed;
// Twinkling effect
self.twinklePhase += self.twinkleSpeed;
starGraphics.alpha = 0.3 + Math.sin(self.twinklePhase) * 0.4;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000022
});
/****
* Game Code
****/
// Game state variables
var currentLevel = 1;
var totalLevels = 5;
var gameState = 'playing'; // 'playing', 'levelComplete', 'gameComplete'
// Game objects
var cannon = null;
var currentMeteor = null;
var lasers = [];
var debrisList = [];
var stars = [];
// Timing variables
var levelStartTime = 0;
var levelDuration = 30 * 60; // 30 seconds at 60 FPS
var lastDebrisSpawnTime = 0;
var debrisSpawnInterval = 3 * 60; // 3 seconds at 60 FPS
// UI elements
var levelText = new Text2('Level 1', {
size: 80,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
levelText.y = 100;
var healthText = new Text2('Meteor Health: 10', {
size: 60,
fill: 0xFF6666
});
healthText.anchor.set(0, 0);
LK.gui.topRight.addChild(healthText);
healthText.x = -400;
healthText.y = 100;
var timeText = new Text2('Time: 30', {
size: 60,
fill: 0x66FF66
});
timeText.anchor.set(1, 0);
LK.gui.topRight.addChild(timeText);
timeText.x = -50;
timeText.y = 180;
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFD700
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -50;
scoreText.y = 240;
// Initialize cannon
cannon = game.addChild(new Cannon());
cannon.x = 2048 / 2;
cannon.y = 2732 - 100;
function startLevel(level) {
// Clear existing objects
for (var i = lasers.length - 1; i >= 0; i--) {
lasers[i].destroy();
lasers.splice(i, 1);
}
for (var j = debrisList.length - 1; j >= 0; j--) {
debrisList[j].destroy();
debrisList.splice(j, 1);
}
if (currentMeteor) {
currentMeteor.destroy();
}
// Create new meteor for this level
currentMeteor = game.addChild(new Meteor());
currentMeteor.x = Math.random() * (2048 - 300) + 150;
currentMeteor.y = 200;
// Scale meteor health and size based on level
var levelMultiplier = 1 + (level - 1) * 0.5;
// First meteor has 200% more health, then +10% per level
var baseHealth = 10 * 3.0; // 200% more health for first meteor (triple the health)
var healthMultiplier = 1 + (level - 1) * 0.1; // 10% increase per level
currentMeteor.health = Math.floor(baseHealth * healthMultiplier);
currentMeteor.maxHealth = currentMeteor.health;
currentMeteor.scaleX = levelMultiplier;
currentMeteor.scaleY = levelMultiplier;
// Calculate speed to cover half screen (from y=200 to y=1366) in exactly 30 seconds
var targetDistance = 2732 / 2 - 200; // Distance to cover half screen
var speedPerTick = targetDistance / levelDuration; // Speed needed per tick
currentMeteor.speed = speedPerTick * (1 + (level - 1) * 0.1); // Slightly faster each level
// Reset timing
levelStartTime = LK.ticks;
lastDebrisSpawnTime = LK.ticks;
// Increase laser firing rate by 20% each level (decrease fire delay)
fireRate = Math.max(2, Math.floor(10 / (1 + (level - 1) * 0.2))); // Start at 10, decrease by 20% each level, minimum 2
// Update UI with descriptive level names
var levelNames = ['Easy', 'Normal', 'Hard', 'Insane', 'Impossible'];
var levelName = levelNames[level - 1] || 'Level ' + level;
levelText.setText(levelName);
healthText.setText('Meteor Health: ' + currentMeteor.health);
gameState = 'playing';
}
function createDebris() {
if (!currentMeteor) return;
var debris = game.addChild(new Debris());
debris.x = currentMeteor.x + (Math.random() - 0.5) * 200;
debris.y = currentMeteor.y + 50;
debrisList.push(debris);
LK.getSound('debris_spawn').play();
}
function fireLaser() {
var laser = game.addChild(new Laser());
laser.x = cannon.x;
laser.y = cannon.y - 40;
lasers.push(laser);
LK.getSound('laser_shoot').play();
}
function createBigExplosion(x, y) {
var explosion = game.addChild(new Explosion(400));
explosion.x = x;
explosion.y = y;
LK.effects.flashScreen(0xff4400, 1500);
}
function createSmallExplosion(x, y) {
var explosion = game.addChild(new Explosion(200));
explosion.x = x;
explosion.y = y;
LK.effects.flashScreen(0xff0000, 800);
}
function createStar() {
var star = game.addChild(new Star());
star.x = Math.random() * 2048;
star.y = -10;
stars.push(star);
}
function initializeStarfield() {
// Create initial stars
for (var i = 0; i < 50; i++) {
var star = game.addChild(new Star());
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
stars.push(star);
}
}
// Input handling
var isFiring = false;
var fireTimer = 0;
var fireRate = 10; // Fire every 10 ticks (6 times per second)
game.down = function (x, y, obj) {
isFiring = true;
fireTimer = 0;
};
game.up = function (x, y, obj) {
isFiring = false;
};
game.move = function (x, y, obj) {
cannon.x = x;
// Keep cannon within screen bounds
if (cannon.x < 60) cannon.x = 60;
if (cannon.x > 2048 - 60) cannon.x = 2048 - 60;
};
// Initialize background starfield
initializeStarfield();
// Start first level
startLevel(1);
// Start background music
LK.playMusic('background_music');
game.update = function () {
if (gameState !== 'playing') return;
// Handle continuous firing
if (isFiring) {
fireTimer++;
if (fireTimer >= fireRate) {
fireLaser();
fireTimer = 0;
}
}
// Update time display
var timeRemaining = Math.max(0, Math.ceil((levelDuration - (LK.ticks - levelStartTime)) / 60));
timeText.setText('Time: ' + timeRemaining);
// Check for level timeout
if (LK.ticks - levelStartTime >= levelDuration) {
// Time's up - game over
LK.showGameOver();
return;
}
// Debris spawning is now handled when meteor is hit
// Update and check lasers
for (var i = lasers.length - 1; i >= 0; i--) {
var laser = lasers[i];
// Remove lasers that go off screen
if (laser.y < -50) {
laser.destroy();
lasers.splice(i, 1);
continue;
}
// Check laser-meteor collision
if (currentMeteor && laser.intersects(currentMeteor)) {
currentMeteor.takeDamage();
LK.setScore(LK.getScore() + 100);
scoreText.setText('Score: ' + LK.getScore());
healthText.setText('Meteor Health: ' + currentMeteor.health);
laser.destroy();
lasers.splice(i, 1);
LK.getSound('meteor_hit').play();
// Spawn debris when meteor is hit
createDebris();
// Check if meteor is destroyed
if (currentMeteor.health <= 0) {
currentMeteor.destroy();
currentMeteor = null;
// Check if all debris are also destroyed before advancing level
if (debrisList.length === 0) {
// Level complete - meteor destroyed and no debris remaining
currentLevel++;
if (currentLevel > totalLevels) {
// Game complete
LK.showYouWin();
} else {
// Start next level after brief delay
LK.setTimeout(function () {
startLevel(currentLevel);
}, 1000);
}
}
// If debris still exist, meteor is destroyed but level continues until all debris are cleared
}
continue;
}
}
// Check if meteor reached cannon (big explosion)
if (currentMeteor && currentMeteor.y >= cannon.y) {
createBigExplosion(currentMeteor.x, currentMeteor.y);
LK.setTimeout(function () {
LK.showGameOver();
}, 500);
return;
}
// Update and check debris
for (var j = debrisList.length - 1; j >= 0; j--) {
var debris = debrisList[j];
// Check if debris passed the cannon (game over condition)
if (debris.y > cannon.y) {
// Game over - debris passed the player
createSmallExplosion(debris.x, debris.y);
LK.setTimeout(function () {
LK.showGameOver();
}, 300);
return;
}
// Remove debris that go off screen
if (debris.y > 2732 + 50) {
debris.destroy();
debrisList.splice(j, 1);
continue;
}
// Check debris-cannon collision
if (debris.intersects(cannon)) {
// Game over with small explosion
createSmallExplosion(debris.x, debris.y);
LK.setTimeout(function () {
LK.showGameOver();
}, 300);
return;
}
// Check debris-laser collision
for (var k = lasers.length - 1; k >= 0; k--) {
var laser = lasers[k];
if (debris.intersects(laser)) {
// Destroy both debris and laser
LK.setScore(LK.getScore() + 100);
scoreText.setText('Score: ' + LK.getScore());
debris.destroy();
debrisList.splice(j, 1);
laser.destroy();
lasers.splice(k, 1);
// Check if meteor is destroyed and all debris are now cleared
if (!currentMeteor && debrisList.length === 0) {
// Level complete - advance to next level
currentLevel++;
if (currentLevel > totalLevels) {
// Game complete
LK.showYouWin();
} else {
// Start next level after brief delay
LK.setTimeout(function () {
startLevel(currentLevel);
}, 1000);
}
}
break;
}
}
}
// Update and manage stars
for (var s = stars.length - 1; s >= 0; s--) {
var star = stars[s];
// Remove stars that go off screen
if (star.y > 2732 + 20) {
star.destroy();
stars.splice(s, 1);
}
}
// Create new stars periodically
if (LK.ticks % 60 === 0) {
// Every second
createStar();
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Cannon = Container.expand(function () {
var self = Container.call(this);
var cannonGraphics = self.attachAsset('cannon', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Debris = Container.expand(function () {
var self = Container.call(this);
var debrisGraphics = self.attachAsset('debris', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = (Math.random() * 6 + 8) * 0.85; // Reduced by 15%
self.horizontalSpeed = (Math.random() - 0.5) * 12; // Random horizontal movement between -6 and +6
self.rotationSpeed = (Math.random() - 0.5) * 0.2;
self.update = function () {
self.y += self.speed;
self.x += self.horizontalSpeed; // Add horizontal movement
// Keep debris within screen bounds
if (self.x < 40) {
self.x = 40;
self.horizontalSpeed = Math.abs(self.horizontalSpeed); // Bounce off left edge
}
if (self.x > 2048 - 40) {
self.x = 2048 - 40;
self.horizontalSpeed = -Math.abs(self.horizontalSpeed); // Bounce off right edge
}
self.rotation += self.rotationSpeed;
};
return self;
});
var Explosion = Container.expand(function (explosionSize) {
var self = Container.call(this);
self.explosionSize = explosionSize || 200; // Default size
self.particles = [];
// Create explosion particles
for (var i = 0; i < 15; i++) {
var particle = self.attachAsset('debris', {
anchorX: 0.5,
anchorY: 0.5
});
particle.alpha = 0.8;
particle.scaleX = 0.3;
particle.scaleY = 0.3;
particle.tint = Math.random() > 0.5 ? 0xff6600 : 0xff0000;
var angle = i / 15 * Math.PI * 2;
var speed = Math.random() * self.explosionSize + 50;
particle.velocityX = Math.cos(angle) * speed;
particle.velocityY = Math.sin(angle) * speed;
particle.rotationSpeed = (Math.random() - 0.5) * 0.3;
self.particles.push(particle);
// Animate particle
tween(particle, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 1500,
easing: tween.easeOut
});
}
self.lifeTime = 0;
self.update = function () {
self.lifeTime++;
// Move particles
for (var p = 0; p < self.particles.length; p++) {
var particle = self.particles[p];
particle.x += particle.velocityX * 0.016;
particle.y += particle.velocityY * 0.016;
particle.velocityY += 5; // Gravity
particle.rotation += particle.rotationSpeed;
}
// Remove explosion after animation
if (self.lifeTime > 90) {
// 1.5 seconds at 60fps
self.destroy();
}
};
return self;
});
var Laser = Container.expand(function () {
var self = Container.call(this);
var laserGraphics = self.attachAsset('laser', {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = -12;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Meteor = Container.expand(function () {
var self = Container.call(this);
var meteorGraphics = self.attachAsset('meteor', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 10;
self.maxHealth = 10;
self.speed = 0.5;
self.lastHitTime = 0;
self.update = function () {
self.y += self.speed;
};
self.takeDamage = function () {
self.health--;
self.lastHitTime = LK.ticks;
LK.effects.flashObject(self, 0xff0000, 200);
};
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starType = Math.floor(Math.random() * 3) + 1;
var starGraphics = self.attachAsset('star' + starType, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 2 + 1;
self.twinkleSpeed = Math.random() * 0.05 + 0.02;
self.twinklePhase = Math.random() * Math.PI * 2;
self.update = function () {
self.y += self.speed;
// Twinkling effect
self.twinklePhase += self.twinkleSpeed;
starGraphics.alpha = 0.3 + Math.sin(self.twinklePhase) * 0.4;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000022
});
/****
* Game Code
****/
// Game state variables
var currentLevel = 1;
var totalLevels = 5;
var gameState = 'playing'; // 'playing', 'levelComplete', 'gameComplete'
// Game objects
var cannon = null;
var currentMeteor = null;
var lasers = [];
var debrisList = [];
var stars = [];
// Timing variables
var levelStartTime = 0;
var levelDuration = 30 * 60; // 30 seconds at 60 FPS
var lastDebrisSpawnTime = 0;
var debrisSpawnInterval = 3 * 60; // 3 seconds at 60 FPS
// UI elements
var levelText = new Text2('Level 1', {
size: 80,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
levelText.y = 100;
var healthText = new Text2('Meteor Health: 10', {
size: 60,
fill: 0xFF6666
});
healthText.anchor.set(0, 0);
LK.gui.topRight.addChild(healthText);
healthText.x = -400;
healthText.y = 100;
var timeText = new Text2('Time: 30', {
size: 60,
fill: 0x66FF66
});
timeText.anchor.set(1, 0);
LK.gui.topRight.addChild(timeText);
timeText.x = -50;
timeText.y = 180;
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFD700
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -50;
scoreText.y = 240;
// Initialize cannon
cannon = game.addChild(new Cannon());
cannon.x = 2048 / 2;
cannon.y = 2732 - 100;
function startLevel(level) {
// Clear existing objects
for (var i = lasers.length - 1; i >= 0; i--) {
lasers[i].destroy();
lasers.splice(i, 1);
}
for (var j = debrisList.length - 1; j >= 0; j--) {
debrisList[j].destroy();
debrisList.splice(j, 1);
}
if (currentMeteor) {
currentMeteor.destroy();
}
// Create new meteor for this level
currentMeteor = game.addChild(new Meteor());
currentMeteor.x = Math.random() * (2048 - 300) + 150;
currentMeteor.y = 200;
// Scale meteor health and size based on level
var levelMultiplier = 1 + (level - 1) * 0.5;
// First meteor has 200% more health, then +10% per level
var baseHealth = 10 * 3.0; // 200% more health for first meteor (triple the health)
var healthMultiplier = 1 + (level - 1) * 0.1; // 10% increase per level
currentMeteor.health = Math.floor(baseHealth * healthMultiplier);
currentMeteor.maxHealth = currentMeteor.health;
currentMeteor.scaleX = levelMultiplier;
currentMeteor.scaleY = levelMultiplier;
// Calculate speed to cover half screen (from y=200 to y=1366) in exactly 30 seconds
var targetDistance = 2732 / 2 - 200; // Distance to cover half screen
var speedPerTick = targetDistance / levelDuration; // Speed needed per tick
currentMeteor.speed = speedPerTick * (1 + (level - 1) * 0.1); // Slightly faster each level
// Reset timing
levelStartTime = LK.ticks;
lastDebrisSpawnTime = LK.ticks;
// Increase laser firing rate by 20% each level (decrease fire delay)
fireRate = Math.max(2, Math.floor(10 / (1 + (level - 1) * 0.2))); // Start at 10, decrease by 20% each level, minimum 2
// Update UI with descriptive level names
var levelNames = ['Easy', 'Normal', 'Hard', 'Insane', 'Impossible'];
var levelName = levelNames[level - 1] || 'Level ' + level;
levelText.setText(levelName);
healthText.setText('Meteor Health: ' + currentMeteor.health);
gameState = 'playing';
}
function createDebris() {
if (!currentMeteor) return;
var debris = game.addChild(new Debris());
debris.x = currentMeteor.x + (Math.random() - 0.5) * 200;
debris.y = currentMeteor.y + 50;
debrisList.push(debris);
LK.getSound('debris_spawn').play();
}
function fireLaser() {
var laser = game.addChild(new Laser());
laser.x = cannon.x;
laser.y = cannon.y - 40;
lasers.push(laser);
LK.getSound('laser_shoot').play();
}
function createBigExplosion(x, y) {
var explosion = game.addChild(new Explosion(400));
explosion.x = x;
explosion.y = y;
LK.effects.flashScreen(0xff4400, 1500);
}
function createSmallExplosion(x, y) {
var explosion = game.addChild(new Explosion(200));
explosion.x = x;
explosion.y = y;
LK.effects.flashScreen(0xff0000, 800);
}
function createStar() {
var star = game.addChild(new Star());
star.x = Math.random() * 2048;
star.y = -10;
stars.push(star);
}
function initializeStarfield() {
// Create initial stars
for (var i = 0; i < 50; i++) {
var star = game.addChild(new Star());
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
stars.push(star);
}
}
// Input handling
var isFiring = false;
var fireTimer = 0;
var fireRate = 10; // Fire every 10 ticks (6 times per second)
game.down = function (x, y, obj) {
isFiring = true;
fireTimer = 0;
};
game.up = function (x, y, obj) {
isFiring = false;
};
game.move = function (x, y, obj) {
cannon.x = x;
// Keep cannon within screen bounds
if (cannon.x < 60) cannon.x = 60;
if (cannon.x > 2048 - 60) cannon.x = 2048 - 60;
};
// Initialize background starfield
initializeStarfield();
// Start first level
startLevel(1);
// Start background music
LK.playMusic('background_music');
game.update = function () {
if (gameState !== 'playing') return;
// Handle continuous firing
if (isFiring) {
fireTimer++;
if (fireTimer >= fireRate) {
fireLaser();
fireTimer = 0;
}
}
// Update time display
var timeRemaining = Math.max(0, Math.ceil((levelDuration - (LK.ticks - levelStartTime)) / 60));
timeText.setText('Time: ' + timeRemaining);
// Check for level timeout
if (LK.ticks - levelStartTime >= levelDuration) {
// Time's up - game over
LK.showGameOver();
return;
}
// Debris spawning is now handled when meteor is hit
// Update and check lasers
for (var i = lasers.length - 1; i >= 0; i--) {
var laser = lasers[i];
// Remove lasers that go off screen
if (laser.y < -50) {
laser.destroy();
lasers.splice(i, 1);
continue;
}
// Check laser-meteor collision
if (currentMeteor && laser.intersects(currentMeteor)) {
currentMeteor.takeDamage();
LK.setScore(LK.getScore() + 100);
scoreText.setText('Score: ' + LK.getScore());
healthText.setText('Meteor Health: ' + currentMeteor.health);
laser.destroy();
lasers.splice(i, 1);
LK.getSound('meteor_hit').play();
// Spawn debris when meteor is hit
createDebris();
// Check if meteor is destroyed
if (currentMeteor.health <= 0) {
currentMeteor.destroy();
currentMeteor = null;
// Check if all debris are also destroyed before advancing level
if (debrisList.length === 0) {
// Level complete - meteor destroyed and no debris remaining
currentLevel++;
if (currentLevel > totalLevels) {
// Game complete
LK.showYouWin();
} else {
// Start next level after brief delay
LK.setTimeout(function () {
startLevel(currentLevel);
}, 1000);
}
}
// If debris still exist, meteor is destroyed but level continues until all debris are cleared
}
continue;
}
}
// Check if meteor reached cannon (big explosion)
if (currentMeteor && currentMeteor.y >= cannon.y) {
createBigExplosion(currentMeteor.x, currentMeteor.y);
LK.setTimeout(function () {
LK.showGameOver();
}, 500);
return;
}
// Update and check debris
for (var j = debrisList.length - 1; j >= 0; j--) {
var debris = debrisList[j];
// Check if debris passed the cannon (game over condition)
if (debris.y > cannon.y) {
// Game over - debris passed the player
createSmallExplosion(debris.x, debris.y);
LK.setTimeout(function () {
LK.showGameOver();
}, 300);
return;
}
// Remove debris that go off screen
if (debris.y > 2732 + 50) {
debris.destroy();
debrisList.splice(j, 1);
continue;
}
// Check debris-cannon collision
if (debris.intersects(cannon)) {
// Game over with small explosion
createSmallExplosion(debris.x, debris.y);
LK.setTimeout(function () {
LK.showGameOver();
}, 300);
return;
}
// Check debris-laser collision
for (var k = lasers.length - 1; k >= 0; k--) {
var laser = lasers[k];
if (debris.intersects(laser)) {
// Destroy both debris and laser
LK.setScore(LK.getScore() + 100);
scoreText.setText('Score: ' + LK.getScore());
debris.destroy();
debrisList.splice(j, 1);
laser.destroy();
lasers.splice(k, 1);
// Check if meteor is destroyed and all debris are now cleared
if (!currentMeteor && debrisList.length === 0) {
// Level complete - advance to next level
currentLevel++;
if (currentLevel > totalLevels) {
// Game complete
LK.showYouWin();
} else {
// Start next level after brief delay
LK.setTimeout(function () {
startLevel(currentLevel);
}, 1000);
}
}
break;
}
}
}
// Update and manage stars
for (var s = stars.length - 1; s >= 0; s--) {
var star = stars[s];
// Remove stars that go off screen
if (star.y > 2732 + 20) {
star.destroy();
stars.splice(s, 1);
}
}
// Create new stars periodically
if (LK.ticks % 60 === 0) {
// Every second
createStar();
}
};
moon like meteor. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Küçük meteor parçası . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
2D top-down view sci-fi laser turret, mounted on a rotating base, glowing energy cell, detailed mechanical parts, metallic finish, compact and powerful look, pixel art or vector style, no background. In-Game asset. 2d. High contrast. No shadows