Code edit (5 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
add new meme and sound effect
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: resultText is not defined' in or related to this line: 'if (resultText && resultText.text === 'GAME OVER') {' Line Number: 1448
User prompt
outroMusic only plays when you write Game Over, it never plays at any other time. Game Music gameMusic3 only plays when the game is playing and Game Over is not written, set this very well.
Code edit (1 edits merged)
Please save this source code
User prompt
Add Meme12 and add sound effect for Meme12.
User prompt
Add sound effect for breast10 and breast11.
User prompt
Add sound effect for breast10 and breast11.
User prompt
Add a new meme. with sound effect.
User prompt
Add a new meme. with sound effect.
Code edit (1 edits merged)
Please save this source code
User prompt
This is fun.. feels a lot like the original and the gameplay controls are smooth.. I scored 18300. For this game, I would suggest adding a high score tally to track your progress so the player can push to beat their personal best scores. I'll definitely be back to try and top mine. 😊 *** I received such a comment, let's make the appropriate plugin.*** ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
make the bullets better. But don't make it rickety.
User prompt
Make a new acet for the spaceship.Make a new acet for the spaceship.Make a new acet for the spaceship.Make a new acet for the spaceship.
User prompt
Make a new acet for the spaceship.
User prompt
don't make the ship out of pixels, make it as an acet instead, and it'll be less cramped.
User prompt
Make the bullet a little bigger.
User prompt
Make the bullet a little bigger.
User prompt
The bullet should only consist of one large pixel, less than one can cause a crash.
/****
* 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() * 14); // Now 0-13 for 14 memes
// 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 AuraParticle = Container.expand(function () {
var self = Container.call(this);
// Create particle visual - turquoise and larger than thrust particles
var particleGraphics = LK.getAsset('bulletShape', {
anchorX: 0.5,
anchorY: 0.5,
width: 36,
// Larger than thrust particles
height: 36,
tint: 0x40E0D0 // Turquoise color for aura
});
particleGraphics.alpha = 1.0;
self.addChild(particleGraphics);
// Particle properties
self.velocity = {
x: 0,
y: 0
};
self.lifespan = 45; // Longer lifespan than thrust particles
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++;
// Pulse the particle size for more dynamic effect
var pulseScale = 1 + 0.2 * Math.sin(self.age * 0.2);
particleGraphics.scale.set(pulseScale, pulseScale);
// 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;
});
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 solid bullet (a single large pixel)
var bulletSize = 60; // Size of the bullet - increased to 60 for better visibility
// Create a single solid element for the bullet
var bulletSprite = LK.getAsset('bulletShape', {
anchorX: 0.5,
anchorY: 0.5,
width: bulletSize,
height: bulletSize,
tint: 0xFFFF00 // Bright yellow color for better visibility
});
bulletGraphics.addChild(bulletSprite);
self.speed = 10;
self.velocity = {
x: 0,
y: 0
};
self.lifespan = 180; // 3 seconds at 60fps - triple the firing range
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;
// Add aura ready text if this is the fire button
self.isFireButton = assetId === 'fireButton';
if (self.isFireButton) {
self.auraReadyText = new Text2('AURA READY!', {
size: 30,
fill: 0xFFFF00
});
self.auraReadyText.anchor.set(0.5, 0.5);
self.auraReadyText.y = -90; // Position above the button
self.auraReadyText.visible = false; // Initially hidden
self.addChild(self.auraReadyText);
}
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;
};
// Method to update aura ready text visibility
self.updateAuraText = function (isAuraReady, cooldownRemaining) {
if (self.isFireButton && self.auraReadyText) {
// Initialize style property if it doesn't exist
if (!self.auraReadyText.style) {
self.auraReadyText.style = {};
}
if (isAuraReady) {
self.auraReadyText.visible = true;
self.auraReadyText.setText('AURA READY!');
self.auraReadyText.style.fill = 0xFFFF00; // Yellow when ready
// Add pulsing animation when aura is ready
if (!self.pulseAnimation) {
self.pulseAnimation = true;
pulsateAuraText();
}
} else {
// Show countdown when not ready
if (cooldownRemaining !== undefined) {
var secondsRemaining = Math.ceil(cooldownRemaining / 60); // Convert frames to seconds
var secondsRemaining = Math.ceil(cooldownRemaining / 60); // Convert frames to seconds
self.auraReadyText.visible = true;
self.auraReadyText.setText('AURA: ' + secondsRemaining + 's');
self.auraReadyText.style.fill = 0x3399FF; // Blue for cooldown
} else {
self.auraReadyText.visible = false;
}
self.pulseAnimation = false;
}
}
function pulsateAuraText() {
if (!self.pulseAnimation) {
return;
}
tween(self.auraReadyText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (!self.pulseAnimation) {
return;
}
tween(self.auraReadyText, {
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: pulsateAuraText
});
}
});
}
};
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() * 14); // Now 0-13 for 14 memes
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)
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;
}
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);
}
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;
// 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 () {
self.finished = true;
};
return self;
});
var OutroSequence = 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();
self.addChild(starfieldLayer);
self.addChild(memesLayer);
self.addChild(textLayer);
self.addChild(shipLayer);
// 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 exploding memes
var memes = [];
for (var j = 0; j < 20; j++) {
var memeType = Math.floor(Math.random() * 14); // 0-13 for 14 memes
var meme = LK.getAsset('meme' + memeType, {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2048,
y: Math.random() * 2732,
scaleX: 0.2,
scaleY: 0.2
});
meme.rotationSpeed = (Math.random() - 0.5) * 0.1;
meme.velocity = {
x: (Math.random() - 0.5) * 8,
y: (Math.random() - 0.5) * 8
};
memes.push(meme);
memesLayer.addChild(meme);
}
// Game result text (Victory or Game Over)
var resultText;
if (score > (storage.highScore || 0) && score > 0) {
resultText = new Text2('VICTORY!', {
size: 120,
fill: 0xFF8000
});
} else {
resultText = new Text2('GAME OVER', {
size: 120,
fill: 0xFF3333 // Red color for Game Over
});
}
resultText.anchor.set(0.5, 0.5);
resultText.x = 2048 / 2;
resultText.y = 2732 / 2 - 300;
resultText.alpha = 0;
textLayer.addChild(resultText);
// Score text
var finalScoreText = new Text2('FINAL SCORE: ' + score, {
size: 80,
fill: 0xFFFFFF
});
finalScoreText.anchor.set(0.5, 0.5);
finalScoreText.x = 2048 / 2;
finalScoreText.y = 2732 / 2;
finalScoreText.alpha = 0;
textLayer.addChild(finalScoreText);
// Add message based on high score
var messageText;
if (score > (storage.highScore || 0) && score > 0) {
messageText = new Text2('AMAZING JOB! NEW HIGH SCORE!', {
size: 60,
fill: 0xFFD700 // Gold color
});
} else {
messageText = new Text2('DON\'T GIVE UP! YOU\'LL DO BETTER NEXT TIME!', {
size: 60,
fill: 0x3399FF // Blue color
});
}
messageText.anchor.set(0.5, 0.5);
messageText.x = 2048 / 2;
messageText.y = 2732 / 2 + 100;
messageText.alpha = 0;
textLayer.addChild(messageText);
// Continue text
var continueText = new Text2('TAP TO CONTINUE', {
size: 60,
fill: 0xFFFFFF
});
continueText.anchor.set(0.5, 0.5);
continueText.x = 2048 / 2;
continueText.y = 2732 / 2 + 300;
continueText.alpha = 0;
textLayer.addChild(continueText);
// Animation sequence
self.phase = 0;
self.timer = 0;
self.finished = false;
self.update = function () {
self.timer++;
// Update stars - moving faster for outro
for (var i = 0; i < stars.length; i++) {
var star = stars[i];
star.y -= star.velocity; // Moving upward instead of downward
if (star.y < -10) {
star.y = 2732 + 10;
star.x = Math.random() * 2048;
}
}
// Update memes - spinning and moving across screen
for (var j = 0; j < memes.length; j++) {
var meme = memes[j];
meme.rotation += meme.rotationSpeed;
meme.x += meme.velocity.x;
meme.y += meme.velocity.y;
// Bounce off edges
if (meme.x < 0 || meme.x > 2048) {
meme.velocity.x *= -1;
}
if (meme.y < 0 || meme.y > 2732) {
meme.velocity.y *= -1;
}
}
// Animation phases
switch (self.phase) {
case 0:
// Initial pause (0-1s)
if (self.timer === 60) {
// After 1s, show result text
self.phase = 1;
tween(resultText, {
alpha: 1,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 800,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(resultText, {
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeOut
});
}
});
}
break;
case 1:
// Victory text (1-3s)
if (self.timer === 180) {
// After 3s, show score
self.phase = 2;
tween(finalScoreText, {
alpha: 1
}, {
duration: 800,
easing: tween.easeOut
});
}
break;
case 2:
// Score display (3-5s)
if (self.timer === 240) {
// After 4s, show motivational message
tween(messageText, {
alpha: 1
}, {
duration: 800,
easing: tween.easeOut
});
}
if (self.timer === 300) {
// After 5s, show continue prompt
self.phase = 3;
tween(continueText, {
alpha: 1
}, {
duration: 500,
easing: tween.easeOut
});
// Pulse the continue text
LK.setInterval(function () {
if (continueText.alpha === 1) {
tween(continueText, {
alpha: 0.5
}, {
duration: 800
});
} else {
tween(continueText, {
alpha: 1
}, {
duration: 800
});
}
}, 1600);
}
break;
case 3:
// Continue prompt (5s+)
// Player can tap to continue
if (self.timer > 360) {
self.canExit = true;
}
break;
}
return self.finished;
};
self.skip = function () {
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;
// Aura ability properties
self.auraReady = false;
self.auraCooldown = 0;
self.auraCooldownMax = 900; // 15 seconds (60fps * 15) - reduced from 20s
self.auraActive = false;
self.auraActiveTime = 0;
self.auraActiveTimeMax = 180; // 3 seconds (increased from 2s)
// 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;
// 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) {
// Create particle every 3 ticks if moving to improve smoothness
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;
}
}
// Handle Aura cooldown and activation
if (!self.auraReady && !self.auraActive) {
self.auraCooldown++;
// Calculate remaining cooldown for display
self.remainingCooldown = self.auraCooldownMax - self.auraCooldown;
if (self.auraCooldown >= self.auraCooldownMax) {
self.auraReady = true;
self.auraCooldown = 0;
self.remainingCooldown = 0;
}
}
// Handle active Aura effects
if (self.auraActive) {
// Pulse the ship with a white glow when aura is active
shipGraphics.tint = 0xFFFFFF;
self.auraActiveTime++;
if (self.auraActiveTime >= self.auraActiveTimeMax) {
self.auraActive = false;
self.auraActiveTime = 0;
shipGraphics.tint = 0xFFFFFF; // Reset tint
// Start cooldown again
self.auraCooldown = 0;
self.auraReady = false;
}
} else {
// Reset tint when aura is not active
shipGraphics.tint = 0xFF8000;
}
return false;
};
self.makeInvulnerable = function (frames) {
self.invulnerable = true;
self.invulnerableTime = frames;
};
// Activate aura ability
self.activateAura = function () {
// Only activate if aura is ready
if (self.auraReady) {
self.auraActive = true;
self.auraActiveTime = 0;
self.auraReady = false;
// Create visual effect - ship glows white
tween(shipGraphics, {
tint: 0xFFFFFF
}, {
duration: 200
});
return true;
}
return false;
};
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: 32,
// Further increased size for better visibility
// Increased size
height: 32,
// Further increased size for better visibility
// Increased size
tint: 0xFFAA00 // Brighter orange-yellow for better visibility
});
particleGraphics.alpha = 1.0; // Fully opaque
self.addChild(particleGraphics);
// 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);
// 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 assign
// Placeholder ID, engine will assign
// 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
// Engine will assign actual ID
// Engine will assign actual ID
// Added new meme image asset
// Added new meme explosion sound asset
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 outroSequence = null;
var outroPlayed = false;
var highScore = 0; // This will be loaded from storage
var highScoreTxt; // UI element for displaying the high score
var newRecordShown = false; // Track if new record notification has been shown
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 = [];
// Play gameMusic3 for intro
LK.playMusic('gameMusic3', {
loop: true,
fade: {
start: 0,
end: 1,
duration: 1000
}
});
introMusicPlayed = true;
// 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;
// Keep gameMusic3 playing - don't stop it
// Start game immediately
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() {
// Reset the new record notification flag
newRecordShown = false;
// Check if we need to play intro
if (!gameStarted && !introPlayed) {
playIntroSequence();
return;
}
// 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);
// Initialize high score from storage, defaulting to 0 if not found
highScore = storage.highScore || 0;
highScoreTxt = new Text2('BEST: ' + highScore, {
size: 40,
fill: 0xFFD700 // A nice gold color for the high score!
});
highScoreTxt.anchor.set(1, 0); // Right-align text
highScoreTxt.x = -20; // Add padding from right edge, same as scoreTxt
highScoreTxt.y = 140; // Position below scoreTxt
LK.gui.topRight.addChild(highScoreTxt);
// Create a container for lives display
var livesContainer = new Container();
livesContainer.x = 70;
livesContainer.y = 50;
LK.gui.top.addChild(livesContainer);
// Add ship icons for lives instead of text
var lifeIcons = [];
for (var i = 0; i < 3; i++) {
var lifeIcon = LK.getAsset('shipAsset', {
anchorX: 0.5,
anchorY: 0.5,
width: 40,
height: 40
});
lifeIcon.x = i * 50; // Space them horizontally
livesContainer.addChild(lifeIcon);
lifeIcons.push(lifeIcon);
}
// Store the icons and container for later access
livesTxt = {
icons: lifeIcons,
container: livesContainer,
update: function update(livesCount) {
for (var i = 0; i < this.icons.length; i++) {
this.icons[i].visible = i < livesCount;
}
}
};
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-13)
var memeType = Math.floor(Math.random() * 14); // Now 0-13 for 14 memes
var asteroid = new Asteroid(2, memeType); // Start with large asteroids and specific meme type
// Apply special behavior based on meme type
if (memeType === 7) {
// "This is Fine" meme - moves slower
asteroid.velocity.x *= 0.6;
asteroid.velocity.y *= 0.6;
} else if (memeType === 9) {
// "Stonks" meme - worth more points
asteroid.getPoints = function () {
return (3 - this.size) * 150; // 50% more points
};
} else if (memeType === 12) {
// Fast meme
asteroid.velocity.x *= 1.5;
asteroid.velocity.y *= 1.5;
}
// Add difficulty scaling based on level
if (level > 3) {
// Scale asteroid speed with level
var speedMultiplier = 1 + (level - 3) * 0.1; // 10% faster per level after 3
speedMultiplier = Math.min(speedMultiplier, 1.5); // Cap at 50% faster
asteroid.velocity.x *= speedMultiplier;
asteroid.velocity.y *= speedMultiplier;
}
// 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.update(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) {
// Check if the current score is a new high score
if (score > highScore) {
highScore = score; // Update our game's high score variable
storage.highScore = highScore; // Persist the new high score
// The highScoreTxt will update automatically on game restart via initGame
// Display a motivational message about the new high score
var newHighScoreText = new Text2('NEW HIGH SCORE! AMAZING WORK!', {
size: 60,
fill: 0xFFD700 // Gold color
});
newHighScoreText.anchor.set(0.5, 0.5);
newHighScoreText.x = 2048 / 2;
newHighScoreText.y = 2732 / 2 - 150;
LK.gui.center.addChild(newHighScoreText);
// Animate the text
tween(newHighScoreText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(newHighScoreText, {
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeIn
});
}
});
// Remove the text after 3 seconds
LK.setTimeout(function () {
LK.gui.center.removeChild(newHighScoreText);
}, 3000);
} else {
// Display a motivational message for not beating the high score
var motivationalText = new Text2('YOU\'LL GET IT NEXT TIME!', {
size: 60,
fill: 0x3399FF // Blue color
});
motivationalText.anchor.set(0.5, 0.5);
motivationalText.x = 2048 / 2;
motivationalText.y = 2732 / 2 - 150;
LK.gui.center.addChild(motivationalText);
// Animate the text
tween(motivationalText, {
alpha: 0.7
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(motivationalText, {
alpha: 1
}, {
duration: 800,
easing: tween.easeInOut
});
}
});
// Remove the text after 3 seconds
LK.setTimeout(function () {
LK.gui.center.removeChild(motivationalText);
}, 3000);
}
LK.setScore(score); // Set the score for the platform's game over UI
// Start the outro sequence instead of showing game over immediately
playOutroSequence();
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);
// Check if player just beat the high score and notification hasn't been shown yet
if (score > highScore && score - asteroid.getPoints() <= highScore && !newRecordShown) {
// Set flag to true so we don't show it again this game
newRecordShown = true;
// Create a temporary notification
var newRecordText = new Text2('NEW RECORD!', {
size: 80,
fill: 0xFFD700 // Gold color
});
newRecordText.anchor.set(0.5, 0.5);
newRecordText.x = 2048 / 2;
newRecordText.y = 2732 / 2;
newRecordText.alpha = 0;
game.addChild(newRecordText);
// Animate the notification
tween(newRecordText, {
alpha: 1,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 500,
easing: tween.elasticOut,
onFinish: function onFinish() {
// Wait 5 seconds before fading out
LK.setTimeout(function () {
tween(newRecordText, {
alpha: 0
}, {
duration: 1500,
easing: tween.easeOut,
onFinish: function onFinish() {
game.removeChild(newRecordText);
}
});
}, 5000);
}
});
// Update high score
highScore = score;
highScoreTxt.setText('BEST: ' + highScore);
}
// 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();
}
// 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
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);
// Play level start sound
LK.getSound('levelStart').play();
// Ensure gameMusic3 keeps playing - no music track changes
if (!musicPlaying) {
// If music isn't playing for some reason, restart gameMusic3
LK.playMusic('gameMusic3', {
loop: true,
fade: {
start: 0,
end: 1,
duration: 1000
}
});
musicPlaying = true;
}
// Create new asteroids for the next level
createAsteroidsForLevel(level);
}
}
// Main game update function
game.update = function () {
// Update intro sequence if active
if (introSequence) {
introSequence.update();
return;
}
// Update outro sequence if active
if (outroSequence) {
outroSequence.update();
return;
}
if (!gameStarted) {
return;
}
// Update ship controls based on button state
ship.isRotatingLeft = leftButton.isPressed;
ship.isRotatingRight = rightButton.isPressed;
ship.isFiring = fireButton.isPressed;
// Update aura ready text on fire button with cooldown info
fireButton.updateAuraText(ship.auraReady, ship.remainingCooldown);
// Ship constantly moves forward, no need for isMoving toggle
// Update ship
if (ship.update()) {
if (ship.auraReady) {
// If aura is ready and firing, activate aura and create bullet
if (ship.activateAura()) {
// Destroy nearby asteroids when aura is activated
destroyNearbyAsteroids();
// Visual effect for aura activation
createAuraEffectParticles();
// Sound effect for aura activation
LK.getSound('shoot').play();
}
}
createBullet();
}
// Update bullets and check for collisions
updateBullets();
// Update asteroids and check for collisions
updateAsteroids();
// Update thrust particles
updateThrustParticles();
};
// Game music and sound state variables
var currentMusicTrack = 0; // Initialize to 0, will be set to 1 on game start
var musicPlaying = false; // Track if music is currently playing
var introMusicPlayed = false; // Track if intro music has played
// Event handlers
game.down = function (x, y, obj) {
// Check if intro is playing
if (introSequence && !introSequence.finished) {
introSequence.skip();
return;
}
// Check if outro is playing and can be exited
if (outroSequence) {
if (outroSequence.canExit) {
outroSequence.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;
}
// Only play gameMusic3
LK.playMusic('gameMusic3', {
loop: true,
fade: {
start: 0,
end: 1,
duration: 800
}
});
// Set current track to match
currentMusicTrack = 3;
musicPlaying = 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;
var touchConsumed = false;
// 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, {});
touchConsumed = true;
}
// Check fire button only if touch not already consumed
if (!touchConsumed) {
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, {});
touchConsumed = true;
}
}
// Check right button only if touch not already consumed
if (!touchConsumed) {
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, {});
touchConsumed = true;
}
}
// Only fire a bullet if no button was pressed and game is active
if (!touchConsumed && gameStarted && ship && !gameOver) {
createBullet();
}
};
// Add up handler to handle releasing buttons
game.up = function (x, y, obj) {
// Reset all button states when touch/click is released
// Safely call button handlers by checking if they exist first
if (leftButton && typeof leftButton.up === 'function') {
leftButton.up(0, 0, {});
}
if (fireButton && typeof fireButton.up === 'function') {
fireButton.up(0, 0, {});
}
if (rightButton && typeof rightButton.up === 'function') {
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);
}
}
}
// Function to destroy asteroids near the ship when aura is activated
function destroyNearbyAsteroids() {
var auraRadius = 350; // Slightly reduced radius for better balance
// Create a visual ring effect for the aura
var auraRing = new Container();
var auraRingGraphic = LK.getAsset('forwardButton', {
anchorX: 0.5,
anchorY: 0.5,
width: auraRadius * 2,
height: auraRadius * 2,
tint: 0x40E0D0 // Turquoise color to match AuraParticle
});
auraRingGraphic.alpha = 0.7;
auraRing.addChild(auraRingGraphic);
auraRing.x = ship.x;
auraRing.y = ship.y;
game.addChild(auraRing);
// Animate the aura ring expanding then fading
tween(auraRingGraphic, {
alpha: 0,
width: auraRadius * 2.5,
height: auraRadius * 2.5
}, {
duration: 1200,
easing: tween.easeOut,
onFinish: function onFinish() {
game.removeChild(auraRing);
}
});
// Flash the ship with turquoise
tween(ship, {
alpha: 0.8
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(ship, {
alpha: 1
}, {
duration: 200,
easing: tween.easeInOut
});
}
});
// Check all asteroids and destroy ones within the aura radius
for (var i = asteroids.length - 1; i >= 0; i--) {
var asteroid = asteroids[i];
var dist = distance(ship.x, ship.y, asteroid.x, asteroid.y);
if (dist <= auraRadius) {
// Different behavior based on asteroid size
if (asteroid.size === 2) {
// Large asteroids: Break into medium asteroids and score points
score += asteroid.getPoints();
scoreTxt.setText('SCORE: ' + score);
// Play the specific meme explosion sound
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();
}
// Create medium asteroids
for (var k = 0; k < 2; k++) {
var newAsteroid = new Asteroid(1, asteroid.memeType);
newAsteroid.x = asteroid.x + (Math.random() - 0.5) * 50;
newAsteroid.y = asteroid.y + (Math.random() - 0.5) * 50;
asteroids.push(newAsteroid);
game.addChild(newAsteroid);
}
// Remove the large asteroid
game.removeChild(asteroid);
asteroids.splice(i, 1);
} else {
// Small and medium asteroids: Destroy completely and score double points
score += asteroid.getPoints() * 2; // Double points for small/medium
scoreTxt.setText('SCORE: ' + score);
// Play explosion sound
var memeTypeSmall = asteroid.memeType !== undefined ? asteroid.memeType : 0;
var explosionSoundId = 'meme' + memeTypeSmall + 'Explosion';
var expSound = LK.getSound(explosionSoundId);
if (expSound) {
expSound.play();
} else {
LK.getSound('explosion').play();
}
// Remove the asteroid
game.removeChild(asteroid);
asteroids.splice(i, 1);
}
}
}
// Check if all asteroids are destroyed after aura
if (asteroids.length === 0) {
// Next level
level++;
levelTxt.setText('LEVEL: ' + level);
LK.getSound('levelStart').play();
createAsteroidsForLevel(level);
}
}
// Function to create particle effects when aura is activated
function createAuraEffectParticles() {
// Create a burst of particles from the ship
for (var i = 0; i < 48; i++) {
// Increased particle count for more impressive effect
var angle = i * (Math.PI * 2 / 48);
var particle = new AuraParticle(); // Use the dedicated AuraParticle class
// Position at the ship
particle.x = ship.x;
particle.y = ship.y;
// Set velocity in all directions with varying speeds
var speed = 4 + Math.random() * 5; // Variable speeds for more organic look
particle.velocity.x = Math.cos(angle) * speed;
particle.velocity.y = Math.sin(angle) * speed;
// Add to game
thrustParticles.push(particle);
game.addChild(particle);
}
// Create a flash effect
LK.effects.flashObject(ship, 0x40E0D0, 500);
}
// Function to play outro sequence
function playOutroSequence() {
// Stop game music and start outro music
LK.playMusic('outroMusic', {
loop: true,
fade: {
start: 0,
end: 1,
duration: 1000
}
});
// Create and add outro sequence
outroSequence = new OutroSequence();
game.addChild(outroSequence);
// Setup a handler for when outro is finished
LK.setInterval(function () {
if (outroSequence && outroSequence.finished) {
game.removeChild(outroSequence);
outroSequence = null;
outroPlayed = true;
// Finally show game over screen when player closes outro
LK.showGameOver();
LK.clearInterval(this);
}
}, 100);
}
; ===================================================================
--- original.js
+++ change.js
@@ -64,8 +64,45 @@
return (3 - self.size) * 100; // Small: 300, Medium: 200, Large: 100
};
return self;
});
+var AuraParticle = Container.expand(function () {
+ var self = Container.call(this);
+ // Create particle visual - turquoise and larger than thrust particles
+ var particleGraphics = LK.getAsset('bulletShape', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 36,
+ // Larger than thrust particles
+ height: 36,
+ tint: 0x40E0D0 // Turquoise color for aura
+ });
+ particleGraphics.alpha = 1.0;
+ self.addChild(particleGraphics);
+ // Particle properties
+ self.velocity = {
+ x: 0,
+ y: 0
+ };
+ self.lifespan = 45; // Longer lifespan than thrust particles
+ 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++;
+ // Pulse the particle size for more dynamic effect
+ var pulseScale = 1 + 0.2 * Math.sin(self.age * 0.2);
+ particleGraphics.scale.set(pulseScale, pulseScale);
+ // 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;
+});
var Bullet = Container.expand(function () {
var self = Container.call(this);
// Create a container for pixel art bullet
var bulletGraphics = new Container();
@@ -142,18 +179,34 @@
self.isPressed = false;
buttonGraphics.alpha = 0.5;
};
// Method to update aura ready text visibility
- self.updateAuraText = function (isAuraReady) {
+ self.updateAuraText = function (isAuraReady, cooldownRemaining) {
if (self.isFireButton && self.auraReadyText) {
- self.auraReadyText.visible = isAuraReady;
- // Add pulsing animation when aura is ready
+ // Initialize style property if it doesn't exist
+ if (!self.auraReadyText.style) {
+ self.auraReadyText.style = {};
+ }
if (isAuraReady) {
+ self.auraReadyText.visible = true;
+ self.auraReadyText.setText('AURA READY!');
+ self.auraReadyText.style.fill = 0xFFFF00; // Yellow when ready
+ // Add pulsing animation when aura is ready
if (!self.pulseAnimation) {
self.pulseAnimation = true;
pulsateAuraText();
}
} else {
+ // Show countdown when not ready
+ if (cooldownRemaining !== undefined) {
+ var secondsRemaining = Math.ceil(cooldownRemaining / 60); // Convert frames to seconds
+ var secondsRemaining = Math.ceil(cooldownRemaining / 60); // Convert frames to seconds
+ self.auraReadyText.visible = true;
+ self.auraReadyText.setText('AURA: ' + secondsRemaining + 's');
+ self.auraReadyText.style.fill = 0x3399FF; // Blue for cooldown
+ } else {
+ self.auraReadyText.visible = false;
+ }
self.pulseAnimation = false;
}
}
function pulsateAuraText() {
@@ -692,12 +745,12 @@
self.invulnerableTime = 0;
// Aura ability properties
self.auraReady = false;
self.auraCooldown = 0;
- self.auraCooldownMax = 1200; // 20 seconds (60fps * 20)
+ self.auraCooldownMax = 900; // 15 seconds (60fps * 15) - reduced from 20s
self.auraActive = false;
self.auraActiveTime = 0;
- self.auraActiveTimeMax = 120; // 2 seconds
+ self.auraActiveTimeMax = 180; // 3 seconds (increased from 2s)
// 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
@@ -797,11 +850,14 @@
}
// Handle Aura cooldown and activation
if (!self.auraReady && !self.auraActive) {
self.auraCooldown++;
+ // Calculate remaining cooldown for display
+ self.remainingCooldown = self.auraCooldownMax - self.auraCooldown;
if (self.auraCooldown >= self.auraCooldownMax) {
self.auraReady = true;
self.auraCooldown = 0;
+ self.remainingCooldown = 0;
}
}
// Handle active Aura effects
if (self.auraActive) {
@@ -976,8 +1032,9 @@
var outroSequence = null;
var outroPlayed = false;
var highScore = 0; // This will be loaded from storage
var highScoreTxt; // UI element for displaying the high score
+var newRecordShown = false; // Track if new record notification has been shown
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
@@ -1019,8 +1076,10 @@
var levelTxt;
var startText;
// Initialize the game
function initGame() {
+ // Reset the new record notification flag
+ newRecordShown = false;
// Check if we need to play intro
if (!gameStarted && !introPlayed) {
playIntroSequence();
return;
@@ -1092,15 +1151,36 @@
highScoreTxt.anchor.set(1, 0); // Right-align text
highScoreTxt.x = -20; // Add padding from right edge, same as scoreTxt
highScoreTxt.y = 140; // Position below scoreTxt
LK.gui.topRight.addChild(highScoreTxt);
- 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);
+ // Create a container for lives display
+ var livesContainer = new Container();
+ livesContainer.x = 70;
+ livesContainer.y = 50;
+ LK.gui.top.addChild(livesContainer);
+ // Add ship icons for lives instead of text
+ var lifeIcons = [];
+ for (var i = 0; i < 3; i++) {
+ var lifeIcon = LK.getAsset('shipAsset', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 40,
+ height: 40
+ });
+ lifeIcon.x = i * 50; // Space them horizontally
+ livesContainer.addChild(lifeIcon);
+ lifeIcons.push(lifeIcon);
+ }
+ // Store the icons and container for later access
+ livesTxt = {
+ icons: lifeIcons,
+ container: livesContainer,
+ update: function update(livesCount) {
+ for (var i = 0; i < this.icons.length; i++) {
+ this.icons[i].visible = i < livesCount;
+ }
+ }
+ };
levelTxt = new Text2('LEVEL: 1', {
size: 40,
fill: 0xFFFFFF
});
@@ -1143,8 +1223,31 @@
for (var i = 0; i < numAsteroids; i++) {
// Create a random meme type (0-13)
var memeType = Math.floor(Math.random() * 14); // Now 0-13 for 14 memes
var asteroid = new Asteroid(2, memeType); // Start with large asteroids and specific meme type
+ // Apply special behavior based on meme type
+ if (memeType === 7) {
+ // "This is Fine" meme - moves slower
+ asteroid.velocity.x *= 0.6;
+ asteroid.velocity.y *= 0.6;
+ } else if (memeType === 9) {
+ // "Stonks" meme - worth more points
+ asteroid.getPoints = function () {
+ return (3 - this.size) * 150; // 50% more points
+ };
+ } else if (memeType === 12) {
+ // Fast meme
+ asteroid.velocity.x *= 1.5;
+ asteroid.velocity.y *= 1.5;
+ }
+ // Add difficulty scaling based on level
+ if (level > 3) {
+ // Scale asteroid speed with level
+ var speedMultiplier = 1 + (level - 3) * 0.1; // 10% faster per level after 3
+ speedMultiplier = Math.min(speedMultiplier, 1.5); // Cap at 50% faster
+ asteroid.velocity.x *= speedMultiplier;
+ asteroid.velocity.y *= speedMultiplier;
+ }
// Position the asteroid away from the player
do {
asteroid.x = Math.random() * 2048;
asteroid.y = Math.random() * 2732;
@@ -1183,9 +1286,9 @@
// Check for collision with the ship
if (!ship.invulnerable && asteroid.intersects(ship)) {
// Player loses a life
lives--;
- livesTxt.setText('LIVES: ' + lives);
+ livesTxt.update(lives);
// Play explosion sound
LK.getSound('explosion').play();
// Flash screen
LK.effects.flashScreen(0xFF0000, 500);
@@ -1285,8 +1388,49 @@
hitAsteroid = true;
// Add score based on asteroid size
score += asteroid.getPoints();
scoreTxt.setText('SCORE: ' + score);
+ // Check if player just beat the high score and notification hasn't been shown yet
+ if (score > highScore && score - asteroid.getPoints() <= highScore && !newRecordShown) {
+ // Set flag to true so we don't show it again this game
+ newRecordShown = true;
+ // Create a temporary notification
+ var newRecordText = new Text2('NEW RECORD!', {
+ size: 80,
+ fill: 0xFFD700 // Gold color
+ });
+ newRecordText.anchor.set(0.5, 0.5);
+ newRecordText.x = 2048 / 2;
+ newRecordText.y = 2732 / 2;
+ newRecordText.alpha = 0;
+ game.addChild(newRecordText);
+ // Animate the notification
+ tween(newRecordText, {
+ alpha: 1,
+ scaleX: 1.5,
+ scaleY: 1.5
+ }, {
+ duration: 500,
+ easing: tween.elasticOut,
+ onFinish: function onFinish() {
+ // Wait 5 seconds before fading out
+ LK.setTimeout(function () {
+ tween(newRecordText, {
+ alpha: 0
+ }, {
+ duration: 1500,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ game.removeChild(newRecordText);
+ }
+ });
+ }, 5000);
+ }
+ });
+ // Update high score
+ highScore = score;
+ highScoreTxt.setText('BEST: ' + highScore);
+ }
// 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';
@@ -1366,10 +1510,10 @@
// Update ship controls based on button state
ship.isRotatingLeft = leftButton.isPressed;
ship.isRotatingRight = rightButton.isPressed;
ship.isFiring = fireButton.isPressed;
- // Update aura ready text on fire button
- fireButton.updateAuraText(ship.auraReady);
+ // Update aura ready text on fire button with cooldown info
+ fireButton.updateAuraText(ship.auraReady, ship.remainingCooldown);
// Ship constantly moves forward, no need for isMoving toggle
// Update ship
if (ship.update()) {
if (ship.auraReady) {
@@ -1435,33 +1579,44 @@
createBullet();
}
// Ensure buttons can detect touch events when pressed
var local;
+ var touchConsumed = false;
// 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, {});
+ touchConsumed = true;
}
- // 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, {});
+ // Check fire button only if touch not already consumed
+ if (!touchConsumed) {
+ 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, {});
+ touchConsumed = true;
+ }
}
- // 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, {});
+ // Check right button only if touch not already consumed
+ if (!touchConsumed) {
+ 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, {});
+ touchConsumed = true;
+ }
}
+ // Only fire a bullet if no button was pressed and game is active
+ if (!touchConsumed && gameStarted && ship && !gameOver) {
+ createBullet();
+ }
};
// Add up handler to handle releasing buttons
game.up = function (x, y, obj) {
// Reset all button states when touch/click is released
@@ -1495,17 +1650,17 @@
}
}
// Function to destroy asteroids near the ship when aura is activated
function destroyNearbyAsteroids() {
- var auraRadius = 400; // Radius in which asteroids will be destroyed
+ var auraRadius = 350; // Slightly reduced radius for better balance
// Create a visual ring effect for the aura
var auraRing = new Container();
var auraRingGraphic = LK.getAsset('forwardButton', {
anchorX: 0.5,
anchorY: 0.5,
width: auraRadius * 2,
height: auraRadius * 2,
- tint: 0xFFFFFF
+ tint: 0x40E0D0 // Turquoise color to match AuraParticle
});
auraRingGraphic.alpha = 0.7;
auraRing.addChild(auraRingGraphic);
auraRing.x = ship.x;
@@ -1522,28 +1677,70 @@
onFinish: function onFinish() {
game.removeChild(auraRing);
}
});
+ // Flash the ship with turquoise
+ tween(ship, {
+ alpha: 0.8
+ }, {
+ duration: 200,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ tween(ship, {
+ alpha: 1
+ }, {
+ duration: 200,
+ easing: tween.easeInOut
+ });
+ }
+ });
// Check all asteroids and destroy ones within the aura radius
for (var i = asteroids.length - 1; i >= 0; i--) {
var asteroid = asteroids[i];
var dist = distance(ship.x, ship.y, asteroid.x, asteroid.y);
if (dist <= auraRadius) {
- // Add score based on asteroid size
- score += asteroid.getPoints() * 2; // Double points for aura destruction
- scoreTxt.setText('SCORE: ' + score);
- // Play the specific meme explosion sound
- var memeType = asteroid.memeType !== undefined ? asteroid.memeType : 0;
- var memeExplosionSoundId = 'meme' + memeType + 'Explosion';
- var explosionSound = LK.getSound(memeExplosionSoundId);
- if (explosionSound) {
- explosionSound.play();
+ // Different behavior based on asteroid size
+ if (asteroid.size === 2) {
+ // Large asteroids: Break into medium asteroids and score points
+ score += asteroid.getPoints();
+ scoreTxt.setText('SCORE: ' + score);
+ // Play the specific meme explosion sound
+ 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();
+ }
+ // Create medium asteroids
+ for (var k = 0; k < 2; k++) {
+ var newAsteroid = new Asteroid(1, asteroid.memeType);
+ newAsteroid.x = asteroid.x + (Math.random() - 0.5) * 50;
+ newAsteroid.y = asteroid.y + (Math.random() - 0.5) * 50;
+ asteroids.push(newAsteroid);
+ game.addChild(newAsteroid);
+ }
+ // Remove the large asteroid
+ game.removeChild(asteroid);
+ asteroids.splice(i, 1);
} else {
- LK.getSound('explosion').play();
+ // Small and medium asteroids: Destroy completely and score double points
+ score += asteroid.getPoints() * 2; // Double points for small/medium
+ scoreTxt.setText('SCORE: ' + score);
+ // Play explosion sound
+ var memeTypeSmall = asteroid.memeType !== undefined ? asteroid.memeType : 0;
+ var explosionSoundId = 'meme' + memeTypeSmall + 'Explosion';
+ var expSound = LK.getSound(explosionSoundId);
+ if (expSound) {
+ expSound.play();
+ } else {
+ LK.getSound('explosion').play();
+ }
+ // Remove the asteroid
+ game.removeChild(asteroid);
+ asteroids.splice(i, 1);
}
- // Remove the asteroid
- game.removeChild(asteroid);
- asteroids.splice(i, 1);
}
}
// Check if all asteroids are destroyed after aura
if (asteroids.length === 0) {
@@ -1556,25 +1753,25 @@
}
// Function to create particle effects when aura is activated
function createAuraEffectParticles() {
// Create a burst of particles from the ship
- for (var i = 0; i < 36; i++) {
- var angle = i * (Math.PI * 2 / 36);
- var particle = new ThrustParticle();
- // Change particle appearance for aura effect
- particle.children[0].tint = 0xFFFFFF;
- particle.children[0].width = 24;
- particle.children[0].height = 24;
+ for (var i = 0; i < 48; i++) {
+ // Increased particle count for more impressive effect
+ var angle = i * (Math.PI * 2 / 48);
+ var particle = new AuraParticle(); // Use the dedicated AuraParticle class
// Position at the ship
particle.x = ship.x;
particle.y = ship.y;
- // Set velocity in all directions
- particle.velocity.x = Math.cos(angle) * 8;
- particle.velocity.y = Math.sin(angle) * 8;
+ // Set velocity in all directions with varying speeds
+ var speed = 4 + Math.random() * 5; // Variable speeds for more organic look
+ particle.velocity.x = Math.cos(angle) * speed;
+ particle.velocity.y = Math.sin(angle) * speed;
// Add to game
thrustParticles.push(particle);
game.addChild(particle);
}
+ // Create a flash effect
+ LK.effects.flashObject(ship, 0x40E0D0, 500);
}
// Function to play outro sequence
function playOutroSequence() {
// Stop game music and start outro music
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
explosion
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
meme13Explosion
Sound effect
ballGrow
Sound effect
ballContract
Sound effect
letterAppear
Sound effect
colorTransform
Sound effect