/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
roverLevel: 1,
speedLevel: 1,
weaponLevel: 1
});
/****
* Classes
****/
var Alien = Container.expand(function () {
var self = Container.call(this);
var alienGraphics = self.attachAsset('alien', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1 + Math.random() * 2;
self.health = 2;
self.active = true;
self.points = 25;
self.movePattern = Math.floor(Math.random() * 3); // 0: straight, 1: zigzag, 2: sine
self.moveCounter = 0;
self.update = function () {
// Alien shooting logic
if (self.active && Math.random() < 0.01) {
// Random chance to shoot
var alienBullet = new AlienBullet();
alienBullet.x = self.x;
alienBullet.y = self.y + 40; // Start below the alien
// Set random direction for multi-directional shooting
alienBullet.directionX = Math.random() * 2 - 1; // Random value between -1 and 1
alienBullet.directionY = 1; // Always shoot downwards
alienBullets.push(alienBullet);
game.addChild(alienBullet);
}
if (!self.active) {
return;
}
self.y += self.speed;
// Different movement patterns
if (self.movePattern === 1) {
// ZigZag
if (self.moveCounter % 60 < 30) {
self.x += 1.5;
} else {
self.x -= 1.5;
}
} else if (self.movePattern === 2) {
// Sine wave
self.x += Math.sin(self.moveCounter / 20) * 2;
}
self.moveCounter++;
// Check if alien is off screen
if (self.y > 2732 + 50) {
self.active = false;
}
};
self.takeDamage = function (amount) {
self.health -= amount;
// Flash effect
LK.effects.flashObject(self, 0xFF0000, 200);
if (self.health <= 0) {
self.destroy();
}
};
self.destroy = function () {
self.active = false;
// Scale out and fade
tween(alienGraphics, {
alpha: 0,
scaleX: 0.2,
scaleY: 0.2,
rotation: Math.PI * 2
}, {
duration: 400,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Alien will be removed by the game update loop
}
});
};
return self;
});
var AlienBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4; // Reduced speed for alien bullets
self.damage = 1;
self.active = true;
self.directionX = 0; // Initialize horizontal direction
self.directionY = 1; // Initialize vertical direction
self.update = function () {
if (!self.active) {
return;
}
self.x += self.speed * self.directionX; // Update x position based on direction
self.y += self.speed * self.directionY; // Update y position based on direction
// Check if bullet is off screen
if (self.y > 2732 + 50 || self.x < -50 || self.x > 2048 + 50) {
self.active = false;
}
};
self.hit = function () {
self.active = false;
tween(bulletGraphics, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
// Bullet will be removed by the game update loop
}
});
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.damage = 1;
self.active = true;
self.update = function () {
if (!self.active) {
return;
}
self.y -= self.speed * 0.5; // Slow down the bullet speed by half
// Check if bullet is off screen
if (self.y < -50) {
self.active = false;
}
};
self.hit = function () {
self.active = false;
tween(bulletGraphics, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
// Bullet will be removed by the game update loop
}
});
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1.5 + Math.random() * 1.5;
self.active = true;
self.update = function () {
if (!self.active) {
return;
}
self.y += self.speed;
// Slowly rotate the obstacle
obstacleGraphics.rotation += 0.01;
// Check if obstacle is off screen
if (self.y > 2732 + 50) {
self.active = false;
}
};
self.hit = function () {
self.active = false;
LK.effects.flashObject(self, 0xFF0000, 200);
tween(obstacleGraphics, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5,
rotation: obstacleGraphics.rotation + Math.PI
}, {
duration: 300,
onFinish: function onFinish() {
// Obstacle will be removed by the game update loop
}
});
};
return self;
});
var Resource = Container.expand(function () {
var self = Container.call(this);
var resourceGraphics = self.attachAsset('resource', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 10;
self.active = true;
self.speed = 2 + Math.random() * 2;
self.update = function () {
if (!self.active) {
return;
}
self.y += self.speed;
// Make the resource bob slightly side to side
self.x += Math.sin(LK.ticks / 20) * 0.8;
// Check if resource is off screen
if (self.y > 2732 + 50) {
self.active = false;
}
};
self.collect = function () {
self.active = false;
tween(resourceGraphics, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 300,
onFinish: function onFinish() {
// Resource will be removed by the game update loop
}
});
};
return self;
});
var Rover = Container.expand(function () {
var self = Container.call(this);
// Main rover body
var roverBody = self.attachAsset('rover', {
anchorX: 0.5,
anchorY: 0.5
});
// Left wheel
var leftWheel = LK.getAsset('wheel', {
anchorX: 0.5,
anchorY: 0.5,
x: -45,
y: 25
});
self.addChild(leftWheel);
// Right wheel
var rightWheel = LK.getAsset('wheel', {
anchorX: 0.5,
anchorY: 0.5,
x: 45,
y: 25
});
self.addChild(rightWheel);
// Solar panel
var solarPanel = LK.getAsset('solar', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -20
});
self.addChild(solarPanel);
// Antenna
var antenna = LK.getAsset('antenna', {
anchorX: 0.5,
anchorY: 0.5,
x: 30,
y: -40
});
self.addChild(antenna);
// Set rover properties
self.speed = 5 + (storage.speedLevel - 1) * 0.8;
self.fireRate = 800 - (storage.weaponLevel - 1) * 100;
self.lastFire = 0;
self.health = 3 + (storage.roverLevel - 1);
self.shieldActive = false;
// Initialize movement
self.isMoving = false;
self.targetX = 0;
self.targetY = 0;
self.moveTowards = function (x, y) {
self.isMoving = true;
self.targetX = x;
self.targetY = y;
};
self.stopMoving = function () {
self.isMoving = false;
};
self.update = function () {
if (self.isMoving) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.speed) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
// Animate wheels
leftWheel.rotation += 0.2;
rightWheel.rotation += 0.2;
} else {
self.x = self.targetX;
self.y = self.targetY;
}
}
// Constrain to game bounds
if (self.x < roverBody.width / 2) {
self.x = roverBody.width / 2;
} else if (self.x > 2048 - roverBody.width / 2) {
self.x = 2048 - roverBody.width / 2;
}
if (self.y < roverBody.height / 2) {
self.y = roverBody.height / 2;
} else if (self.y > 2732 - roverBody.height / 2) {
self.y = 2732 - roverBody.height / 2;
}
};
self.fire = function () {
var currentTime = Date.now();
if (currentTime - self.lastFire < self.fireRate) {
return null;
}
self.lastFire = currentTime;
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y - 40;
bullet.damage = storage.weaponLevel;
// Play shoot sound
LK.getSound('shoot').play();
return bullet;
};
self.takeDamage = function () {
if (self.shieldActive) {
return;
}
self.health--;
LK.effects.flashObject(self, 0xFF0000, 300);
LK.getSound('damage').play();
// Activate brief shield
self.shieldActive = true;
tween(roverBody, {
alpha: 0.5
}, {
duration: 200,
onFinish: function onFinish() {
tween(roverBody, {
alpha: 1
}, {
duration: 200
});
}
});
// Deactivate shield after invulnerability period
LK.setTimeout(function () {
self.shieldActive = false;
}, 1500);
return self.health <= 0;
};
self.fire = function () {
var currentTime = Date.now();
if (currentTime - self.lastFire < self.fireRate) {
return null;
}
self.lastFire = currentTime;
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y - 40;
bullet.damage = storage.weaponLevel;
// Play shoot sound
LK.getSound('shoot').play();
return bullet;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xC0392B // Mars red
});
/****
* Game Code
****/
// Game state variables
var score = 0;
var level = 1;
var gameActive = true;
var spawnRate = 120; // Frames between spawns
var spawnCounter = 0;
var difficultyTimer = 0;
// Game objects
var rover;
var bullets = [];
var alienBullets = []; // Array to track alien bullets
var resources = [];
var aliens = [];
var obstacles = [];
// Background - Mars terrain
var terrainBackground = LK.getAsset('terrain', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(terrainBackground);
// Create rover
rover = new Rover();
rover.x = 2048 / 2;
rover.y = 2732 - 200;
game.addChild(rover);
// UI elements
var scoreTxt = new Text2('SCORE: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -scoreTxt.width - 20;
scoreTxt.y = 20;
var levelTxt = new Text2('LEVEL: 1', {
size: 60,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0, 0);
LK.gui.top.addChild(levelTxt);
levelTxt.y = 20;
var healthTxt = new Text2('HEALTH: ' + rover.health, {
size: 60,
fill: 0xFFFFFF
});
healthTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(healthTxt);
healthTxt.x = -healthTxt.width - 20;
healthTxt.y = 90;
// Touch controls
var dragNode = null;
// Handle touch/mouse down
game.down = function (x, y, obj) {
if (!gameActive) {
return;
}
// Fire when touching the top half of the screen
if (y < 2732 / 2) {
var newBullet = rover.fire();
if (newBullet) {
bullets.push(newBullet);
game.addChild(newBullet);
}
} else {
// Move rover when touching the bottom half
rover.moveTowards(x, y);
dragNode = rover;
}
};
// Handle touch/mouse move
game.move = function (x, y, obj) {
if (!gameActive || !dragNode) {
return;
}
rover.moveTowards(x, y);
};
// Handle touch/mouse up
game.up = function (x, y, obj) {
dragNode = null;
};
// Spawn a resource
function spawnResource() {
var resource = new Resource();
resource.x = 100 + Math.random() * (2048 - 200);
resource.y = -50;
resources.push(resource);
game.addChild(resource);
}
// Spawn an alien
function spawnAlien() {
var alien = new Alien();
alien.x = 100 + Math.random() * (2048 - 200);
alien.y = -50;
alien.health = 1 + Math.floor(level / 3);
alien.points = 25 + level * 5;
aliens.push(alien);
game.addChild(alien);
}
// Spawn an obstacle
function spawnObstacle() {
var obstacle = new Obstacle();
obstacle.x = 100 + Math.random() * (2048 - 200);
obstacle.y = -50;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Update score display
function updateScore(newScore) {
score = newScore;
scoreTxt.setText('SCORE: ' + score);
scoreTxt.x = -scoreTxt.width - 20;
// Update high score if needed
if (score > storage.highScore) {
storage.highScore = score;
}
}
// Update level display
function updateLevel(newLevel) {
level = newLevel;
levelTxt.setText('LEVEL: ' + level);
// Increase difficulty with level
spawnRate = Math.max(60, 120 - level * 10);
}
// Update health display
function updateHealth() {
healthTxt.setText('HEALTH: ' + rover.health);
healthTxt.x = -healthTxt.width - 20;
}
// Start background music
LK.playMusic('bgMusic', {
loop: true,
fade: {
start: 0,
end: 0.3,
duration: 1000
}
});
// Game update loop
game.update = function () {
if (!gameActive) {
return;
}
// Increase difficulty over time
difficultyTimer++;
if (difficultyTimer >= 900) {
// Every 15 seconds
difficultyTimer = 0;
updateLevel(level + 1);
}
// Spawn objects
spawnCounter++;
if (spawnCounter >= spawnRate) {
spawnCounter = 0;
// Randomly decide what to spawn
var rand = Math.random();
if (rand < 0.5) {
spawnResource();
} else if (rand < 0.8) {
spawnAlien();
} else {
spawnObstacle();
}
}
// Update rover
rover.update();
// Auto fire bullets from rover
var newBullet = rover.fire();
if (newBullet) {
bullets.push(newBullet);
game.addChild(newBullet);
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
bullet.update();
// Remove inactive bullets
if (!bullet.active) {
game.removeChild(bullet);
bullets.splice(i, 1);
}
}
// Update alien bullets
for (var i = alienBullets.length - 1; i >= 0; i--) {
var alienBullet = alienBullets[i];
alienBullet.update();
// Check for collision with rover
if (alienBullet.active && alienBullet.intersects(rover)) {
alienBullet.hit();
var gameOver = rover.takeDamage();
updateHealth();
if (gameOver) {
endGame();
}
}
// Remove inactive alien bullets
if (!alienBullet.active) {
game.removeChild(alienBullet);
alienBullets.splice(i, 1);
}
}
// Update resources
for (var i = resources.length - 1; i >= 0; i--) {
var resource = resources[i];
resource.update();
// Check for collision with rover
if (resource.active && resource.intersects(rover)) {
resource.collect();
updateScore(score + resource.value);
rover.health = Math.min(rover.health + 1, 3 + (storage.roverLevel - 1)); // Restore health, max health depends on rover level
updateHealth(); // Update health display
LK.getSound('collect').play();
}
// Remove inactive resources
if (!resource.active) {
game.removeChild(resource);
resources.splice(i, 1);
}
}
// Update aliens
for (var i = aliens.length - 1; i >= 0; i--) {
var alien = aliens[i];
alien.update();
// Check for collision with bullets
for (var j = bullets.length - 1; j >= 0; j--) {
var bullet = bullets[j];
if (alien.active && bullet.active && alien.intersects(bullet)) {
bullet.hit();
alien.takeDamage(bullet.damage);
if (!alien.active) {
updateScore(score + alien.points);
}
}
}
// Check for collision with rover
if (alien.active && alien.intersects(rover)) {
alien.destroy();
var gameOver = rover.takeDamage();
updateHealth();
if (gameOver) {
endGame();
}
}
// Remove inactive aliens
if (!alien.active) {
game.removeChild(alien);
aliens.splice(i, 1);
}
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
obstacle.update();
// Check for collision with bullets
for (var j = bullets.length - 1; j >= 0; j--) {
var bullet = bullets[j];
if (obstacle.active && bullet.active && obstacle.intersects(bullet)) {
bullet.hit();
// Obstacles are not destroyed by bullets, but bullets are destroyed
}
}
// Check for collision with rover
if (obstacle.active && obstacle.intersects(rover)) {
obstacle.hit();
var gameOver = rover.takeDamage();
updateHealth();
if (gameOver) {
endGame();
}
}
// Remove inactive obstacles
if (!obstacle.active) {
game.removeChild(obstacle);
obstacles.splice(i, 1);
}
}
};
// End the game
function endGame() {
gameActive = false;
// Save final score to leaderboard
LK.setScore(score);
// Play explosion sound
LK.getSound('explosion').play();
// Flash screen and show game over
LK.effects.flashScreen(0xFF0000, 1000);
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
} /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
roverLevel: 1,
speedLevel: 1,
weaponLevel: 1
});
/****
* Classes
****/
var Alien = Container.expand(function () {
var self = Container.call(this);
var alienGraphics = self.attachAsset('alien', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1 + Math.random() * 2;
self.health = 2;
self.active = true;
self.points = 25;
self.movePattern = Math.floor(Math.random() * 3); // 0: straight, 1: zigzag, 2: sine
self.moveCounter = 0;
self.update = function () {
// Alien shooting logic
if (self.active && Math.random() < 0.01) {
// Random chance to shoot
var alienBullet = new AlienBullet();
alienBullet.x = self.x;
alienBullet.y = self.y + 40; // Start below the alien
// Set random direction for multi-directional shooting
alienBullet.directionX = Math.random() * 2 - 1; // Random value between -1 and 1
alienBullet.directionY = 1; // Always shoot downwards
alienBullets.push(alienBullet);
game.addChild(alienBullet);
}
if (!self.active) {
return;
}
self.y += self.speed;
// Different movement patterns
if (self.movePattern === 1) {
// ZigZag
if (self.moveCounter % 60 < 30) {
self.x += 1.5;
} else {
self.x -= 1.5;
}
} else if (self.movePattern === 2) {
// Sine wave
self.x += Math.sin(self.moveCounter / 20) * 2;
}
self.moveCounter++;
// Check if alien is off screen
if (self.y > 2732 + 50) {
self.active = false;
}
};
self.takeDamage = function (amount) {
self.health -= amount;
// Flash effect
LK.effects.flashObject(self, 0xFF0000, 200);
if (self.health <= 0) {
self.destroy();
}
};
self.destroy = function () {
self.active = false;
// Scale out and fade
tween(alienGraphics, {
alpha: 0,
scaleX: 0.2,
scaleY: 0.2,
rotation: Math.PI * 2
}, {
duration: 400,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Alien will be removed by the game update loop
}
});
};
return self;
});
var AlienBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4; // Reduced speed for alien bullets
self.damage = 1;
self.active = true;
self.directionX = 0; // Initialize horizontal direction
self.directionY = 1; // Initialize vertical direction
self.update = function () {
if (!self.active) {
return;
}
self.x += self.speed * self.directionX; // Update x position based on direction
self.y += self.speed * self.directionY; // Update y position based on direction
// Check if bullet is off screen
if (self.y > 2732 + 50 || self.x < -50 || self.x > 2048 + 50) {
self.active = false;
}
};
self.hit = function () {
self.active = false;
tween(bulletGraphics, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
// Bullet will be removed by the game update loop
}
});
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.damage = 1;
self.active = true;
self.update = function () {
if (!self.active) {
return;
}
self.y -= self.speed * 0.5; // Slow down the bullet speed by half
// Check if bullet is off screen
if (self.y < -50) {
self.active = false;
}
};
self.hit = function () {
self.active = false;
tween(bulletGraphics, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
// Bullet will be removed by the game update loop
}
});
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1.5 + Math.random() * 1.5;
self.active = true;
self.update = function () {
if (!self.active) {
return;
}
self.y += self.speed;
// Slowly rotate the obstacle
obstacleGraphics.rotation += 0.01;
// Check if obstacle is off screen
if (self.y > 2732 + 50) {
self.active = false;
}
};
self.hit = function () {
self.active = false;
LK.effects.flashObject(self, 0xFF0000, 200);
tween(obstacleGraphics, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5,
rotation: obstacleGraphics.rotation + Math.PI
}, {
duration: 300,
onFinish: function onFinish() {
// Obstacle will be removed by the game update loop
}
});
};
return self;
});
var Resource = Container.expand(function () {
var self = Container.call(this);
var resourceGraphics = self.attachAsset('resource', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 10;
self.active = true;
self.speed = 2 + Math.random() * 2;
self.update = function () {
if (!self.active) {
return;
}
self.y += self.speed;
// Make the resource bob slightly side to side
self.x += Math.sin(LK.ticks / 20) * 0.8;
// Check if resource is off screen
if (self.y > 2732 + 50) {
self.active = false;
}
};
self.collect = function () {
self.active = false;
tween(resourceGraphics, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 300,
onFinish: function onFinish() {
// Resource will be removed by the game update loop
}
});
};
return self;
});
var Rover = Container.expand(function () {
var self = Container.call(this);
// Main rover body
var roverBody = self.attachAsset('rover', {
anchorX: 0.5,
anchorY: 0.5
});
// Left wheel
var leftWheel = LK.getAsset('wheel', {
anchorX: 0.5,
anchorY: 0.5,
x: -45,
y: 25
});
self.addChild(leftWheel);
// Right wheel
var rightWheel = LK.getAsset('wheel', {
anchorX: 0.5,
anchorY: 0.5,
x: 45,
y: 25
});
self.addChild(rightWheel);
// Solar panel
var solarPanel = LK.getAsset('solar', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -20
});
self.addChild(solarPanel);
// Antenna
var antenna = LK.getAsset('antenna', {
anchorX: 0.5,
anchorY: 0.5,
x: 30,
y: -40
});
self.addChild(antenna);
// Set rover properties
self.speed = 5 + (storage.speedLevel - 1) * 0.8;
self.fireRate = 800 - (storage.weaponLevel - 1) * 100;
self.lastFire = 0;
self.health = 3 + (storage.roverLevel - 1);
self.shieldActive = false;
// Initialize movement
self.isMoving = false;
self.targetX = 0;
self.targetY = 0;
self.moveTowards = function (x, y) {
self.isMoving = true;
self.targetX = x;
self.targetY = y;
};
self.stopMoving = function () {
self.isMoving = false;
};
self.update = function () {
if (self.isMoving) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.speed) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
// Animate wheels
leftWheel.rotation += 0.2;
rightWheel.rotation += 0.2;
} else {
self.x = self.targetX;
self.y = self.targetY;
}
}
// Constrain to game bounds
if (self.x < roverBody.width / 2) {
self.x = roverBody.width / 2;
} else if (self.x > 2048 - roverBody.width / 2) {
self.x = 2048 - roverBody.width / 2;
}
if (self.y < roverBody.height / 2) {
self.y = roverBody.height / 2;
} else if (self.y > 2732 - roverBody.height / 2) {
self.y = 2732 - roverBody.height / 2;
}
};
self.fire = function () {
var currentTime = Date.now();
if (currentTime - self.lastFire < self.fireRate) {
return null;
}
self.lastFire = currentTime;
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y - 40;
bullet.damage = storage.weaponLevel;
// Play shoot sound
LK.getSound('shoot').play();
return bullet;
};
self.takeDamage = function () {
if (self.shieldActive) {
return;
}
self.health--;
LK.effects.flashObject(self, 0xFF0000, 300);
LK.getSound('damage').play();
// Activate brief shield
self.shieldActive = true;
tween(roverBody, {
alpha: 0.5
}, {
duration: 200,
onFinish: function onFinish() {
tween(roverBody, {
alpha: 1
}, {
duration: 200
});
}
});
// Deactivate shield after invulnerability period
LK.setTimeout(function () {
self.shieldActive = false;
}, 1500);
return self.health <= 0;
};
self.fire = function () {
var currentTime = Date.now();
if (currentTime - self.lastFire < self.fireRate) {
return null;
}
self.lastFire = currentTime;
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y - 40;
bullet.damage = storage.weaponLevel;
// Play shoot sound
LK.getSound('shoot').play();
return bullet;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xC0392B // Mars red
});
/****
* Game Code
****/
// Game state variables
var score = 0;
var level = 1;
var gameActive = true;
var spawnRate = 120; // Frames between spawns
var spawnCounter = 0;
var difficultyTimer = 0;
// Game objects
var rover;
var bullets = [];
var alienBullets = []; // Array to track alien bullets
var resources = [];
var aliens = [];
var obstacles = [];
// Background - Mars terrain
var terrainBackground = LK.getAsset('terrain', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(terrainBackground);
// Create rover
rover = new Rover();
rover.x = 2048 / 2;
rover.y = 2732 - 200;
game.addChild(rover);
// UI elements
var scoreTxt = new Text2('SCORE: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -scoreTxt.width - 20;
scoreTxt.y = 20;
var levelTxt = new Text2('LEVEL: 1', {
size: 60,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0, 0);
LK.gui.top.addChild(levelTxt);
levelTxt.y = 20;
var healthTxt = new Text2('HEALTH: ' + rover.health, {
size: 60,
fill: 0xFFFFFF
});
healthTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(healthTxt);
healthTxt.x = -healthTxt.width - 20;
healthTxt.y = 90;
// Touch controls
var dragNode = null;
// Handle touch/mouse down
game.down = function (x, y, obj) {
if (!gameActive) {
return;
}
// Fire when touching the top half of the screen
if (y < 2732 / 2) {
var newBullet = rover.fire();
if (newBullet) {
bullets.push(newBullet);
game.addChild(newBullet);
}
} else {
// Move rover when touching the bottom half
rover.moveTowards(x, y);
dragNode = rover;
}
};
// Handle touch/mouse move
game.move = function (x, y, obj) {
if (!gameActive || !dragNode) {
return;
}
rover.moveTowards(x, y);
};
// Handle touch/mouse up
game.up = function (x, y, obj) {
dragNode = null;
};
// Spawn a resource
function spawnResource() {
var resource = new Resource();
resource.x = 100 + Math.random() * (2048 - 200);
resource.y = -50;
resources.push(resource);
game.addChild(resource);
}
// Spawn an alien
function spawnAlien() {
var alien = new Alien();
alien.x = 100 + Math.random() * (2048 - 200);
alien.y = -50;
alien.health = 1 + Math.floor(level / 3);
alien.points = 25 + level * 5;
aliens.push(alien);
game.addChild(alien);
}
// Spawn an obstacle
function spawnObstacle() {
var obstacle = new Obstacle();
obstacle.x = 100 + Math.random() * (2048 - 200);
obstacle.y = -50;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Update score display
function updateScore(newScore) {
score = newScore;
scoreTxt.setText('SCORE: ' + score);
scoreTxt.x = -scoreTxt.width - 20;
// Update high score if needed
if (score > storage.highScore) {
storage.highScore = score;
}
}
// Update level display
function updateLevel(newLevel) {
level = newLevel;
levelTxt.setText('LEVEL: ' + level);
// Increase difficulty with level
spawnRate = Math.max(60, 120 - level * 10);
}
// Update health display
function updateHealth() {
healthTxt.setText('HEALTH: ' + rover.health);
healthTxt.x = -healthTxt.width - 20;
}
// Start background music
LK.playMusic('bgMusic', {
loop: true,
fade: {
start: 0,
end: 0.3,
duration: 1000
}
});
// Game update loop
game.update = function () {
if (!gameActive) {
return;
}
// Increase difficulty over time
difficultyTimer++;
if (difficultyTimer >= 900) {
// Every 15 seconds
difficultyTimer = 0;
updateLevel(level + 1);
}
// Spawn objects
spawnCounter++;
if (spawnCounter >= spawnRate) {
spawnCounter = 0;
// Randomly decide what to spawn
var rand = Math.random();
if (rand < 0.5) {
spawnResource();
} else if (rand < 0.8) {
spawnAlien();
} else {
spawnObstacle();
}
}
// Update rover
rover.update();
// Auto fire bullets from rover
var newBullet = rover.fire();
if (newBullet) {
bullets.push(newBullet);
game.addChild(newBullet);
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
bullet.update();
// Remove inactive bullets
if (!bullet.active) {
game.removeChild(bullet);
bullets.splice(i, 1);
}
}
// Update alien bullets
for (var i = alienBullets.length - 1; i >= 0; i--) {
var alienBullet = alienBullets[i];
alienBullet.update();
// Check for collision with rover
if (alienBullet.active && alienBullet.intersects(rover)) {
alienBullet.hit();
var gameOver = rover.takeDamage();
updateHealth();
if (gameOver) {
endGame();
}
}
// Remove inactive alien bullets
if (!alienBullet.active) {
game.removeChild(alienBullet);
alienBullets.splice(i, 1);
}
}
// Update resources
for (var i = resources.length - 1; i >= 0; i--) {
var resource = resources[i];
resource.update();
// Check for collision with rover
if (resource.active && resource.intersects(rover)) {
resource.collect();
updateScore(score + resource.value);
rover.health = Math.min(rover.health + 1, 3 + (storage.roverLevel - 1)); // Restore health, max health depends on rover level
updateHealth(); // Update health display
LK.getSound('collect').play();
}
// Remove inactive resources
if (!resource.active) {
game.removeChild(resource);
resources.splice(i, 1);
}
}
// Update aliens
for (var i = aliens.length - 1; i >= 0; i--) {
var alien = aliens[i];
alien.update();
// Check for collision with bullets
for (var j = bullets.length - 1; j >= 0; j--) {
var bullet = bullets[j];
if (alien.active && bullet.active && alien.intersects(bullet)) {
bullet.hit();
alien.takeDamage(bullet.damage);
if (!alien.active) {
updateScore(score + alien.points);
}
}
}
// Check for collision with rover
if (alien.active && alien.intersects(rover)) {
alien.destroy();
var gameOver = rover.takeDamage();
updateHealth();
if (gameOver) {
endGame();
}
}
// Remove inactive aliens
if (!alien.active) {
game.removeChild(alien);
aliens.splice(i, 1);
}
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
obstacle.update();
// Check for collision with bullets
for (var j = bullets.length - 1; j >= 0; j--) {
var bullet = bullets[j];
if (obstacle.active && bullet.active && obstacle.intersects(bullet)) {
bullet.hit();
// Obstacles are not destroyed by bullets, but bullets are destroyed
}
}
// Check for collision with rover
if (obstacle.active && obstacle.intersects(rover)) {
obstacle.hit();
var gameOver = rover.takeDamage();
updateHealth();
if (gameOver) {
endGame();
}
}
// Remove inactive obstacles
if (!obstacle.active) {
game.removeChild(obstacle);
obstacles.splice(i, 1);
}
}
};
// End the game
function endGame() {
gameActive = false;
// Save final score to leaderboard
LK.setScore(score);
// Play explosion sound
LK.getSound('explosion').play();
// Flash screen and show game over
LK.effects.flashScreen(0xFF0000, 1000);
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
vertical gray top down image mars scifi rover. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
top down image purple squid alien. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
blue thunder orb entity. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
yellow bright aurora. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows