Code edit (1 edits merged)
Please save this source code
User prompt
Asteroid Miner
User prompt
Please continue polishing my design document.
Initial prompt
Reaction Time Test Test how quickly you can react to a visual stimulus. Click when the color changes! Current Time: 0 ms Best Time: 0 ms Average Time: 0 ms Click to start! Back to Games How to Play Click the blue area to start the test. Wait for the color to change from blue to green. Click as quickly as possible when the color changes to green. If you click too early (before the color changes), it will be considered a false start. Complete 5 attempts to see your final results and rating. Benefits Measure Reaction Speed: Get an accurate measurement of your visual reaction time. Improve Focus: Train your brain to stay alert and respond quickly to visual changes. Track Progress: Keep practicing to see improvement in your reaction times. Gaming Performance: Faster reaction times transfer directly to better gaming performance.
/**** * 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');