/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Asteroid = Container.expand(function (type) { var self = Container.call(this); var assetTypes = { 1: { asset: 'asteroid1', points: 5, health: 5 }, 2: { asset: 'asteroid2', points: 10, health: 10 }, 3: { asset: 'asteroid3', points: 15, health: 15 }, 4: { asset: 'goldAsteroid', points: 25, health: 8 } }; self.type = type || 1; self.info = assetTypes[self.type]; self.health = self.info.health; self.points = self.info.points; self.mined = false; var asteroidGraphics = self.attachAsset(self.info.asset, { anchorX: 0.5, anchorY: 0.5 }); // Random speed and direction self.speedX = (Math.random() - 0.5) * 3; self.speedY = Math.random() * 2 + 1; // Random initial rotation and rotation speed self.rotation = Math.random() * Math.PI * 2; self.rotationSpeed = (Math.random() - 0.5) * 0.05; self.update = function () { // Update position self.x += self.speedX; self.y += self.speedY; // Update rotation self.rotation += self.rotationSpeed; // Wrap around edges if (self.x < -100) self.x = 2048 + 100; if (self.x > 2048 + 100) self.x = -100; }; self.mine = function (damage) { if (self.mined) return 0; self.health -= damage; // Visual feedback for mining tween(self, { alpha: 0.5 }, { duration: 100, onFinish: function onFinish() { tween(self, { alpha: 1 }, { duration: 100 }); } }); if (self.health <= 0) { self.mined = true; tween(self, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 500, onFinish: function onFinish() { // Return points when fully mined return self.points; } }); return self.points; } return 0; }; return self; }); var MiningShip = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('miningShip', { anchorX: 0.5, anchorY: 0.5 }); self.fuel = 100; self.hasShield = false; self.speed = 5; self.miningDamage = 0.5; self.update = function () { // Implement ship behavior if (self.fuel > 0) { // Deplete fuel passively self.fuel -= 0.03; } }; self.activateShield = function () { if (!self.hasShield) { self.hasShield = true; tween(shipGraphics, { tint: 0x2ecc71 }, { duration: 300, onFinish: function onFinish() { // Set a timeout to deactivate shield after 10 seconds LK.setTimeout(function () { self.deactivateShield(); }, 10000); } }); } }; self.deactivateShield = function () { self.hasShield = false; tween(shipGraphics, { tint: 0xFFFFFF }, { duration: 300 }); }; self.refuel = function (amount) { self.fuel = Math.min(100, self.fuel + amount); }; return self; }); var Powerup = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'fuel'; var assetId = self.type === 'fuel' ? 'fuelPowerup' : 'shieldPowerup'; var powerupGraphics = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // Random vertical speed self.speedY = Math.random() * 1.5 + 1; // Bobbing animation self.bobPhase = Math.random() * Math.PI * 2; self.bobSpeed = 0.05; self.bobAmount = 10; self.originalX = 0; self.update = function () { // Update position self.y += self.speedY; // Bobbing effect self.bobPhase += self.bobSpeed; if (self.originalX) { self.x = self.originalX + Math.sin(self.bobPhase) * self.bobAmount; } }; self.collect = function () { tween(self, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 300 }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ // Game state constants var STATE_READY = 'ready'; var STATE_PLAYING = 'playing'; var STATE_GAME_OVER = 'gameover'; // Game state variables var gameState = STATE_READY; var score = 0; var level = 1; var asteroids = []; var powerups = []; var ship; var dragMode = false; var lastSpawnTime = 0; var spawnInterval = 1500; // milliseconds var powerupSpawnChance = 0.2; var maxAsteroids = 10; // Game UI elements var scoreTxt; var fuelBar; var fuelBarBackground; var levelTxt; function initializeGame() { // Reset game state gameState = STATE_PLAYING; score = 0; level = 1; asteroids = []; powerups = []; lastSpawnTime = 0; LK.setScore(0); // Create mining ship ship = new MiningShip(); ship.x = 2048 / 2; ship.y = 2732 - 200; game.addChild(ship); // Initialize UI createUI(); // Play background music LK.playMusic('bgMusic'); } function createUI() { // Score text scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); scoreTxt.x = -250; scoreTxt.y = 20; // Level text levelTxt = new Text2('Level: 1', { size: 60, fill: 0xFFFFFF }); levelTxt.anchor.set(0, 0); LK.gui.topRight.addChild(levelTxt); levelTxt.x = -250; levelTxt.y = 90; // Fuel bar background fuelBarBackground = LK.getAsset('miningShip', { anchorX: 0, anchorY: 0.5, scaleX: 3, scaleY: 0.3, tint: 0x333333 }); fuelBarBackground.x = 120; fuelBarBackground.y = 40; LK.gui.topLeft.addChild(fuelBarBackground); // Fuel bar fuelBar = LK.getAsset('miningShip', { anchorX: 0, anchorY: 0.5, scaleX: 3, scaleY: 0.3, tint: 0xe74c3c }); fuelBar.x = 120; fuelBar.y = 40; LK.gui.topLeft.addChild(fuelBar); } function updateUI() { scoreTxt.setText('Score: ' + score); levelTxt.setText('Level: ' + level); // Update fuel bar fuelBar.scaleX = ship.fuel / 100 * 3; } function spawnAsteroid() { if (asteroids.length >= maxAsteroids) return; // More variety and difficulty with level progression var typeChance = Math.random(); var type = 1; if (level >= 2 && typeChance > 0.6) type = 2; if (level >= 3 && typeChance > 0.8) type = 3; if (level >= 4 && typeChance > 0.95) type = 4; var asteroid = new Asteroid(type); // Random position at top of screen with some horizontal variation asteroid.x = Math.random() * 2048; asteroid.y = -200; asteroids.push(asteroid); game.addChild(asteroid); } function spawnPowerup() { if (Math.random() > powerupSpawnChance) return; var type = Math.random() > 0.7 ? 'shield' : 'fuel'; var powerup = new Powerup(type); // Random position at top of screen powerup.x = Math.random() * (2048 - 200) + 100; powerup.y = -100; powerup.originalX = powerup.x; powerups.push(powerup); game.addChild(powerup); } function checkCollisions() { // Check asteroid collisions with ship for (var i = asteroids.length - 1; i >= 0; i--) { var asteroid = asteroids[i]; // Remove asteroids that go off-screen if (asteroid.y > 2732 + 200) { asteroid.destroy(); asteroids.splice(i, 1); continue; } // Check for mining distance (close enough to mine but not colliding) var dx = ship.x - asteroid.x; var dy = ship.y - asteroid.y; var distance = Math.sqrt(dx * dx + dy * dy); var miningDistance = (shipSize + asteroid.width / 2) * 1.2; var collisionDistance = shipSize + asteroid.width / 2 - 20; // Ship is close enough to mine the asteroid if (distance < miningDistance && distance > collisionDistance) { var pointsGained = asteroid.mine(ship.miningDamage); if (pointsGained > 0) { score += pointsGained; LK.setScore(score); LK.getSound('mine').play(); // Remove mined asteroid asteroid.destroy(); asteroids.splice(i, 1); // Check for level up checkLevelUp(); } } // Ship collided with asteroid else if (distance < collisionDistance) { if (ship.hasShield) { // Shield absorbs the impact ship.deactivateShield(); LK.getSound('collision').play(); // Destroy asteroid on shield impact asteroid.destroy(); asteroids.splice(i, 1); } else { // Collision penalty ship.fuel -= 10; LK.getSound('collision').play(); LK.effects.flashScreen(0xff0000, 300); // Move asteroid away to prevent multiple collisions asteroid.x += (Math.random() - 0.5) * 300; asteroid.y += 200; if (ship.fuel <= 0) { gameOver(); } } } } // Check powerup collisions for (var j = powerups.length - 1; j >= 0; j--) { var powerup = powerups[j]; // Remove powerups that go off-screen if (powerup.y > 2732 + 100) { powerup.destroy(); powerups.splice(j, 1); continue; } // Check for collision with ship if (ship.intersects(powerup)) { LK.getSound('collect').play(); if (powerup.type === 'fuel') { ship.refuel(30); } else if (powerup.type === 'shield') { ship.activateShield(); } powerup.collect(); powerup.destroy(); powerups.splice(j, 1); } } } function checkLevelUp() { // Level up every 100 points var newLevel = Math.floor(score / 100) + 1; if (newLevel > level) { level = newLevel; maxAsteroids = 10 + (level - 1) * 2; spawnInterval = Math.max(500, 1500 - (level - 1) * 200); powerupSpawnChance = Math.min(0.4, 0.2 + (level - 1) * 0.05); // Increase mining effectiveness ship.miningDamage = 0.5 + (level - 1) * 0.2; // Visual feedback for level up LK.effects.flashScreen(0x2ecc71, 500); } } function gameOver() { gameState = STATE_GAME_OVER; LK.showGameOver(); } // Ship size calculation for collision detection var shipGraphics = ship ? ship.getChildAt(0) : null; var shipSize = shipGraphics ? shipGraphics.width / 2 : 60; // Input handlers function handleMove(x, y, obj) { if (gameState !== STATE_PLAYING) return; if (dragMode && ship) { ship.x = x; ship.y = y; // Consume fuel when moving ship.fuel -= 0.05; if (ship.fuel <= 0) { gameOver(); } } } game.move = handleMove; game.down = function (x, y, obj) { if (gameState === STATE_READY) { initializeGame(); } else if (gameState === STATE_PLAYING && ship) { dragMode = true; handleMove(x, y, obj); } }; game.up = function (x, y, obj) { dragMode = false; }; // Game update loop game.update = function () { if (gameState !== STATE_PLAYING) return; // Update all game elements if (ship) ship.update(); // Spawn new asteroids at intervals if (Date.now() - lastSpawnTime > spawnInterval) { spawnAsteroid(); spawnPowerup(); lastSpawnTime = Date.now(); } // Update all asteroids for (var i = 0; i < asteroids.length; i++) { asteroids[i].update(); } // Update all powerups for (var j = 0; j < powerups.length; j++) { powerups[j].update(); } // Check for collisions checkCollisions(); // Update UI updateUI(); // Game over if ship runs out of fuel if (ship && ship.fuel <= 0) { gameOver(); } }; // Initialize UI for start screen createUI(); scoreTxt.setText('Tap to Start'); levelTxt.setText('Asteroid Miner');
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Asteroid = Container.expand(function (type) {
var self = Container.call(this);
var assetTypes = {
1: {
asset: 'asteroid1',
points: 5,
health: 5
},
2: {
asset: 'asteroid2',
points: 10,
health: 10
},
3: {
asset: 'asteroid3',
points: 15,
health: 15
},
4: {
asset: 'goldAsteroid',
points: 25,
health: 8
}
};
self.type = type || 1;
self.info = assetTypes[self.type];
self.health = self.info.health;
self.points = self.info.points;
self.mined = false;
var asteroidGraphics = self.attachAsset(self.info.asset, {
anchorX: 0.5,
anchorY: 0.5
});
// Random speed and direction
self.speedX = (Math.random() - 0.5) * 3;
self.speedY = Math.random() * 2 + 1;
// Random initial rotation and rotation speed
self.rotation = Math.random() * Math.PI * 2;
self.rotationSpeed = (Math.random() - 0.5) * 0.05;
self.update = function () {
// Update position
self.x += self.speedX;
self.y += self.speedY;
// Update rotation
self.rotation += self.rotationSpeed;
// Wrap around edges
if (self.x < -100) self.x = 2048 + 100;
if (self.x > 2048 + 100) self.x = -100;
};
self.mine = function (damage) {
if (self.mined) return 0;
self.health -= damage;
// Visual feedback for mining
tween(self, {
alpha: 0.5
}, {
duration: 100,
onFinish: function onFinish() {
tween(self, {
alpha: 1
}, {
duration: 100
});
}
});
if (self.health <= 0) {
self.mined = true;
tween(self, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 500,
onFinish: function onFinish() {
// Return points when fully mined
return self.points;
}
});
return self.points;
}
return 0;
};
return self;
});
var MiningShip = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('miningShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.fuel = 100;
self.hasShield = false;
self.speed = 5;
self.miningDamage = 0.5;
self.update = function () {
// Implement ship behavior
if (self.fuel > 0) {
// Deplete fuel passively
self.fuel -= 0.03;
}
};
self.activateShield = function () {
if (!self.hasShield) {
self.hasShield = true;
tween(shipGraphics, {
tint: 0x2ecc71
}, {
duration: 300,
onFinish: function onFinish() {
// Set a timeout to deactivate shield after 10 seconds
LK.setTimeout(function () {
self.deactivateShield();
}, 10000);
}
});
}
};
self.deactivateShield = function () {
self.hasShield = false;
tween(shipGraphics, {
tint: 0xFFFFFF
}, {
duration: 300
});
};
self.refuel = function (amount) {
self.fuel = Math.min(100, self.fuel + amount);
};
return self;
});
var Powerup = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'fuel';
var assetId = self.type === 'fuel' ? 'fuelPowerup' : 'shieldPowerup';
var powerupGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
// Random vertical speed
self.speedY = Math.random() * 1.5 + 1;
// Bobbing animation
self.bobPhase = Math.random() * Math.PI * 2;
self.bobSpeed = 0.05;
self.bobAmount = 10;
self.originalX = 0;
self.update = function () {
// Update position
self.y += self.speedY;
// Bobbing effect
self.bobPhase += self.bobSpeed;
if (self.originalX) {
self.x = self.originalX + Math.sin(self.bobPhase) * self.bobAmount;
}
};
self.collect = function () {
tween(self, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 300
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Game state constants
var STATE_READY = 'ready';
var STATE_PLAYING = 'playing';
var STATE_GAME_OVER = 'gameover';
// Game state variables
var gameState = STATE_READY;
var score = 0;
var level = 1;
var asteroids = [];
var powerups = [];
var ship;
var dragMode = false;
var lastSpawnTime = 0;
var spawnInterval = 1500; // milliseconds
var powerupSpawnChance = 0.2;
var maxAsteroids = 10;
// Game UI elements
var scoreTxt;
var fuelBar;
var fuelBarBackground;
var levelTxt;
function initializeGame() {
// Reset game state
gameState = STATE_PLAYING;
score = 0;
level = 1;
asteroids = [];
powerups = [];
lastSpawnTime = 0;
LK.setScore(0);
// Create mining ship
ship = new MiningShip();
ship.x = 2048 / 2;
ship.y = 2732 - 200;
game.addChild(ship);
// Initialize UI
createUI();
// Play background music
LK.playMusic('bgMusic');
}
function createUI() {
// Score text
scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -250;
scoreTxt.y = 20;
// Level text
levelTxt = new Text2('Level: 1', {
size: 60,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(levelTxt);
levelTxt.x = -250;
levelTxt.y = 90;
// Fuel bar background
fuelBarBackground = LK.getAsset('miningShip', {
anchorX: 0,
anchorY: 0.5,
scaleX: 3,
scaleY: 0.3,
tint: 0x333333
});
fuelBarBackground.x = 120;
fuelBarBackground.y = 40;
LK.gui.topLeft.addChild(fuelBarBackground);
// Fuel bar
fuelBar = LK.getAsset('miningShip', {
anchorX: 0,
anchorY: 0.5,
scaleX: 3,
scaleY: 0.3,
tint: 0xe74c3c
});
fuelBar.x = 120;
fuelBar.y = 40;
LK.gui.topLeft.addChild(fuelBar);
}
function updateUI() {
scoreTxt.setText('Score: ' + score);
levelTxt.setText('Level: ' + level);
// Update fuel bar
fuelBar.scaleX = ship.fuel / 100 * 3;
}
function spawnAsteroid() {
if (asteroids.length >= maxAsteroids) return;
// More variety and difficulty with level progression
var typeChance = Math.random();
var type = 1;
if (level >= 2 && typeChance > 0.6) type = 2;
if (level >= 3 && typeChance > 0.8) type = 3;
if (level >= 4 && typeChance > 0.95) type = 4;
var asteroid = new Asteroid(type);
// Random position at top of screen with some horizontal variation
asteroid.x = Math.random() * 2048;
asteroid.y = -200;
asteroids.push(asteroid);
game.addChild(asteroid);
}
function spawnPowerup() {
if (Math.random() > powerupSpawnChance) return;
var type = Math.random() > 0.7 ? 'shield' : 'fuel';
var powerup = new Powerup(type);
// Random position at top of screen
powerup.x = Math.random() * (2048 - 200) + 100;
powerup.y = -100;
powerup.originalX = powerup.x;
powerups.push(powerup);
game.addChild(powerup);
}
function checkCollisions() {
// Check asteroid collisions with ship
for (var i = asteroids.length - 1; i >= 0; i--) {
var asteroid = asteroids[i];
// Remove asteroids that go off-screen
if (asteroid.y > 2732 + 200) {
asteroid.destroy();
asteroids.splice(i, 1);
continue;
}
// Check for mining distance (close enough to mine but not colliding)
var dx = ship.x - asteroid.x;
var dy = ship.y - asteroid.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var miningDistance = (shipSize + asteroid.width / 2) * 1.2;
var collisionDistance = shipSize + asteroid.width / 2 - 20;
// Ship is close enough to mine the asteroid
if (distance < miningDistance && distance > collisionDistance) {
var pointsGained = asteroid.mine(ship.miningDamage);
if (pointsGained > 0) {
score += pointsGained;
LK.setScore(score);
LK.getSound('mine').play();
// Remove mined asteroid
asteroid.destroy();
asteroids.splice(i, 1);
// Check for level up
checkLevelUp();
}
}
// Ship collided with asteroid
else if (distance < collisionDistance) {
if (ship.hasShield) {
// Shield absorbs the impact
ship.deactivateShield();
LK.getSound('collision').play();
// Destroy asteroid on shield impact
asteroid.destroy();
asteroids.splice(i, 1);
} else {
// Collision penalty
ship.fuel -= 10;
LK.getSound('collision').play();
LK.effects.flashScreen(0xff0000, 300);
// Move asteroid away to prevent multiple collisions
asteroid.x += (Math.random() - 0.5) * 300;
asteroid.y += 200;
if (ship.fuel <= 0) {
gameOver();
}
}
}
}
// Check powerup collisions
for (var j = powerups.length - 1; j >= 0; j--) {
var powerup = powerups[j];
// Remove powerups that go off-screen
if (powerup.y > 2732 + 100) {
powerup.destroy();
powerups.splice(j, 1);
continue;
}
// Check for collision with ship
if (ship.intersects(powerup)) {
LK.getSound('collect').play();
if (powerup.type === 'fuel') {
ship.refuel(30);
} else if (powerup.type === 'shield') {
ship.activateShield();
}
powerup.collect();
powerup.destroy();
powerups.splice(j, 1);
}
}
}
function checkLevelUp() {
// Level up every 100 points
var newLevel = Math.floor(score / 100) + 1;
if (newLevel > level) {
level = newLevel;
maxAsteroids = 10 + (level - 1) * 2;
spawnInterval = Math.max(500, 1500 - (level - 1) * 200);
powerupSpawnChance = Math.min(0.4, 0.2 + (level - 1) * 0.05);
// Increase mining effectiveness
ship.miningDamage = 0.5 + (level - 1) * 0.2;
// Visual feedback for level up
LK.effects.flashScreen(0x2ecc71, 500);
}
}
function gameOver() {
gameState = STATE_GAME_OVER;
LK.showGameOver();
}
// Ship size calculation for collision detection
var shipGraphics = ship ? ship.getChildAt(0) : null;
var shipSize = shipGraphics ? shipGraphics.width / 2 : 60;
// Input handlers
function handleMove(x, y, obj) {
if (gameState !== STATE_PLAYING) return;
if (dragMode && ship) {
ship.x = x;
ship.y = y;
// Consume fuel when moving
ship.fuel -= 0.05;
if (ship.fuel <= 0) {
gameOver();
}
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (gameState === STATE_READY) {
initializeGame();
} else if (gameState === STATE_PLAYING && ship) {
dragMode = true;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragMode = false;
};
// Game update loop
game.update = function () {
if (gameState !== STATE_PLAYING) return;
// Update all game elements
if (ship) ship.update();
// Spawn new asteroids at intervals
if (Date.now() - lastSpawnTime > spawnInterval) {
spawnAsteroid();
spawnPowerup();
lastSpawnTime = Date.now();
}
// Update all asteroids
for (var i = 0; i < asteroids.length; i++) {
asteroids[i].update();
}
// Update all powerups
for (var j = 0; j < powerups.length; j++) {
powerups[j].update();
}
// Check for collisions
checkCollisions();
// Update UI
updateUI();
// Game over if ship runs out of fuel
if (ship && ship.fuel <= 0) {
gameOver();
}
};
// Initialize UI for start screen
createUI();
scoreTxt.setText('Tap to Start');
levelTxt.setText('Asteroid Miner');