User prompt
Give the larger asteroid a thirty percent spawn rate
User prompt
Make large asteroids take ten hits to destroy
User prompt
Make it so that rarely, large asteroids, which give out a hundred points and an extra life, will spawn, but if they hit you, you lose all of your lives.
User prompt
Make laser fire every .3 seconds
User prompt
Give the player 5 lives
User prompt
Make the Laser fire every 2 seconds
User prompt
Make the asteroids slower and give out 10 points each when destroyed
User prompt
Make the background more space-like
User prompt
Add the ability to go left and right
Code edit (1 edits merged)
Please save this source code
User prompt
Space Dog: Asteroid Blaster
Initial prompt
Make a game where you're a dog in space. Shooting asteroids.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Asteroid var Asteroid = Container.expand(function () { var self = Container.call(this); var asteroid = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5 }); // Randomize rotation asteroid.rotation = Math.random() * Math.PI * 2; // Speed and direction self.speedY = 3 + Math.random() * 2; // 3-5 px/frame (slower) self.speedX = (Math.random() - 0.5) * 2; // -1 to 1 px/frame (slower) // For collision self.radius = asteroid.width * 0.5; // For rotation animation self.rotSpeed = (Math.random() - 0.5) * 0.04; // Update method self.update = function () { self.y += self.speedY; self.x += self.speedX; asteroid.rotation += self.rotSpeed; }; return self; }); // Dog Ship (Player) var DogShip = Container.expand(function () { var self = Container.call(this); var ship = self.attachAsset('dogShip', { anchorX: 0.5, anchorY: 0.5 }); // For collision, use the container itself self.radius = ship.width * 0.5; // For drag effect self.isDragging = false; return self; }); // Large Asteroid (rare, big, dangerous) var LargeAsteroid = Container.expand(function () { var self = Container.call(this); var asteroid = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.1, scaleY: 2.1 }); // Randomize rotation asteroid.rotation = Math.random() * Math.PI * 2; // Slower speed, but still moves self.speedY = 2 + Math.random() * 1.5; // 2-3.5 px/frame self.speedX = (Math.random() - 0.5) * 1.2; // -0.6 to 0.6 px/frame self.radius = asteroid.width * 0.5 * 2.1; // scale radius self.rotSpeed = (Math.random() - 0.5) * 0.025; self.isLargeAsteroid = true; // Add hit points for large asteroid self.hp = 10; self.update = function () { self.y += self.speedY; self.x += self.speedX; asteroid.rotation += self.rotSpeed; }; // Method to take damage self.takeDamage = function () { self.hp--; // Optionally, you could add a visual effect here (e.g. flash) if (self.hp <= 0) { self.destroy(); return true; // destroyed } return false; // not destroyed }; return self; }); // Laser var Laser = Container.expand(function () { var self = Container.call(this); var laser = self.attachAsset('laser', { anchorX: 0.5, anchorY: 0.5 }); self.speedY = -22; // Fast upward // For collision self.radius = laser.width * 0.5; self.update = function () { self.y += self.speedY; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x0a0a1a }); /**** * Game Code ****/ // Play background music // Spaceship (dog ship) // Asteroid // Laser // Sound for shooting // Sound for asteroid destroyed // Music (background) LK.playMusic('spaceMusic'); // --- Space background: animated twinkling stars --- var starCount = 60; var stars = []; for (var i = 0; i < starCount; i++) { var star = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.18 + Math.random() * 0.12, scaleY: 0.18 + Math.random() * 0.12, x: Math.random() * 2048, y: Math.random() * 2732 }); star.alpha = 0.5 + Math.random() * 0.5; star._twinkleSpeed = 0.008 + Math.random() * 0.012; star._twinklePhase = Math.random() * Math.PI * 2; stars.push(star); // Add behind everything game.addChildAt(star, 0); } // Score display var scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Game variables var dogShip; var asteroids = []; var lasers = []; var dragNode = null; var lastGameOver = false; var asteroidSpawnTick = 0; // Player lives var lives = 5; // Lives display var livesTxt = new Text2('Lives: 5', { size: 90, fill: "#fff" }); livesTxt.anchor.set(0.5, 0); LK.gui.top.addChild(livesTxt); livesTxt.y = 120; // Place below score // Place dog ship at bottom center, above bottom edge dogShip = new DogShip(); game.addChild(dogShip); dogShip.x = 2048 / 2; dogShip.y = 2732 - 320; // Prevent dogShip from going off screen function clampShipPosition() { var margin = dogShip.radius + 30; if (dogShip.x < margin) dogShip.x = margin; if (dogShip.x > 2048 - margin) dogShip.x = 2048 - margin; if (dogShip.y < margin + 120) dogShip.y = margin + 120; // Don't go under score if (dogShip.y > 2732 - margin) dogShip.y = 2732 - margin; } // Touch/mouse drag to move dog ship function handleMove(x, y, obj) { if (dragNode) { dragNode.x = x; dragNode.y = y; clampShipPosition(); } } game.move = handleMove; game.down = function (x, y, obj) { // Only start drag if touch is on the ship var dx = x - dogShip.x; var dy = y - dogShip.y; if (dx * dx + dy * dy < dogShip.radius * dogShip.radius) { dragNode = dogShip; handleMove(x, y, obj); } }; game.up = function (x, y, obj) { dragNode = null; }; // Laser will now fire automatically every 2 seconds (see interval below) // For mobile, treat down as tap if not dragging game.down = function (x, y, obj) { var dx = x - dogShip.x; var dy = y - dogShip.y; if (dx * dx + dy * dy < dogShip.radius * dogShip.radius) { dragNode = dogShip; handleMove(x, y, obj); } else { // Not on ship: tap left/right to move // Define left/right/center regions var leftEdge = 0; var rightEdge = 2048; var centerWidth = 400; var leftRegion = (rightEdge - centerWidth) / 2; var rightRegion = (rightEdge + centerWidth) / 2; if (x < leftRegion) { // Move ship left by a fixed amount dogShip.x -= 220; clampShipPosition(); } else if (x > rightRegion) { // Move ship right by a fixed amount dogShip.x += 220; clampShipPosition(); } // No shooting on tap, as laser is now automatic } }; // Fire laser every 0.3 seconds automatically var laserInterval = LK.setInterval(function () { if (lastGameOver) return; var laser = new Laser(); laser.x = dogShip.x; laser.y = dogShip.y - dogShip.radius - 30; lasers.push(laser); game.addChild(laser); LK.getSound('laserShoot').play(); }, 300); // Asteroid spawn logic function spawnAsteroid() { // 30% chance for a large asteroid var isLarge = Math.random() < 0.3; var asteroid; if (isLarge) { asteroid = new LargeAsteroid(); } else { asteroid = new Asteroid(); } // Spawn at random X, just above top var margin = asteroid.radius + 40; asteroid.x = margin + Math.random() * (2048 - margin * 2); asteroid.y = -asteroid.radius - 40; asteroids.push(asteroid); game.addChild(asteroid); } // Collision detection (circle vs circle) function circlesIntersect(a, b) { var dx = a.x - b.x; var dy = a.y - b.y; var r = a.radius + b.radius - 10; // -10 for some forgiveness return dx * dx + dy * dy < r * r; } // Main game update game.update = function () { // Animate stars (twinkle) for (var si = 0; si < stars.length; si++) { var s = stars[si]; s.alpha = 0.5 + 0.5 * Math.sin(LK.ticks * s._twinkleSpeed + s._twinklePhase); } // Asteroid spawn rate: every 40-70 ticks, randomize for tension asteroidSpawnTick--; if (asteroidSpawnTick <= 0) { spawnAsteroid(); asteroidSpawnTick = 40 + Math.floor(Math.random() * 30); } // Update asteroids for (var i = asteroids.length - 1; i >= 0; i--) { var a = asteroids[i]; a.update(); // Remove if off screen if (a.y - a.radius > 2732 + 60) { a.destroy(); asteroids.splice(i, 1); continue; } // Check collision with dogShip if (!lastGameOver && circlesIntersect(a, dogShip)) { if (a.isLargeAsteroid) { // Large asteroid: lose all lives instantly lives = 0; livesTxt.setText('Lives: 0'); LK.effects.flashScreen(0xff0000, 1200); tween(dogShip, { alpha: 0.2 }, { duration: 500, easing: tween.easeOut }); // Remove asteroid a.destroy(); asteroids.splice(i, 1); lastGameOver = true; LK.showGameOver(); return; } else { // Normal asteroid: lose one life lives--; livesTxt.setText('Lives: ' + lives); LK.effects.flashScreen(0xff0000, 900); tween(dogShip, { alpha: 0.2 }, { duration: 400, easing: tween.easeOut }); // Remove asteroid a.destroy(); asteroids.splice(i, 1); if (lives <= 0) { lastGameOver = true; LK.showGameOver(); return; } else { // Briefly flash ship, restore alpha tween(dogShip, { alpha: 1 }, { duration: 400, easing: tween.easeOut }); } } } } // Update lasers for (var j = lasers.length - 1; j >= 0; j--) { var l = lasers[j]; l.update(); // Remove if off screen if (l.y + l.radius < -60) { l.destroy(); lasers.splice(j, 1); continue; } // Check collision with asteroids for (var k = asteroids.length - 1; k >= 0; k--) { var a2 = asteroids[k]; if (circlesIntersect(l, a2)) { LK.getSound('asteroidHit').play(); if (a2.isLargeAsteroid) { // Only destroy laser, decrement hp, destroy asteroid if hp reaches 0 l.destroy(); lasers.splice(j, 1); var destroyed = a2.takeDamage(); if (destroyed) { asteroids.splice(k, 1); LK.setScore(LK.getScore() + 100); scoreTxt.setText(LK.getScore()); // Extra life! lives++; livesTxt.setText('Lives: ' + lives); // Big explosion effect LK.effects.flashObject(dogShip, 0xffe000, 400); } } else { // Normal asteroid: destroy both a2.destroy(); asteroids.splice(k, 1); l.destroy(); lasers.splice(j, 1); LK.setScore(LK.getScore() + 10); scoreTxt.setText(LK.getScore()); // Small asteroid explosion effect LK.effects.flashObject(dogShip, 0x00e0ff, 200); } break; } } } }; // Reset state on new game LK.on('gameStart', function () { // Remove all asteroids and lasers for (var i = 0; i < asteroids.length; i++) asteroids[i].destroy(); for (var j = 0; j < lasers.length; j++) lasers[j].destroy(); asteroids = []; lasers = []; // Reset dogShip dogShip.x = 2048 / 2; dogShip.y = 2732 - 320; dogShip.alpha = 1; lastGameOver = false; scoreTxt.setText('0'); LK.setScore(0); asteroidSpawnTick = 30; clampShipPosition(); // Reset lives lives = 5; livesTxt.setText('Lives: ' + lives); // Restart music LK.playMusic('spaceMusic'); // Restart laser interval if (typeof laserInterval !== "undefined") { LK.clearInterval(laserInterval); } laserInterval = LK.setInterval(function () { if (lastGameOver) return; var laser = new Laser(); laser.x = dogShip.x; laser.y = dogShip.y - dogShip.radius - 30; lasers.push(laser); game.addChild(laser); LK.getSound('laserShoot').play(); }, 300); });
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Asteroid
var Asteroid = Container.expand(function () {
var self = Container.call(this);
var asteroid = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5
});
// Randomize rotation
asteroid.rotation = Math.random() * Math.PI * 2;
// Speed and direction
self.speedY = 3 + Math.random() * 2; // 3-5 px/frame (slower)
self.speedX = (Math.random() - 0.5) * 2; // -1 to 1 px/frame (slower)
// For collision
self.radius = asteroid.width * 0.5;
// For rotation animation
self.rotSpeed = (Math.random() - 0.5) * 0.04;
// Update method
self.update = function () {
self.y += self.speedY;
self.x += self.speedX;
asteroid.rotation += self.rotSpeed;
};
return self;
});
// Dog Ship (Player)
var DogShip = Container.expand(function () {
var self = Container.call(this);
var ship = self.attachAsset('dogShip', {
anchorX: 0.5,
anchorY: 0.5
});
// For collision, use the container itself
self.radius = ship.width * 0.5;
// For drag effect
self.isDragging = false;
return self;
});
// Large Asteroid (rare, big, dangerous)
var LargeAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroid = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.1,
scaleY: 2.1
});
// Randomize rotation
asteroid.rotation = Math.random() * Math.PI * 2;
// Slower speed, but still moves
self.speedY = 2 + Math.random() * 1.5; // 2-3.5 px/frame
self.speedX = (Math.random() - 0.5) * 1.2; // -0.6 to 0.6 px/frame
self.radius = asteroid.width * 0.5 * 2.1; // scale radius
self.rotSpeed = (Math.random() - 0.5) * 0.025;
self.isLargeAsteroid = true;
// Add hit points for large asteroid
self.hp = 10;
self.update = function () {
self.y += self.speedY;
self.x += self.speedX;
asteroid.rotation += self.rotSpeed;
};
// Method to take damage
self.takeDamage = function () {
self.hp--;
// Optionally, you could add a visual effect here (e.g. flash)
if (self.hp <= 0) {
self.destroy();
return true; // destroyed
}
return false; // not destroyed
};
return self;
});
// Laser
var Laser = Container.expand(function () {
var self = Container.call(this);
var laser = self.attachAsset('laser', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedY = -22; // Fast upward
// For collision
self.radius = laser.width * 0.5;
self.update = function () {
self.y += self.speedY;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0a0a1a
});
/****
* Game Code
****/
// Play background music
// Spaceship (dog ship)
// Asteroid
// Laser
// Sound for shooting
// Sound for asteroid destroyed
// Music (background)
LK.playMusic('spaceMusic');
// --- Space background: animated twinkling stars ---
var starCount = 60;
var stars = [];
for (var i = 0; i < starCount; i++) {
var star = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.18 + Math.random() * 0.12,
scaleY: 0.18 + Math.random() * 0.12,
x: Math.random() * 2048,
y: Math.random() * 2732
});
star.alpha = 0.5 + Math.random() * 0.5;
star._twinkleSpeed = 0.008 + Math.random() * 0.012;
star._twinklePhase = Math.random() * Math.PI * 2;
stars.push(star);
// Add behind everything
game.addChildAt(star, 0);
}
// Score display
var scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Game variables
var dogShip;
var asteroids = [];
var lasers = [];
var dragNode = null;
var lastGameOver = false;
var asteroidSpawnTick = 0;
// Player lives
var lives = 5;
// Lives display
var livesTxt = new Text2('Lives: 5', {
size: 90,
fill: "#fff"
});
livesTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(livesTxt);
livesTxt.y = 120; // Place below score
// Place dog ship at bottom center, above bottom edge
dogShip = new DogShip();
game.addChild(dogShip);
dogShip.x = 2048 / 2;
dogShip.y = 2732 - 320;
// Prevent dogShip from going off screen
function clampShipPosition() {
var margin = dogShip.radius + 30;
if (dogShip.x < margin) dogShip.x = margin;
if (dogShip.x > 2048 - margin) dogShip.x = 2048 - margin;
if (dogShip.y < margin + 120) dogShip.y = margin + 120; // Don't go under score
if (dogShip.y > 2732 - margin) dogShip.y = 2732 - margin;
}
// Touch/mouse drag to move dog ship
function handleMove(x, y, obj) {
if (dragNode) {
dragNode.x = x;
dragNode.y = y;
clampShipPosition();
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Only start drag if touch is on the ship
var dx = x - dogShip.x;
var dy = y - dogShip.y;
if (dx * dx + dy * dy < dogShip.radius * dogShip.radius) {
dragNode = dogShip;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Laser will now fire automatically every 2 seconds (see interval below)
// For mobile, treat down as tap if not dragging
game.down = function (x, y, obj) {
var dx = x - dogShip.x;
var dy = y - dogShip.y;
if (dx * dx + dy * dy < dogShip.radius * dogShip.radius) {
dragNode = dogShip;
handleMove(x, y, obj);
} else {
// Not on ship: tap left/right to move
// Define left/right/center regions
var leftEdge = 0;
var rightEdge = 2048;
var centerWidth = 400;
var leftRegion = (rightEdge - centerWidth) / 2;
var rightRegion = (rightEdge + centerWidth) / 2;
if (x < leftRegion) {
// Move ship left by a fixed amount
dogShip.x -= 220;
clampShipPosition();
} else if (x > rightRegion) {
// Move ship right by a fixed amount
dogShip.x += 220;
clampShipPosition();
}
// No shooting on tap, as laser is now automatic
}
};
// Fire laser every 0.3 seconds automatically
var laserInterval = LK.setInterval(function () {
if (lastGameOver) return;
var laser = new Laser();
laser.x = dogShip.x;
laser.y = dogShip.y - dogShip.radius - 30;
lasers.push(laser);
game.addChild(laser);
LK.getSound('laserShoot').play();
}, 300);
// Asteroid spawn logic
function spawnAsteroid() {
// 30% chance for a large asteroid
var isLarge = Math.random() < 0.3;
var asteroid;
if (isLarge) {
asteroid = new LargeAsteroid();
} else {
asteroid = new Asteroid();
}
// Spawn at random X, just above top
var margin = asteroid.radius + 40;
asteroid.x = margin + Math.random() * (2048 - margin * 2);
asteroid.y = -asteroid.radius - 40;
asteroids.push(asteroid);
game.addChild(asteroid);
}
// Collision detection (circle vs circle)
function circlesIntersect(a, b) {
var dx = a.x - b.x;
var dy = a.y - b.y;
var r = a.radius + b.radius - 10; // -10 for some forgiveness
return dx * dx + dy * dy < r * r;
}
// Main game update
game.update = function () {
// Animate stars (twinkle)
for (var si = 0; si < stars.length; si++) {
var s = stars[si];
s.alpha = 0.5 + 0.5 * Math.sin(LK.ticks * s._twinkleSpeed + s._twinklePhase);
}
// Asteroid spawn rate: every 40-70 ticks, randomize for tension
asteroidSpawnTick--;
if (asteroidSpawnTick <= 0) {
spawnAsteroid();
asteroidSpawnTick = 40 + Math.floor(Math.random() * 30);
}
// Update asteroids
for (var i = asteroids.length - 1; i >= 0; i--) {
var a = asteroids[i];
a.update();
// Remove if off screen
if (a.y - a.radius > 2732 + 60) {
a.destroy();
asteroids.splice(i, 1);
continue;
}
// Check collision with dogShip
if (!lastGameOver && circlesIntersect(a, dogShip)) {
if (a.isLargeAsteroid) {
// Large asteroid: lose all lives instantly
lives = 0;
livesTxt.setText('Lives: 0');
LK.effects.flashScreen(0xff0000, 1200);
tween(dogShip, {
alpha: 0.2
}, {
duration: 500,
easing: tween.easeOut
});
// Remove asteroid
a.destroy();
asteroids.splice(i, 1);
lastGameOver = true;
LK.showGameOver();
return;
} else {
// Normal asteroid: lose one life
lives--;
livesTxt.setText('Lives: ' + lives);
LK.effects.flashScreen(0xff0000, 900);
tween(dogShip, {
alpha: 0.2
}, {
duration: 400,
easing: tween.easeOut
});
// Remove asteroid
a.destroy();
asteroids.splice(i, 1);
if (lives <= 0) {
lastGameOver = true;
LK.showGameOver();
return;
} else {
// Briefly flash ship, restore alpha
tween(dogShip, {
alpha: 1
}, {
duration: 400,
easing: tween.easeOut
});
}
}
}
}
// Update lasers
for (var j = lasers.length - 1; j >= 0; j--) {
var l = lasers[j];
l.update();
// Remove if off screen
if (l.y + l.radius < -60) {
l.destroy();
lasers.splice(j, 1);
continue;
}
// Check collision with asteroids
for (var k = asteroids.length - 1; k >= 0; k--) {
var a2 = asteroids[k];
if (circlesIntersect(l, a2)) {
LK.getSound('asteroidHit').play();
if (a2.isLargeAsteroid) {
// Only destroy laser, decrement hp, destroy asteroid if hp reaches 0
l.destroy();
lasers.splice(j, 1);
var destroyed = a2.takeDamage();
if (destroyed) {
asteroids.splice(k, 1);
LK.setScore(LK.getScore() + 100);
scoreTxt.setText(LK.getScore());
// Extra life!
lives++;
livesTxt.setText('Lives: ' + lives);
// Big explosion effect
LK.effects.flashObject(dogShip, 0xffe000, 400);
}
} else {
// Normal asteroid: destroy both
a2.destroy();
asteroids.splice(k, 1);
l.destroy();
lasers.splice(j, 1);
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
// Small asteroid explosion effect
LK.effects.flashObject(dogShip, 0x00e0ff, 200);
}
break;
}
}
}
};
// Reset state on new game
LK.on('gameStart', function () {
// Remove all asteroids and lasers
for (var i = 0; i < asteroids.length; i++) asteroids[i].destroy();
for (var j = 0; j < lasers.length; j++) lasers[j].destroy();
asteroids = [];
lasers = [];
// Reset dogShip
dogShip.x = 2048 / 2;
dogShip.y = 2732 - 320;
dogShip.alpha = 1;
lastGameOver = false;
scoreTxt.setText('0');
LK.setScore(0);
asteroidSpawnTick = 30;
clampShipPosition();
// Reset lives
lives = 5;
livesTxt.setText('Lives: ' + lives);
// Restart music
LK.playMusic('spaceMusic');
// Restart laser interval
if (typeof laserInterval !== "undefined") {
LK.clearInterval(laserInterval);
}
laserInterval = LK.setInterval(function () {
if (lastGameOver) return;
var laser = new Laser();
laser.x = dogShip.x;
laser.y = dogShip.y - dogShip.radius - 30;
lasers.push(laser);
game.addChild(laser);
LK.getSound('laserShoot').play();
}, 300);
});
Modern App Store icon, high definition, square with rounded corners, for a game titled "Space Dog: Asteroid Blaster" and with the description "Control a spacefaring dog, shoot asteroids, and avoid collisions to survive and score points.". No text on icon!
A BIG GRAY ASTEROID. In-Game asset. 2d. High contrast. No shadows. Retro 8bt
16 bit super nintendo