Code edit (2 edits merged)
Please save this source code
User prompt
Optimization fix, no change in mechanics. Fix baka stutters while playing the game.
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'up')' in or related to this line: 'leftButton.up(0, 0, {});' Line Number: 1110
Code edit (1 edits merged)
Please save this source code
User prompt
so that the particles coming out of the back of the rocket are more pronounced.
User prompt
so that the particles coming out of the back of the rocket are more pronounced.
User prompt
get a better feel for the thrust of the rocket.
User prompt
Add sound effects for all memes to explode.
User prompt
Make sound effects for all memes. for explosion
User prompt
Make sound effects for all memes. for explosion
User prompt
put a separate explosion sound for each memes. and make it work correctly.
User prompt
put a separate explosion sound for each memes. and make it work correctly.put a separate explosion sound for each memes. and make it work correctly.put a separate explosion sound for each memes. and make it work correctly.put a separate explosion sound for each memes. and make it work correctly.put a separate explosion sound for each memes. and make it work correctly.put a separate explosion sound for each memes. and make it work correctly.
User prompt
put a separate explosion sound for each memes. and make it work correctly.
User prompt
breast midium disappears when struck
User prompt
Put a separate explosion sound for each memes.
User prompt
Put a separate explosion sound for each memes.Put a separate explosion sound for each memes.Put a separate explosion sound for each memes.Put a separate explosion sound for each memes.
User prompt
Put a separate explosion sound for each memes.
User prompt
put a separate popping sound for each nozzle.
User prompt
Add 3 different background music and take turns.
User prompt
Add 3 different background music and take turns.
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.
/**** * 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; // Add pulsing effect self.pulseSpeed = 0.01 + Math.random() * 0.03; self.pulseTime = Math.random() * Math.PI * 2; // Random starting phase self.baseScale = 1.0; self.update = function () { // Move self.x += self.velocity.x; self.y += self.velocity.y; // Rotate asteroidGraphics.rotation += self.rotationSpeed; // Pulse effect based on meme type self.pulseTime += self.pulseSpeed; var pulseAmount = Math.sin(self.pulseTime) * 0.1 + 1.0; asteroidGraphics.scale.set(self.baseScale * pulseAmount, self.baseScale * pulseAmount); // Add occasional glitch effect for memes - but with lower chance and controlled sound if (Math.random() < 0.002) { // Reduced to 0.2% chance per frame // 0.5% chance per frame var originalTint = asteroidGraphics.children[0].tint; var glitchColors = [0xFF00FF, 0x00FFFF, 0xFFFF00, 0xFF0000, 0x00FF00, 0x0000FF]; var glitchColor = glitchColors[Math.floor(Math.random() * glitchColors.length)]; asteroidGraphics.children[0].tint = glitchColor; // Only play sounds during actual gameplay, not during intro if (self.memeType !== undefined && gameStarted && !introSequence) { var glitchSound = LK.getSound('meme' + self.memeType + 'Explosion'); if (glitchSound) { glitchSound.play({ volume: 0.1 // Reduced volume }); } } LK.setTimeout(function () { if (asteroidGraphics && asteroidGraphics.children[0]) { asteroidGraphics.children[0].tint = originalTint; } }, 100); } // 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; // Doubled from 12 to 24 var pixelSize = 6; // Doubled from 3 to 6 var pixelGap = 1; // 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: 2, scaleY: 2 }); 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 IntroSequence = Container.expand(function () { var self = Container.call(this); // Layers for effects var starfieldLayer = new Container(); var memesLayer = new Container(); var textLayer = new Container(); var shipLayer = new Container(); var titleLayer = new Container(); self.addChild(starfieldLayer); self.addChild(memesLayer); self.addChild(textLayer); self.addChild(shipLayer); self.addChild(titleLayer); // Create starfield var stars = []; for (var i = 0; i < 100; i++) { var star = LK.getAsset('bulletShape', { anchorX: 0.5, anchorY: 0.5, width: 3 + Math.random() * 5, height: 3 + Math.random() * 5, x: Math.random() * 2048, y: Math.random() * 2732, tint: 0xFFFFFF }); star.alpha = 0.3 + Math.random() * 0.7; star.velocity = 10 + Math.random() * 20; stars.push(star); starfieldLayer.addChild(star); } // Create distant meme silhouettes var silhouettes = []; for (var j = 0; j < 10; j++) { var memeType = Math.floor(Math.random() * 10); var meme = LK.getAsset('meme' + memeType, { anchorX: 0.5, anchorY: 0.5, x: 200 + Math.random() * 1600, y: -300 - Math.random() * 600, tint: 0x333333 }); meme.alpha = 0.3; meme.scale.set(0.3, 0.3); silhouettes.push(meme); memesLayer.addChild(meme); } // Emergency broadcast text var emergencyText = new Text2('MEME OVERLOAD DETECTED', { size: 80, fill: 0xFF3333 }); emergencyText.anchor.set(0.5, 0.5); emergencyText.x = 2048 / 2; emergencyText.y = 2732 / 2; emergencyText.alpha = 0; textLayer.addChild(emergencyText); // Hero ship var heroShip = new Ship(); heroShip.x = 2048 / 2; heroShip.y = 2732 + 100; heroShip.alpha = 0; shipLayer.addChild(heroShip); // Title var titleText = new Text2('MEMES ASTEROID WAR', { size: 120, fill: 0xFF8000 }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 2732 / 2 - 300; titleText.alpha = 0; titleLayer.addChild(titleText); // Call to action var ctaText = new Text2('TAP TO DEFEND THE INTERNET', { size: 60, fill: 0xFFFFFF }); ctaText.anchor.set(0.5, 0.5); ctaText.x = 2048 / 2; ctaText.y = 2732 / 2 + 300; ctaText.alpha = 0; titleLayer.addChild(ctaText); // Animation sequence self.phase = 0; self.timer = 0; self.finished = false; self.update = function () { self.timer++; // Update stars for (var i = 0; i < stars.length; i++) { var star = stars[i]; star.y += star.velocity; if (star.y > 2732) { star.y = -10; star.x = Math.random() * 2048; } } // Animation phases switch (self.phase) { case 0: // Starfield intro (0-2s) // Play intro music at the start - only once at the very beginning if (self.timer === 1) { LK.getSound('introMusic').play(); } if (self.timer === 60) { // After 1s, start meme approach self.phase = 1; } break; case 1: // Meme approach (2-4s) for (var j = 0; j < silhouettes.length; j++) { silhouettes[j].y += 3; silhouettes[j].scale.x += 0.003; silhouettes[j].scale.y += 0.003; } // Instead of random chaotic sounds, play a structured sound at specific moments if (self.timer === 90) { // Play a single sound at 1.5s LK.getSound('meme0Explosion').play({ volume: 0.2 }); } else if (self.timer === 150) { // Play another sound at 2.5s LK.getSound('meme5Explosion').play({ volume: 0.2 }); } if (self.timer === 180) { // After 3s, show emergency text self.phase = 2; tween(emergencyText, { alpha: 1 }, { duration: 500, easing: tween.easeOut }); // Make text glitch effect LK.setInterval(function () { emergencyText.scale.set(1 + Math.random() * 0.05, 1 + Math.random() * 0.05); emergencyText.x = 2048 / 2 + (Math.random() * 20 - 10); }, 80); // Play alarm sound for emergency - only play once LK.getSound('levelStart').play(); } break; case 2: // Emergency broadcast (4-6s) for (var k = 0; k < silhouettes.length; k++) { silhouettes[k].y += 3; silhouettes[k].scale.x += 0.004; silhouettes[k].scale.y += 0.004; } if (self.timer === 300) { // After 5s, fade out emergency text and show ship self.phase = 3; tween(emergencyText, { alpha: 0 }, { duration: 500 }); // Animate hero ship rising heroShip.alpha = 1; tween(heroShip, { y: 2732 / 2 + 200 }, { duration: 1500, easing: tween.easeOut }); } break; case 3: // Ship reveal (6-8s) if (self.timer === 420) { // After 7s, show title self.phase = 4; // Play title reveal sound - only once LK.getSound('gameStart').play(); // Animate title card tween(titleText, { alpha: 1 }, { duration: 800, easing: tween.easeOut }); // Create distortion effect on title var titleDistort = LK.setInterval(function () { titleText.scale.set(1 + Math.random() * 0.03, 1 + Math.random() * 0.03); if (self.timer > 480) { LK.clearInterval(titleDistort); titleText.scale.set(1, 1); } }, 50); } break; case 4: // Title card (8-10s) if (self.timer === 540) { // After 9s, show CTA self.phase = 5; tween(ctaText, { alpha: 1 }, { duration: 500, easing: tween.easeOut }); // Make CTA pulse LK.setInterval(function () { if (ctaText.alpha === 1) { tween(ctaText, { alpha: 0.5 }, { duration: 800 }); } else { tween(ctaText, { alpha: 1 }, { duration: 800 }); } }, 1600); } break; case 5: // CTA (10s+) if (self.timer === 660) { // After 11s total, finish intro self.finished = true; } break; } return self.finished; }; self.skip = function () { // Stop all potentially playing sounds to avoid sound clutter LK.getSound('introMusic').stop(); LK.getSound('meme0Explosion').stop(); LK.getSound('meme1Explosion').stop(); LK.getSound('meme2Explosion').stop(); LK.getSound('meme3Explosion').stop(); LK.getSound('meme4Explosion').stop(); LK.getSound('meme5Explosion').stop(); LK.getSound('meme6Explosion').stop(); LK.getSound('meme7Explosion').stop(); LK.getSound('meme8Explosion').stop(); LK.getSound('meme9Explosion').stop(); LK.getSound('levelStart').stop(); // Small delay to ensure all sounds are cleared before playing the new one LK.setTimeout(function () { // Play game start sound instead - with a slight delay LK.getSound('gameStart').play(); }, 100); self.finished = true; }; 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 = 72; // Scale up to 1.5 times larger from 48 to 72 var pixelSize = 12; // Increase pixel size for more distinct lines var pixelGap = 1; // 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.20; // Increased thrust power for faster acceleration self.dragFactor = 0.97; // Slightly increased drag to slow down faster self.maxSpeed = 8; // Increased maximum speed self.velocity = { x: 0, y: 0 }; // Track previous position for movement calculations self.lastX = 0; self.lastY = 0; self.lastInvulnerable = false; // 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 - appear more frequently when moving (now every frame if moving) if (speed > 0.5) { // Removed LK.ticks % 2 check 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; // Play subtle thrust sound occasionally if (LK.ticks % 20 === 0) { // Quiet thrust sound LK.getSound('beatSound').play({ volume: 0.2 }); } // 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; } // Special effect when ship becomes invulnerable (after being hit) if (self.lastInvulnerable === false && self.invulnerable === true) { // Create explosion effect for (var i = 0; i < 20; i++) { if (typeof game.addThrustParticle === 'function') { var particle = new ThrustParticle(); particle.x = self.x; particle.y = self.y; // Random direction var angle = Math.random() * Math.PI * 2; var speed = 1 + Math.random() * 4; particle.velocity.x = Math.cos(angle) * speed; particle.velocity.y = Math.sin(angle) * speed; // Set particle color to white/blue for shield effect if (particle.children[0]) { particle.children[0].tint = 0x00FFFF; } particle.lifespan = 40 + Math.random() * 20; game.addThrustParticle(particle); } } } self.lastInvulnerable = self.invulnerable; // 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: 24, // Further increased size // Increased size height: 24, // Further increased size // Increased size tint: 0xFF8000 // Orange color }); particleGraphics.alpha = 0.9; self.addChild(particleGraphics); // Add a glow effect by adding a second, larger particle behind it var glowGraphics = LK.getAsset('bulletShape', { anchorX: 0.5, anchorY: 0.5, width: 36, // Larger than the main particle height: 36, // Larger than the main particle tint: 0xFFFF00 // Yellow/gold glow }); glowGraphics.alpha = 0.4; // Semi-transparent self.addChildAt(glowGraphics, 0); // Add behind the main particle // Particle properties self.velocity = { x: 0, y: 0 }; self.lifespan = 35; // Increased 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); // Update glow effect if (self.children.length > 1) { var glowGraphics = self.children[0]; glowGraphics.alpha = 0.4 * (1 - lifeRatio); // Pulse the glow for more dynamic effect var pulseScale = 1.0 + 0.2 * Math.sin(self.age * 0.2); glowGraphics.scale.set(pulseScale, pulseScale); // Change glow color over time for fire trail effect if (self.age < self.lifespan * 0.3) { glowGraphics.tint = 0xFFFF00; // Yellow at start } else if (self.age < self.lifespan * 0.6) { glowGraphics.tint = 0xFF8000; // Orange in middle } else { glowGraphics.tint = 0xFF0000; // Red at end } } // Add scale effect var scaleRatio = 1.0 - lifeRatio * 0.5; particleGraphics.scale.set(scaleRatio, scaleRatio); // 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 ****/ // Placeholder ID - Engine will handle // Placeholder ID - Engine will handle // Placeholder ID - Engine will handle // Placeholder ID - Engine will handle // Placeholder ID - Engine will handle // Placeholder ID - Engine will handle // Placeholder ID - Engine will handle // Placeholder ID - Engine will handle // Placeholder ID - Engine will handle // Assuming ID is correct // Replace with actual ID // Replace with actual ID // Replace with actual ID // Music Tracks - assuming unique IDs exist for each // Replace with actual ID // Replace with actual ID // Replace with actual ID // Replace with actual ID // Replace with actual ID // Replace with actual ID // Replace with actual ID // Replace with actual ID // Replace with actual ID // Replace with actual ID // Meme explosion sounds - assuming unique IDs exist for each // Placeholder: Replace with actual music ID // Placeholder: Replace with actual music ID // Placeholder: Replace with actual music ID // Initialize music tracks // Placeholder: Replace with actual sound ID or properties // Placeholder: Replace with actual sound ID or properties // Placeholder: Replace with actual sound ID or properties // Placeholder: Replace with actual sound ID or properties // Placeholder: Replace with actual sound ID or properties // Placeholder: Replace with actual sound ID or properties // Placeholder: Replace with actual sound ID or properties // Placeholder: Replace with actual sound ID or properties // Placeholder: Replace with actual sound ID or properties // Placeholder: Replace with actual sound ID or properties // Initialize meme explosion sounds // Placeholder: Replace with actual sound ID // Placeholder: Replace with actual sound ID // Placeholder: Replace with actual sound ID // Placeholder: Replace with actual sound ID // Placeholder: Replace with actual sound ID // Placeholder: Replace with actual sound ID // Placeholder: Replace with actual sound ID // Placeholder: Replace with actual sound ID // Placeholder: Replace with actual sound ID // Placeholder: Replace with actual sound ID // Initialize music tracks // Initialize meme explosion sounds // Add music assets // Add music assets // Sounds for each meme type // Game variables // Add sound assets for each meme asteroid (meme0 to meme9) // Sound for tapping to start // Sound for starting a new level // Sound for the rhythmic beat // Placeholder ID - Engine will handle // Placeholder ID - Engine will handle // These variables need to be accessible in the global scope for all classes 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 introPlayed = false; var introSequence = null; var triangleSize = 36; // Ship triangle size for bullet positioning (half of the size now) // Function to play intro sequence function playIntroSequence() { // Clear any existing game objects bullets = []; asteroids = []; thrustParticles = []; // Create and add intro sequence introSequence = new IntroSequence(); game.addChild(introSequence); // Setup a handler for when intro is finished LK.setInterval(function () { if (introSequence && introSequence.finished) { game.removeChild(introSequence); introSequence = null; introPlayed = true; initGame(); LK.clearInterval(this); } }, 100); } // UI elements var leftButton; var rightButton; var fireButton; var scoreTxt; var livesTxt; var levelTxt; var startText; // Initialize the game function initGame() { // Check if we need to play intro if (!gameStarted && !introPlayed) { playIntroSequence(); return; } else if (gameStarted && !gameOver) { // Start background music if game is starting directly if (currentMusicTrack === 0) { currentMusicTrack = 1; LK.playMusic('gameMusic' + currentMusicTrack, { loop: true, fade: { start: 0, end: 1, duration: 500 } }); } } // 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(2, 2); // Make button bigger 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(2, 2); // Make button bigger 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(2, 2); // Make button bigger 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: 40, fill: 0xFFFFFF }); scoreTxt.anchor.set(1, 0); // Right-align text scoreTxt.x = -20; // Add padding from right edge scoreTxt.y = 80; // Position further below the Glaud text LK.gui.topRight.addChild(scoreTxt); livesTxt = new Text2('LIVES: 3', { size: 40, fill: 0xFFFFFF }); livesTxt.anchor.set(0.5, 0); // Center anchor horizontally livesTxt.x = 70; // Moved slightly to the left LK.gui.top.addChild(livesTxt); levelTxt = new Text2('LEVEL: 1', { size: 40, fill: 0xFFFFFF }); levelTxt.anchor.set(0, 0); // Left-align text levelTxt.x = 180; // Move further right from top-left menu icon but slightly to the left levelTxt.y = 80; // Move lower down from top edge LK.gui.topLeft.addChild(levelTxt); // Start screen text if (!gameStarted) { // Create gray background for start text var startBackground = new Container(); var bgShape = LK.getAsset('bulletShape', { anchorX: 0.5, anchorY: 0.5, width: 1000, height: 250, tint: 0x333333 }); bgShape.alpha = 0.9; startBackground.addChild(bgShape); startText = new Text2('TAP TO START', { size: 140, // Slightly smaller size fill: 0xFFFFFF }); startText.anchor.set(0.5, 0.5); startBackground.addChild(startText); LK.gui.center.addChild(startBackground); } // Clear any existing game objects bullets = []; asteroids = []; thrustParticles = []; // Initialize asteroids for the first level createAsteroidsForLevel(level); } 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 based on meme type var memeType = asteroid.memeType !== undefined ? asteroid.memeType : 0; var memeExplosionSoundId = 'meme' + memeType + 'Explosion'; var explosionSound = LK.getSound(memeExplosionSoundId); if (explosionSound) { explosionSound.play(); } else { LK.getSound('explosion').play(); } // Flash screen with meme color var memeColors = [0xFF5733, 0x33FF57, 0x5733FF, 0xFF33A1, 0x33A1FF, 0xFFC133, 0x33FFC1, 0xC133FF, 0xA1FF33, 0xFF3357]; var flashColor = memeColors[memeType] || 0xFF0000; LK.effects.flashScreen(flashColor, 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); // Get the asteroid's meme type, defaulting to 0 if undefined var memeType = asteroid.memeType !== undefined ? asteroid.memeType : 0; // Construct the specific meme explosion sound ID var memeExplosionSoundId = 'meme' + memeType + 'Explosion'; // Try to get the specific meme explosion sound var explosionSound = LK.getSound(memeExplosionSoundId); // Play the specific meme explosion sound or fallback to generic explosion if (explosionSound) { explosionSound.play(); } else { // Fallback to generic explosion sound console.log('Fallback explosion sound for memeType:', memeType); LK.getSound('explosion').play(); } // Create explosion particles var memeColors = [0xFF5733, 0x33FF57, 0x5733FF, 0xFF33A1, 0x33A1FF, 0xFFC133, 0x33FFC1, 0xC133FF, 0xA1FF33, 0xFF3357]; var explosionColor = memeColors[memeType] || 0xFF8000; var numParticles = asteroid.size * 10; // More particles for larger asteroids for (var p = 0; p < numParticles; p++) { var particle = new ThrustParticle(); particle.x = asteroid.x; particle.y = asteroid.y; // Random direction var angle = Math.random() * Math.PI * 2; var speed = 1 + Math.random() * 3; particle.velocity.x = Math.cos(angle) * speed; particle.velocity.y = Math.sin(angle) * speed; // Set particle color to match meme if (particle.children[0]) { particle.children[0].tint = explosionColor; } // Longer lifespan for more dramatic effect particle.lifespan = 30 + Math.random() * 30; thrustParticles.push(particle); game.addChild(particle); } // Create a flash effect at the explosion location LK.effects.flashObject(asteroid, explosionColor, 300); // Break large asteroids (size 2) into smaller pieces if (asteroid.size === 2) { for (var k = 0; k < 2; k++) { // Create medium asteroids (size 1) var newAsteroid = new Asteroid(1, asteroid.memeType); newAsteroid.x = asteroid.x; newAsteroid.y = asteroid.y; // Add some velocity variation for more natural breakup var angle = Math.random() * Math.PI * 2; var speed = 0.5 + Math.random() * 1; newAsteroid.velocity.x = Math.cos(angle) * speed; newAsteroid.velocity.y = Math.sin(angle) * speed; // Add a tween effect for spawning newAsteroid.scale.set(0.1, 0.1); tween(newAsteroid.scale, { x: 1.0, y: 1.0 }, { duration: 300, easing: tween.easeOutBack }); asteroids.push(newAsteroid); game.addChild(newAsteroid); } } // Remove the hit asteroid (large, medium, or small) 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); // Create level transition effect var levelUpText = new Text2('LEVEL ' + level, { size: 200, fill: 0xFFFF00 }); levelUpText.anchor.set(0.5, 0.5); levelUpText.x = 2048 / 2; levelUpText.y = 2732 / 2; levelUpText.alpha = 0; game.addChild(levelUpText); // Animate the level text tween(levelUpText, { alpha: 1, y: levelUpText.y - 100 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { tween(levelUpText, { alpha: 0, y: levelUpText.y - 100 }, { duration: 1000, easing: tween.easeIn, onFinish: function onFinish() { game.removeChild(levelUpText); } }); } }); // Play level start sound LK.getSound('levelStart').play(); // Flash the screen with level color based on level number (cycle through colors) var levelColors = [0xFFFF00, 0x00FFFF, 0xFF00FF, 0x00FF00, 0xFF0000, 0x0000FF]; var levelColor = levelColors[(level - 1) % levelColors.length]; LK.effects.flashScreen(levelColor, 800); // Change music track on level up currentMusicTrack = currentMusicTrack % 3 + 1; LK.playMusic('gameMusic' + currentMusicTrack, { loop: true, fade: { start: 0, end: 1, duration: 1000 } }); // Wait a moment before spawning new asteroids for dramatic effect LK.setTimeout(function () { // Create new asteroids for the next level with special intro effect createAsteroidsForLevel(level); // Make each asteroid appear with a scale effect for (var i = 0; i < asteroids.length; i++) { var asteroid = asteroids[i]; asteroid.scale.set(0.1, 0.1); // Stagger the animations slightly LK.setTimeout(function (a) { return function () { tween(a.scale, { x: 1.0, y: 1.0 }, { duration: 500, easing: tween.easeOutBack }); }; }(asteroid), i * 100); } }, 1500); } } // Main game update function game.update = function () { // Update intro sequence if active if (introSequence) { introSequence.update(); return; } 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(); }; // Game music track variable var currentMusicTrack = 0; // Initialize to 0, will be set to 1 on game start // Event handlers game.down = function (x, y, obj) { // Check if intro is playing if (introSequence && !introSequence.finished) { introSequence.skip(); return; } if (!gameStarted) { gameStarted = true; LK.getSound('gameStart').play(); // Play start sound if (startText && startText.parent) { startText.parent.parent.removeChild(startText.parent); 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) // Start the initial music track currentMusicTrack = 1; LK.playMusic('gameMusic' + currentMusicTrack, { loop: true }); } // 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
@@ -39,14 +39,45 @@
y: Math.sin(angle) * speed
};
// Random rotation
self.rotationSpeed = (Math.random() - 0.5) * 0.05;
+ // Add pulsing effect
+ self.pulseSpeed = 0.01 + Math.random() * 0.03;
+ self.pulseTime = Math.random() * Math.PI * 2; // Random starting phase
+ self.baseScale = 1.0;
self.update = function () {
// Move
self.x += self.velocity.x;
self.y += self.velocity.y;
// Rotate
asteroidGraphics.rotation += self.rotationSpeed;
+ // Pulse effect based on meme type
+ self.pulseTime += self.pulseSpeed;
+ var pulseAmount = Math.sin(self.pulseTime) * 0.1 + 1.0;
+ asteroidGraphics.scale.set(self.baseScale * pulseAmount, self.baseScale * pulseAmount);
+ // Add occasional glitch effect for memes - but with lower chance and controlled sound
+ if (Math.random() < 0.002) {
+ // Reduced to 0.2% chance per frame
+ // 0.5% chance per frame
+ var originalTint = asteroidGraphics.children[0].tint;
+ var glitchColors = [0xFF00FF, 0x00FFFF, 0xFFFF00, 0xFF0000, 0x00FF00, 0x0000FF];
+ var glitchColor = glitchColors[Math.floor(Math.random() * glitchColors.length)];
+ asteroidGraphics.children[0].tint = glitchColor;
+ // Only play sounds during actual gameplay, not during intro
+ if (self.memeType !== undefined && gameStarted && !introSequence) {
+ var glitchSound = LK.getSound('meme' + self.memeType + 'Explosion');
+ if (glitchSound) {
+ glitchSound.play({
+ volume: 0.1 // Reduced volume
+ });
+ }
+ }
+ LK.setTimeout(function () {
+ if (asteroidGraphics && asteroidGraphics.children[0]) {
+ asteroidGraphics.children[0].tint = originalTint;
+ }
+ }, 100);
+ }
// Wrap around screen edges
if (self.x < -50) {
self.x = 2098;
}
@@ -169,8 +200,266 @@
buttonGraphics.alpha = 0.5;
};
return self;
});
+var IntroSequence = Container.expand(function () {
+ var self = Container.call(this);
+ // Layers for effects
+ var starfieldLayer = new Container();
+ var memesLayer = new Container();
+ var textLayer = new Container();
+ var shipLayer = new Container();
+ var titleLayer = new Container();
+ self.addChild(starfieldLayer);
+ self.addChild(memesLayer);
+ self.addChild(textLayer);
+ self.addChild(shipLayer);
+ self.addChild(titleLayer);
+ // Create starfield
+ var stars = [];
+ for (var i = 0; i < 100; i++) {
+ var star = LK.getAsset('bulletShape', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 3 + Math.random() * 5,
+ height: 3 + Math.random() * 5,
+ x: Math.random() * 2048,
+ y: Math.random() * 2732,
+ tint: 0xFFFFFF
+ });
+ star.alpha = 0.3 + Math.random() * 0.7;
+ star.velocity = 10 + Math.random() * 20;
+ stars.push(star);
+ starfieldLayer.addChild(star);
+ }
+ // Create distant meme silhouettes
+ var silhouettes = [];
+ for (var j = 0; j < 10; j++) {
+ var memeType = Math.floor(Math.random() * 10);
+ var meme = LK.getAsset('meme' + memeType, {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 200 + Math.random() * 1600,
+ y: -300 - Math.random() * 600,
+ tint: 0x333333
+ });
+ meme.alpha = 0.3;
+ meme.scale.set(0.3, 0.3);
+ silhouettes.push(meme);
+ memesLayer.addChild(meme);
+ }
+ // Emergency broadcast text
+ var emergencyText = new Text2('MEME OVERLOAD DETECTED', {
+ size: 80,
+ fill: 0xFF3333
+ });
+ emergencyText.anchor.set(0.5, 0.5);
+ emergencyText.x = 2048 / 2;
+ emergencyText.y = 2732 / 2;
+ emergencyText.alpha = 0;
+ textLayer.addChild(emergencyText);
+ // Hero ship
+ var heroShip = new Ship();
+ heroShip.x = 2048 / 2;
+ heroShip.y = 2732 + 100;
+ heroShip.alpha = 0;
+ shipLayer.addChild(heroShip);
+ // Title
+ var titleText = new Text2('MEMES ASTEROID WAR', {
+ size: 120,
+ fill: 0xFF8000
+ });
+ titleText.anchor.set(0.5, 0.5);
+ titleText.x = 2048 / 2;
+ titleText.y = 2732 / 2 - 300;
+ titleText.alpha = 0;
+ titleLayer.addChild(titleText);
+ // Call to action
+ var ctaText = new Text2('TAP TO DEFEND THE INTERNET', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ ctaText.anchor.set(0.5, 0.5);
+ ctaText.x = 2048 / 2;
+ ctaText.y = 2732 / 2 + 300;
+ ctaText.alpha = 0;
+ titleLayer.addChild(ctaText);
+ // Animation sequence
+ self.phase = 0;
+ self.timer = 0;
+ self.finished = false;
+ self.update = function () {
+ self.timer++;
+ // Update stars
+ for (var i = 0; i < stars.length; i++) {
+ var star = stars[i];
+ star.y += star.velocity;
+ if (star.y > 2732) {
+ star.y = -10;
+ star.x = Math.random() * 2048;
+ }
+ }
+ // Animation phases
+ switch (self.phase) {
+ case 0:
+ // Starfield intro (0-2s)
+ // Play intro music at the start - only once at the very beginning
+ if (self.timer === 1) {
+ LK.getSound('introMusic').play();
+ }
+ if (self.timer === 60) {
+ // After 1s, start meme approach
+ self.phase = 1;
+ }
+ break;
+ case 1:
+ // Meme approach (2-4s)
+ for (var j = 0; j < silhouettes.length; j++) {
+ silhouettes[j].y += 3;
+ silhouettes[j].scale.x += 0.003;
+ silhouettes[j].scale.y += 0.003;
+ }
+ // Instead of random chaotic sounds, play a structured sound at specific moments
+ if (self.timer === 90) {
+ // Play a single sound at 1.5s
+ LK.getSound('meme0Explosion').play({
+ volume: 0.2
+ });
+ } else if (self.timer === 150) {
+ // Play another sound at 2.5s
+ LK.getSound('meme5Explosion').play({
+ volume: 0.2
+ });
+ }
+ if (self.timer === 180) {
+ // After 3s, show emergency text
+ self.phase = 2;
+ tween(emergencyText, {
+ alpha: 1
+ }, {
+ duration: 500,
+ easing: tween.easeOut
+ });
+ // Make text glitch effect
+ LK.setInterval(function () {
+ emergencyText.scale.set(1 + Math.random() * 0.05, 1 + Math.random() * 0.05);
+ emergencyText.x = 2048 / 2 + (Math.random() * 20 - 10);
+ }, 80);
+ // Play alarm sound for emergency - only play once
+ LK.getSound('levelStart').play();
+ }
+ break;
+ case 2:
+ // Emergency broadcast (4-6s)
+ for (var k = 0; k < silhouettes.length; k++) {
+ silhouettes[k].y += 3;
+ silhouettes[k].scale.x += 0.004;
+ silhouettes[k].scale.y += 0.004;
+ }
+ if (self.timer === 300) {
+ // After 5s, fade out emergency text and show ship
+ self.phase = 3;
+ tween(emergencyText, {
+ alpha: 0
+ }, {
+ duration: 500
+ });
+ // Animate hero ship rising
+ heroShip.alpha = 1;
+ tween(heroShip, {
+ y: 2732 / 2 + 200
+ }, {
+ duration: 1500,
+ easing: tween.easeOut
+ });
+ }
+ break;
+ case 3:
+ // Ship reveal (6-8s)
+ if (self.timer === 420) {
+ // After 7s, show title
+ self.phase = 4;
+ // Play title reveal sound - only once
+ LK.getSound('gameStart').play();
+ // Animate title card
+ tween(titleText, {
+ alpha: 1
+ }, {
+ duration: 800,
+ easing: tween.easeOut
+ });
+ // Create distortion effect on title
+ var titleDistort = LK.setInterval(function () {
+ titleText.scale.set(1 + Math.random() * 0.03, 1 + Math.random() * 0.03);
+ if (self.timer > 480) {
+ LK.clearInterval(titleDistort);
+ titleText.scale.set(1, 1);
+ }
+ }, 50);
+ }
+ break;
+ case 4:
+ // Title card (8-10s)
+ if (self.timer === 540) {
+ // After 9s, show CTA
+ self.phase = 5;
+ tween(ctaText, {
+ alpha: 1
+ }, {
+ duration: 500,
+ easing: tween.easeOut
+ });
+ // Make CTA pulse
+ LK.setInterval(function () {
+ if (ctaText.alpha === 1) {
+ tween(ctaText, {
+ alpha: 0.5
+ }, {
+ duration: 800
+ });
+ } else {
+ tween(ctaText, {
+ alpha: 1
+ }, {
+ duration: 800
+ });
+ }
+ }, 1600);
+ }
+ break;
+ case 5:
+ // CTA (10s+)
+ if (self.timer === 660) {
+ // After 11s total, finish intro
+ self.finished = true;
+ }
+ break;
+ }
+ return self.finished;
+ };
+ self.skip = function () {
+ // Stop all potentially playing sounds to avoid sound clutter
+ LK.getSound('introMusic').stop();
+ LK.getSound('meme0Explosion').stop();
+ LK.getSound('meme1Explosion').stop();
+ LK.getSound('meme2Explosion').stop();
+ LK.getSound('meme3Explosion').stop();
+ LK.getSound('meme4Explosion').stop();
+ LK.getSound('meme5Explosion').stop();
+ LK.getSound('meme6Explosion').stop();
+ LK.getSound('meme7Explosion').stop();
+ LK.getSound('meme8Explosion').stop();
+ LK.getSound('meme9Explosion').stop();
+ LK.getSound('levelStart').stop();
+ // Small delay to ensure all sounds are cleared before playing the new one
+ LK.setTimeout(function () {
+ // Play game start sound instead - with a slight delay
+ LK.getSound('gameStart').play();
+ }, 100);
+ self.finished = true;
+ };
+ return self;
+});
var Ship = Container.expand(function () {
var self = Container.call(this);
// Create a custom triangle ship
var shipGraphics = new Container();
@@ -241,8 +530,9 @@
};
// Track previous position for movement calculations
self.lastX = 0;
self.lastY = 0;
+ self.lastInvulnerable = false;
// Apply rotation to ship graphics
shipGraphics.rotation = self.rot;
self.update = function () {
// Store last position
@@ -288,8 +578,15 @@
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;
+ // Play subtle thrust sound occasionally
+ if (LK.ticks % 20 === 0) {
+ // Quiet thrust sound
+ LK.getSound('beatSound').play({
+ volume: 0.2
+ });
+ }
// Add to game via event
if (typeof game.addThrustParticle === 'function') {
game.addThrustParticle(particle);
}
@@ -309,8 +606,31 @@
}
if (self.y > 2732) {
self.y = 0;
}
+ // Special effect when ship becomes invulnerable (after being hit)
+ if (self.lastInvulnerable === false && self.invulnerable === true) {
+ // Create explosion effect
+ for (var i = 0; i < 20; i++) {
+ if (typeof game.addThrustParticle === 'function') {
+ var particle = new ThrustParticle();
+ particle.x = self.x;
+ particle.y = self.y;
+ // Random direction
+ var angle = Math.random() * Math.PI * 2;
+ var speed = 1 + Math.random() * 4;
+ particle.velocity.x = Math.cos(angle) * speed;
+ particle.velocity.y = Math.sin(angle) * speed;
+ // Set particle color to white/blue for shield effect
+ if (particle.children[0]) {
+ particle.children[0].tint = 0x00FFFF;
+ }
+ particle.lifespan = 40 + Math.random() * 20;
+ game.addThrustParticle(particle);
+ }
+ }
+ }
+ self.lastInvulnerable = self.invulnerable;
// Handle firing
if (self.isFiring) {
if (self.fireTimer <= 0) {
self.fireTimer = self.fireDelay;
@@ -352,8 +672,20 @@
tint: 0xFF8000 // Orange color
});
particleGraphics.alpha = 0.9;
self.addChild(particleGraphics);
+ // Add a glow effect by adding a second, larger particle behind it
+ var glowGraphics = LK.getAsset('bulletShape', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 36,
+ // Larger than the main particle
+ height: 36,
+ // Larger than the main particle
+ tint: 0xFFFF00 // Yellow/gold glow
+ });
+ glowGraphics.alpha = 0.4; // Semi-transparent
+ self.addChildAt(glowGraphics, 0); // Add behind the main particle
// Particle properties
self.velocity = {
x: 0,
y: 0
@@ -368,8 +700,27 @@
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);
+ // Update glow effect
+ if (self.children.length > 1) {
+ var glowGraphics = self.children[0];
+ glowGraphics.alpha = 0.4 * (1 - lifeRatio);
+ // Pulse the glow for more dynamic effect
+ var pulseScale = 1.0 + 0.2 * Math.sin(self.age * 0.2);
+ glowGraphics.scale.set(pulseScale, pulseScale);
+ // Change glow color over time for fire trail effect
+ if (self.age < self.lifespan * 0.3) {
+ glowGraphics.tint = 0xFFFF00; // Yellow at start
+ } else if (self.age < self.lifespan * 0.6) {
+ glowGraphics.tint = 0xFF8000; // Orange in middle
+ } else {
+ glowGraphics.tint = 0xFF0000; // Red at end
+ }
+ }
+ // Add scale effect
+ var scaleRatio = 1.0 - lifeRatio * 0.5;
+ particleGraphics.scale.set(scaleRatio, scaleRatio);
// Return true if particle should be removed
return self.age >= self.lifespan;
};
return self;
@@ -387,68 +738,69 @@
* Game Code
****/
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
-// 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
-// Sounds for each meme type
-// Add music assets
-// Add music assets
-// Initialize meme explosion sounds
-// Initialize music tracks
-// Placeholder: Replace with actual sound ID
-// Placeholder: Replace with actual sound ID
-// Placeholder: Replace with actual sound ID
-// Placeholder: Replace with actual sound ID
-// Placeholder: Replace with actual sound ID
-// Placeholder: Replace with actual sound ID
-// Placeholder: Replace with actual sound ID
-// Placeholder: Replace with actual sound ID
-// Placeholder: Replace with actual sound ID
-// Placeholder: Replace with actual sound ID
-// Initialize meme explosion sounds
-// Placeholder: Replace with actual sound ID or properties
-// Placeholder: Replace with actual sound ID or properties
-// Placeholder: Replace with actual sound ID or properties
-// Placeholder: Replace with actual sound ID or properties
-// Placeholder: Replace with actual sound ID or properties
-// Placeholder: Replace with actual sound ID or properties
-// Placeholder: Replace with actual sound ID or properties
-// Placeholder: Replace with actual sound ID or properties
-// Placeholder: Replace with actual sound ID or properties
-// Placeholder: Replace with actual sound ID or properties
-// Initialize music tracks
-// Placeholder: Replace with actual music ID
-// Placeholder: Replace with actual music ID
-// Placeholder: Replace with actual music ID
-// Meme explosion sounds - assuming unique IDs exist for each
+// Placeholder ID - Engine will handle
+// Placeholder ID - Engine will handle
+// Placeholder ID - Engine will handle
+// Placeholder ID - Engine will handle
+// Placeholder ID - Engine will handle
+// Placeholder ID - Engine will handle
+// Placeholder ID - Engine will handle
+// Assuming ID is correct
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
+// Music Tracks - assuming unique IDs exist for each
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
-// Music Tracks - assuming unique IDs exist for each
// Replace with actual ID
// Replace with actual ID
// Replace with actual ID
-// Assuming ID is correct
+// Meme explosion sounds - assuming unique IDs exist for each
+// Placeholder: Replace with actual music ID
+// Placeholder: Replace with actual music ID
+// Placeholder: Replace with actual music ID
+// Initialize music tracks
+// Placeholder: Replace with actual sound ID or properties
+// Placeholder: Replace with actual sound ID or properties
+// Placeholder: Replace with actual sound ID or properties
+// Placeholder: Replace with actual sound ID or properties
+// Placeholder: Replace with actual sound ID or properties
+// Placeholder: Replace with actual sound ID or properties
+// Placeholder: Replace with actual sound ID or properties
+// Placeholder: Replace with actual sound ID or properties
+// Placeholder: Replace with actual sound ID or properties
+// Placeholder: Replace with actual sound ID or properties
+// Initialize meme explosion sounds
+// Placeholder: Replace with actual sound ID
+// Placeholder: Replace with actual sound ID
+// Placeholder: Replace with actual sound ID
+// Placeholder: Replace with actual sound ID
+// Placeholder: Replace with actual sound ID
+// Placeholder: Replace with actual sound ID
+// Placeholder: Replace with actual sound ID
+// Placeholder: Replace with actual sound ID
+// Placeholder: Replace with actual sound ID
+// Placeholder: Replace with actual sound ID
+// Initialize music tracks
+// Initialize meme explosion sounds
+// Add music assets
+// Add music assets
+// Sounds for each meme type
+// Game variables
+// Add sound assets for each meme asteroid (meme0 to meme9)
+// Sound for tapping to start
+// Sound for starting a new level
+// Sound for the rhythmic beat
// Placeholder ID - Engine will handle
// Placeholder ID - Engine will handle
-// Placeholder ID - Engine will handle
-// Placeholder ID - Engine will handle
-// Placeholder ID - Engine will handle
-// Placeholder ID - Engine will handle
-// Placeholder ID - Engine will handle
-// Placeholder ID - Engine will handle
-// Placeholder ID - Engine will handle
+// These variables need to be accessible in the global scope for all classes
var ship;
var bullets = [];
var asteroids = [];
var thrustParticles = []; // Array to store thrust particles
@@ -456,9 +808,31 @@
var lives = 3;
var level = 1;
var gameStarted = false;
var gameOver = false;
+var introPlayed = false;
+var introSequence = null;
var triangleSize = 36; // Ship triangle size for bullet positioning (half of the size now)
+// Function to play intro sequence
+function playIntroSequence() {
+ // Clear any existing game objects
+ bullets = [];
+ asteroids = [];
+ thrustParticles = [];
+ // Create and add intro sequence
+ introSequence = new IntroSequence();
+ game.addChild(introSequence);
+ // Setup a handler for when intro is finished
+ LK.setInterval(function () {
+ if (introSequence && introSequence.finished) {
+ game.removeChild(introSequence);
+ introSequence = null;
+ introPlayed = true;
+ initGame();
+ LK.clearInterval(this);
+ }
+ }, 100);
+}
// UI elements
var leftButton;
var rightButton;
var fireButton;
@@ -467,8 +841,26 @@
var levelTxt;
var startText;
// Initialize the game
function initGame() {
+ // Check if we need to play intro
+ if (!gameStarted && !introPlayed) {
+ playIntroSequence();
+ return;
+ } else if (gameStarted && !gameOver) {
+ // Start background music if game is starting directly
+ if (currentMusicTrack === 0) {
+ currentMusicTrack = 1;
+ LK.playMusic('gameMusic' + currentMusicTrack, {
+ loop: true,
+ fade: {
+ start: 0,
+ end: 1,
+ duration: 500
+ }
+ });
+ }
+ }
// Create ship
ship = new Ship();
ship.x = 2048 / 2;
ship.y = 200; // Position at top middle
@@ -617,12 +1009,21 @@
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);
+ // Play explosion sound based on meme type
+ var memeType = asteroid.memeType !== undefined ? asteroid.memeType : 0;
+ var memeExplosionSoundId = 'meme' + memeType + 'Explosion';
+ var explosionSound = LK.getSound(memeExplosionSoundId);
+ if (explosionSound) {
+ explosionSound.play();
+ } else {
+ LK.getSound('explosion').play();
+ }
+ // Flash screen with meme color
+ var memeColors = [0xFF5733, 0x33FF57, 0x5733FF, 0xFF33A1, 0x33A1FF, 0xFFC133, 0x33FFC1, 0xC133FF, 0xA1FF33, 0xFF3357];
+ var flashColor = memeColors[memeType] || 0xFF0000;
+ LK.effects.flashScreen(flashColor, 500);
// Make ship invulnerable for a few seconds
ship.makeInvulnerable(180);
// Game over if no lives left
if (lives <= 0) {
@@ -666,16 +1067,53 @@
// Fallback to generic explosion sound
console.log('Fallback explosion sound for memeType:', memeType);
LK.getSound('explosion').play();
}
+ // Create explosion particles
+ var memeColors = [0xFF5733, 0x33FF57, 0x5733FF, 0xFF33A1, 0x33A1FF, 0xFFC133, 0x33FFC1, 0xC133FF, 0xA1FF33, 0xFF3357];
+ var explosionColor = memeColors[memeType] || 0xFF8000;
+ var numParticles = asteroid.size * 10; // More particles for larger asteroids
+ for (var p = 0; p < numParticles; p++) {
+ var particle = new ThrustParticle();
+ particle.x = asteroid.x;
+ particle.y = asteroid.y;
+ // Random direction
+ var angle = Math.random() * Math.PI * 2;
+ var speed = 1 + Math.random() * 3;
+ particle.velocity.x = Math.cos(angle) * speed;
+ particle.velocity.y = Math.sin(angle) * speed;
+ // Set particle color to match meme
+ if (particle.children[0]) {
+ particle.children[0].tint = explosionColor;
+ }
+ // Longer lifespan for more dramatic effect
+ particle.lifespan = 30 + Math.random() * 30;
+ thrustParticles.push(particle);
+ game.addChild(particle);
+ }
+ // Create a flash effect at the explosion location
+ LK.effects.flashObject(asteroid, explosionColor, 300);
// Break large asteroids (size 2) into smaller pieces
if (asteroid.size === 2) {
for (var k = 0; k < 2; k++) {
// Create medium asteroids (size 1)
var newAsteroid = new Asteroid(1, asteroid.memeType);
newAsteroid.x = asteroid.x;
newAsteroid.y = asteroid.y;
- // No velocity inheritance - just use the default size-based velocity
+ // Add some velocity variation for more natural breakup
+ var angle = Math.random() * Math.PI * 2;
+ var speed = 0.5 + Math.random() * 1;
+ newAsteroid.velocity.x = Math.cos(angle) * speed;
+ newAsteroid.velocity.y = Math.sin(angle) * speed;
+ // Add a tween effect for spawning
+ newAsteroid.scale.set(0.1, 0.1);
+ tween(newAsteroid.scale, {
+ x: 1.0,
+ y: 1.0
+ }, {
+ duration: 300,
+ easing: tween.easeOutBack
+ });
asteroids.push(newAsteroid);
game.addChild(newAsteroid);
}
}
@@ -695,10 +1133,44 @@
if (asteroids.length === 0) {
// Next level
level++;
levelTxt.setText('LEVEL: ' + level);
+ // Create level transition effect
+ var levelUpText = new Text2('LEVEL ' + level, {
+ size: 200,
+ fill: 0xFFFF00
+ });
+ levelUpText.anchor.set(0.5, 0.5);
+ levelUpText.x = 2048 / 2;
+ levelUpText.y = 2732 / 2;
+ levelUpText.alpha = 0;
+ game.addChild(levelUpText);
+ // Animate the level text
+ tween(levelUpText, {
+ alpha: 1,
+ y: levelUpText.y - 100
+ }, {
+ duration: 1000,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(levelUpText, {
+ alpha: 0,
+ y: levelUpText.y - 100
+ }, {
+ duration: 1000,
+ easing: tween.easeIn,
+ onFinish: function onFinish() {
+ game.removeChild(levelUpText);
+ }
+ });
+ }
+ });
// Play level start sound
LK.getSound('levelStart').play();
+ // Flash the screen with level color based on level number (cycle through colors)
+ var levelColors = [0xFFFF00, 0x00FFFF, 0xFF00FF, 0x00FF00, 0xFF0000, 0x0000FF];
+ var levelColor = levelColors[(level - 1) % levelColors.length];
+ LK.effects.flashScreen(levelColor, 800);
// Change music track on level up
currentMusicTrack = currentMusicTrack % 3 + 1;
LK.playMusic('gameMusic' + currentMusicTrack, {
loop: true,
@@ -707,14 +1179,39 @@
end: 1,
duration: 1000
}
});
- // Create new asteroids for the next level
- createAsteroidsForLevel(level);
+ // Wait a moment before spawning new asteroids for dramatic effect
+ LK.setTimeout(function () {
+ // Create new asteroids for the next level with special intro effect
+ createAsteroidsForLevel(level);
+ // Make each asteroid appear with a scale effect
+ for (var i = 0; i < asteroids.length; i++) {
+ var asteroid = asteroids[i];
+ asteroid.scale.set(0.1, 0.1);
+ // Stagger the animations slightly
+ LK.setTimeout(function (a) {
+ return function () {
+ tween(a.scale, {
+ x: 1.0,
+ y: 1.0
+ }, {
+ duration: 500,
+ easing: tween.easeOutBack
+ });
+ };
+ }(asteroid), i * 100);
+ }
+ }, 1500);
}
}
// Main game update function
game.update = function () {
+ // Update intro sequence if active
+ if (introSequence) {
+ introSequence.update();
+ return;
+ }
if (!gameStarted) {
return;
}
// Update ship controls based on button state
@@ -736,8 +1233,13 @@
// Game music track variable
var currentMusicTrack = 0; // Initialize to 0, will be set to 1 on game start
// Event handlers
game.down = function (x, y, obj) {
+ // Check if intro is playing
+ if (introSequence && !introSequence.finished) {
+ introSequence.skip();
+ return;
+ }
if (!gameStarted) {
gameStarted = true;
LK.getSound('gameStart').play(); // Play start sound
if (startText && startText.parent) {
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