User prompt
minimize level, lives and score 0.5.
User prompt
tap to start will disappear from the screen when the game starts.
User prompt
The background of the tap to start place should be a dark gray background and cover the entire text.
User prompt
minimize the tap to start location very slightly and add a gray background.
User prompt
move the lives place very slightly to the left.
User prompt
move your lives a little to the right.
User prompt
move your lives a little to the right.
User prompt
move your lives a little to the left.
User prompt
shift the level slightly to the left.
User prompt
Move the level a little to the right and down.
User prompt
Let's move the score a little lower.
User prompt
just enlarge the text by 2 times
Code edit (2 edits merged)
Please save this source code
User prompt
enlarge all articles by 2x ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Asteroid Battle Blitz
Initial prompt
asteroid breast war
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Asteroid = Container.expand(function (size, memeType) { var self = Container.call(this); // Size can be 0 (small), 1 (medium), or 2 (large) self.size = size || 2; // Create a container for the asteroid var asteroidGraphics = new Container(); self.addChild(asteroidGraphics); // Store the meme type or generate a random one if not provided self.memeType = memeType !== undefined ? memeType : Math.floor(Math.random() * 10); // Create the asteroid image based on size var assetId; if (self.size === 0) { assetId = 'memeSmall'; } else if (self.size === 1) { assetId = 'memeMedium'; } else { assetId = 'meme' + self.memeType; } // Add the meme image as the asteroid var memeImage = LK.getAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); asteroidGraphics.addChild(memeImage); // Random velocity var speed = (3 - self.size) * 0.8 + 0.5; // Smaller asteroids move faster var angle = Math.random() * Math.PI * 2; self.velocity = { x: Math.cos(angle) * speed, y: Math.sin(angle) * speed }; // Random rotation self.rotationSpeed = (Math.random() - 0.5) * 0.05; self.update = function () { // Move self.x += self.velocity.x; self.y += self.velocity.y; // Rotate asteroidGraphics.rotation += self.rotationSpeed; // Wrap around screen edges if (self.x < -50) { self.x = 2098; } if (self.x > 2098) { self.x = -50; } if (self.y < -50) { self.y = 2782; } if (self.y > 2782) { self.y = -50; } }; self.getPoints = function () { return (3 - self.size) * 100; // Small: 300, Medium: 200, Large: 100 }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); // Create a container for pixel art bullet var bulletGraphics = new Container(); self.addChild(bulletGraphics); // Create a small pixel art square (bullet) var bulletSize = 24; // Increased by 2x from 12 to 24 var pixelSize = 6; // Increased by 2x from 3 to 6 var pixelGap = 2; // Gap between pixels for hollow effect // Draw the outline of the square var points = [{ x: -bulletSize / 2, y: -bulletSize / 2 }, // Top left { x: bulletSize / 2, y: -bulletSize / 2 }, // Top right { x: bulletSize / 2, y: bulletSize / 2 }, // Bottom right { x: -bulletSize / 2, y: bulletSize / 2 } // Bottom left ]; // Draw the square outline for (var i = 0; i < 4; i++) { var startPoint = points[i]; var endPoint = points[(i + 1) % 4]; // Calculate steps var dx = endPoint.x - startPoint.x; var dy = endPoint.y - startPoint.y; var steps = Math.max(Math.abs(dx), Math.abs(dy)) / pixelSize; // Draw pixels along the line for (var step = 0; step <= steps; step++) { var px = startPoint.x + dx * (step / steps); var py = startPoint.y + dy * (step / steps); var pixel = LK.getAsset('bulletShape', { anchorX: 0.5, anchorY: 0.5, width: pixelSize - pixelGap, height: pixelSize - pixelGap, x: px, y: py, tint: 0xFF8000 // Orange color }); bulletGraphics.addChild(pixel); } } self.speed = 10; self.velocity = { x: 0, y: 0 }; self.lifespan = 60; // 1 second at 60fps self.age = 0; self.update = function () { self.x += self.velocity.x; self.y += self.velocity.y; self.age++; // Wrap around screen edges if (self.x < 0) { self.x = 2048; } if (self.x > 2048) { self.x = 0; } if (self.y < 0) { self.y = 2732; } if (self.y > 2732) { self.y = 0; } }; return self; }); var Button = Container.expand(function (assetId) { var self = Container.call(this); // Create button as a solid shape var buttonGraphics = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5, scaleX: 4, scaleY: 4 }); buttonGraphics.alpha = 0.5; // Determine button shape based on assetId var isCircle = assetId === 'fireButton' || assetId === 'forwardButton'; var buttonSize = 60; // Radius or half-width self.isPressed = false; self.down = function (x, y, obj) { self.isPressed = true; buttonGraphics.alpha = 0.8; }; self.up = function (x, y, obj) { self.isPressed = false; buttonGraphics.alpha = 0.5; }; return self; }); var Ship = Container.expand(function () { var self = Container.call(this); // Create a custom triangle ship var shipGraphics = new Container(); self.addChild(shipGraphics); // Create a pixel art triangle var triangleSize = 144; // Scale up to 2x from 72 to 144 var pixelSize = 24; // Increase pixel size for more distinct lines (2x) var pixelGap = 2; // Gap between pixels for hollow effect // Create triangle points - pointing right by default (0 degrees = right) var points = [{ x: triangleSize, y: 0 }, // Front tip (pointing right) { x: -triangleSize / 2, y: -triangleSize / 2 }, // Top left { x: -triangleSize / 2, y: triangleSize / 2 } // Bottom left ]; // Draw the outline with pixel art style for (var i = 0; i < 3; i++) { var startPoint = points[i]; var endPoint = points[(i + 1) % 3]; // Calculate step count based on distance var dx = endPoint.x - startPoint.x; var dy = endPoint.y - startPoint.y; var steps = Math.max(Math.abs(dx), Math.abs(dy)) / pixelSize; // Draw pixels along the line for (var step = 0; step <= steps; step++) { var px = startPoint.x + dx * (step / steps); var py = startPoint.y + dy * (step / steps); var pixel = LK.getAsset('shipShape', { anchorX: 0.5, anchorY: 0.5, width: pixelSize - pixelGap, height: pixelSize - pixelGap, x: px, y: py, tint: 0xFF8000 // Orange color }); shipGraphics.addChild(pixel); } } shipGraphics.x = 0; shipGraphics.y = 0; // Ship properties self.rot = 0; // Start pointing right (0 radians) self.rotationSpeed = 0.05; // Reduced rotation speed for less sensitive steering self.isRotatingLeft = false; self.isRotatingRight = false; self.isFiring = false; self.fireDelay = 15; // frames between shots self.fireTimer = 0; self.invulnerable = false; self.invulnerableTime = 0; // Physics-based movement properties - much simpler direct movement self.thrustPower = 0.15; // Reduced thrust power for slower acceleration self.dragFactor = 0.97; // Slightly increased drag to slow down faster self.maxSpeed = 6; // Lower maximum speed self.velocity = { x: 0, y: 0 }; // Track previous position for movement calculations self.lastX = 0; self.lastY = 0; // Apply rotation to ship graphics shipGraphics.rotation = self.rot; self.update = function () { // Store last position self.lastX = self.x; self.lastY = self.y; // Handle rotation if (self.isRotatingLeft) { self.rot -= self.rotationSpeed; } if (self.isRotatingRight) { self.rot += self.rotationSpeed; } // Apply rotation to ship visual shipGraphics.rotation = self.rot; // Calculate direction vector from rotation // 0 = right, PI/2 = down, PI = left, -PI/2 = up var dirX = Math.cos(self.rot); var dirY = Math.sin(self.rot); // Apply thrust force in direction ship is facing (always moving) self.velocity.x += dirX * self.thrustPower; self.velocity.y += dirY * self.thrustPower; // Apply drag/friction self.velocity.x *= self.dragFactor; self.velocity.y *= self.dragFactor; // Calculate current speed var speed = Math.sqrt(self.velocity.x * self.velocity.x + self.velocity.y * self.velocity.y); // Apply speed limit if necessary if (speed > self.maxSpeed) { self.velocity.x = self.velocity.x / speed * self.maxSpeed; self.velocity.y = self.velocity.y / speed * self.maxSpeed; } // Create thrust particles if (speed > 0.5 && LK.ticks % 3 === 0) { var particle = new ThrustParticle(); // Position at the back of the ship (opposite of direction) var backX = self.x - dirX * triangleSize * 0.5; var backY = self.y - dirY * triangleSize * 0.5; // Add some randomness backX += (Math.random() - 0.5) * 10; backY += (Math.random() - 0.5) * 10; particle.x = backX; particle.y = backY; // Set velocity opposite to ship direction with some randomness particle.velocity.x = -dirX * (1 + Math.random()) + (Math.random() - 0.5) * 0.5; particle.velocity.y = -dirY * (1 + Math.random()) + (Math.random() - 0.5) * 0.5; // Add to game via event if (typeof game.addThrustParticle === 'function') { game.addThrustParticle(particle); } } // Update position based on velocity self.x += self.velocity.x; self.y += self.velocity.y; // Wrap around screen edges if (self.x < 0) { self.x = 2048; } if (self.x > 2048) { self.x = 0; } if (self.y < 0) { self.y = 2732; } if (self.y > 2732) { self.y = 0; } // Handle firing if (self.isFiring) { if (self.fireTimer <= 0) { self.fireTimer = self.fireDelay; return true; // Signal to create a bullet } } if (self.fireTimer > 0) { self.fireTimer--; } // Handle invulnerability if (self.invulnerable) { self.invulnerableTime--; shipGraphics.alpha = Math.sin(LK.ticks * 0.5) * 0.5 + 0.5; if (self.invulnerableTime <= 0) { self.invulnerable = false; shipGraphics.alpha = 1; } } return false; }; self.makeInvulnerable = function (frames) { self.invulnerable = true; self.invulnerableTime = frames; }; return self; }); var ThrustParticle = Container.expand(function () { var self = Container.call(this); // Create particle visual - larger and more visible var particleGraphics = LK.getAsset('bulletShape', { anchorX: 0.5, anchorY: 0.5, width: 16, height: 16, tint: 0xFF8000 // Orange color }); particleGraphics.alpha = 0.9; self.addChild(particleGraphics); // Particle properties self.velocity = { x: 0, y: 0 }; self.lifespan = 25; // Longer lifespan for better visibility self.age = 0; self.update = function () { // Move according to velocity self.x += self.velocity.x; self.y += self.velocity.y; // Age the particle self.age++; // Fade out as it ages, with a faster tail-end fade var lifeRatio = self.age / self.lifespan; particleGraphics.alpha = 0.9 * (1 - lifeRatio * lifeRatio); // Return true if particle should be removed return self.age >= self.lifespan; }; return self; }); /**** * Initialize Game ****/ // Function to add thrust particles - called from Ship update var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Sound for the rhythmic beat // Sound for starting a new level // Sound for tapping to start // Add sound assets for each meme asteroid (meme0 to meme9) // Game variables var ship; var bullets = []; var asteroids = []; var thrustParticles = []; // Array to store thrust particles var score = 0; var lives = 3; var level = 1; var gameStarted = false; var gameOver = false; var triangleSize = 72; // Ship triangle size for bullet positioning (2x larger) // UI elements var leftButton; var rightButton; var fireButton; var scoreTxt; var livesTxt; var levelTxt; var startText; // Initialize the game function initGame() { // Create ship ship = new Ship(); ship.x = 2048 / 2; ship.y = 200; // Position at top middle ship.makeInvulnerable(120); // 2 seconds // Add visual effect to indicate ship is ready for movement tween(ship, { alpha: 0.5 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(ship, { alpha: 1 }, { duration: 500, easing: tween.easeInOut }); } }); game.addChild(ship); // Create control buttons leftButton = new Button('rotateLeftButton'); leftButton.x = 300; // Position on the left side leftButton.y = 2732 - 200; // Position at the bottom leftButton.scale.set(4, 4); // Make button bigger (2x) game.addChild(leftButton); // Fire button in the middle fireButton = new Button('fireButton'); fireButton.x = 2048 / 2; // Position in middle fireButton.y = 2732 - 200; // Position at the bottom fireButton.scale.set(4, 4); // Make button bigger (2x) game.addChild(fireButton); // No forward button needed - ship will constantly move forward // Right rotation button rightButton = new Button('rotateRightButton'); rightButton.x = 2048 - 300; // Position on the right side rightButton.y = 2732 - 200; // Position at the bottom rightButton.scale.set(4, 4); // Make button bigger (2x) game.addChild(rightButton); // Create UI text // Create Glaud text in orange var glaudText = new Text2('Glaud', { size: 60, fill: 0xFF8000 // Orange color }); glaudText.anchor.set(1, 0); // Right-align text glaudText.x = -20; // Add padding from right edge glaudText.y = 0; // Position at very top LK.gui.topRight.addChild(glaudText); scoreTxt = new Text2('SCORE: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(1, 0); // Right-align text scoreTxt.x = -20; // Add padding from right edge scoreTxt.y = 35; // Position below the Glaud text LK.gui.topRight.addChild(scoreTxt); livesTxt = new Text2('LIVES: 3', { size: 80, fill: 0xFFFFFF }); livesTxt.anchor.set(0.5, 0); // Center anchor horizontally LK.gui.top.addChild(livesTxt); levelTxt = new Text2('LEVEL: 1', { size: 80, fill: 0xFFFFFF }); levelTxt.anchor.set(0, 0); // Left-align text levelTxt.x = 120; // Keep away from top-left menu icon levelTxt.y = 20; // Add padding from top edge LK.gui.topLeft.addChild(levelTxt); // Start screen text if (!gameStarted) { startText = new Text2('TAP TO START', { size: 160, fill: 0xFFFFFF }); startText.anchor.set(0.5, 0.5); LK.gui.center.addChild(startText); } // Clear any existing game objects bullets = []; asteroids = []; thrustParticles = []; // Initialize asteroids for the first level createAsteroidsForLevel(level); // Start game music LK.playMusic('gameMusic', { loop: true }); } function createAsteroidsForLevel(level) { // Number of asteroids based on level var numAsteroids = Math.min(4 + level, 12); for (var i = 0; i < numAsteroids; i++) { // Create a random meme type (0-9) var memeType = Math.floor(Math.random() * 10); var asteroid = new Asteroid(2, memeType); // Start with large asteroids and specific meme type // Position the asteroid away from the player do { asteroid.x = Math.random() * 2048; asteroid.y = Math.random() * 2732; } while (distance(asteroid.x, asteroid.y, ship.x, ship.y) < 300); asteroids.push(asteroid); game.addChild(asteroid); } } function distance(x1, y1, x2, y2) { return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); } function createBullet() { var bullet = new Bullet(); // Use ship's rotation directly var angle = ship.rot; // Calculate the position at the tip of the ship based on the triangle geometry // For the redesigned ship (pointing up at 0 rotation), the tip is -triangleSize units in Y var offsetX = Math.cos(angle) * triangleSize; var offsetY = Math.sin(angle) * triangleSize; // Position bullet at the tip of the ship bullet.x = ship.x + offsetX; bullet.y = ship.y + offsetY; // Set bullet velocity to match ship's exact facing direction bullet.velocity.x = Math.cos(angle) * bullet.speed; bullet.velocity.y = Math.sin(angle) * bullet.speed; // Add bullet to game bullets.push(bullet); game.addChild(bullet); // Play shoot sound LK.getSound('shoot').play(); } function updateAsteroids() { for (var i = asteroids.length - 1; i >= 0; i--) { var asteroid = asteroids[i]; asteroid.update(); // Check for collision with the ship if (!ship.invulnerable && asteroid.intersects(ship)) { // Player loses a life lives--; livesTxt.setText('LIVES: ' + lives); // Play explosion sound LK.getSound('explosion').play(); // Flash screen LK.effects.flashScreen(0xFF0000, 500); // Make ship invulnerable for a few seconds ship.makeInvulnerable(180); // Game over if no lives left if (lives <= 0) { LK.setScore(score); LK.showGameOver(); gameOver = true; return; } } } } function updateBullets() { for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; bullet.update(); // Remove bullets that have lived too long if (bullet.age > bullet.lifespan) { game.removeChild(bullet); bullets.splice(i, 1); continue; } // Check for collisions with asteroids var hitAsteroid = false; for (var j = asteroids.length - 1; j >= 0; j--) { var asteroid = asteroids[j]; if (bullet.intersects(asteroid)) { hitAsteroid = true; // Add score based on asteroid size score += asteroid.getPoints(); scoreTxt.setText('SCORE: ' + score); // Play specific meme sound based on asteroid type if (asteroid.memeType !== undefined && LK.getSound('meme' + asteroid.memeType)) { LK.getSound('meme' + asteroid.memeType).play(); } // Break asteroid into smaller pieces only if it's medium or large if (asteroid.size > 1) { for (var k = 0; k < 2; k++) { var newAsteroid = new Asteroid(asteroid.size - 1, asteroid.memeType); newAsteroid.x = asteroid.x; newAsteroid.y = asteroid.y; // No velocity inheritance - just use the default size-based velocity asteroids.push(newAsteroid); game.addChild(newAsteroid); } } // Remove the asteroid game.removeChild(asteroid); asteroids.splice(j, 1); break; } } if (hitAsteroid) { // Remove the bullet game.removeChild(bullet); bullets.splice(i, 1); } } // Check if all asteroids are destroyed if (asteroids.length === 0) { // Next level level++; levelTxt.setText('LEVEL: ' + level); // Play level start sound LK.getSound('levelStart').play(); // Create new asteroids for the next level createAsteroidsForLevel(level); } } // Main game update function game.update = function () { if (!gameStarted) { return; } // Update ship controls based on button state ship.isRotatingLeft = leftButton.isPressed; ship.isRotatingRight = rightButton.isPressed; ship.isFiring = fireButton.isPressed; // Ship constantly moves forward, no need for isMoving toggle // Update ship if (ship.update()) { createBullet(); } // Update bullets and check for collisions updateBullets(); // Update asteroids and check for collisions updateAsteroids(); // Update thrust particles updateThrustParticles(); }; // Event handlers game.down = function (x, y, obj) { if (!gameStarted) { gameStarted = true; LK.getSound('gameStart').play(); // Play start sound if (startText) { LK.gui.center.removeChild(startText); startText = null; } // Start the rhythmic beat sound LK.setInterval(function () { // Check if the game is still running and not game over to avoid sound clutter if (gameStarted && !gameOver) { LK.getSound('beatSound').play(); } }, 500); // Play every 500ms (adjust timing as needed for desired beat) } // Fire bullet when clicking anywhere on screen (if game started) if (gameStarted && ship && !gameOver) { createBullet(); } // Ensure buttons can detect touch events when pressed var local; // Check left button local = leftButton.toLocal({ x: x, y: y }); if (local.x >= -leftButton.width / 2 && local.x <= leftButton.width / 2 && local.y >= -leftButton.height / 2 && local.y <= leftButton.height / 2) { leftButton.down(local.x, local.y, {}); } // Check fire button local = fireButton.toLocal({ x: x, y: y }); if (local.x >= -fireButton.width / 2 && local.x <= fireButton.width / 2 && local.y >= -fireButton.height / 2 && local.y <= fireButton.height / 2) { fireButton.down(local.x, local.y, {}); } // Forward button removed - ship moves constantly // Check right button local = rightButton.toLocal({ x: x, y: y }); if (local.x >= -rightButton.width / 2 && local.x <= rightButton.width / 2 && local.y >= -rightButton.height / 2 && local.y <= rightButton.height / 2) { rightButton.down(local.x, local.y, {}); } }; // Add up handler to handle releasing buttons game.up = function (x, y, obj) { // Reset all button states when touch/click is released leftButton.up(0, 0, {}); fireButton.up(0, 0, {}); rightButton.up(0, 0, {}); }; // Initialize the game when this script runs initGame(); // Function to add thrust particles - called from Ship update game.addThrustParticle = function (particle) { thrustParticles.push(particle); game.addChild(particle); }; // Function to update thrust particles function updateThrustParticles() { for (var i = thrustParticles.length - 1; i >= 0; i--) { var particle = thrustParticles[i]; // If particle update returns true, it means the particle should be removed if (particle.update()) { game.removeChild(particle); thrustParticles.splice(i, 1); } } }
===================================================================
--- original.js
+++ change.js
@@ -1,729 +1,716 @@
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
-var storage = LK.import("@upit/storage.v1", {
- highScore: 0,
- level: 1
-});
+var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
-var Asteroid = Container.expand(function () {
+var Asteroid = Container.expand(function (size, memeType) {
var self = Container.call(this);
- // Random size between 0.6 and 1.8
- var scale = 0.6 + Math.random() * 1.2;
- var asteroidGraphics = self.attachAsset('asteroid', {
+ // Size can be 0 (small), 1 (medium), or 2 (large)
+ self.size = size || 2;
+ // Create a container for the asteroid
+ var asteroidGraphics = new Container();
+ self.addChild(asteroidGraphics);
+ // Store the meme type or generate a random one if not provided
+ self.memeType = memeType !== undefined ? memeType : Math.floor(Math.random() * 10);
+ // Create the asteroid image based on size
+ var assetId;
+ if (self.size === 0) {
+ assetId = 'memeSmall';
+ } else if (self.size === 1) {
+ assetId = 'memeMedium';
+ } else {
+ assetId = 'meme' + self.memeType;
+ }
+ // Add the meme image as the asteroid
+ var memeImage = LK.getAsset(assetId, {
anchorX: 0.5,
- anchorY: 0.5,
- scaleX: scale,
- scaleY: scale
+ anchorY: 0.5
});
- // Asteroid properties based on size
- self.speed = 3 + Math.random() * 4;
+ asteroidGraphics.addChild(memeImage);
+ // Random velocity
+ var speed = (3 - self.size) * 0.8 + 0.5; // Smaller asteroids move faster
+ var angle = Math.random() * Math.PI * 2;
+ self.velocity = {
+ x: Math.cos(angle) * speed,
+ y: Math.sin(angle) * speed
+ };
+ // Random rotation
self.rotationSpeed = (Math.random() - 0.5) * 0.05;
- self.health = Math.floor(20 * scale);
- self.scoreValue = Math.floor(50 * scale);
self.update = function () {
- self.y += self.speed;
- self.rotation += self.rotationSpeed;
+ // Move
+ self.x += self.velocity.x;
+ self.y += self.velocity.y;
+ // Rotate
+ asteroidGraphics.rotation += self.rotationSpeed;
+ // Wrap around screen edges
+ if (self.x < -50) {
+ self.x = 2098;
+ }
+ if (self.x > 2098) {
+ self.x = -50;
+ }
+ if (self.y < -50) {
+ self.y = 2782;
+ }
+ if (self.y > 2782) {
+ self.y = -50;
+ }
};
- self.takeDamage = function (amount) {
- self.health -= amount;
- // Flash asteroid when hit
- LK.effects.flashObject(self, 0xff0000, 200);
- return self.health <= 0;
+ self.getPoints = function () {
+ return (3 - self.size) * 100; // Small: 300, Medium: 200, Large: 100
};
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 = -15; // Moving upward
- self.damage = 10;
- self.update = function () {
- self.y += self.speed;
+ // Create a container for pixel art bullet
+ var bulletGraphics = new Container();
+ self.addChild(bulletGraphics);
+ // Create a small pixel art square (bullet)
+ var bulletSize = 24; // Increased by 2x from 12 to 24
+ var pixelSize = 6; // Increased by 2x from 3 to 6
+ var pixelGap = 2; // Gap between pixels for hollow effect
+ // Draw the outline of the square
+ var points = [{
+ x: -bulletSize / 2,
+ y: -bulletSize / 2
+ },
+ // Top left
+ {
+ x: bulletSize / 2,
+ y: -bulletSize / 2
+ },
+ // Top right
+ {
+ x: bulletSize / 2,
+ y: bulletSize / 2
+ },
+ // Bottom right
+ {
+ x: -bulletSize / 2,
+ y: bulletSize / 2
+ } // Bottom left
+ ];
+ // Draw the square outline
+ for (var i = 0; i < 4; i++) {
+ var startPoint = points[i];
+ var endPoint = points[(i + 1) % 4];
+ // Calculate steps
+ var dx = endPoint.x - startPoint.x;
+ var dy = endPoint.y - startPoint.y;
+ var steps = Math.max(Math.abs(dx), Math.abs(dy)) / pixelSize;
+ // Draw pixels along the line
+ for (var step = 0; step <= steps; step++) {
+ var px = startPoint.x + dx * (step / steps);
+ var py = startPoint.y + dy * (step / steps);
+ var pixel = LK.getAsset('bulletShape', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: pixelSize - pixelGap,
+ height: pixelSize - pixelGap,
+ x: px,
+ y: py,
+ tint: 0xFF8000 // Orange color
+ });
+ bulletGraphics.addChild(pixel);
+ }
+ }
+ self.speed = 10;
+ self.velocity = {
+ x: 0,
+ y: 0
};
- return self;
-});
-var EnemyBullet = Container.expand(function () {
- var self = Container.call(this);
- var bulletGraphics = self.attachAsset('enemyBullet', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- self.speed = 10; // Moving downward
- self.damage = 10;
+ self.lifespan = 60; // 1 second at 60fps
+ self.age = 0;
self.update = function () {
- self.y += self.speed;
- };
- return self;
-});
-var EnemyShip = Container.expand(function () {
- var self = Container.call(this);
- var shipGraphics = self.attachAsset('enemyShip', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- // Enemy ship properties
- self.speed = 2 + Math.random() * 2;
- self.health = 30;
- self.scoreValue = 100;
- self.movementPattern = Math.floor(Math.random() * 3); // 0: straight, 1: zigzag, 2: sine wave
- self.movementCounter = 0;
- self.fireInterval = 60 + Math.floor(Math.random() * 60); // Frames between shots
- self.fireCounter = Math.floor(Math.random() * 60); // Randomize initial fire timing
- self.update = function () {
- // Basic downward movement
- self.y += self.speed;
- // Apply movement pattern
- self.movementCounter++;
- switch (self.movementPattern) {
- case 0:
- // Straight down
- break;
- case 1:
- // Zigzag
- self.x += Math.sin(self.movementCounter * 0.1) * 3;
- break;
- case 2:
- // Sine wave
- self.x += Math.sin(self.movementCounter * 0.05) * 4;
- break;
+ self.x += self.velocity.x;
+ self.y += self.velocity.y;
+ self.age++;
+ // Wrap around screen edges
+ if (self.x < 0) {
+ self.x = 2048;
}
- // Update fire counter
- self.fireCounter++;
- };
- self.shouldFire = function () {
- if (self.fireCounter >= self.fireInterval) {
- self.fireCounter = 0;
- return true;
+ if (self.x > 2048) {
+ self.x = 0;
}
- return false;
+ if (self.y < 0) {
+ self.y = 2732;
+ }
+ if (self.y > 2732) {
+ self.y = 0;
+ }
};
- self.takeDamage = function (amount) {
- self.health -= amount;
- // Flash enemy when hit
- LK.effects.flashObject(self, 0xff0000, 200);
- return self.health <= 0;
- };
return self;
});
-var Explosion = Container.expand(function () {
+var Button = Container.expand(function (assetId) {
var self = Container.call(this);
- var explosionGraphics = self.attachAsset('explosion', {
+ // Create button as a solid shape
+ var buttonGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
- alpha: 0.8
+ scaleX: 4,
+ scaleY: 4
});
- self.lifetime = 20; // Frames until explosion disappears
- self.update = function () {
- self.lifetime--;
- // Scale up and fade out
- self.scale.x += 0.05;
- self.scale.y += 0.05;
- explosionGraphics.alpha = self.lifetime / 20;
- return self.lifetime <= 0; // Return true if explosion should be removed
+ buttonGraphics.alpha = 0.5;
+ // Determine button shape based on assetId
+ var isCircle = assetId === 'fireButton' || assetId === 'forwardButton';
+ var buttonSize = 60; // Radius or half-width
+ self.isPressed = false;
+ self.down = function (x, y, obj) {
+ self.isPressed = true;
+ buttonGraphics.alpha = 0.8;
};
+ self.up = function (x, y, obj) {
+ self.isPressed = false;
+ buttonGraphics.alpha = 0.5;
+ };
return self;
});
-var PlayerShip = Container.expand(function () {
+var Ship = Container.expand(function () {
var self = Container.call(this);
- var shipGraphics = self.attachAsset('playerShip', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- // Ship properties
- self.speed = 8;
- self.health = 100;
- self.maxHealth = 100;
- self.shieldActive = false;
- self.shieldDuration = 0;
- self.shieldGraphics = null;
- self.fireRate = 15;
- self.powerUpTimer = 0;
- self.powerUpType = null;
- self.activateShield = function (duration) {
- if (!self.shieldGraphics) {
- self.shieldGraphics = self.attachAsset('shield', {
+ // Create a custom triangle ship
+ var shipGraphics = new Container();
+ self.addChild(shipGraphics);
+ // Create a pixel art triangle
+ var triangleSize = 144; // Scale up to 2x from 72 to 144
+ var pixelSize = 24; // Increase pixel size for more distinct lines (2x)
+ var pixelGap = 2; // Gap between pixels for hollow effect
+ // Create triangle points - pointing right by default (0 degrees = right)
+ var points = [{
+ x: triangleSize,
+ y: 0
+ },
+ // Front tip (pointing right)
+ {
+ x: -triangleSize / 2,
+ y: -triangleSize / 2
+ },
+ // Top left
+ {
+ x: -triangleSize / 2,
+ y: triangleSize / 2
+ } // Bottom left
+ ];
+ // Draw the outline with pixel art style
+ for (var i = 0; i < 3; i++) {
+ var startPoint = points[i];
+ var endPoint = points[(i + 1) % 3];
+ // Calculate step count based on distance
+ var dx = endPoint.x - startPoint.x;
+ var dy = endPoint.y - startPoint.y;
+ var steps = Math.max(Math.abs(dx), Math.abs(dy)) / pixelSize;
+ // Draw pixels along the line
+ for (var step = 0; step <= steps; step++) {
+ var px = startPoint.x + dx * (step / steps);
+ var py = startPoint.y + dy * (step / steps);
+ var pixel = LK.getAsset('shipShape', {
anchorX: 0.5,
anchorY: 0.5,
- alpha: 0.5
+ width: pixelSize - pixelGap,
+ height: pixelSize - pixelGap,
+ x: px,
+ y: py,
+ tint: 0xFF8000 // Orange color
});
- } else {
- self.shieldGraphics.alpha = 0.5;
+ shipGraphics.addChild(pixel);
}
- self.shieldActive = true;
- self.shieldDuration = duration;
+ }
+ shipGraphics.x = 0;
+ shipGraphics.y = 0;
+ // Ship properties
+ self.rot = 0; // Start pointing right (0 radians)
+ self.rotationSpeed = 0.05; // Reduced rotation speed for less sensitive steering
+ self.isRotatingLeft = false;
+ self.isRotatingRight = false;
+ self.isFiring = false;
+ self.fireDelay = 15; // frames between shots
+ self.fireTimer = 0;
+ self.invulnerable = false;
+ self.invulnerableTime = 0;
+ // Physics-based movement properties - much simpler direct movement
+ self.thrustPower = 0.15; // Reduced thrust power for slower acceleration
+ self.dragFactor = 0.97; // Slightly increased drag to slow down faster
+ self.maxSpeed = 6; // Lower maximum speed
+ self.velocity = {
+ x: 0,
+ y: 0
};
- self.deactivateShield = function () {
- if (self.shieldGraphics) {
- self.shieldGraphics.alpha = 0;
+ // Track previous position for movement calculations
+ self.lastX = 0;
+ self.lastY = 0;
+ // Apply rotation to ship graphics
+ shipGraphics.rotation = self.rot;
+ self.update = function () {
+ // Store last position
+ self.lastX = self.x;
+ self.lastY = self.y;
+ // Handle rotation
+ if (self.isRotatingLeft) {
+ self.rot -= self.rotationSpeed;
}
- self.shieldActive = false;
- self.shieldDuration = 0;
- };
- self.takeDamage = function (amount) {
- if (self.shieldActive) {
- return;
+ if (self.isRotatingRight) {
+ self.rot += self.rotationSpeed;
}
- self.health -= amount;
- if (self.health <= 0) {
- self.health = 0;
- return true; // Ship destroyed
+ // Apply rotation to ship visual
+ shipGraphics.rotation = self.rot;
+ // Calculate direction vector from rotation
+ // 0 = right, PI/2 = down, PI = left, -PI/2 = up
+ var dirX = Math.cos(self.rot);
+ var dirY = Math.sin(self.rot);
+ // Apply thrust force in direction ship is facing (always moving)
+ self.velocity.x += dirX * self.thrustPower;
+ self.velocity.y += dirY * self.thrustPower;
+ // Apply drag/friction
+ self.velocity.x *= self.dragFactor;
+ self.velocity.y *= self.dragFactor;
+ // Calculate current speed
+ var speed = Math.sqrt(self.velocity.x * self.velocity.x + self.velocity.y * self.velocity.y);
+ // Apply speed limit if necessary
+ if (speed > self.maxSpeed) {
+ self.velocity.x = self.velocity.x / speed * self.maxSpeed;
+ self.velocity.y = self.velocity.y / speed * self.maxSpeed;
}
- // Flash ship when damaged
- LK.effects.flashObject(self, 0xff0000, 300);
- return false; // Ship still alive
- };
- self.activatePowerUp = function (type, duration) {
- // Reset any current power-up
- if (self.powerUpType) {
- self.deactivatePowerUp();
+ // Create thrust particles
+ if (speed > 0.5 && LK.ticks % 3 === 0) {
+ var particle = new ThrustParticle();
+ // Position at the back of the ship (opposite of direction)
+ var backX = self.x - dirX * triangleSize * 0.5;
+ var backY = self.y - dirY * triangleSize * 0.5;
+ // Add some randomness
+ backX += (Math.random() - 0.5) * 10;
+ backY += (Math.random() - 0.5) * 10;
+ particle.x = backX;
+ particle.y = backY;
+ // Set velocity opposite to ship direction with some randomness
+ particle.velocity.x = -dirX * (1 + Math.random()) + (Math.random() - 0.5) * 0.5;
+ particle.velocity.y = -dirY * (1 + Math.random()) + (Math.random() - 0.5) * 0.5;
+ // Add to game via event
+ if (typeof game.addThrustParticle === 'function') {
+ game.addThrustParticle(particle);
+ }
}
- self.powerUpType = type;
- self.powerUpTimer = duration;
- // Apply power-up effect
- switch (type) {
- case 'speed':
- self.speed = 12;
- shipGraphics.tint = 0x2ecc71; // Green tint for speed
- break;
- case 'fireRate':
- self.fireRate = 5;
- shipGraphics.tint = 0xf1c40f; // Yellow tint for fire rate
- break;
+ // Update position based on velocity
+ self.x += self.velocity.x;
+ self.y += self.velocity.y;
+ // Wrap around screen edges
+ if (self.x < 0) {
+ self.x = 2048;
}
- };
- self.deactivatePowerUp = function () {
- // Reset to default values
- self.speed = 8;
- self.fireRate = 15;
- shipGraphics.tint = 0xffffff; // Reset tint
- self.powerUpType = null;
- };
- self.update = function () {
- // Update shield
- if (self.shieldActive) {
- self.shieldDuration--;
- if (self.shieldDuration <= 0) {
- self.deactivateShield();
+ if (self.x > 2048) {
+ self.x = 0;
+ }
+ if (self.y < 0) {
+ self.y = 2732;
+ }
+ if (self.y > 2732) {
+ self.y = 0;
+ }
+ // Handle firing
+ if (self.isFiring) {
+ if (self.fireTimer <= 0) {
+ self.fireTimer = self.fireDelay;
+ return true; // Signal to create a bullet
}
}
- // Update power-ups
- if (self.powerUpType) {
- self.powerUpTimer--;
- if (self.powerUpTimer <= 0) {
- self.deactivatePowerUp();
+ if (self.fireTimer > 0) {
+ self.fireTimer--;
+ }
+ // Handle invulnerability
+ if (self.invulnerable) {
+ self.invulnerableTime--;
+ shipGraphics.alpha = Math.sin(LK.ticks * 0.5) * 0.5 + 0.5;
+ if (self.invulnerableTime <= 0) {
+ self.invulnerable = false;
+ shipGraphics.alpha = 1;
}
}
+ return false;
};
+ self.makeInvulnerable = function (frames) {
+ self.invulnerable = true;
+ self.invulnerableTime = frames;
+ };
return self;
});
-var PowerUp = Container.expand(function () {
+var ThrustParticle = Container.expand(function () {
var self = Container.call(this);
- var powerupGraphics = self.attachAsset('powerUp', {
+ // Create particle visual - larger and more visible
+ var particleGraphics = LK.getAsset('bulletShape', {
anchorX: 0.5,
- anchorY: 0.5
+ anchorY: 0.5,
+ width: 16,
+ height: 16,
+ tint: 0xFF8000 // Orange color
});
- // Define power-up types and set random type
- var types = ['shield', 'speed', 'fireRate'];
- self.type = types[Math.floor(Math.random() * types.length)];
- self.speed = 2 + Math.random() * 2;
- self.duration = 300; // 5 seconds at 60fps
- // Set color based on type
- switch (self.type) {
- case 'shield':
- powerupGraphics.tint = 0x3498db; // Blue
- break;
- case 'speed':
- powerupGraphics.tint = 0x2ecc71; // Green
- break;
- case 'fireRate':
- powerupGraphics.tint = 0xf1c40f; // Yellow
- break;
- }
+ particleGraphics.alpha = 0.9;
+ self.addChild(particleGraphics);
+ // Particle properties
+ self.velocity = {
+ x: 0,
+ y: 0
+ };
+ self.lifespan = 25; // Longer lifespan for better visibility
+ self.age = 0;
self.update = function () {
- self.y += self.speed;
- self.rotation += 0.02; // Rotate for visual effect
+ // Move according to velocity
+ self.x += self.velocity.x;
+ self.y += self.velocity.y;
+ // Age the particle
+ self.age++;
+ // Fade out as it ages, with a faster tail-end fade
+ var lifeRatio = self.age / self.lifespan;
+ particleGraphics.alpha = 0.9 * (1 - lifeRatio * lifeRatio);
+ // Return true if particle should be removed
+ return self.age >= self.lifespan;
};
return self;
});
/****
* Initialize Game
****/
+// Function to add thrust particles - called from Ship update
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
-// Game state variables
-var gameWidth = 2048;
-var gameHeight = 2732;
-var player;
-var playerBullets = [];
-var enemyBullets = [];
+// Sound for the rhythmic beat
+// Sound for starting a new level
+// Sound for tapping to start
+// Add sound assets for each meme asteroid (meme0 to meme9)
+// Game variables
+var ship;
+var bullets = [];
var asteroids = [];
-var enemies = [];
-var powerUps = [];
-var explosions = [];
+var thrustParticles = []; // Array to store thrust particles
var score = 0;
-var level = storage.level;
var lives = 3;
-var gameActive = true;
-var lastShootTime = 0;
-var waveTimer = 0;
-var nextWaveTime = 300; // 5 seconds at 60fps
-var waveCount = 0;
-var levelComplete = false;
-// Scoring and UI elements
-var scoreTxt = new Text2('SCORE: 0', {
- size: 80,
- fill: 0xFFFFFF
-});
-scoreTxt.anchor.set(0, 0);
-LK.gui.topRight.addChild(scoreTxt);
-var levelTxt = new Text2('LEVEL: ' + level, {
- size: 80,
- fill: 0xFFFFFF
-});
-levelTxt.anchor.set(1, 0);
-LK.gui.topLeft.addChild(levelTxt);
-levelTxt.x = 200; // Move away from the corner
-var livesTxt = new Text2('LIVES: ' + lives, {
- size: 80,
- fill: 0xFFFFFF
-});
-livesTxt.anchor.set(0.5, 0);
-LK.gui.top.addChild(livesTxt);
-// Initialize player
-function initializePlayer() {
- player = new PlayerShip();
- player.x = gameWidth / 2;
- player.y = gameHeight - 200;
- game.addChild(player);
+var level = 1;
+var gameStarted = false;
+var gameOver = false;
+var triangleSize = 72; // Ship triangle size for bullet positioning (2x larger)
+// UI elements
+var leftButton;
+var rightButton;
+var fireButton;
+var scoreTxt;
+var livesTxt;
+var levelTxt;
+var startText;
+// Initialize the game
+function initGame() {
+ // Create ship
+ ship = new Ship();
+ ship.x = 2048 / 2;
+ ship.y = 200; // Position at top middle
+ ship.makeInvulnerable(120); // 2 seconds
+ // Add visual effect to indicate ship is ready for movement
+ tween(ship, {
+ alpha: 0.5
+ }, {
+ duration: 500,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ tween(ship, {
+ alpha: 1
+ }, {
+ duration: 500,
+ easing: tween.easeInOut
+ });
+ }
+ });
+ game.addChild(ship);
+ // Create control buttons
+ leftButton = new Button('rotateLeftButton');
+ leftButton.x = 300; // Position on the left side
+ leftButton.y = 2732 - 200; // Position at the bottom
+ leftButton.scale.set(4, 4); // Make button bigger (2x)
+ game.addChild(leftButton);
+ // Fire button in the middle
+ fireButton = new Button('fireButton');
+ fireButton.x = 2048 / 2; // Position in middle
+ fireButton.y = 2732 - 200; // Position at the bottom
+ fireButton.scale.set(4, 4); // Make button bigger (2x)
+ game.addChild(fireButton);
+ // No forward button needed - ship will constantly move forward
+ // Right rotation button
+ rightButton = new Button('rotateRightButton');
+ rightButton.x = 2048 - 300; // Position on the right side
+ rightButton.y = 2732 - 200; // Position at the bottom
+ rightButton.scale.set(4, 4); // Make button bigger (2x)
+ game.addChild(rightButton);
+ // Create UI text
+ // Create Glaud text in orange
+ var glaudText = new Text2('Glaud', {
+ size: 60,
+ fill: 0xFF8000 // Orange color
+ });
+ glaudText.anchor.set(1, 0); // Right-align text
+ glaudText.x = -20; // Add padding from right edge
+ glaudText.y = 0; // Position at very top
+ LK.gui.topRight.addChild(glaudText);
+ scoreTxt = new Text2('SCORE: 0', {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ scoreTxt.anchor.set(1, 0); // Right-align text
+ scoreTxt.x = -20; // Add padding from right edge
+ scoreTxt.y = 35; // Position below the Glaud text
+ LK.gui.topRight.addChild(scoreTxt);
+ livesTxt = new Text2('LIVES: 3', {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ livesTxt.anchor.set(0.5, 0); // Center anchor horizontally
+ LK.gui.top.addChild(livesTxt);
+ levelTxt = new Text2('LEVEL: 1', {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ levelTxt.anchor.set(0, 0); // Left-align text
+ levelTxt.x = 120; // Keep away from top-left menu icon
+ levelTxt.y = 20; // Add padding from top edge
+ LK.gui.topLeft.addChild(levelTxt);
+ // Start screen text
+ if (!gameStarted) {
+ startText = new Text2('TAP TO START', {
+ size: 160,
+ fill: 0xFFFFFF
+ });
+ startText.anchor.set(0.5, 0.5);
+ LK.gui.center.addChild(startText);
+ }
+ // Clear any existing game objects
+ bullets = [];
+ asteroids = [];
+ thrustParticles = [];
+ // Initialize asteroids for the first level
+ createAsteroidsForLevel(level);
+ // Start game music
+ LK.playMusic('gameMusic', {
+ loop: true
+ });
}
-// Create a new asteroid
-function createAsteroid() {
- var asteroid = new Asteroid();
- asteroid.x = Math.random() * gameWidth;
- asteroid.y = -100;
- asteroids.push(asteroid);
- game.addChild(asteroid);
+function createAsteroidsForLevel(level) {
+ // Number of asteroids based on level
+ var numAsteroids = Math.min(4 + level, 12);
+ for (var i = 0; i < numAsteroids; i++) {
+ // Create a random meme type (0-9)
+ var memeType = Math.floor(Math.random() * 10);
+ var asteroid = new Asteroid(2, memeType); // Start with large asteroids and specific meme type
+ // Position the asteroid away from the player
+ do {
+ asteroid.x = Math.random() * 2048;
+ asteroid.y = Math.random() * 2732;
+ } while (distance(asteroid.x, asteroid.y, ship.x, ship.y) < 300);
+ asteroids.push(asteroid);
+ game.addChild(asteroid);
+ }
}
-// Create a new enemy ship
-function createEnemy() {
- var enemy = new EnemyShip();
- enemy.x = Math.random() * gameWidth;
- enemy.y = -100;
- enemies.push(enemy);
- game.addChild(enemy);
+function distance(x1, y1, x2, y2) {
+ return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
-// Create a player bullet
-function createPlayerBullet() {
+function createBullet() {
var bullet = new Bullet();
- bullet.x = player.x;
- bullet.y = player.y - 40;
- playerBullets.push(bullet);
+ // Use ship's rotation directly
+ var angle = ship.rot;
+ // Calculate the position at the tip of the ship based on the triangle geometry
+ // For the redesigned ship (pointing up at 0 rotation), the tip is -triangleSize units in Y
+ var offsetX = Math.cos(angle) * triangleSize;
+ var offsetY = Math.sin(angle) * triangleSize;
+ // Position bullet at the tip of the ship
+ bullet.x = ship.x + offsetX;
+ bullet.y = ship.y + offsetY;
+ // Set bullet velocity to match ship's exact facing direction
+ bullet.velocity.x = Math.cos(angle) * bullet.speed;
+ bullet.velocity.y = Math.sin(angle) * bullet.speed;
+ // Add bullet to game
+ bullets.push(bullet);
game.addChild(bullet);
// Play shoot sound
LK.getSound('shoot').play();
- // Update last shoot time
- lastShootTime = LK.ticks;
}
-// Create an enemy bullet
-function createEnemyBullet(enemy) {
- var bullet = new EnemyBullet();
- bullet.x = enemy.x;
- bullet.y = enemy.y + 30;
- enemyBullets.push(bullet);
- game.addChild(bullet);
-}
-// Create a power-up
-function createPowerUp(x, y) {
- // 20% chance to spawn a power-up
- if (Math.random() < 0.2) {
- var powerUp = new PowerUp();
- powerUp.x = x;
- powerUp.y = y;
- powerUps.push(powerUp);
- game.addChild(powerUp);
- }
-}
-// Create an explosion
-function createExplosion(x, y, scale) {
- var explosion = new Explosion();
- explosion.x = x;
- explosion.y = y;
- explosion.scale.set(scale || 1);
- explosions.push(explosion);
- game.addChild(explosion);
- // Play explosion sound
- LK.getSound('explosion').play();
-}
-// Start a new wave of enemies and asteroids
-function startWave() {
- waveCount++;
- // Number of asteroids and enemies increases with level and wave
- var numAsteroids = 5 + Math.floor(level * 1.5) + Math.floor(waveCount * 0.5);
- var numEnemies = Math.floor(level * 0.8) + Math.floor(waveCount * 0.3);
- // Spawn asteroids over time
- for (var i = 0; i < numAsteroids; i++) {
- LK.setTimeout(createAsteroid, i * 30);
- }
- // Spawn enemies over time
- for (var j = 0; j < numEnemies; j++) {
- LK.setTimeout(createEnemy, j * 60 + 600); // Delay enemies a bit after asteroids
- }
-}
-// Check for level completion
-function checkLevelCompletion() {
- // Level is complete when all waves are finished and all enemies and asteroids are cleared
- if (waveCount >= level + 2 && enemies.length === 0 && asteroids.length === 0 && !levelComplete) {
- levelComplete = true;
- // Display level complete message
- var levelCompleteTxt = new Text2('LEVEL ' + level + ' COMPLETE!', {
- size: 120,
- fill: 0xFFFFFF
- });
- levelCompleteTxt.anchor.set(0.5, 0.5);
- LK.gui.center.addChild(levelCompleteTxt);
- // Start next level after delay
- LK.setTimeout(function () {
- level++;
- storage.level = level;
- // Reset game state for next level
- levelTxt.setText('LEVEL: ' + level);
- waveCount = 0;
- waveTimer = 0;
- levelComplete = false;
- // Remove level complete text
- LK.gui.center.removeChild(levelCompleteTxt);
- }, 3000);
- }
-}
-// Update score display
-function updateScore(points) {
- score += points;
- LK.setScore(score);
- scoreTxt.setText('SCORE: ' + score);
- // Update high score if needed
- if (score > storage.highScore) {
- storage.highScore = score;
- }
-}
-// Reset game state
-function resetGame() {
- // Clear all game objects
- playerBullets = [];
- enemyBullets = [];
- asteroids = [];
- enemies = [];
- powerUps = [];
- explosions = [];
- // Reset variables
- score = 0;
- lives = 3;
- waveCount = 0;
- waveTimer = 0;
- levelComplete = false;
- gameActive = true;
- // Update UI
- scoreTxt.setText('SCORE: 0');
- livesTxt.setText('LIVES: ' + lives);
- levelTxt.setText('LEVEL: ' + level);
- // Initialize player
- initializePlayer();
- // Start first wave
- startWave();
-}
-// Initialize game
-function initGame() {
- game.setBackgroundColor(0x0a0a2a); // Dark blue space background
- // Initialize player
- initializePlayer();
- // Start music
- LK.playMusic('spaceTheme', {
- fade: {
- start: 0,
- end: 0.4,
- duration: 1000
+function updateAsteroids() {
+ for (var i = asteroids.length - 1; i >= 0; i--) {
+ var asteroid = asteroids[i];
+ asteroid.update();
+ // Check for collision with the ship
+ if (!ship.invulnerable && asteroid.intersects(ship)) {
+ // Player loses a life
+ lives--;
+ livesTxt.setText('LIVES: ' + lives);
+ // Play explosion sound
+ LK.getSound('explosion').play();
+ // Flash screen
+ LK.effects.flashScreen(0xFF0000, 500);
+ // Make ship invulnerable for a few seconds
+ ship.makeInvulnerable(180);
+ // Game over if no lives left
+ if (lives <= 0) {
+ LK.setScore(score);
+ LK.showGameOver();
+ gameOver = true;
+ return;
+ }
}
- });
- // Start first wave
- startWave();
-}
-// Dragging support for touch controls
-var isDragging = false;
-// Mouse/touch handlers
-game.down = function (x, y, obj) {
- if (!gameActive) {
- return;
}
- // Start dragging
- isDragging = true;
- // Move player to touch position
- player.x = x;
- player.y = y;
-};
-game.up = function (x, y, obj) {
- isDragging = false;
-};
-game.move = function (x, y, obj) {
- if (!gameActive || !isDragging) {
- return;
- }
- // Move player to follow touch
- player.x = x;
- // Limit vertical movement to bottom half of screen
- player.y = Math.max(gameHeight / 2, Math.min(y, gameHeight - 100));
-};
-// Game update function
-game.update = function () {
- if (!gameActive) {
- return;
- }
- // Update player
- if (player) {
- player.update();
- // Keep player within screen bounds
- player.x = Math.max(50, Math.min(player.x, gameWidth - 50));
- player.y = Math.max(50, Math.min(player.y, gameHeight - 50));
- // Auto-fire based on fire rate
- if (LK.ticks - lastShootTime >= player.fireRate) {
- createPlayerBullet();
- }
- }
- // Wave timer logic
- if (!levelComplete) {
- waveTimer++;
- if (waveTimer >= nextWaveTime && waveCount < level + 2) {
- startWave();
- waveTimer = 0;
- nextWaveTime = 600; // 10 seconds between waves
- }
- }
- // Update player bullets
- for (var i = playerBullets.length - 1; i >= 0; i--) {
- var bullet = playerBullets[i];
+}
+function updateBullets() {
+ for (var i = bullets.length - 1; i >= 0; i--) {
+ var bullet = bullets[i];
bullet.update();
- // Remove bullets that go off screen
- if (bullet.y < -50) {
+ // Remove bullets that have lived too long
+ if (bullet.age > bullet.lifespan) {
game.removeChild(bullet);
- playerBullets.splice(i, 1);
+ bullets.splice(i, 1);
continue;
}
- // Check collision with asteroids
+ // Check for collisions with asteroids
+ var hitAsteroid = false;
for (var j = asteroids.length - 1; j >= 0; j--) {
var asteroid = asteroids[j];
if (bullet.intersects(asteroid)) {
- // Damage asteroid
- if (asteroid.takeDamage(bullet.damage)) {
- // Asteroid destroyed
- updateScore(asteroid.scoreValue);
- createExplosion(asteroid.x, asteroid.y, asteroid.scale.x);
- createPowerUp(asteroid.x, asteroid.y);
- game.removeChild(asteroid);
- asteroids.splice(j, 1);
+ hitAsteroid = true;
+ // Add score based on asteroid size
+ score += asteroid.getPoints();
+ scoreTxt.setText('SCORE: ' + score);
+ // Play specific meme sound based on asteroid type
+ if (asteroid.memeType !== undefined && LK.getSound('meme' + asteroid.memeType)) {
+ LK.getSound('meme' + asteroid.memeType).play();
}
- // Remove bullet
- game.removeChild(bullet);
- playerBullets.splice(i, 1);
- break;
- }
- }
- // Check collision with enemies
- if (bullet) {
- for (var k = enemies.length - 1; k >= 0; k--) {
- var enemy = enemies[k];
- if (bullet.intersects(enemy)) {
- // Damage enemy
- if (enemy.takeDamage(bullet.damage)) {
- // Enemy destroyed
- updateScore(enemy.scoreValue);
- createExplosion(enemy.x, enemy.y, 1.2);
- createPowerUp(enemy.x, enemy.y);
- game.removeChild(enemy);
- enemies.splice(k, 1);
+ // Break asteroid into smaller pieces only if it's medium or large
+ if (asteroid.size > 1) {
+ for (var k = 0; k < 2; k++) {
+ var newAsteroid = new Asteroid(asteroid.size - 1, asteroid.memeType);
+ newAsteroid.x = asteroid.x;
+ newAsteroid.y = asteroid.y;
+ // No velocity inheritance - just use the default size-based velocity
+ asteroids.push(newAsteroid);
+ game.addChild(newAsteroid);
}
- // Remove bullet
- game.removeChild(bullet);
- playerBullets.splice(i, 1);
- break;
}
+ // Remove the asteroid
+ game.removeChild(asteroid);
+ asteroids.splice(j, 1);
+ break;
}
}
- }
- // Update enemy bullets
- for (var i = enemyBullets.length - 1; i >= 0; i--) {
- var bullet = enemyBullets[i];
- bullet.update();
- // Remove bullets that go off screen
- if (bullet.y > gameHeight + 50) {
+ if (hitAsteroid) {
+ // Remove the bullet
game.removeChild(bullet);
- enemyBullets.splice(i, 1);
- continue;
+ bullets.splice(i, 1);
}
- // Check collision with player
- if (player && bullet.intersects(player)) {
- // Damage player
- if (player.takeDamage(bullet.damage)) {
- // Player lost a life
- lives--;
- livesTxt.setText('LIVES: ' + lives);
- if (lives <= 0) {
- // Game over
- createExplosion(player.x, player.y, 2);
- game.removeChild(player);
- player = null;
- gameActive = false;
- LK.showGameOver();
- } else {
- // Respawn player
- createExplosion(player.x, player.y, 1.5);
- game.removeChild(player);
- // Small delay before respawning
- LK.setTimeout(function () {
- initializePlayer();
- }, 1000);
- }
- }
- // Remove bullet
- game.removeChild(bullet);
- enemyBullets.splice(i, 1);
- }
}
- // Update asteroids
- for (var i = asteroids.length - 1; i >= 0; i--) {
- var asteroid = asteroids[i];
- asteroid.update();
- // Remove asteroids that go off screen
- if (asteroid.y > gameHeight + 100) {
- game.removeChild(asteroid);
- asteroids.splice(i, 1);
- continue;
- }
- // Check collision with player
- if (player && asteroid.intersects(player)) {
- if (player.takeDamage(20)) {
- // Player lost a life
- lives--;
- livesTxt.setText('LIVES: ' + lives);
- if (lives <= 0) {
- // Game over
- createExplosion(player.x, player.y, 2);
- game.removeChild(player);
- player = null;
- gameActive = false;
- LK.showGameOver();
- } else {
- // Respawn player
- createExplosion(player.x, player.y, 1.5);
- game.removeChild(player);
- // Small delay before respawning
- LK.setTimeout(function () {
- initializePlayer();
- }, 1000);
- }
- }
- // Destroy asteroid
- createExplosion(asteroid.x, asteroid.y, asteroid.scale.x);
- game.removeChild(asteroid);
- asteroids.splice(i, 1);
- }
+ // Check if all asteroids are destroyed
+ if (asteroids.length === 0) {
+ // Next level
+ level++;
+ levelTxt.setText('LEVEL: ' + level);
+ // Play level start sound
+ LK.getSound('levelStart').play();
+ // Create new asteroids for the next level
+ createAsteroidsForLevel(level);
}
- // Update enemies
- for (var i = enemies.length - 1; i >= 0; i--) {
- var enemy = enemies[i];
- enemy.update();
- // Remove enemies that go off screen
- if (enemy.y > gameHeight + 100) {
- game.removeChild(enemy);
- enemies.splice(i, 1);
- continue;
- }
- // Check if enemy should fire
- if (enemy.shouldFire() && player) {
- createEnemyBullet(enemy);
- }
- // Check collision with player
- if (player && enemy.intersects(player)) {
- if (player.takeDamage(30)) {
- // Player lost a life
- lives--;
- livesTxt.setText('LIVES: ' + lives);
- if (lives <= 0) {
- // Game over
- createExplosion(player.x, player.y, 2);
- game.removeChild(player);
- player = null;
- gameActive = false;
- LK.showGameOver();
- } else {
- // Respawn player
- createExplosion(player.x, player.y, 1.5);
- game.removeChild(player);
- // Small delay before respawning
- LK.setTimeout(function () {
- initializePlayer();
- }, 1000);
- }
- }
- // Destroy enemy
- createExplosion(enemy.x, enemy.y, 1.2);
- game.removeChild(enemy);
- enemies.splice(i, 1);
- }
+}
+// Main game update function
+game.update = function () {
+ if (!gameStarted) {
+ return;
}
- // Update power-ups
- for (var i = powerUps.length - 1; i >= 0; i--) {
- var powerUp = powerUps[i];
- powerUp.update();
- // Remove power-ups that go off screen
- if (powerUp.y > gameHeight + 50) {
- game.removeChild(powerUp);
- powerUps.splice(i, 1);
- continue;
+ // Update ship controls based on button state
+ ship.isRotatingLeft = leftButton.isPressed;
+ ship.isRotatingRight = rightButton.isPressed;
+ ship.isFiring = fireButton.isPressed;
+ // Ship constantly moves forward, no need for isMoving toggle
+ // Update ship
+ if (ship.update()) {
+ createBullet();
+ }
+ // Update bullets and check for collisions
+ updateBullets();
+ // Update asteroids and check for collisions
+ updateAsteroids();
+ // Update thrust particles
+ updateThrustParticles();
+};
+// Event handlers
+game.down = function (x, y, obj) {
+ if (!gameStarted) {
+ gameStarted = true;
+ LK.getSound('gameStart').play(); // Play start sound
+ if (startText) {
+ LK.gui.center.removeChild(startText);
+ startText = null;
}
- // Check collision with player
- if (player && powerUp.intersects(player)) {
- // Apply power-up effect
- switch (powerUp.type) {
- case 'shield':
- player.activateShield(300); // 5 second shield
- break;
- case 'speed':
- player.activatePowerUp('speed', 300); // 5 second speed boost
- break;
- case 'fireRate':
- player.activatePowerUp('fireRate', 300); // 5 second fire rate boost
- break;
+ // Start the rhythmic beat sound
+ LK.setInterval(function () {
+ // Check if the game is still running and not game over to avoid sound clutter
+ if (gameStarted && !gameOver) {
+ LK.getSound('beatSound').play();
}
- // Play power-up sound
- LK.getSound('powerUp').play();
- // Remove power-up
- game.removeChild(powerUp);
- powerUps.splice(i, 1);
- }
+ }, 500); // Play every 500ms (adjust timing as needed for desired beat)
}
- // Update explosions
- for (var i = explosions.length - 1; i >= 0; i--) {
- var explosion = explosions[i];
- if (explosion.update()) {
- // Remove explosion if lifetime is over
- game.removeChild(explosion);
- explosions.splice(i, 1);
- }
+ // Fire bullet when clicking anywhere on screen (if game started)
+ if (gameStarted && ship && !gameOver) {
+ createBullet();
}
- // Check for level completion
- checkLevelCompletion();
+ // Ensure buttons can detect touch events when pressed
+ var local;
+ // Check left button
+ local = leftButton.toLocal({
+ x: x,
+ y: y
+ });
+ if (local.x >= -leftButton.width / 2 && local.x <= leftButton.width / 2 && local.y >= -leftButton.height / 2 && local.y <= leftButton.height / 2) {
+ leftButton.down(local.x, local.y, {});
+ }
+ // Check fire button
+ local = fireButton.toLocal({
+ x: x,
+ y: y
+ });
+ if (local.x >= -fireButton.width / 2 && local.x <= fireButton.width / 2 && local.y >= -fireButton.height / 2 && local.y <= fireButton.height / 2) {
+ fireButton.down(local.x, local.y, {});
+ }
+ // Forward button removed - ship moves constantly
+ // Check right button
+ local = rightButton.toLocal({
+ x: x,
+ y: y
+ });
+ if (local.x >= -rightButton.width / 2 && local.x <= rightButton.width / 2 && local.y >= -rightButton.height / 2 && local.y <= rightButton.height / 2) {
+ rightButton.down(local.x, local.y, {});
+ }
};
-// Initialize the game
-initGame();
\ No newline at end of file
+// Add up handler to handle releasing buttons
+game.up = function (x, y, obj) {
+ // Reset all button states when touch/click is released
+ leftButton.up(0, 0, {});
+ fireButton.up(0, 0, {});
+ rightButton.up(0, 0, {});
+};
+// Initialize the game when this script runs
+initGame();
+// Function to add thrust particles - called from Ship update
+game.addThrustParticle = function (particle) {
+ thrustParticles.push(particle);
+ game.addChild(particle);
+};
+// Function to update thrust particles
+function updateThrustParticles() {
+ for (var i = thrustParticles.length - 1; i >= 0; i--) {
+ var particle = thrustParticles[i];
+ // If particle update returns true, it means the particle should be removed
+ if (particle.update()) {
+ game.removeChild(particle);
+ thrustParticles.splice(i, 1);
+ }
+ }
+}
\ No newline at end of file
bulletShape. In-Game asset. 2d. High contrast. No shadows
fireButton is round and orange with a bullet pattern.. In-Game asset. 2d. High contrast. No shadows
rotateLeftButton is a square button with an arrow towards the left side.. In-Game asset. 2d. High contrast. No shadows
amungas memes no text one cracter. In-Game asset. 2d. High contrast. No shadows
trol face no text one cracter. In-Game asset. 2d. High contrast. No shadows
make those famous dog memes that are so well known.one cracter. head. In-Game asset. 2d. High contrast. No shadows
very well known pickles make Rick memes. single character. no writing.. In-Game asset. 2d. High contrast. No shadows
making very well known cat memes. single character. no writing.. In-Game asset. 2d. High contrast. No shadows
make very well known white ghost memes. single character. no writing.. In-Game asset. 2d. High contrast. No shadows
make very well known frog memes. single character. no writing. just head grinning. In-Game asset. 2d. High contrast. No shadows
make very well known duck memes. single character. no writing.. In-Game asset. 2d. High contrast. No shadows
make very well known rainbow cat memes. single character. no writing.. In-Game asset. 2d. High contrast. No shadows
very well known squid game just make cookie memes. single character. no writing.. In-Game asset. 2d. High contrast. No shadows
make very well known minecraft memes. single character. no writing.. In-Game asset. 2d. High contrast. No shadows
It's a spaceship made of orange pixels, reminiscent of arcade games.. In-Game asset. 2d. High contrast. No shadows
Not the hand with the cat.
A stylish orange letter G.. In-Game asset. 2d. High contrast. No shadows
shoot
Sound effect
meme0Explosion
Sound effect
meme1Explosion
Sound effect
meme2Explosion
Sound effect
meme3Explosion
Sound effect
meme4Explosion
Sound effect
meme5Explosion
Sound effect
meme6Explosion
Sound effect
meme7Explosion
Sound effect
meme8Explosion
Sound effect
meme9Explosion
Sound effect
levelStart
Sound effect
gameStart
Sound effect
beatSound
Sound effect
gameMusic1
Music
gameMusic2
Music
introMusic
Sound effect
gameMusic3
Music
meme10Explosion
Sound effect
meme11Explosion
Sound effect
meme12Explosion
Sound effect
outroMusic
Music