User prompt
Make Joystick use those assets
User prompt
Change Bart's movement to use a joystick (not the ones for console, a joystick used in action mobile games)
User prompt
Low quality mode changes resolution from HD to FHD
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of undefined (setting 'resolution')' in or related to this line: 'game.renderer.resolution = 0.5; // Reduce resolution by 50%' Line Number: 3406
User prompt
Add a low quality mode that makes the game much smoother but reduces the quality to 360p
User prompt
Remove the new subweapons
User prompt
I can't buy the new subweapons: Fix that
User prompt
Add assets for new subweapons
User prompt
Now you can watch a 30 second Itchy and Scratchy show ad to skip fees in Giant Mutant rush
User prompt
Add new feature: Carnival! Play mini games to get some coins. There's an entry fee of 10 coins per mini game (Minigames: Itchy tac Scratchy: It's basically tic tac toe, nothing special; Hit the mole: hit 5 Scratchies in a row to win coins, however, if you hit an Itchy, you lose; Horse betting: Bet between Itchy's or Scratchy's horse in a race, if you bet correctly, you gain coins!) and don't forget to add assets and make them highly polished โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add new feature: Carnival! Play mini games to get some coins. There's an entry fee of 10 coins per mini game (Minigames: Itchy tac Scratchy: It's basically tic tac toe, nothing special; Hit the mole: hit 5 Scratchies in a row to win coins, however, if you hit an Itchy, you lose; Horse betting: Bet between Itchy's or Scratchy's horse in a race, if you bet correctly, you gain coins!)
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'self.statusText.style.fill = 0xFF0000;' Line Number: 1295
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'self.cells[row][col].text.style.fill = player === 1 ? 0xFF0000 : 0x0000FF;' Line Number: 1690
User prompt
Add new feature: Carnival! Play mini games to get some coins. There's an entry fee of 10 coins per mini game (Minigames: Itchy tac Scratchy: It's basically tic tac toe but with 5 rows and 5 columns; Hit the mole: hit 5 Scratchies in a row to win coins, however, if you hit an Itchy, you lose; Horse betting: Bet between Itchy's or Scratchy's horse in a race, if you bet correctly, you gain coins!) โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add 3 sub weapons of YOUR CHOICE
User prompt
Add assets for UFO striker
User prompt
I can't buy new subweapons
User prompt
I can't buy new subweapons
User prompt
Add new Sub weapons: Marge (Marge can cook Cakes that have an aura around them that heals Bart: The cakes last for roughly 10 seconds and Marge cooks them every 7.5 seconds), Toy store: Allows you to switch weapons (not subweapons) during battle! โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add Encyclopedia entries for Giant Mutants
User prompt
UFO Striker should be faster
User prompt
Add new Giant Mutant: UFO Striker! A slow moving UFO that has 30550 HP and will try to kidnap you! Being kidnapped is a 5 seconds cut scene and happens whenever the UFO touches Bart! (Abilities: Stun-Ray: a projectile that stuns Bart for 0.75 seconds: being stunned means that you can't move until the stun ends; Replica: does a random move from any random boss every 7.5 seconds; Clone: The boss makes a blue tinted Replica of itself every 100 seconds: the Replica has 10000 HP) โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
When pots explode, they should disappear
User prompt
Now pots always drop pottery sherds
User prompt
Pots now explode after 4 seconds of being created to "Reduce lag" โช๐ก Consider importing and using the following plugins: @upit/tween.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var AlienMeal = Container.expand(function () { var self = Container.call(this); var mealGraphics = self.attachAsset('alien_meal', { anchorX: 0.5, anchorY: 0.5 }); self.invincibilityDuration = 600; // 10 seconds at 60fps self.checkRadius = 80; self.lifetime = 600; // 10 seconds self.consumed = false; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; return; } // Pulsing effect to show it's active mealGraphics.alpha = 0.7 + Math.sin(LK.ticks * 0.2) * 0.3; // Check for non-cook mutants touching the meal if (!self.consumed) { for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; // Skip cook mutants - they can't consume their own meals if (enemy instanceof CookMutant) continue; var dx = enemy.x - self.x; var dy = enemy.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < self.checkRadius) { // Give invincibility to this enemy enemy.invincible = true; enemy.invincibilityTimer = self.invincibilityDuration; // Visual effect for invincibility gain LK.effects.flashObject(enemy, 0x00FFFF, 500); tween(enemy, { tint: 0x00FFFF }, { duration: 200, easing: tween.easeOut }); tween(enemy, { tint: 0xFFFFFF }, { duration: 200, easing: tween.easeIn }); // Mark meal as consumed self.consumed = true; self.shouldDestroy = true; return; } } } }; return self; }); var Bart = Container.expand(function () { var self = Container.call(this); var bartGraphics = self.attachAsset('bart_slingshot', { anchorX: 0.5, anchorY: 0.5 }); self.bartGraphics = bartGraphics; self.currentWeapon = 'slingshot'; self.updateWeaponVisual = function (weaponId) { if (self.currentWeapon === weaponId) return; self.currentWeapon = weaponId; var oldGraphics = self.bartGraphics; var newGraphics = self.attachAsset('bart_' + weaponId, { anchorX: 0.5, anchorY: 0.5 }); newGraphics.x = oldGraphics.x; newGraphics.y = oldGraphics.y; newGraphics.rotation = oldGraphics.rotation; newGraphics.alpha = oldGraphics.alpha; newGraphics.scaleX = oldGraphics.scaleX; newGraphics.scaleY = oldGraphics.scaleY; self.removeChild(oldGraphics); self.bartGraphics = newGraphics; }; self.maxHealth = 100; self.health = self.maxHealth; self.level = 1; self.xp = 0; self.xpToNext = 100; self.damage = 10; self.fireRate = 30; self.fireTimer = 0; self.coins = 0; self.stunned = false; self.stunnedTimer = 0; self.takeDamage = function (damage) { self.health -= damage; LK.getSound('hut').play(); LK.effects.flashObject(self, 0xFF0000, 500); if (healthBarFill) { healthBarFill.scaleX = Math.max(0, self.health / self.maxHealth); } if (self.health <= 0) { try { storage.coins = self.coins; } catch (e) { console.log('Could not save coins on game over:', e); } LK.showGameOver(); } }; self.gainXP = function (amount) { self.xp += amount; while (self.xp >= self.xpToNext) { self.xp -= self.xpToNext; self.level++; self.xpToNext = self.level * 100; self.maxHealth += 20; self.health = self.maxHealth; if (healthBarFill) { healthBarFill.scaleX = 1; } self.damage += 5; self.fireRate = Math.max(10, self.fireRate - 2); LK.getSound('levelup').play(); LK.effects.flashScreen(0xFFFF00, 300); } }; self.update = function () { if (self.stunned) { self.stunnedTimer--; if (self.stunnedTimer <= 0) { self.stunned = false; } } self.fireTimer--; }; return self; }); var Boss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 500; self.health = self.maxHealth; self.speed = 1; self.xpValue = 100; self.coinChance = 1; self.powerupChance = 0.5; self.invincible = true; self.invincibilityTimer = 180; // 3 seconds at 60fps var healthBarBg = self.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, y: -100 }); self.healthBarFill = self.attachAsset('healthbar_fill', { anchorX: 0, anchorY: 0.5, x: -100, y: -100 }); self.takeDamage = function (damage) { if (self.invincible) return; // No damage during invincibility self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 200); self.healthBarFill.scaleX = Math.max(0, self.health / self.maxHealth); if (self.health <= 0) { self.shouldDestroy = true; LK.getSound('hit').play(); } }; self.update = function () { if (self.invincible) { self.invincibilityTimer--; bossGraphics.alpha = 0.5 + Math.sin(LK.ticks * 0.3) * 0.3; // Flashing effect if (self.invincibilityTimer <= 0) { self.invincible = false; bossGraphics.alpha = 1; // Reset to full opacity } } if (bart) { var dx = bart.x - self.x; var dy = bart.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } } }; return self; }); var BowlingBall = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('bowling_ball', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.damage = 15; self.targetX = 0; self.targetY = 0; self.directionSet = false; self.velocityX = 0; self.velocityY = 0; self.lifetime = 180; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; return; } if (!self.directionSet) { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.velocityX = dx / dist * self.speed; self.velocityY = dy / dist * self.speed; } self.directionSet = true; } self.x += self.velocityX; self.y += self.velocityY; self.rotation += 0.2; }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 10; self.speed = 15; self.target = null; self.lifetime = 60; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; return; } if (self.target && !self.target.destroyed) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } } else { self.y -= self.speed; } }; return self; }); var Coin = Container.expand(function () { var self = Container.call(this); var coinGraphics = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.value = 5; self.lifetime = 300; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; } self.rotation += 0.05; }; return self; }); var Concert = Container.expand(function () { var self = Container.call(this); var concertGraphics = self.attachAsset('concert', { anchorX: 0.5, anchorY: 0.5 }); // Band members self.drummer = self.attachAsset('drummer', { anchorX: 0.5, anchorY: 0.5, x: -250, y: -100 }); self.vocal = self.attachAsset('vocal', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -120 }); self.rocker = self.attachAsset('rocker', { anchorX: 0.5, anchorY: 0.5, x: 250, y: -100 }); self.maxHealth = 25750; self.health = self.maxHealth; self.speed = 0; // Cannot move self.xpValue = 2500; self.coinChance = 1; self.powerupChance = 1; self.isInstantKillBoss = true; // Special flag to not destroy on contact // Timers for abilities self.drummerTimer = 225; // 3.75 seconds self.swearTimer = 600; // 10 seconds self.rockMusicTimer = 300; // 5 seconds self.damageMultiplier = 1.0; // Starts at 100% damage self.maxDamageMultiplier = 1.9; // Max 190% (90% increase) // Regular mutant spawn timer self.regularSpawnTimer = 120; // 2 seconds // New attack timers self.noisyDrummingTimer = 600; // 10 seconds self.risingRockstarsTimer = 900; // 15 seconds self.stereoSoundsTimer = 3600; // 60 seconds // Health bar var healthBarBg = self.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, y: -350, scaleX: 2 }); self.healthBarFill = self.attachAsset('healthbar_fill', { anchorX: 0, anchorY: 0.5, x: -200, y: -350, scaleX: 2 }); self.takeDamage = function (damage) { self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 200); self.healthBarFill.scaleX = Math.max(0, self.health / self.maxHealth) * 2; if (self.health <= 0) { self.shouldDestroy = true; LK.getSound('hit').play(); // Drop tons of coins for (var i = 0; i < 30; i++) { spawnItem(self.x + (Math.random() - 0.5) * 400, self.y + (Math.random() - 0.5) * 300, 'coin'); } } }; self.update = function () { // Update timers self.drummerTimer--; self.swearTimer--; self.rockMusicTimer--; self.regularSpawnTimer--; self.noisyDrummingTimer--; self.risingRockstarsTimer--; self.stereoSoundsTimer--; // Excessive Drumming - shoot 3 soundwaves in spread if (self.drummerTimer <= 0 && bart) { for (var i = -1; i <= 1; i++) { var soundWave = new SoundWave(); soundWave.x = self.x + self.drummer.x; soundWave.y = self.y + self.drummer.y; // Calculate spread angle var angle = Math.atan2(bart.y - soundWave.y, bart.x - soundWave.x); angle += i * 0.3; // 0.3 radians spread soundWave.targetX = soundWave.x + Math.cos(angle) * 1000; soundWave.targetY = soundWave.y + Math.sin(angle) * 1000; soundWave.damage = 15 * self.damageMultiplier; // Slightly more damage than regular enemyProjectiles.push(soundWave); game.addChild(soundWave); } self.drummerTimer = 225; // Reset to 3.75 seconds LK.effects.flashObject(self.drummer, 0xFF00FF, 500); // Drummer animation tween(self.drummer, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut }); tween(self.drummer, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); } // Noisy Drumming - shoot 10 sound waves really fast if (self.noisyDrummingTimer <= 0 && bart) { for (var i = 0; i < 10; i++) { // Delay each sound wave slightly for rapid fire effect LK.setTimeout(function (index) { return function () { if (bart && !self.destroyed) { var soundWave = new SoundWave(); soundWave.x = self.x + self.drummer.x; soundWave.y = self.y + self.drummer.y; // Random spread pattern var angle = Math.atan2(bart.y - soundWave.y, bart.x - soundWave.x); angle += (Math.random() - 0.5) * 0.8; // Random spread soundWave.targetX = soundWave.x + Math.cos(angle) * 1000; soundWave.targetY = soundWave.y + Math.sin(angle) * 1000; soundWave.damage = 20 * self.damageMultiplier; // More damage soundWave.speed = 10; // Faster enemyProjectiles.push(soundWave); game.addChild(soundWave); LK.effects.flashObject(self.drummer, 0xFFFF00, 100); } }; }(i), i * 100); // 100ms between each wave } self.noisyDrummingTimer = 600; // Reset to 10 seconds } // Swear-fest - increase damage multiplier if (self.swearTimer <= 0) { if (self.damageMultiplier < self.maxDamageMultiplier) { self.damageMultiplier += 0.15; // 15% increase self.damageMultiplier = Math.min(self.damageMultiplier, self.maxDamageMultiplier); } self.swearTimer = 600; // Reset to 10 seconds LK.effects.flashScreen(0xFF0000, 300); LK.effects.flashObject(self.vocal, 0xFF0000, 1000); // Vocal animation tween(self.vocal, { scaleX: 1.5, scaleY: 1.5 }, { duration: 300, easing: tween.easeOut }); tween(self.vocal, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeIn }); // Update all enemies' damage for (var i = 0; i < enemies.length; i++) { if (enemies[i] !== self) { enemies[i].damageMultiplier = self.damageMultiplier; } } } // Rock Music - make all mutants faster if (self.rockMusicTimer <= 0) { for (var i = 0; i < enemies.length; i++) { if (enemies[i] !== self && !enemies[i].rockerBoosted) { enemies[i].originalSpeed = enemies[i].speed; enemies[i].speed *= 1.3; // 30% speed boost enemies[i].rockerBoosted = true; enemies[i].rockerBoostTimer = 300; // 5 seconds LK.effects.flashObject(enemies[i], 0x00FF00, 500); } } self.rockMusicTimer = 300; // Reset to 5 seconds LK.effects.flashObject(self.rocker, 0x00FF00, 1000); // Rocker animation tween(self.rocker, { scaleX: 1.4, scaleY: 1.4, rotation: 0.3 }, { duration: 250, easing: tween.easeOut }); tween(self.rocker, { scaleX: 1, scaleY: 1, rotation: 0 }, { duration: 250, easing: tween.easeIn }); } // Rising Rockstars - summon band member mutants if (self.risingRockstarsTimer <= 0) { // Spawn Drummer Mutant var drummer = new DrummerMutant(); drummer.x = self.x - 300; drummer.y = self.y + 300; drummer.invincible = false; drummer.invincibilityTimer = 0; drummer.damageMultiplier = self.damageMultiplier; enemies.push(drummer); game.addChild(drummer); // Spawn Vocal Mutant var vocal = new VocalMutant(); vocal.x = self.x; vocal.y = self.y + 350; vocal.invincible = false; vocal.invincibilityTimer = 0; vocal.damageMultiplier = self.damageMultiplier; enemies.push(vocal); game.addChild(vocal); // Spawn Rocker Mutant var rocker = new RockerMutant(); rocker.x = self.x + 300; rocker.y = self.y + 300; rocker.invincible = false; rocker.invincibilityTimer = 0; rocker.damageMultiplier = self.damageMultiplier; enemies.push(rocker); game.addChild(rocker); self.risingRockstarsTimer = 900; // Reset to 15 seconds LK.effects.flashScreen(0xFF00FF, 500); // Animation for summoning tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 300, easing: tween.easeOut }); tween(self, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeIn }); } // Rock fans - spawn regular mutants continuously if (self.regularSpawnTimer <= 0) { var mutant = new Mutant(); mutant.x = self.x + (Math.random() - 0.5) * 600; mutant.y = self.y + 200; // Apply current damage multiplier mutant.damageMultiplier = self.damageMultiplier; // Scale mutant stats based on wave mutant.speed = 2 + wave * 0.3; mutant.maxHealth = 30 + wave * 15; mutant.health = mutant.maxHealth; mutant.xpValue = 10 + wave * 2; mutant.invincible = false; mutant.invincibilityTimer = 0; enemies.push(mutant); game.addChild(mutant); self.regularSpawnTimer = 120; // Reset to 2 seconds } // Handle rocker boost timers for all enemies for (var i = 0; i < enemies.length; i++) { if (enemies[i].rockerBoosted && enemies[i].rockerBoostTimer) { enemies[i].rockerBoostTimer--; if (enemies[i].rockerBoostTimer <= 0) { enemies[i].speed = enemies[i].originalSpeed; enemies[i].rockerBoosted = false; } } } // Stereo Sounds - all band members shoot homing instakill soundwaves if (self.stereoSoundsTimer <= 0 && bart) { // Warning flash LK.effects.flashScreen(0xFF0000, 1000); // Drummer shoots homing soundwave var drummerWave = new SoundWave(); drummerWave.x = self.x + self.drummer.x; drummerWave.y = self.y + self.drummer.y; drummerWave.damage = 9999; // Instakill drummerWave.speed = 4; // Slower but homing drummerWave.isHoming = true; // Mark as homing drummerWave.target = bart; enemyProjectiles.push(drummerWave); game.addChild(drummerWave); // Vocal shoots homing soundwave var vocalWave = new SoundWave(); vocalWave.x = self.x + self.vocal.x; vocalWave.y = self.y + self.vocal.y; vocalWave.damage = 9999; // Instakill vocalWave.speed = 4; // Slower but homing vocalWave.isHoming = true; // Mark as homing vocalWave.target = bart; enemyProjectiles.push(vocalWave); game.addChild(vocalWave); // Rocker shoots homing soundwave var rockerWave = new SoundWave(); rockerWave.x = self.x + self.rocker.x; rockerWave.y = self.y + self.rocker.y; rockerWave.damage = 9999; // Instakill rockerWave.speed = 4; // Slower but homing rockerWave.isHoming = true; // Mark as homing rockerWave.target = bart; enemyProjectiles.push(rockerWave); game.addChild(rockerWave); self.stereoSoundsTimer = 3600; // Reset to 60 seconds // Epic animation for all band members tween(self.drummer, { scaleX: 2, scaleY: 2, tint: 0xFF0000 }, { duration: 500, easing: tween.easeOut }); tween(self.vocal, { scaleX: 2, scaleY: 2, tint: 0xFF0000 }, { duration: 500, easing: tween.easeOut }); tween(self.rocker, { scaleX: 2, scaleY: 2, tint: 0xFF0000 }, { duration: 500, easing: tween.easeOut }); // Reset after animation tween(self.drummer, { scaleX: 1, scaleY: 1, tint: 0xFFFFFF }, { duration: 500, easing: tween.easeIn }); tween(self.vocal, { scaleX: 1, scaleY: 1, tint: 0xFFFFFF }, { duration: 500, easing: tween.easeIn }); tween(self.rocker, { scaleX: 1, scaleY: 1, tint: 0xFFFFFF }, { duration: 500, easing: tween.easeIn }); } // Pulsing effect for band members self.drummer.y = -100 + Math.sin(LK.ticks * 0.1) * 10; self.vocal.y = -120 + Math.sin(LK.ticks * 0.15) * 8; self.rocker.y = -100 + Math.sin(LK.ticks * 0.12) * 12; }; return self; }); var CookMutant = Container.expand(function () { var self = Container.call(this); var mutantGraphics = self.attachAsset('cook_mutant', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 60; self.health = self.maxHealth; self.speed = 1.5; self.xpValue = 30; self.coinChance = 0.5; self.powerupChance = 0.2; self.cookTimer = 0; self.cookInterval = 240; // 4 seconds self.invincible = true; self.invincibilityTimer = 180; // 3 seconds at 60fps self.takeDamage = function (damage) { if (self.invincible) return; // No damage during invincibility self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 200); if (self.health <= 0) { self.shouldDestroy = true; LK.getSound('hit').play(); } }; self.update = function () { if (self.invincible) { self.invincibilityTimer--; mutantGraphics.alpha = 0.5 + Math.sin(LK.ticks * 0.3) * 0.3; // Flashing effect if (self.invincibilityTimer <= 0) { self.invincible = false; mutantGraphics.alpha = 1; // Reset to full opacity } } self.cookTimer--; if (bart) { var dx = bart.x - self.x; var dy = bart.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Cook alien meals when close to other enemies if (self.cookTimer <= 0) { var nearbyEnemies = []; for (var i = 0; i < enemies.length; i++) { if (enemies[i] !== self) { var eDx = enemies[i].x - self.x; var eDy = enemies[i].y - self.y; var eDist = Math.sqrt(eDx * eDx + eDy * eDy); if (eDist < 300) { nearbyEnemies.push(enemies[i]); } } } if (nearbyEnemies.length > 0) { // Create an alien meal var meal = new AlienMeal(); meal.x = self.x + (Math.random() - 0.5) * 100; meal.y = self.y + (Math.random() - 0.5) * 100; alienMeals.push(meal); game.addChild(meal); self.cookTimer = self.cookInterval; LK.effects.flashObject(self, 0x00FF00, 300); } } } }; return self; }); var Dart = Container.expand(function () { var self = Container.call(this); var dartGraphics = self.attachAsset('dart', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 10; self.speed = 20; self.target = null; self.lifetime = 60; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; return; } if (self.target && !self.target.destroyed) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; self.rotation = Math.atan2(dy, dx) + Math.PI / 2; // Point towards target } } else { self.y -= self.speed; } }; return self; }); var DrummerMutant = Container.expand(function () { var self = Container.call(this); var mutantGraphics = self.attachAsset('drummer_mutant', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 150; self.health = self.maxHealth; self.speed = 0.8; self.xpValue = 45; self.coinChance = 0.6; self.powerupChance = 0.3; self.shootTimer = 0; self.shootInterval = 90; // 1.5 seconds base self.invincible = true; self.invincibilityTimer = 180; self.takeDamage = function (damage) { if (self.invincible) return; self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 200); if (self.health <= 0) { self.shouldDestroy = true; LK.getSound('hit').play(); } }; self.update = function () { if (self.invincible) { self.invincibilityTimer--; mutantGraphics.alpha = 0.5 + Math.sin(LK.ticks * 0.3) * 0.3; if (self.invincibilityTimer <= 0) { self.invincible = false; mutantGraphics.alpha = 1; } } self.shootTimer--; // Check if Vocal is on screen to double attack speed var vocalOnScreen = false; for (var i = 0; i < enemies.length; i++) { if (enemies[i] instanceof VocalMutant && enemies[i] !== self) { vocalOnScreen = true; break; } } var currentInterval = vocalOnScreen ? self.shootInterval / 2 : self.shootInterval; if (bart) { var dx = bart.x - self.x; var dy = bart.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Shoot sound waves at Bart (infinite range) if (self.shootTimer <= 0) { var soundWave = new SoundWave(); soundWave.x = self.x; soundWave.y = self.y; soundWave.targetX = bart.x; soundWave.targetY = bart.y; enemyProjectiles.push(soundWave); game.addChild(soundWave); self.shootTimer = currentInterval; // Visual effect when shooting LK.effects.flashObject(self, 0xFF00FF, 300); } } }; return self; }); var Encyclopedia = Container.expand(function () { var self = Container.call(this); // Background var bg = self.attachAsset('encyclopedia', { anchorX: 0.5, anchorY: 0.5 }); // Title self.titleText = new Text2('ENCYCLOPEDIA', { size: 80, fill: 0xFFFF00 }); self.titleText.anchor.set(0.5, 0.5); self.titleText.y = -300; self.addChild(self.titleText); // Page content container self.pageContainer = new Container(); self.addChild(self.pageContainer); // Close button var closeButton = self.attachAsset('info_button', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 350 }); var closeText = new Text2('CLOSE', { size: 40, fill: 0xFFFFFF }); closeText.anchor.set(0.5, 0.5); closeText.y = 350; self.addChild(closeText); // Navigation buttons var prevButton = self.attachAsset('info_button', { anchorX: 0.5, anchorY: 0.5, x: -200, y: 280, scaleX: 0.8 }); var prevText = new Text2('< PREV', { size: 35, fill: 0xFFFFFF }); prevText.anchor.set(0.5, 0.5); prevText.x = -200; prevText.y = 280; self.addChild(prevText); var nextButton = self.attachAsset('info_button', { anchorX: 0.5, anchorY: 0.5, x: 200, y: 280, scaleX: 0.8 }); var nextText = new Text2('NEXT >', { size: 35, fill: 0xFFFFFF }); nextText.anchor.set(0.5, 0.5); nextText.x = 200; nextText.y = 280; self.addChild(nextText); // Page indicator self.pageIndicator = new Text2('Page 1/1', { size: 30, fill: 0xAAAAAA }); self.pageIndicator.anchor.set(0.5, 0.5); self.pageIndicator.y = 320; self.addChild(self.pageIndicator); self.currentPage = 0; self.pages = []; // Initialize encyclopedia content self.initializePages = function () { self.pages = [ // Enemies { title: "MUTANT", content: "Basic enemy that moves towards Bart.\nHealth: 30 + (wave ร 15)\nSpeed: 2 + (wave ร 0.3)\nXP Value: 10 + (wave ร 2)\nAppears from: Wave 1" }, { title: "FAST MUTANT", content: "Quick enemy that rushes at Bart.\nHealth: 15 + (wave ร 8)\nSpeed: 4 + (wave ร 0.4)\nXP Value: 15 + (wave ร 2)\nAppears from: Wave 2" }, { title: "SHOOTER MUTANT", content: "Fires bowling balls at Bart.\nHealth: 50 + (wave ร 10)\nSpeed: 1.5 + (wave ร 0.2)\nXP Value: 25 + (wave ร 3)\nAppears from: Wave 7" }, { title: "COOK MUTANT", content: "Creates alien meals that grant invincibility.\nHealth: 60 + (wave ร 10)\nSpeed: 1.5 + (wave ร 0.2)\nXP Value: 30 + (wave ร 4)\nAppears from: Wave 6" }, { title: "POET MUTANT", content: "Summons other mutants to help!\nHealth: 80 + (wave ร 12)\nSpeed: 1 + (wave ร 0.15)\nXP Value: 40 + (wave ร 5)\nAppears from: Wave 8" }, { title: "SAMURAI MUTANT", content: "Has a spinning katana that reflects projectiles.\nHealth: 100 + (wave ร 15)\nSpeed: 1.2 + (wave ร 0.2)\nXP Value: 50 + (wave ร 6)\nAppears from: Wave 8" }, { title: "DRUMMER MUTANT", content: "High HP, shoots sound waves. Attack speed doubles if Vocal is present.\nHealth: 150 + (wave ร 20)\nSpeed: 0.8 + (wave ร 0.1)\nXP Value: 45 + (wave ร 5)\nAppears from: Wave 13" }, { title: "VOCAL MUTANT", content: "Fast with low HP. Damage doubles if Rocker is present.\nHealth: 40 + (wave ร 10)\nSpeed: 5 + (wave ร 0.5)\nXP Value: 35 + (wave ร 4)\nAppears from: Wave 13" }, { title: "ROCKER MUTANT", content: "Boosts ally speed for 5 seconds. Enhanced boost if Drummer is present.\nHealth: 70 + (wave ร 15)\nSpeed: 2.5 + (wave ร 0.3)\nXP Value: 40 + (wave ร 5)\nAppears from: Wave 13" }, { title: "BOSS", content: "Powerful enemy that appears every 5 waves.\nHealth: 500 + ((wave-5) ร 200)\nSpeed: 1 + (wave ร 0.1)\nXP Value: 100 + (wave ร 20)\nAppears: Waves 5, 10, 15, 20..." }, // Weapons { title: "SLINGSHOT", content: "The default weapon.\nDamage: 10\nFire Rate: Medium\nProjectiles: 1\nCost: FREE (Starting weapon)" }, { title: "DART GUN", content: "High damage, slow fire rate.\nDamage: 50\nFire Rate: Slow\nProjectiles: 1\nCost: 100 coins" }, { title: "SCATTERSHOT", content: "Shoots peanuts that split.\nDamage: 15 (5 per split)\nFire Rate: Medium-Slow\nProjectiles: 1โ3\nCost: 250 coins" }, { title: "DUCKY TRIPLE", content: "Shoots 3 projectiles in a spread.\nDamage: 25\nFire Rate: Medium\nProjectiles: 3\nCost: 500 coins" }, { title: "SPRAYCAN", content: "Stuns enemies on hit.\nDamage: 8\nFire Rate: Slow\nStun: 1.2 seconds\nCost: 750 coins" }, { title: "KRUSTY'S FLOWER", content: "Water beam with rapid fire.\nDamage: 3\nFire Rate: Very Fast\nProjectiles: 1 (continuous)\nCost: 1000 coins" }, { title: "TOY BOW", content: "Bart is now armed with a bow! Lower damage but 100% more XP.\nDamage: 12\nFire Rate: Medium-Fast\nSpecial: Double XP from all enemies\nCost: 600 coins" }, { title: "POT-A-BOMB", content: "Bart holds a pot! Area damage with explosive potential.\nDamage: 35 (area effect)\nFire Rate: Slow\nSpecial: 30% chance to split into 4 diagonal shards\nCost: 800 coins" }, // Subweapons { title: "SANTA'S LITTLE HELPER", content: "Fast ally that bites enemies.\nDamage: 15 per bite\nSpeed: 12\nSight Range: 800 pixels\nCost: 750 coins" }, { title: "KRUSTY BURGER SHOP", content: "Spawns powerups periodically.\nSpawn Rate: Every 15 seconds\nPowerup Types: Damage/Fire Rate\nCost: 1200 coins" }, { title: "SNOWBALL II", content: "Sneaky cat that distracts enemies.\nDistraction Range: 600 pixels\nReduces invincibility by 50%\nSpeed: 8\nCost: 900 coins" }, { title: "MAGGIE'S PACIFIER", content: "Shoots pacifiers at random enemies.\nDamage: 20 per hit\nFire Rate: Every 1.5 seconds\nSleep Effect: 2 seconds in 150px radius\nCost: 1000 coins" }, { title: "LISA'S SAXOPHONE", content: "Creates protective sound barriers.\nBarrier Health: 150 HP\nBarrier Duration: 10 seconds\nBlocks enemy projectiles\nSlows enemies by 70%\nCost: 1500 coins" }, { title: "MARGE'S VACUUM", content: "Sucks in items automatically.\nSuction Range: 400 pixels\nCleanup Blast: Every 5 seconds\nBlast Damage: 25 to nearby enemies\nCost: 1100 coins" }, // Game Features { title: "POWER-UPS", content: "Dropped by enemies randomly.\nโข Damage Boost: +5 damage\nโข Fire Rate: -5 fire rate delay\nDrop chance varies by enemy type." }, { title: "COINS", content: "Currency for buying weapons.\nValue: 5 coins each\nDropped by defeated enemies.\nCoins are saved between games!" }, { title: "ALIEN MEALS", content: "Created by Cook Mutants.\nGrants 10 seconds invincibility.\nCan be destroyed by shooting.\nOnly non-cook mutants can consume." }, { title: "INVINCIBILITY", content: "Enemy spawn protection:\nโข Waves 1-9: 3 seconds\nโข Waves 10-14: 1.5 seconds\nโข Wave 15+: No invincibility" }, { title: "LEVELING SYSTEM", content: "Gain XP from defeating enemies.\nEach level grants:\nโข +20 max health\nโข +5 damage\nโข -2 fire rate delay\nFull heal on level up!" }, { title: "WAVE PROGRESSION", content: "Infinite waves with scaling difficulty.\nBosses appear every 5 waves.\nEnemies get stronger each wave.\nNew enemy types unlock at higher waves." }]; }; self.showPage = function (pageIndex) { // Clear previous content self.pageContainer.removeChildren(); if (pageIndex >= 0 && pageIndex < self.pages.length) { var page = self.pages[pageIndex]; // Page title var pageTitle = new Text2(page.title, { size: 60, fill: 0x00FFFF }); pageTitle.anchor.set(0.5, 0.5); pageTitle.y = -200; self.pageContainer.addChild(pageTitle); // Page content var lines = page.content.split('\n'); var yOffset = -100; for (var i = 0; i < lines.length; i++) { var contentLine = new Text2(lines[i], { size: 35, fill: 0xFFFFFF }); contentLine.anchor.set(0.5, 0.5); contentLine.y = yOffset; self.pageContainer.addChild(contentLine); yOffset += 45; } self.currentPage = pageIndex; self.pageIndicator.setText('Page ' + (pageIndex + 1) + '/' + self.pages.length); } }; self.nextPage = function () { if (self.currentPage < self.pages.length - 1) { self.showPage(self.currentPage + 1); } }; self.prevPage = function () { if (self.currentPage > 0) { self.showPage(self.currentPage - 1); } }; self.initializePages(); self.showPage(0); return self; }); var FastMutant = Container.expand(function () { var self = Container.call(this); var mutantGraphics = self.attachAsset('fast_mutant', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 15; self.health = self.maxHealth; self.speed = 4; self.xpValue = 15; self.coinChance = 0.2; self.powerupChance = 0.05; self.invincible = true; self.invincibilityTimer = 180; // 3 seconds at 60fps self.takeDamage = function (damage) { if (self.invincible) return; // No damage during invincibility self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 200); if (self.health <= 0) { self.shouldDestroy = true; LK.getSound('hit').play(); } }; self.update = function () { // Handle sleep effect if (self.sleeping) { self.sleepTimer--; if (self.sleepTimer <= 0) { self.sleeping = false; self.speed = self.originalSpeed; tween(self, { alpha: 1 }, { duration: 200, easing: tween.easeIn }); } return; // Don't move when sleeping } if (self.invincible) { self.invincibilityTimer--; mutantGraphics.alpha = 0.5 + Math.sin(LK.ticks * 0.3) * 0.3; // Flashing effect if (self.invincibilityTimer <= 0) { self.invincible = false; mutantGraphics.alpha = 1; // Reset to full opacity } } var target = self.distractedBy || bart; if (target) { var dx = target.x - self.x; var dy = target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } if (self.distractedBy && dist < 100) { self.distractedBy = null; } } }; return self; }); var FlowerBeam = Container.expand(function () { var self = Container.call(this); var beamGraphics = self.attachAsset('flower_beam', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 10; self.speed = 25; self.target = null; self.lifetime = 60; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; return; } if (self.target && !self.target.destroyed) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; self.rotation = Math.atan2(dy, dx) + Math.PI / 2; // Point towards target } } else { self.y -= self.speed; } }; return self; }); var KrustyShop = Container.expand(function () { var self = Container.call(this); var shopGraphics = self.attachAsset('krusty_shop', { anchorX: 0.5, anchorY: 0.5 }); self.powerupTimer = 900; // 15 seconds at 60fps self.update = function () { self.powerupTimer--; // Pulse effect when close to spawning powerup if (self.powerupTimer < 60) { shopGraphics.alpha = 0.5 + Math.sin(LK.ticks * 0.5) * 0.5; } else { shopGraphics.alpha = 1; } if (self.powerupTimer <= 0) { // Spawn powerup spawnItem(self.x, self.y, 'powerup'); self.powerupTimer = 900; // Reset timer LK.effects.flashObject(self, 0xFFFF00, 500); } // Gentle floating animation self.y += Math.sin(LK.ticks * 0.03) * 0.3; }; return self; }); var LeaderBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('leader_bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.damage = 90; self.targetX = 0; self.targetY = 0; self.directionSet = false; self.velocityX = 0; self.velocityY = 0; self.lifetime = 180; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; return; } if (!self.directionSet) { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.velocityX = dx / dist * self.speed; self.velocityY = dy / dist * self.speed; } self.directionSet = true; } self.x += self.velocityX; self.y += self.velocityY; self.rotation += 0.15; }; return self; }); var LisaSaxophone = Container.expand(function () { var self = Container.call(this); var saxGraphics = self.attachAsset('sound_wave', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, tint: 0xFFD700 // Gold color for saxophone }); self.barrierTimer = 0; self.barrierInterval = 480; // 8 seconds self.barriers = []; self.update = function () { self.barrierTimer--; // Gentle swaying animation self.rotation = Math.sin(LK.ticks * 0.05) * 0.1; if (self.barrierTimer <= 0) { // Create sound barrier var barrier = new SoundBarrier(); barrier.x = self.x; barrier.y = self.y - 100; self.barriers.push(barrier); game.addChild(barrier); self.barrierTimer = self.barrierInterval; // Visual effect when creating barrier LK.effects.flashObject(self, 0xFFD700, 500); tween(saxGraphics, { scaleX: 1.5, scaleY: 1.5 }, { duration: 300, easing: tween.easeOut }); tween(saxGraphics, { scaleX: 0.8, scaleY: 0.8 }, { duration: 300, easing: tween.easeIn }); } // Clean up destroyed barriers self.barriers = self.barriers.filter(function (barrier) { return !barrier.destroyed && !barrier.shouldDestroy; }); }; return self; }); var MaggiePacifier = Container.expand(function () { var self = Container.call(this); var pacifierGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, tint: 0xFF69B4 // Pink tint for pacifier }); self.shootTimer = 0; self.shootInterval = 90; // 1.5 seconds self.projectileSpeed = 8; self.projectileDamage = 20; self.update = function () { self.shootTimer--; // Bobbing animation self.y += Math.sin(LK.ticks * 0.1) * 0.5; if (self.shootTimer <= 0 && enemies.length > 0) { // Find random enemy to shoot at var targetEnemy = enemies[Math.floor(Math.random() * enemies.length)]; if (targetEnemy) { var pacifier = new PacifierProjectile(); pacifier.x = self.x; pacifier.y = self.y; pacifier.target = targetEnemy; pacifier.damage = self.projectileDamage; bullets.push(pacifier); game.addChild(pacifier); self.shootTimer = self.shootInterval; // Visual effect when shooting tween(pacifierGraphics, { scaleX: 1.3, scaleY: 1.3 }, { duration: 100, easing: tween.easeOut }); tween(pacifierGraphics, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.easeIn }); } } }; return self; }); var MargeVacuum = Container.expand(function () { var self = Container.call(this); var vacuumGraphics = self.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 1.2, tint: 0x4B0082 // Indigo color for vacuum }); // Vacuum nozzle var nozzle = self.attachAsset('healthbar_fill', { anchorX: 0, anchorY: 0.5, x: 40, y: 0, scaleX: 0.4, scaleY: 0.3, tint: 0x808080 }); self.suctionRadius = 400; self.suctionPower = 8; self.cleanupTimer = 0; self.cleanupInterval = 300; // 5 seconds self.isActive = false; self.update = function () { // Vacuum animation vacuumGraphics.rotation = Math.sin(LK.ticks * 0.1) * 0.05; nozzle.scaleY = 0.3 + Math.sin(LK.ticks * 0.2) * 0.05; // Suck in items for (var i = 0; i < items.length; i++) { var item = items[i]; var dx = self.x - item.x; var dy = self.y - item.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < self.suctionRadius && dist > 20) { // Pull items towards vacuum item.x += dx / dist * self.suctionPower; item.y += dy / dist * self.suctionPower; // Speed up spinning when being sucked item.rotation += 0.3; if (!self.isActive) { self.isActive = true; // Start vacuum sound effect tween(vacuumGraphics, { scaleX: 1, scaleY: 1.4 }, { duration: 200, easing: tween.easeOut }); } } } // Also pull in pottery shards from destroyed pots for (var i = 0; i < bullets.length; i++) { if (bullets[i] instanceof PotteryShard) { var shard = bullets[i]; var dx = self.x - shard.x; var dy = self.y - shard.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < self.suctionRadius && dist > 20) { shard.x += dx / dist * (self.suctionPower * 0.5); shard.y += dy / dist * (self.suctionPower * 0.5); } } } if (self.isActive && items.length === 0) { self.isActive = false; tween(vacuumGraphics, { scaleX: 0.8, scaleY: 1.2 }, { duration: 200, easing: tween.easeIn }); } // Periodic cleanup blast self.cleanupTimer--; if (self.cleanupTimer <= 0) { self.performCleanupBlast(); self.cleanupTimer = self.cleanupInterval; } }; self.performCleanupBlast = function () { // Visual effect LK.effects.flashObject(self, 0xFFFFFF, 500); // Create expanding ring effect var ring = game.attachAsset('sound_wave', { anchorX: 0.5, anchorY: 0.5, x: self.x, y: self.y, scaleX: 0.1, scaleY: 0.1, tint: 0x4B0082, alpha: 0.8 }); tween(ring, { scaleX: 6, scaleY: 6, alpha: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { ring.destroy(); } }); // Damage and push back nearby enemies for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var dx = enemy.x - self.x; var dy = enemy.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 300) { enemy.takeDamage(25); // Push enemies away if (dist > 0) { enemy.x += dx / dist * 100; enemy.y += dy / dist * 100; } } } }; return self; }); var Mutant = Container.expand(function () { var self = Container.call(this); var mutantGraphics = self.attachAsset('mutant', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 30; self.health = self.maxHealth; self.speed = 2; self.xpValue = 10; self.coinChance = 0.3; self.powerupChance = 0.1; self.invincible = true; self.invincibilityTimer = 180; // 3 seconds at 60fps self.stunned = false; self.stunnedTimer = 0; self.takeDamage = function (damage, stunDuration) { if (self.invincible) return; // No damage during invincibility self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 200); if (stunDuration && stunDuration > 0) { self.stunned = true; self.stunnedTimer = stunDuration; } if (self.health <= 0) { self.shouldDestroy = true; LK.getSound('hit').play(); } }; self.update = function () { // Handle sleep effect if (self.sleeping) { self.sleepTimer--; if (self.sleepTimer <= 0) { self.sleeping = false; self.speed = self.originalSpeed; tween(self, { alpha: 1 }, { duration: 200, easing: tween.easeIn }); } return; // Don't move when sleeping } if (self.stunned) { self.stunnedTimer--; mutantGraphics.tint = 0x00FF00; // Green tint when stunned if (self.stunnedTimer <= 0) { self.stunned = false; mutantGraphics.tint = 0xFFFFFF; } return; // Don't move when stunned } if (self.invincible) { self.invincibilityTimer--; mutantGraphics.alpha = 0.5 + Math.sin(LK.ticks * 0.3) * 0.3; // Flashing effect if (self.invincibilityTimer <= 0) { self.invincible = false; mutantGraphics.alpha = 1; // Reset to full opacity } } // Check if distracted by Snowball II var target = self.distractedBy || bart; if (target) { var dx = target.x - self.x; var dy = target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Reset distraction after getting close if (self.distractedBy && dist < 100) { self.distractedBy = null; } } }; return self; }); var MutantLeader = Container.expand(function () { var self = Container.call(this); var leaderGraphics = self.attachAsset('mutant_leader', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); self.maxHealth = 20000; self.health = self.maxHealth; self.speed = 3; self.xpValue = 1000; self.coinChance = 1; self.coinValue = 100; // Drops 100 coins self.powerupChance = 1; self.isInstantKillBoss = true; // Special flag to not destroy on contact self.rageMode = false; self.originalSpeed = self.speed; // Timers for abilities self.callForHelpTimer = 600; // 10 seconds self.gunAttackTimer = 300; // 5 seconds self.whistleTimer = 1200; // 20 seconds // Health bar var healthBarBg = self.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, y: -150, scaleX: 1.5 }); self.healthBarFill = self.attachAsset('healthbar_fill', { anchorX: 0, anchorY: 0.5, x: -150, y: -150, scaleX: 1.5 }); self.takeDamage = function (damage) { self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 200); self.healthBarFill.scaleX = Math.max(0, self.health / self.maxHealth) * 1.5; if (self.health <= 0) { self.shouldDestroy = true; LK.getSound('hit').play(); // Drop tons of coins for (var i = 0; i < 20; i++) { spawnItem(self.x + (Math.random() - 0.5) * 200, self.y + (Math.random() - 0.5) * 200, 'coin'); } } }; self.update = function () { // Update timers self.callForHelpTimer--; self.gunAttackTimer--; self.whistleTimer--; // Check for rage mode activation at 50% health if (!self.rageMode && self.health <= self.maxHealth / 2) { self.rageMode = true; self.speed = self.originalSpeed * 1.5; // 50% faster LK.effects.flashObject(self, 0xFF0000, 1000); LK.effects.flashScreen(0xFF0000, 500); // Visual effect for rage activation tween(leaderGraphics, { scaleX: 2.5, scaleY: 2.5 }, { duration: 500, easing: tween.easeOut }); tween(leaderGraphics, { scaleX: 1.5, scaleY: 1.5 }, { duration: 500, easing: tween.easeIn }); } if (bart) { var dx = bart.x - self.x; var dy = bart.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); // Move towards Bart if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Call for help ability - faster in rage mode var helpInterval = self.rageMode ? 270 : 600; // 4.5 seconds in rage, 10 seconds normal if (self.callForHelpTimer <= 0) { // Summon 3 random enemies for (var i = 0; i < 3; i++) { var enemyType = Math.random(); var enemy; if (enemyType < 0.33) { enemy = new Mutant(); } else if (enemyType < 0.66) { enemy = new FastMutant(); } else { enemy = new ShooterMutant(); } // Spawn on opposite side of screen from Bart enemy.x = bart.x < 1024 ? 1800 : 200; enemy.y = Math.random() * 1800 + 400; enemy.invincible = false; enemy.invincibilityTimer = 0; enemies.push(enemy); game.addChild(enemy); } self.callForHelpTimer = helpInterval; LK.effects.flashObject(self, 0x00FF00, 500); // Play call help sound LK.getSound('Callhelp').play(); } // Gun attack ability if (self.gunAttackTimer <= 0) { var bullet = new LeaderBullet(); bullet.x = self.x; bullet.y = self.y; bullet.targetX = bart.x; bullet.targetY = bart.y; bullet.damage = 90; // Insane damage but not instant kill bullet.speed = 12; enemyProjectiles.push(bullet); game.addChild(bullet); self.gunAttackTimer = 300; LK.effects.flashObject(self, 0xFF0000, 300); } // Whistle ability - reduce Bart's attack speed if (self.whistleTimer <= 0) { bart.originalFireRate = bart.fireRate; bart.fireRate = bart.fireRate * 2; // Double fire rate delay (slower) bart.attackSpeedDebuffTimer = 285; // 4.75 seconds self.whistleTimer = 1200; LK.effects.flashScreen(0x0000FF, 500); LK.effects.flashObject(self, 0x0000FF, 1000); // Change Bart to debuffed visual bart.updateWeaponVisual('debuffed'); // Play whistle sound LK.getSound('Whistleblow').play(); // Visual effect on Bart tween(leaderGraphics, { scaleX: 2, scaleY: 2 }, { duration: 300, easing: tween.easeOut }); tween(leaderGraphics, { scaleX: 1.5, scaleY: 1.5 }, { duration: 300, easing: tween.easeIn }); } } }; return self; }); var PacifierProjectile = Container.expand(function () { var self = Container.call(this); var projectileGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6, tint: 0xFF69B4 }); self.damage = 20; self.speed = 8; self.target = null; self.lifetime = 120; self.sleepRadius = 150; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; return; } if (self.target && !self.target.destroyed) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Apply sleep effect to nearby enemies for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var eDx = enemy.x - self.x; var eDy = enemy.y - self.y; var eDist = Math.sqrt(eDx * eDx + eDy * eDy); if (eDist < self.sleepRadius && !enemy.sleeping) { enemy.sleeping = true; enemy.sleepTimer = 120; // 2 seconds of sleep enemy.originalSpeed = enemy.speed; enemy.speed = 0; // Visual effect for sleeping tween(enemy, { alpha: 0.5 }, { duration: 200, easing: tween.easeOut }); } } } else { self.y -= self.speed; } self.rotation += 0.15; }; return self; }); var Peanut = Container.expand(function () { var self = Container.call(this); var peanutGraphics = self.attachAsset('peanut', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 15; self.speed = 12; self.target = null; self.lifetime = 60; self.hasSplit = false; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; return; } if (self.target && !self.target.destroyed) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } } else { self.y -= self.speed; } self.rotation += 0.1; }; return self; }); var PoetMutant = Container.expand(function () { var self = Container.call(this); var mutantGraphics = self.attachAsset('poet_mutant', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 80; self.health = self.maxHealth; self.speed = 1; self.xpValue = 40; self.coinChance = 0.6; self.powerupChance = 0.25; self.summonTimer = 0; self.summonInterval = 180; // 3 seconds self.invincible = true; self.invincibilityTimer = 180; // 3 seconds at 60fps self.takeDamage = function (damage) { if (self.invincible) return; // No damage during invincibility self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 200); if (self.health <= 0) { self.shouldDestroy = true; LK.getSound('hit').play(); } }; self.update = function () { if (self.invincible) { self.invincibilityTimer--; mutantGraphics.alpha = 0.5 + Math.sin(LK.ticks * 0.3) * 0.3; // Flashing effect if (self.invincibilityTimer <= 0) { self.invincible = false; mutantGraphics.alpha = 1; // Reset to full opacity } } self.summonTimer--; // Apply damage multiplier if it exists var actualDamage = 10; if (self.damageMultiplier) { actualDamage = Math.floor(10 * self.damageMultiplier); } if (bart) { var dx = bart.x - self.x; var dy = bart.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Summon mutants when close to player if (self.summonTimer <= 0 && dist < 800) { // Summon a basic mutant var summonedMutant = new Mutant(); summonedMutant.x = self.x + (Math.random() - 0.5) * 200; summonedMutant.y = self.y + (Math.random() - 0.5) * 200; summonedMutant.maxHealth = 20 + wave * 8; summonedMutant.health = summonedMutant.maxHealth; summonedMutant.speed = 2 + wave * 0.2; enemies.push(summonedMutant); game.addChild(summonedMutant); self.summonTimer = self.summonInterval; LK.effects.flashObject(self, 0xFF00FF, 300); } } }; return self; }); var PotBomb = Container.expand(function () { var self = Container.call(this); var potGraphics = self.attachAsset('pot_bomb', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 35; self.speed = 12; self.target = null; self.lifetime = 240; // 4 seconds at 60fps - auto-explode to reduce lag self.exploded = false; self.explosionRadius = 120; self.splitChance = 0.3; // 30% chance to split into shards self.update = function () { self.lifetime--; // Auto-explode after 4 seconds (240 frames at 60fps) to reduce lag if (self.lifetime <= 0) { self.explode(); return; } if (self.target && !self.target.destroyed) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; self.rotation += 0.15; // Spinning pot effect } } else { self.y -= self.speed; } }; self.explode = function () { if (self.exploded) return; self.exploded = true; // Hide the pot immediately potGraphics.visible = false; // Visual explosion effect LK.effects.flashScreen(0xFF8C00, 300); // Area damage to all enemies within radius for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var dx = enemy.x - self.x; var dy = enemy.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < self.explosionRadius) { enemy.takeDamage(self.damage); LK.effects.flashObject(enemy, 0xFF8C00, 300); } } // Always split into pottery shards for (var i = 0; i < 4; i++) { var shard = new PotteryShard(); shard.x = self.x; shard.y = self.y; // Set diagonal directions: NE, NW, SE, SW var angle = i * Math.PI / 2 + Math.PI / 4; // 45, 135, 225, 315 degrees shard.velocityX = Math.cos(angle) * shard.speed; shard.velocityY = Math.sin(angle) * shard.speed; bullets.push(shard); game.addChild(shard); } self.shouldDestroy = true; }; return self; }); var PotteryShard = Container.expand(function () { var self = Container.call(this); var shardGraphics = self.attachAsset('pottery_shard', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 15; self.speed = 10; self.velocityX = 0; self.velocityY = 0; self.lifetime = 60; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; return; } self.x += self.velocityX; self.y += self.velocityY; self.rotation += 0.2; // Spinning shard effect }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.type = Math.random() < 0.5 ? 'damage' : 'firerate'; self.lifetime = 300; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; } self.rotation += 0.03; self.y += Math.sin(LK.ticks * 0.05) * 0.5; }; return self; }); var RockerMutant = Container.expand(function () { var self = Container.call(this); var mutantGraphics = self.attachAsset('rocker_mutant', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 70; self.health = self.maxHealth; self.speed = 2.5; self.xpValue = 40; self.coinChance = 0.5; self.powerupChance = 0.2; self.boostTimer = 0; self.boostInterval = 300; // 5 seconds self.invincible = true; self.invincibilityTimer = 180; self.takeDamage = function (damage) { if (self.invincible) return; self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 200); if (self.health <= 0) { self.shouldDestroy = true; LK.getSound('hit').play(); } }; self.update = function () { if (self.invincible) { self.invincibilityTimer--; mutantGraphics.alpha = 0.5 + Math.sin(LK.ticks * 0.3) * 0.3; if (self.invincibilityTimer <= 0) { self.invincible = false; mutantGraphics.alpha = 1; } } self.boostTimer--; // Check if Drummer is on screen for enhanced boost var drummerOnScreen = false; for (var i = 0; i < enemies.length; i++) { if (enemies[i] instanceof DrummerMutant && enemies[i] !== self) { drummerOnScreen = true; break; } } // Apply speed boost to all allies if (self.boostTimer <= 0) { var boostAmount = drummerOnScreen ? 1.5 : 1; // Extra boost if drummer present for (var i = 0; i < enemies.length; i++) { if (enemies[i] !== self && !enemies[i].speedBoosted) { enemies[i].originalSpeed = enemies[i].speed; enemies[i].speed += boostAmount; enemies[i].speedBoosted = true; enemies[i].speedBoostTimer = 300; // 5 seconds // Visual effect for boosted enemies LK.effects.flashObject(enemies[i], 0x00FF00, 500); } } self.boostTimer = self.boostInterval; // Visual effect when boosting LK.effects.flashObject(self, 0x00FF00, 1000); mutantGraphics.tint = 0x00FF00; tween(mutantGraphics, { tint: 0xFFFFFF }, { duration: 500, easing: tween.easeOut }); } if (bart) { var dx = bart.x - self.x; var dy = bart.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } } }; return self; }); var RubberArrow = Container.expand(function () { var self = Container.call(this); var arrowGraphics = self.attachAsset('rubber_arrow', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 20; self.speed = 18; self.target = null; self.lifetime = 80; self.pierceCount = 0; self.maxPierce = 3; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; return; } if (self.target && !self.target.destroyed) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; self.rotation = Math.atan2(dy, dx); } } else { self.y -= self.speed; } }; return self; }); var SamuraiMutant = Container.expand(function () { var self = Container.call(this); var mutantGraphics = self.attachAsset('samurai_mutant', { anchorX: 0.5, anchorY: 0.5 }); // Create katana - much bigger self.katana = self.attachAsset('katana', { anchorX: 0.5, anchorY: 0.5, x: 300, y: 0, scaleX: 2.5, scaleY: 2.5 }); self.maxHealth = 100; self.health = self.maxHealth; self.speed = 1.2; self.xpValue = 50; self.coinChance = 0.7; self.powerupChance = 0.3; self.invincible = true; self.invincibilityTimer = 180; // 3 seconds at 60fps self.katanaAngle = 0; self.katanaRadius = 300; // Much farther from mutant self.reflectRadius = 350; // Increased to match farther katana self.takeDamage = function (damage) { if (self.invincible) return; // No damage during invincibility self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 200); if (self.health <= 0) { self.shouldDestroy = true; LK.getSound('hit').play(); } }; self.update = function () { if (self.invincible) { self.invincibilityTimer--; mutantGraphics.alpha = 0.5 + Math.sin(LK.ticks * 0.3) * 0.3; // Flashing effect if (self.invincibilityTimer <= 0) { self.invincible = false; mutantGraphics.alpha = 1; // Reset to full opacity } } // Rotate katana around the mutant - much faster self.katanaAngle += 0.3; // Much faster rotation speed self.katana.x = Math.cos(self.katanaAngle) * self.katanaRadius; self.katana.y = Math.sin(self.katanaAngle) * self.katanaRadius; self.katana.rotation = self.katanaAngle + Math.PI / 2; // Orient katana tangentially // Move towards Bart if (bart) { var dx = bart.x - self.x; var dy = bart.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } } }; return self; }); var SantaHelper = Container.expand(function () { var self = Container.call(this); var helperGraphics = self.attachAsset('santa_helper', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 12; self.damage = 15; self.target = null; self.attackCooldown = 0; self.findTarget = function () { var closestEnemy = null; var closestDist = Infinity; for (var i = 0; i < enemies.length; i++) { var dx = enemies[i].x - self.x; var dy = enemies[i].y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < closestDist && dist < 800) { closestDist = dist; closestEnemy = enemies[i]; } } return closestEnemy; }; self.update = function () { self.attackCooldown--; // Find new target if current target is destroyed if (!self.target || self.target.shouldDestroy || self.target.destroyed) { self.target = self.findTarget(); } if (self.target) { // Move towards target aggressively var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Attack if close enough if (dist < 60 && self.attackCooldown <= 0) { self.target.takeDamage(self.damage); self.attackCooldown = 20; // Attack every 0.33 seconds LK.effects.flashObject(self, 0xFF0000, 200); // Bite animation effect tween(helperGraphics, { scaleX: 1.3, scaleY: 1.3 }, { duration: 100, easing: tween.easeOut }); tween(helperGraphics, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.easeIn }); } } else { // Follow Bart if no enemies if (bart) { var dx = bart.x - self.x; var dy = bart.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 80) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } } } }; return self; }); var ShooterMutant = Container.expand(function () { var self = Container.call(this); var mutantGraphics = self.attachAsset('shooter_mutant', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 50; self.health = self.maxHealth; self.speed = 1.5; self.xpValue = 25; self.coinChance = 0.4; self.powerupChance = 0.15; self.shootTimer = 0; self.shootInterval = 120; self.invincible = true; self.invincibilityTimer = 180; // 3 seconds at 60fps self.takeDamage = function (damage) { if (self.invincible) return; // No damage during invincibility self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 200); if (self.health <= 0) { self.shouldDestroy = true; LK.getSound('hit').play(); } }; self.update = function () { if (self.invincible) { self.invincibilityTimer--; mutantGraphics.alpha = 0.5 + Math.sin(LK.ticks * 0.3) * 0.3; // Flashing effect if (self.invincibilityTimer <= 0) { self.invincible = false; mutantGraphics.alpha = 1; // Reset to full opacity } } self.shootTimer--; if (bart) { var dx = bart.x - self.x; var dy = bart.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } if (self.shootTimer <= 0 && dist < 2567) { var bowlingBall = new BowlingBall(); bowlingBall.x = self.x; bowlingBall.y = self.y; bowlingBall.targetX = bart.x; bowlingBall.targetY = bart.y; enemyProjectiles.push(bowlingBall); game.addChild(bowlingBall); self.shootTimer = self.shootInterval; } } }; return self; }); var SmallNut = Container.expand(function () { var self = Container.call(this); var nutGraphics = self.attachAsset('small_nut', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 5; self.speed = 10; self.velocityX = 0; self.velocityY = 0; self.lifetime = 40; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; return; } self.x += self.velocityX; self.y += self.velocityY; self.rotation += 0.2; }; return self; }); var SnowballCat = Container.expand(function () { var self = Container.call(this); var catGraphics = self.attachAsset('snowball_cat', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.distractionRadius = 600; self.runDirection = 1; self.runTimer = 0; self.invincibilityReduction = 0.5; // Reduces invincibility time by 50% self.velocityX = (Math.random() - 0.5) * self.speed * 2; // Random X velocity self.velocityY = (Math.random() - 0.5) * self.speed * 2; // Random Y velocity self.directionChangeTimer = 0; self.update = function () { // Change direction randomly every 1-3 seconds self.directionChangeTimer++; if (self.directionChangeTimer > 60 + Math.random() * 120) { self.velocityX = (Math.random() - 0.5) * self.speed * 2; self.velocityY = (Math.random() - 0.5) * self.speed * 2; self.directionChangeTimer = 0; } // Move in current direction self.x += self.velocityX; self.y += self.velocityY; // Bounce off edges with some randomness if (self.x < 50) { self.x = 50; self.velocityX = Math.abs(self.velocityX) * (0.8 + Math.random() * 0.4); self.velocityY = (Math.random() - 0.5) * self.speed; } else if (self.x > 1998) { self.x = 1998; self.velocityX = -Math.abs(self.velocityX) * (0.8 + Math.random() * 0.4); self.velocityY = (Math.random() - 0.5) * self.speed; } if (self.y < 50) { self.y = 50; self.velocityY = Math.abs(self.velocityY) * (0.8 + Math.random() * 0.4); self.velocityX = (Math.random() - 0.5) * self.speed; } else if (self.y > 2682) { self.y = 2682; self.velocityY = -Math.abs(self.velocityY) * (0.8 + Math.random() * 0.4); self.velocityX = (Math.random() - 0.5) * self.speed; } // Check for nearby enemies to distract for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var dx = self.x - enemy.x; var dy = self.y - enemy.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < self.distractionRadius) { // Make enemy follow the cat instead of Bart enemy.distractedBy = self; // Reduce invincibility time if enemy is invincible if (enemy.invincible && enemy.invincibilityTimer > 0) { enemy.invincibilityTimer = Math.floor(enemy.invincibilityTimer * self.invincibilityReduction); } } } // Animated running effect with rotation based on movement direction var catGraphics = self.children[0]; catGraphics.scaleX = 1 + Math.sin(LK.ticks * 0.3) * 0.1; catGraphics.rotation = Math.atan2(self.velocityY, self.velocityX) * 0.2; // Face movement direction }; return self; }); var SoundBarrier = Container.expand(function () { var self = Container.call(this); // Create a wide barrier using multiple sound waves self.waves = []; for (var i = 0; i < 5; i++) { var wave = self.attachAsset('sound_wave', { anchorX: 0.5, anchorY: 0.5, x: (i - 2) * 80, y: 0, scaleX: 1.2, scaleY: 0.8, tint: 0xFFD700, alpha: 0.6 }); self.waves.push(wave); } self.health = 150; self.lifetime = 600; // 10 seconds self.width = 400; self.height = 80; self.takeDamage = function (damage) { self.health -= damage; LK.effects.flashObject(self, 0xFF0000, 200); if (self.health <= 0) { self.shouldDestroy = true; } }; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; return; } // Pulsing effect for (var i = 0; i < self.waves.length; i++) { self.waves[i].alpha = 0.4 + Math.sin(LK.ticks * 0.1 + i * 0.5) * 0.2; self.waves[i].scaleY = 0.8 + Math.sin(LK.ticks * 0.15 + i * 0.3) * 0.1; } // Block enemy projectiles for (var i = enemyProjectiles.length - 1; i >= 0; i--) { var projectile = enemyProjectiles[i]; var dx = Math.abs(projectile.x - self.x); var dy = Math.abs(projectile.y - self.y); if (dx < self.width / 2 && dy < self.height / 2) { self.takeDamage(projectile.damage || 10); projectile.destroy(); enemyProjectiles.splice(i, 1); } } // Slow down enemies passing through for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var dx = Math.abs(enemy.x - self.x); var dy = Math.abs(enemy.y - self.y); if (dx < self.width / 2 && dy < self.height / 2) { if (!enemy.barrierSlowed) { enemy.barrierSlowed = true; enemy.originalBarrierSpeed = enemy.speed; enemy.speed *= 0.3; // 70% speed reduction } } else if (enemy.barrierSlowed) { enemy.speed = enemy.originalBarrierSpeed; enemy.barrierSlowed = false; } } }; return self; }); var SoundWave = Container.expand(function () { var self = Container.call(this); var waveGraphics = self.attachAsset('sound_wave', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 20; // Much faster than before self.damage = 12; self.targetX = 0; self.targetY = 0; self.directionSet = false; self.velocityX = 0; self.velocityY = 0; self.lifetime = 300; // Much longer lifespan self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; return; } // Homing behavior for instakill soundwaves if (self.isHoming && self.target && !self.target.destroyed) { // Make homing sound waves smaller and faster with longer lifespan if (self.lifetime === 300) { // Initialize on first frame waveGraphics.scaleX = 0.7; // Smaller than regular sound waves waveGraphics.scaleY = 0.7; self.lifetime = 350; // Slightly bigger lifespan than regular } var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * (self.speed * 1.2); // Faster than regular speed self.y += dy / dist * (self.speed * 1.2); } // Make it glow red for instakill waves if (self.damage >= 9999) { waveGraphics.tint = 0xFF0000; } } else { // Standard projectile movement like bowling balls if (!self.directionSet) { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.velocityX = dx / dist * self.speed; self.velocityY = dy / dist * self.speed; } self.directionSet = true; } self.x += self.velocityX; self.y += self.velocityY; } // Enhanced glowing effect using tween waveGraphics.alpha = 0.8 + Math.sin(LK.ticks * 0.3) * 0.2; // Continuous scaling glow effect tween(waveGraphics, { scaleX: 1.2, scaleY: 1.2, alpha: 0.9 }, { duration: 500, easing: tween.easeInOut }); tween(waveGraphics, { scaleX: 1.0, scaleY: 1.0, alpha: 0.6 }, { duration: 500, easing: tween.easeInOut }); }; return self; }); var Spray = Container.expand(function () { var self = Container.call(this); var sprayGraphics = self.attachAsset('spray', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 8; self.speed = 15; self.target = null; self.lifetime = 45; self.stunDuration = 72; // 1.2 seconds at 60fps self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; return; } if (self.target && !self.target.destroyed) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; self.rotation = Math.atan2(dy, dx); } } else { self.y -= self.speed; } sprayGraphics.alpha = 0.7 + Math.sin(LK.ticks * 0.3) * 0.3; }; return self; }); var StunRay = Container.expand(function () { var self = Container.call(this); var rayGraphics = self.attachAsset('sound_wave', { anchorX: 0.5, anchorY: 0.5, tint: 0x9400D3 // Purple color for stun ray }); self.speed = 12; self.damage = 30; self.stunDuration = 45; // 0.75 seconds at 60fps self.targetX = 0; self.targetY = 0; self.directionSet = false; self.velocityX = 0; self.velocityY = 0; self.lifetime = 240; self.update = function () { self.lifetime--; if (self.lifetime <= 0) { self.shouldDestroy = true; return; } if (!self.directionSet) { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.velocityX = dx / dist * self.speed; self.velocityY = dy / dist * self.speed; } self.directionSet = true; } self.x += self.velocityX; self.y += self.velocityY; // Pulsing effect rayGraphics.alpha = 0.6 + Math.sin(LK.ticks * 0.4) * 0.4; rayGraphics.scaleX = 1 + Math.sin(LK.ticks * 0.3) * 0.2; rayGraphics.scaleY = 1 + Math.sin(LK.ticks * 0.3) * 0.2; }; return self; }); var UFOStriker = Container.expand(function () { var self = Container.call(this); // Create UFO body using proper UFO asset var ufoBody = self.attachAsset('ufo_striker', { anchorX: 0.5, anchorY: 0.5 }); // Add a dome on top var ufoDome = self.attachAsset('ufo_dome', { anchorX: 0.5, anchorY: 0.5, y: -60, alpha: 0.8 }); self.maxHealth = 30550; self.health = self.maxHealth; self.speed = 2; // Faster speed (was 0.5) self.xpValue = 3000; self.coinChance = 1; self.coinValue = 200; self.powerupChance = 1; self.isInstantKillBoss = true; // Timers for abilities self.stunRayTimer = 180; // 3 seconds self.replicaTimer = 450; // 7.5 seconds self.cloneTimer = 6000; // 100 seconds self.kidnappingTarget = null; self.kidnappingProgress = 0; self.clones = []; // Health bar var healthBarBg = self.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, y: -180, scaleX: 2 }); self.healthBarFill = self.attachAsset('healthbar_fill', { anchorX: 0, anchorY: 0.5, x: -200, y: -180, scaleX: 2 }); self.takeDamage = function (damage) { // Can't take damage while kidnapping if (self.kidnappingTarget) return; self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 200); self.healthBarFill.scaleX = Math.max(0, self.health / self.maxHealth) * 2; if (self.health <= 0) { self.shouldDestroy = true; LK.getSound('hit').play(); // Drop many coins for (var i = 0; i < 40; i++) { spawnItem(self.x + (Math.random() - 0.5) * 300, self.y + (Math.random() - 0.5) * 300, 'coin'); } } }; self.startKidnapping = function (target) { self.kidnappingTarget = target; self.kidnappingProgress = 0; // Freeze Bart target.stunned = true; target.stunnedTimer = 300; // 5 seconds // Create tractor beam effect var tractorBeam = self.attachAsset('tractor_beam', { anchorX: 0.5, anchorY: 0, y: 50, scaleY: 1, tint: 0x00FF00, alpha: 0.6 }); self.tractorBeam = tractorBeam; // Start pulling animation tween(target, { y: self.y + 100 }, { duration: 5000, easing: tween.linear, onFinish: function onFinish() { // Kidnapping complete - game over target.health = 0; target.takeDamage(0); } }); }; self.executeRandomBossMove = function () { // List of possible boss moves to replicate var moves = ['summonEnemies', 'shootProjectiles', 'areaAttack', 'speedBoost']; var selectedMove = moves[Math.floor(Math.random() * moves.length)]; switch (selectedMove) { case 'summonEnemies': // Summon 2 random enemies (like Mutant Leader) for (var i = 0; i < 2; i++) { var enemyType = Math.random(); var enemy; if (enemyType < 0.5) { enemy = new Mutant(); } else { enemy = new FastMutant(); } enemy.x = self.x + (Math.random() - 0.5) * 400; enemy.y = self.y + 200; enemy.invincible = false; enemy.invincibilityTimer = 0; enemies.push(enemy); game.addChild(enemy); } LK.effects.flashObject(self, 0x00FF00, 500); break; case 'shootProjectiles': // Shoot multiple sound waves (like Concert) if (bart) { for (var i = -2; i <= 2; i++) { var soundWave = new SoundWave(); soundWave.x = self.x; soundWave.y = self.y; var angle = Math.atan2(bart.y - soundWave.y, bart.x - soundWave.x); angle += i * 0.3; soundWave.targetX = soundWave.x + Math.cos(angle) * 1000; soundWave.targetY = soundWave.y + Math.sin(angle) * 1000; soundWave.damage = 25; enemyProjectiles.push(soundWave); game.addChild(soundWave); } } LK.effects.flashObject(self, 0xFF00FF, 500); break; case 'areaAttack': // Flash area damage (like pot explosion) LK.effects.flashScreen(0xFF0000, 300); if (bart) { var dx = bart.x - self.x; var dy = bart.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 400) { bart.takeDamage(40); } } break; case 'speedBoost': // Boost all enemy speeds (like Concert's Rock Music) for (var i = 0; i < enemies.length; i++) { if (enemies[i] !== self && !enemies[i].ufoSpeedBoosted) { enemies[i].originalSpeed = enemies[i].speed; enemies[i].speed *= 1.5; enemies[i].ufoSpeedBoosted = true; enemies[i].ufoSpeedBoostTimer = 300; LK.effects.flashObject(enemies[i], 0x00FF00, 500); } } break; } }; self.createClone = function () { var clone = new UFOStrikerClone(); clone.x = self.x + (Math.random() - 0.5) * 300; clone.y = self.y + (Math.random() - 0.5) * 300; self.clones.push(clone); enemies.push(clone); game.addChild(clone); LK.effects.flashScreen(0x0000FF, 500); // Animation for cloning tween(self, { scaleX: 1.3, scaleY: 1.3 }, { duration: 300, easing: tween.easeOut }); tween(self, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeIn }); }; self.update = function () { // Update timers self.stunRayTimer--; self.replicaTimer--; self.cloneTimer--; // Clean up destroyed clones self.clones = self.clones.filter(function (clone) { return !clone.destroyed && !clone.shouldDestroy; }); // Handle UFO speed boost timers for (var i = 0; i < enemies.length; i++) { if (enemies[i].ufoSpeedBoosted && enemies[i].ufoSpeedBoostTimer) { enemies[i].ufoSpeedBoostTimer--; if (enemies[i].ufoSpeedBoostTimer <= 0) { enemies[i].speed = enemies[i].originalSpeed; enemies[i].ufoSpeedBoosted = false; } } } // Kidnapping logic if (self.kidnappingTarget) { self.kidnappingProgress++; // Update tractor beam if (self.tractorBeam) { var dx = self.kidnappingTarget.x - self.x; var dy = self.kidnappingTarget.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); self.tractorBeam.rotation = Math.atan2(dy, dx) + Math.PI / 2; self.tractorBeam.scaleY = dist / 600; // Adjust beam length based on tractor beam height } if (self.kidnappingProgress >= 300) { // Kidnapping complete self.kidnappingTarget = null; if (self.tractorBeam) { self.removeChild(self.tractorBeam); self.tractorBeam = null; } } return; // Don't do other actions while kidnapping } if (bart) { var dx = bart.x - self.x; var dy = bart.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); // Try to kidnap if touching Bart if (dist < 100 && !bart.stunned) { self.startKidnapping(bart); return; } // Move towards Bart slowly if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Stun-Ray ability if (self.stunRayTimer <= 0) { var stunRay = new StunRay(); stunRay.x = self.x; stunRay.y = self.y; stunRay.targetX = bart.x; stunRay.targetY = bart.y; enemyProjectiles.push(stunRay); game.addChild(stunRay); self.stunRayTimer = 180; LK.effects.flashObject(self, 0x9400D3, 300); } // Replica ability if (self.replicaTimer <= 0) { self.executeRandomBossMove(); self.replicaTimer = 450; } // Clone ability if (self.cloneTimer <= 0 && self.clones.length < 3) { self.createClone(); self.cloneTimer = 6000; } } // UFO hovering animation ufoBody.y = Math.sin(LK.ticks * 0.05) * 10; ufoDome.y = -60 + Math.sin(LK.ticks * 0.05) * 10; // Add pulsing glow effect to dome ufoDome.alpha = 0.6 + Math.sin(LK.ticks * 0.1) * 0.2; }; return self; }); var UFOStrikerClone = Container.expand(function () { var self = Container.call(this); // Create UFO shape with blue tint var ufoBody = self.attachAsset('ufo_striker', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, tint: 0x0000FF // Blue tint for clone }); var ufoDome = self.attachAsset('ufo_dome', { anchorX: 0.5, anchorY: 0.5, y: -50, scaleX: 0.8, scaleY: 0.8, tint: 0x00BFFF, alpha: 0.7 }); self.maxHealth = 10000; self.health = self.maxHealth; self.speed = 0.8; self.xpValue = 500; self.coinChance = 0.8; self.powerupChance = 0.5; // Simple AI - just move and shoot self.shootTimer = 120; self.takeDamage = function (damage) { self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 200); if (self.health <= 0) { self.shouldDestroy = true; LK.getSound('hit').play(); } }; self.update = function () { self.shootTimer--; if (bart) { var dx = bart.x - self.x; var dy = bart.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Shoot stun rays if (self.shootTimer <= 0) { var stunRay = new StunRay(); stunRay.x = self.x; stunRay.y = self.y; stunRay.targetX = bart.x; stunRay.targetY = bart.y; stunRay.damage = 15; // Less damage than original stunRay.stunDuration = 30; // 0.5 seconds enemyProjectiles.push(stunRay); game.addChild(stunRay); self.shootTimer = 120; } } // UFO hovering animation ufoBody.y = Math.sin(LK.ticks * 0.05 + self.x) * 8; ufoDome.y = -50 + Math.sin(LK.ticks * 0.05 + self.x) * 8; // Pulsing glow effect for clone dome ufoDome.alpha = 0.5 + Math.sin(LK.ticks * 0.12) * 0.2; }; return self; }); var VocalMutant = Container.expand(function () { var self = Container.call(this); var mutantGraphics = self.attachAsset('vocal_mutant', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 40; self.health = self.maxHealth; self.speed = 5; self.xpValue = 35; self.coinChance = 0.4; self.powerupChance = 0.15; self.baseDamage = 15; // Base damage when swearing at Bart self.invincible = true; self.invincibilityTimer = 180; self.takeDamage = function (damage) { if (self.invincible) return; self.health -= damage; LK.effects.flashObject(self, 0xFFFFFF, 200); if (self.health <= 0) { self.shouldDestroy = true; LK.getSound('hit').play(); } }; self.getDamage = function () { // Check if Rocker is on screen to double damage var rockerOnScreen = false; for (var i = 0; i < enemies.length; i++) { if (enemies[i] instanceof RockerMutant && enemies[i] !== self) { rockerOnScreen = true; break; } } return rockerOnScreen ? self.baseDamage * 2 : self.baseDamage; }; self.update = function () { if (self.invincible) { self.invincibilityTimer--; mutantGraphics.alpha = 0.5 + Math.sin(LK.ticks * 0.3) * 0.3; if (self.invincibilityTimer <= 0) { self.invincible = false; mutantGraphics.alpha = 1; } } if (bart) { var dx = bart.x - self.x; var dy = bart.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000080 }); /**** * Game Code ****/ var bart; var enemies = []; var bullets = []; var items = []; var enemyProjectiles = []; var alienMeals = []; var wave = 1; var enemiesKilled = 0; var spawnTimer = 0; var dragTarget = null; var gameStarted = false; var titleScreen; var startButton; var titleText; var shopScreen; var shopButton; var selectedWeapon = 'slingshot'; var unlockedWeapons = ['slingshot']; var weaponPrices = { dartgun: 100, scattershot: 250, ducky: 500, spraycan: 750, flower: 1000, bow: 600, pot: 800 }; var isGiantMutantRush = false; var giantMutantRushButton; var mutantLeaderSpawned = false; var weaponStats = { slingshot: { damage: 10, fireRate: 30, projectileCount: 1 }, dartgun: { damage: 50, fireRate: 60, projectileCount: 1 }, scattershot: { damage: 15, fireRate: 40, projectileCount: 1 }, ducky: { damage: 25, fireRate: 45, projectileCount: 3 }, spraycan: { damage: 8, fireRate: 50, projectileCount: 1 }, flower: { damage: 3, fireRate: 6, projectileCount: 1 }, bow: { damage: 12, fireRate: 35, projectileCount: 1 }, pot: { damage: 35, fireRate: 55, projectileCount: 1 } }; var selectedSubweapon = null; var unlockedSubweapons = []; var subweaponPrices = { santa_helper: 750, krusty_shop: 1200, snowball_cat: 900, maggie_pacifier: 1000, lisa_saxophone: 1500, marge_vacuum: 1100 }; var activeSubweapon = null; var encyclopediaScreen; // Create title screen titleScreen = new Container(); game.addChild(titleScreen); // Title text titleText = new Text2('BART vs MUTANTS', { size: 120, fill: 0xFFFF00 }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 800; titleScreen.addChild(titleText); // Start button background startButton = titleScreen.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1400, scaleX: 2, scaleY: 3 }); // Start button text var startText = new Text2('START', { size: 80, fill: 0xFFFFFF }); startText.anchor.set(0.5, 0.5); startText.x = 1024; startText.y = 1400; titleScreen.addChild(startText); // Instructions text var instructionsText = new Text2('Drag to move โข Auto-shoot enemies', { size: 50, fill: 0xAAAAAA }); instructionsText.anchor.set(0.5, 0.5); instructionsText.x = 1024; instructionsText.y = 1600; titleScreen.addChild(instructionsText); // Title screen coins display var titleCoinsText = new Text2('Coins: 0', { size: 60, fill: 0xFFD700 }); titleCoinsText.anchor.set(1, 0); titleCoinsText.x = 1948; titleCoinsText.y = 100; titleScreen.addChild(titleCoinsText); // Shop button background shopButton = titleScreen.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1800, scaleX: 2, scaleY: 2 }); // Shop button text var shopButtonText = new Text2('KRUSTY BURGER', { size: 60, fill: 0xFFFF00 }); shopButtonText.anchor.set(0.5, 0.5); shopButtonText.x = 1024; shopButtonText.y = 1800; titleScreen.addChild(shopButtonText); // Encyclopedia button background var encyclopediaButton = titleScreen.attachAsset('info_button', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 2100, scaleX: 2, scaleY: 2 }); // Encyclopedia button text var encyclopediaButtonText = new Text2('ENCYCLOPEDIA', { size: 60, fill: 0x00FFFF }); encyclopediaButtonText.anchor.set(0.5, 0.5); encyclopediaButtonText.x = 1024; encyclopediaButtonText.y = 2100; titleScreen.addChild(encyclopediaButtonText); // Giant Mutant Rush button background giantMutantRushButton = titleScreen.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 2400, scaleX: 2.5, scaleY: 2 }); giantMutantRushButton.tint = 0xFF0000; // Giant Mutant Rush button text var giantRushText = new Text2('GIANT MUTANT RUSH!', { size: 50, fill: 0xFFFF00 }); giantRushText.anchor.set(0.5, 0.5); giantRushText.x = 1024; giantRushText.y = 2400; titleScreen.addChild(giantRushText); // Boss selection screen var bossSelectionScreen = new Container(); bossSelectionScreen.visible = false; game.addChild(bossSelectionScreen); // Boss selection title var bossSelectionTitle = new Text2('SELECT YOUR OPPONENT', { size: 100, fill: 0xFF0000 }); bossSelectionTitle.anchor.set(0.5, 0.5); bossSelectionTitle.x = 1024; bossSelectionTitle.y = 200; bossSelectionScreen.addChild(bossSelectionTitle); // Boss selection coins display var bossSelectionCoinsText = new Text2('Coins: 0', { size: 60, fill: 0xFFD700 }); bossSelectionCoinsText.anchor.set(1, 0); bossSelectionCoinsText.x = 1948; bossSelectionCoinsText.y = 100; bossSelectionScreen.addChild(bossSelectionCoinsText); // Entry fee text var entryFeeText = new Text2('Entry Fee: 50 Coins', { size: 50, fill: 0xFFD700 }); entryFeeText.anchor.set(0.5, 0.5); entryFeeText.x = 1024; entryFeeText.y = 350; bossSelectionScreen.addChild(entryFeeText); // Mutant Leader selection button var mutantLeaderButton = bossSelectionScreen.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 600, scaleX: 3, scaleY: 2 }); mutantLeaderButton.tint = 0x800080; var mutantLeaderText = new Text2('MUTANT LEADER', { size: 60, fill: 0xFFFFFF }); mutantLeaderText.anchor.set(0.5, 0.5); mutantLeaderText.x = 1024; mutantLeaderText.y = 570; bossSelectionScreen.addChild(mutantLeaderText); var mutantLeaderDesc = new Text2('HP: 20000 | Summons allies & debuffs', { size: 35, fill: 0xAAAAAA }); mutantLeaderDesc.anchor.set(0.5, 0.5); mutantLeaderDesc.x = 1024; mutantLeaderDesc.y = 630; bossSelectionScreen.addChild(mutantLeaderDesc); // Concert selection button var concertButton = bossSelectionScreen.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 850, scaleX: 3, scaleY: 2 }); concertButton.tint = 0x2678d7; var concertText = new Text2('CONCERT', { size: 60, fill: 0xFFFFFF }); concertText.anchor.set(0.5, 0.5); concertText.x = 1024; concertText.y = 820; bossSelectionScreen.addChild(concertText); var concertDesc = new Text2('HP: 25750 | Band attacks & buffs', { size: 35, fill: 0xAAAAAA }); concertDesc.anchor.set(0.5, 0.5); concertDesc.x = 1024; concertDesc.y = 880; bossSelectionScreen.addChild(concertDesc); // UFO Striker selection button var ufoButton = bossSelectionScreen.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1100, scaleX: 3, scaleY: 2 }); ufoButton.tint = 0x4B0082; var ufoText = new Text2('UFO STRIKER', { size: 60, fill: 0xFFFFFF }); ufoText.anchor.set(0.5, 0.5); ufoText.x = 1024; ufoText.y = 1070; bossSelectionScreen.addChild(ufoText); var ufoDesc = new Text2('HP: 30550 | Kidnapping & cloning', { size: 35, fill: 0xAAAAAA }); ufoDesc.anchor.set(0.5, 0.5); ufoDesc.x = 1024; ufoDesc.y = 1130; bossSelectionScreen.addChild(ufoDesc); // Random boss selection button var randomBossButton = bossSelectionScreen.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1350, scaleX: 3, scaleY: 2 }); randomBossButton.tint = 0xFFD700; var randomBossText = new Text2('RANDOM BOSS', { size: 60, fill: 0x000000 }); randomBossText.anchor.set(0.5, 0.5); randomBossText.x = 1024; randomBossText.y = 1320; bossSelectionScreen.addChild(randomBossText); var randomBossDesc = new Text2('Let fate decide your opponent!', { size: 35, fill: 0x666666 }); randomBossDesc.anchor.set(0.5, 0.5); randomBossDesc.x = 1024; randomBossDesc.y = 1380; bossSelectionScreen.addChild(randomBossDesc); // Back button for boss selection var bossBackButton = bossSelectionScreen.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, x: 200, y: 200, scaleX: 1.5, scaleY: 1.5 }); var bossBackText = new Text2('BACK', { size: 50, fill: 0xFFFFFF }); bossBackText.anchor.set(0.5, 0.5); bossBackText.x = 200; bossBackText.y = 200; bossSelectionScreen.addChild(bossBackText); // Variable to store selected boss var selectedGiantMutant = null; // GUI elements (hidden initially) var levelText = new Text2('Level 1', { size: 60, fill: 0xFFFFFF }); levelText.anchor.set(0, 0); levelText.x = 150; levelText.visible = false; LK.gui.topLeft.addChild(levelText); var xpBarBg = LK.gui.top.attachAsset('xpbar_bg', { anchorX: 0.5, anchorY: 0, y: 10 }); xpBarBg.visible = false; var xpBarFill = LK.gui.top.attachAsset('xpbar_fill', { anchorX: 0, anchorY: 0, x: -150, y: 10, scaleX: 0 }); xpBarFill.visible = false; var coinText = new Text2('Coins: 0', { size: 50, fill: 0xFFD700 }); coinText.anchor.set(1, 0); coinText.visible = false; LK.gui.topRight.addChild(coinText); var healthBarBg = LK.gui.topLeft.attachAsset('healthbar_bg', { anchorX: 0, anchorY: 0, x: 120, y: 80 }); healthBarBg.visible = false; var healthBarFill = LK.gui.topLeft.attachAsset('healthbar_fill', { anchorX: 0, anchorY: 0, x: 120, y: 80, scaleX: 1 }); healthBarFill.visible = false; var waveText = new Text2('Wave 1', { size: 80, fill: 0xFFFFFF }); waveText.anchor.set(0.5, 0.5); waveText.visible = false; LK.gui.center.addChild(waveText); var scoreText = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 1); scoreText.visible = false; LK.gui.bottom.addChild(scoreText); // Load saved data var savedCoins = 0; var savedWeapons = null; var savedSelected = null; var savedSubweapons = null; var savedSelectedSubweapon = null; try { savedCoins = storage.coins || 0; savedWeapons = storage.unlockedWeapons; savedSelected = storage.selectedWeapon; savedSubweapons = storage.unlockedSubweapons; savedSelectedSubweapon = storage.selectedSubweapon; } catch (e) { console.log('Storage not available:', e); } if (savedWeapons) { unlockedWeapons = savedWeapons; } if (savedSelected) { selectedWeapon = savedSelected; } if (savedSubweapons) { unlockedSubweapons = savedSubweapons; } if (savedSelectedSubweapon) { selectedSubweapon = savedSelectedSubweapon; } bart = game.addChild(new Bart()); bart.x = 1024; bart.y = 2000; bart.visible = false; bart.coins = savedCoins; // Set initial weapon visual bart.updateWeaponVisual(selectedWeapon); // Update coin display immediately coinText.setText('Coins: ' + bart.coins); // Update title screen coins display titleCoinsText.setText('Coins: ' + bart.coins); // Create shop screen shopScreen = new Container(); shopScreen.visible = false; game.addChild(shopScreen); // Create encyclopedia screen encyclopediaScreen = new Encyclopedia(); encyclopediaScreen.x = 1024; encyclopediaScreen.y = 1366; encyclopediaScreen.visible = false; game.addChild(encyclopediaScreen); // Shop tab system variables var currentTab = 'weapons'; // Shop title var shopTitle = new Text2('KRUSTY BURGER', { size: 100, fill: 0xFFFF00 }); shopTitle.anchor.set(0.5, 0.5); shopTitle.x = 1024; shopTitle.y = 150; shopScreen.addChild(shopTitle); // Weapons tab button var weaponsTabButton = shopScreen.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, x: 750, y: 250, scaleX: 2, scaleY: 1.5 }); weaponsTabButton.tint = 0x00FF00; // Active tab color var weaponsTabText = new Text2('WEAPONS', { size: 50, fill: 0xFFFFFF }); weaponsTabText.anchor.set(0.5, 0.5); weaponsTabText.x = 750; weaponsTabText.y = 250; shopScreen.addChild(weaponsTabText); // Subweapons tab button var subweaponsTabButton = shopScreen.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, x: 1298, y: 250, scaleX: 2, scaleY: 1.5 }); var subweaponsTabText = new Text2('SUBWEAPONS', { size: 50, fill: 0xFFFFFF }); subweaponsTabText.anchor.set(0.5, 0.5); subweaponsTabText.x = 1298; subweaponsTabText.y = 250; shopScreen.addChild(subweaponsTabText); // Back button var backButton = shopScreen.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, x: 200, y: 200, scaleX: 1.5, scaleY: 1.5 }); var backText = new Text2('BACK', { size: 50, fill: 0xFFFFFF }); backText.anchor.set(0.5, 0.5); backText.x = 200; backText.y = 200; shopScreen.addChild(backText); // Coins display in shop var shopCoinsText = new Text2('Coins: 0', { size: 60, fill: 0xFFD700 }); shopCoinsText.anchor.set(1, 0.5); shopCoinsText.x = 1848; shopCoinsText.y = 200; shopScreen.addChild(shopCoinsText); // Containers for different tab content var weaponsContainer = new Container(); var subweaponsContainer = new Container(); shopScreen.addChild(weaponsContainer); shopScreen.addChild(subweaponsContainer); subweaponsContainer.visible = false; // Start with weapons tab active // Weapon buttons var weaponData = [{ id: 'slingshot', name: 'Slingshot', desc: 'The Default Weapon', y: 400 }, { id: 'dartgun', name: 'Dart Gun', desc: 'High damage, slow fire rate', y: 550 }, { id: 'scattershot', name: 'Scattershot', desc: 'Shoots peanuts that split into 3', y: 700 }, { id: 'ducky', name: 'Ducky Triple', desc: 'Shoots 3 projectiles', y: 850 }, { id: 'bow', name: 'Toy Bow', desc: 'Lower damage but 100% more XP!', y: 1000 }, { id: 'spraycan', name: 'Spraycan', desc: 'Medium damage, stuns for 1.2s', y: 1150 }, { id: 'pot', name: 'Pot-a-Bomb', desc: 'Area damage, chance to split into shards', y: 1300 }, { id: 'flower', name: "Krusty's Flower", desc: 'Water beam, rapid fire', y: 1450 }]; // Subweapon buttons var subweaponData = [{ id: 'santa_helper', name: "Santa's Little Helper", desc: 'Fast ally that bites enemies', y: 400 }, { id: 'krusty_shop', name: 'Krusty Burger Shop', desc: 'Spawns powerups every 15 seconds', y: 550 }, { id: 'snowball_cat', name: 'Snowball II', desc: 'Distracts enemies & reduces invincibility', y: 700 }, { id: 'maggie_pacifier', name: "Maggie's Pacifier", desc: 'Shoots pacifiers that make enemies sleep', y: 850 }, { id: 'lisa_saxophone', name: "Lisa's Saxophone", desc: 'Creates sound barriers that block projectiles', y: 1000 }, { id: 'marge_vacuum', name: "Marge's Vacuum", desc: 'Sucks in items & blasts enemies away', y: 1150 }]; subweaponData.forEach(function (subweapon) { // Subweapon button background var subweaponBg = subweaponsContainer.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: subweapon.y, scaleX: 8, scaleY: 2.4 }); subweaponBg.subweaponId = subweapon.id; // Subweapon name var subweaponName = new Text2(subweapon.name, { size: 50, fill: 0x00FFFF }); subweaponName.anchor.set(0.5, 0.5); subweaponName.x = 800; subweaponName.y = subweapon.y - 15; subweaponsContainer.addChild(subweaponName); // Subweapon description var subweaponDesc = new Text2(subweapon.desc, { size: 35, fill: 0xAAAAAA }); subweaponDesc.anchor.set(0.5, 0.5); subweaponDesc.x = 800; subweaponDesc.y = subweapon.y + 15; subweaponsContainer.addChild(subweaponDesc); // Price/status text var priceText = new Text2('Cost: ' + subweaponPrices[subweapon.id], { size: 45, fill: 0xFFD700 }); priceText.anchor.set(0.5, 0.5); priceText.x = 1400; priceText.y = subweapon.y; priceText.subweaponId = subweapon.id; subweaponsContainer.addChild(priceText); }); weaponData.forEach(function (weapon) { // Weapon button background var weaponBg = weaponsContainer.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: weapon.y, scaleX: 8, scaleY: 3 }); weaponBg.weaponId = weapon.id; // Weapon name var weaponName = new Text2(weapon.name, { size: 60, fill: 0xFFFFFF }); weaponName.anchor.set(0.5, 0.5); weaponName.x = 800; weaponName.y = weapon.y - 20; weaponsContainer.addChild(weaponName); // Weapon description var weaponDesc = new Text2(weapon.desc, { size: 40, fill: 0xAAAAAA }); weaponDesc.anchor.set(0.5, 0.5); weaponDesc.x = 800; weaponDesc.y = weapon.y + 20; weaponsContainer.addChild(weaponDesc); // Price/status text var priceText = new Text2(weapon.id === 'slingshot' ? 'OWNED' : 'Cost: ' + weaponPrices[weapon.id], { size: 50, fill: weapon.id === 'slingshot' ? 0x00FF00 : 0xFFD700 }); priceText.anchor.set(0.5, 0.5); priceText.x = 1400; priceText.y = weapon.y; priceText.weaponId = weapon.id; weaponsContainer.addChild(priceText); }); function switchShopTab(tabName) { currentTab = tabName; if (tabName === 'weapons') { weaponsContainer.visible = true; subweaponsContainer.visible = false; weaponsTabButton.tint = 0x00FF00; // Active tab color subweaponsTabButton.tint = 0xFFFFFF; // Inactive tab color } else if (tabName === 'subweapons') { weaponsContainer.visible = false; subweaponsContainer.visible = true; weaponsTabButton.tint = 0xFFFFFF; // Inactive tab color subweaponsTabButton.tint = 0x00FF00; // Active tab color } } function updateShopDisplay() { // Update coins in shop var shopCoinsText = shopScreen.children.find(function (child) { return child instanceof Text2 && child.text && child.text.startsWith('Coins:'); }); if (shopCoinsText) { shopCoinsText.setText('Coins: ' + bart.coins); } // Update title screen coins display titleCoinsText.setText('Coins: ' + bart.coins); // Update weapon status texts weaponsContainer.children.forEach(function (child) { if (child instanceof Text2 && child.weaponId) { if (unlockedWeapons.indexOf(child.weaponId) !== -1) { var newText = selectedWeapon === child.weaponId ? 'EQUIPPED' : 'OWNED'; var newColor = selectedWeapon === child.weaponId ? 0x00FFFF : 0x00FF00; child.setText(newText); // Remove old text and create new one with correct color var parent = child.parent; var x = child.x; var y = child.y; var weaponId = child.weaponId; parent.removeChild(child); var newTextObj = new Text2(newText, { size: 50, fill: newColor }); newTextObj.anchor.set(0.5, 0.5); newTextObj.x = x; newTextObj.y = y; newTextObj.weaponId = weaponId; parent.addChild(newTextObj); } } }); // Update subweapon status texts subweaponsContainer.children.forEach(function (child) { if (child instanceof Text2 && child.subweaponId) { if (unlockedSubweapons.indexOf(child.subweaponId) !== -1) { var newText = selectedSubweapon === child.subweaponId ? 'EQUIPPED' : 'OWNED'; var newColor = selectedSubweapon === child.subweaponId ? 0x00FFFF : 0x00FF00; child.setText(newText); // Remove old text and create new one with correct color var parent = child.parent; var x = child.x; var y = child.y; var subweaponId = child.subweaponId; parent.removeChild(child); var newTextObj = new Text2(newText, { size: 45, fill: newColor }); newTextObj.anchor.set(0.5, 0.5); newTextObj.x = x; newTextObj.y = y; newTextObj.subweaponId = subweaponId; parent.addChild(newTextObj); } } }); } function startGame() { gameStarted = true; // Hide title screen titleScreen.visible = false; // Show game elements bart.visible = true; levelText.visible = true; xpBarBg.visible = true; xpBarFill.visible = true; coinText.visible = true; waveText.visible = true; scoreText.visible = true; healthBarBg.visible = true; healthBarFill.visible = true; // Apply selected weapon stats var stats = weaponStats[selectedWeapon]; bart.damage = stats.damage; bart.fireRate = stats.fireRate; // Update Bart's visual appearance bart.updateWeaponVisual(selectedWeapon); // Giant Mutant Rush mode setup if (isGiantMutantRush) { // Set Bart to level 10 bart.level = 10; bart.xpToNext = 1000; bart.maxHealth = 100 + 9 * 20; // 9 level ups worth of health bart.health = bart.maxHealth; bart.damage = stats.damage + 9 * 5; // 9 level ups worth of damage bart.fireRate = Math.max(10, stats.fireRate - 9 * 2); // 9 level ups worth of fire rate // Update UI levelText.setText('Level ' + bart.level); healthBarFill.scaleX = 1; waveText.setText('GIANT MUTANT RUSH!'); waveText.tint = 0xFF0000; // Spawn the selected boss if (selectedGiantMutant === 'mutant_leader') { // Spawn the Mutant Leader var leader = new MutantLeader(); leader.x = 1024; leader.y = 400; enemies.push(leader); game.addChild(leader); } else if (selectedGiantMutant === 'concert') { // Spawn the Concert var concert = new Concert(); concert.x = 1024; concert.y = 400; // At top of screen enemies.push(concert); game.addChild(concert); } else if (selectedGiantMutant === 'ufo_striker') { // Spawn the UFO Striker var ufo = new UFOStriker(); ufo.x = 1024; ufo.y = 400; enemies.push(ufo); game.addChild(ufo); } else { // Random selection (fallback) var giantType = Math.random() * 3; if (giantType < 1) { // Spawn the Mutant Leader var leader = new MutantLeader(); leader.x = 1024; leader.y = 400; enemies.push(leader); game.addChild(leader); } else if (giantType < 2) { // Spawn the Concert var concert = new Concert(); concert.x = 1024; concert.y = 400; // At top of screen enemies.push(concert); game.addChild(concert); } else { // Spawn the UFO Striker var ufo = new UFOStriker(); ufo.x = 1024; ufo.y = 400; enemies.push(ufo); game.addChild(ufo); } } mutantLeaderSpawned = true; } // Spawn active subweapon if (selectedSubweapon) { if (selectedSubweapon === 'santa_helper') { activeSubweapon = new SantaHelper(); activeSubweapon.x = bart.x + 80; activeSubweapon.y = bart.y + 50; game.addChild(activeSubweapon); } else if (selectedSubweapon === 'krusty_shop') { activeSubweapon = new KrustyShop(); activeSubweapon.x = bart.x + 150; activeSubweapon.y = bart.y - 100; game.addChild(activeSubweapon); } else if (selectedSubweapon === 'snowball_cat') { activeSubweapon = new SnowballCat(); activeSubweapon.x = bart.x - 150; activeSubweapon.y = bart.y; game.addChild(activeSubweapon); } else if (selectedSubweapon === 'maggie_pacifier') { activeSubweapon = new MaggiePacifier(); activeSubweapon.x = bart.x - 100; activeSubweapon.y = bart.y - 150; game.addChild(activeSubweapon); } else if (selectedSubweapon === 'lisa_saxophone') { activeSubweapon = new LisaSaxophone(); activeSubweapon.x = bart.x + 100; activeSubweapon.y = bart.y - 100; game.addChild(activeSubweapon); } else if (selectedSubweapon === 'marge_vacuum') { activeSubweapon = new MargeVacuum(); activeSubweapon.x = bart.x; activeSubweapon.y = bart.y + 100; game.addChild(activeSubweapon); } } // Show initial wave text waveText.setText('Wave 1'); tween(waveText, { scaleX: 2, scaleY: 2 }, { duration: 500, easing: tween.elasticOut }); tween(waveText, { scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.elasticIn }); } function spawnEnemy() { var enemy; // Boss waves: 5, 10, 15, 20 if (wave % 5 === 0) { enemy = new Boss(); // Scale boss health and speed based on wave enemy.maxHealth = 500 + (wave - 5) * 200; enemy.health = enemy.maxHealth; enemy.speed = 1 + wave * 0.1; enemy.xpValue = 100 + wave * 20; } else { var mutantType = Math.random(); if (wave >= 8 && mutantType < 0.1) { enemy = new SamuraiMutant(); enemy.speed = 1.2 + wave * 0.2; enemy.maxHealth = 100 + wave * 15; enemy.health = enemy.maxHealth; enemy.xpValue = 50 + wave * 6; } else if (wave >= 13 && mutantType < 0.15) { enemy = new DrummerMutant(); enemy.speed = 0.8 + wave * 0.1; enemy.maxHealth = 150 + wave * 20; enemy.health = enemy.maxHealth; enemy.xpValue = 45 + wave * 5; } else if (wave >= 13 && mutantType < 0.25) { enemy = new VocalMutant(); enemy.speed = 5 + wave * 0.5; enemy.maxHealth = 40 + wave * 10; enemy.health = enemy.maxHealth; enemy.xpValue = 35 + wave * 4; } else if (wave >= 13 && mutantType < 0.35) { enemy = new RockerMutant(); enemy.speed = 2.5 + wave * 0.3; enemy.maxHealth = 70 + wave * 15; enemy.health = enemy.maxHealth; enemy.xpValue = 40 + wave * 5; } else if (wave >= 8 && mutantType < 0.45) { enemy = new PoetMutant(); enemy.speed = 1 + wave * 0.15; enemy.maxHealth = 80 + wave * 12; enemy.health = enemy.maxHealth; enemy.xpValue = 40 + wave * 5; } else if (wave >= 7 && mutantType < 0.55) { enemy = new ShooterMutant(); enemy.speed = 1.5 + wave * 0.2; enemy.maxHealth = 50 + wave * 10; enemy.health = enemy.maxHealth; enemy.xpValue = 25 + wave * 3; } else if (wave >= 6 && mutantType < 0.45) { enemy = new CookMutant(); enemy.speed = 1.5 + wave * 0.2; enemy.maxHealth = 60 + wave * 10; enemy.health = enemy.maxHealth; enemy.xpValue = 30 + wave * 4; } else if (wave >= 2 && mutantType < 0.65) { enemy = new FastMutant(); enemy.speed = 4 + wave * 0.4; enemy.maxHealth = 15 + wave * 8; enemy.health = enemy.maxHealth; enemy.xpValue = 15 + wave * 2; } else { enemy = new Mutant(); // Progressive scaling for mutants across all 20 waves enemy.speed = 2 + wave * 0.3; enemy.maxHealth = 30 + wave * 15; enemy.health = enemy.maxHealth; enemy.xpValue = 10 + wave * 2; } // Adjust invincibility based on wave if (wave >= 15) { // No invincibility at wave 15 onwards enemy.invincible = false; enemy.invincibilityTimer = 0; } else if (wave >= 10) { // Reduced invincibility (1.5 seconds) at wave 10 onwards enemy.invincibilityTimer = 90; // 1.5 seconds at 60fps } else { // Normal invincibility for waves 1-9 (3 seconds) enemy.invincibilityTimer = 180; // 3 seconds at 60fps } // Special mutant variants for higher waves if (wave >= 10) { enemy.speed += 1; enemy.maxHealth += 50; enemy.health = enemy.maxHealth; mutantGraphics = enemy.children[0]; if (mutantGraphics) { mutantGraphics.tint = 0xFF6666; // Red tint for stronger mutants } } if (wave >= 15) { enemy.speed += 1; enemy.maxHealth += 100; enemy.health = enemy.maxHealth; mutantGraphics = enemy.children[0]; if (mutantGraphics) { mutantGraphics.tint = 0xFF0000; // Dark red tint for elite mutants } } } enemy.x = Math.random() * 1848 + 100; enemy.y = -100; enemies.push(enemy); game.addChild(enemy); } function shootBullet() { if (bart.fireTimer > 0 || enemies.length === 0) return; var closestEnemy = null; var closestDist = Infinity; for (var i = 0; i < enemies.length; i++) { var dx = enemies[i].x - bart.x; var dy = enemies[i].y - bart.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < closestDist) { closestDist = dist; closestEnemy = enemies[i]; } } if (closestEnemy && closestDist < 800) { var stats = weaponStats[selectedWeapon]; if (selectedWeapon === 'flower') { // Continuous beam weapon var bullet = new FlowerBeam(); bullet.x = bart.x; bullet.y = bart.y; bullet.target = closestEnemy; bullet.damage = bart.damage; bullet.speed = 25; bullets.push(bullet); game.addChild(bullet); } else if (selectedWeapon === 'dartgun') { // Dart gun projectile var bullet = new Dart(); bullet.x = bart.x; bullet.y = bart.y; bullet.target = closestEnemy; bullet.damage = bart.damage; bullets.push(bullet); game.addChild(bullet); } else if (selectedWeapon === 'scattershot') { // Scattershot peanut var bullet = new Peanut(); bullet.x = bart.x; bullet.y = bart.y; bullet.target = closestEnemy; bullet.damage = bart.damage; bullets.push(bullet); game.addChild(bullet); } else if (selectedWeapon === 'bow') { // Toy Bow rubber arrow var bullet = new RubberArrow(); bullet.x = bart.x; bullet.y = bart.y; bullet.target = closestEnemy; bullet.damage = bart.damage; bullets.push(bullet); game.addChild(bullet); } else if (selectedWeapon === 'pot') { // Pot-a-Bomb projectile var bullet = new PotBomb(); bullet.x = bart.x; bullet.y = bart.y; bullet.target = closestEnemy; bullet.damage = bart.damage; bullets.push(bullet); game.addChild(bullet); } else if (selectedWeapon === 'spraycan') { // Spraycan projectile var bullet = new Spray(); bullet.x = bart.x; bullet.y = bart.y; bullet.target = closestEnemy; bullet.damage = bart.damage; bullets.push(bullet); game.addChild(bullet); } else if (selectedWeapon === 'ducky') { // Triple shot with spread for (var i = -1; i <= 1; i++) { var bullet = new Bullet(); bullet.x = bart.x + i * 30; bullet.y = bart.y; // Create spread by offsetting target position var spreadAngle = i * 0.3; // 0.3 radians spread per bullet var targetDx = closestEnemy.x - bart.x; var targetDy = closestEnemy.y - bart.y; var targetDist = Math.sqrt(targetDx * targetDx + targetDy * targetDy); // Apply spread to target direction var currentAngle = Math.atan2(targetDy, targetDx); var newAngle = currentAngle + spreadAngle; // Create a virtual target with spread var virtualTarget = { x: bart.x + Math.cos(newAngle) * targetDist, y: bart.y + Math.sin(newAngle) * targetDist }; bullet.target = virtualTarget; bullet.damage = bart.damage; bullets.push(bullet); game.addChild(bullet); } } else { // Single shot (slingshot) var bullet = new Bullet(); bullet.x = bart.x; bullet.y = bart.y; bullet.target = closestEnemy; bullet.damage = bart.damage; bullets.push(bullet); game.addChild(bullet); } bart.fireTimer = bart.fireRate; LK.getSound('shoot').play(); } } function spawnItem(x, y, type) { var item; if (type === 'coin') { item = new Coin(); } else { item = new PowerUp(); } item.x = x; item.y = y; items.push(item); game.addChild(item); } game.down = function (x, y, obj) { if (!gameStarted) { if (bossSelectionScreen.visible) { // Boss selection screen interactions if (x > 100 && x < 300 && y > 100 && y < 300) { // Back button bossSelectionScreen.visible = false; titleScreen.visible = true; } else if (x > 724 && x < 1324 && y > 500 && y < 700) { // Mutant Leader button if (bart.coins >= 50) { bart.coins -= 50; try { storage.coins = bart.coins; } catch (e) { console.log('Could not save coins for Boss rush entry fee:', e); } coinText.setText('Coins: ' + bart.coins); titleCoinsText.setText('Coins: ' + bart.coins); bossSelectionCoinsText.setText('Coins: ' + bart.coins); selectedGiantMutant = 'mutant_leader'; isGiantMutantRush = true; bossSelectionScreen.visible = false; startGame(); } } else if (x > 724 && x < 1324 && y > 750 && y < 950) { // Concert button if (bart.coins >= 50) { bart.coins -= 50; try { storage.coins = bart.coins; } catch (e) { console.log('Could not save coins for Boss rush entry fee:', e); } coinText.setText('Coins: ' + bart.coins); titleCoinsText.setText('Coins: ' + bart.coins); bossSelectionCoinsText.setText('Coins: ' + bart.coins); selectedGiantMutant = 'concert'; isGiantMutantRush = true; bossSelectionScreen.visible = false; startGame(); } } else if (x > 724 && x < 1324 && y > 1000 && y < 1200) { // UFO Striker button if (bart.coins >= 50) { bart.coins -= 50; try { storage.coins = bart.coins; } catch (e) { console.log('Could not save coins for Boss rush entry fee:', e); } coinText.setText('Coins: ' + bart.coins); titleCoinsText.setText('Coins: ' + bart.coins); bossSelectionCoinsText.setText('Coins: ' + bart.coins); selectedGiantMutant = 'ufo_striker'; isGiantMutantRush = true; bossSelectionScreen.visible = false; startGame(); } } else if (x > 724 && x < 1324 && y > 1250 && y < 1450) { // Random boss button if (bart.coins >= 50) { bart.coins -= 50; try { storage.coins = bart.coins; } catch (e) { console.log('Could not save coins for Boss rush entry fee:', e); } coinText.setText('Coins: ' + bart.coins); titleCoinsText.setText('Coins: ' + bart.coins); bossSelectionCoinsText.setText('Coins: ' + bart.coins); selectedGiantMutant = 'random'; isGiantMutantRush = true; bossSelectionScreen.visible = false; startGame(); } } } else if (encyclopediaScreen.visible) { // Encyclopedia interactions var localX = x - encyclopediaScreen.x; var localY = y - encyclopediaScreen.y; if (localX > -75 && localX < 75 && localY > 325 && localY < 375) { // Close button encyclopediaScreen.visible = false; titleScreen.visible = true; } else if (localX > -275 && localX < -125 && localY > 255 && localY < 305) { // Previous button encyclopediaScreen.prevPage(); } else if (localX > 125 && localX < 275 && localY > 255 && localY < 305) { // Next button encyclopediaScreen.nextPage(); } } else if (shopScreen.visible) { // Shop interactions if (x > 100 && x < 300 && y > 100 && y < 300) { // Back button shopScreen.visible = false; titleScreen.visible = true; } // Tab buttons if (x > 650 && x < 850 && y > 200 && y < 300) { // Weapons tab switchShopTab('weapons'); } else if (x > 1198 && x < 1398 && y > 200 && y < 300) { // Subweapons tab switchShopTab('subweapons'); } // Subweapon buttons (only when subweapons tab is active) if (currentTab === 'subweapons') { var subweaponY = [400, 550, 700]; var subweaponIds = ['santa_helper', 'krusty_shop', 'snowball_cat']; for (var i = 0; i < subweaponY.length; i++) { if (x > 224 && x < 1824 && y > subweaponY[i] - 96 && y < subweaponY[i] + 96) { var subweaponId = subweaponIds[i]; if (unlockedSubweapons.indexOf(subweaponId) !== -1) { // Already owned - equip it selectedSubweapon = selectedSubweapon === subweaponId ? null : subweaponId; try { storage.selectedSubweapon = selectedSubweapon; } catch (e) { console.log('Could not save selected subweapon:', e); } updateShopDisplay(); } else if (bart.coins >= subweaponPrices[subweaponId]) { // Can afford - buy it bart.coins -= subweaponPrices[subweaponId]; unlockedSubweapons.push(subweaponId); selectedSubweapon = subweaponId; try { storage.coins = bart.coins; storage.unlockedSubweapons = unlockedSubweapons; storage.selectedSubweapon = selectedSubweapon; } catch (e) { console.log('Could not save subweapon purchase:', e); } updateShopDisplay(); } } } } // Weapon buttons (only when weapons tab is active) if (currentTab === 'weapons') { var weaponY = [400, 550, 700, 850, 1000, 1150, 1300, 1450]; var weaponIds = ['slingshot', 'dartgun', 'scattershot', 'ducky', 'bow', 'spraycan', 'pot', 'flower']; for (var i = 0; i < weaponY.length; i++) { if (x > 224 && x < 1824 && y > weaponY[i] - 120 && y < weaponY[i] + 120) { var weaponId = weaponIds[i]; if (unlockedWeapons.indexOf(weaponId) !== -1) { // Already owned - equip it selectedWeapon = weaponId; bart.updateWeaponVisual(selectedWeapon); try { storage.selectedWeapon = selectedWeapon; } catch (e) { console.log('Could not save selected weapon:', e); } updateShopDisplay(); } else if (bart.coins >= weaponPrices[weaponId]) { // Can afford - buy it bart.coins -= weaponPrices[weaponId]; unlockedWeapons.push(weaponId); selectedWeapon = weaponId; bart.updateWeaponVisual(selectedWeapon); try { storage.coins = bart.coins; storage.unlockedWeapons = unlockedWeapons; storage.selectedWeapon = selectedWeapon; } catch (e) { console.log('Could not save weapon purchase:', e); } updateShopDisplay(); } } } } } else { // Title screen if (x > 824 && x < 1224 && y > 1300 && y < 1500) { // Start button startGame(); } else if (x > 824 && x < 1224 && y > 1700 && y < 1900) { // Shop button titleScreen.visible = false; shopScreen.visible = true; updateShopDisplay(); } else if (x > 824 && x < 1224 && y > 2000 && y < 2200) { // Encyclopedia button titleScreen.visible = false; encyclopediaScreen.visible = true; } else if (x > 724 && x < 1324 && y > 2300 && y < 2500) { // Giant Mutant Rush button - show boss selection if (bart.coins >= 50) { titleScreen.visible = false; bossSelectionScreen.visible = true; bossSelectionCoinsText.setText('Coins: ' + bart.coins); } else { // Flash button red to indicate insufficient funds LK.effects.flashObject(giantMutantRushButton, 0xFF0000, 500); } } } } else { dragTarget = bart; } }; game.up = function (x, y, obj) { dragTarget = null; }; game.move = function (x, y, obj) { if (dragTarget && !bart.stunned) { dragTarget.x = Math.max(60, Math.min(1988, x)); dragTarget.y = Math.max(80, Math.min(2652, y)); } }; game.update = function () { if (!gameStarted) { // Animate title on title screen titleText.y = 800 + Math.sin(LK.ticks * 0.05) * 20; return; } // Handle attack speed debuff if (bart.attackSpeedDebuffTimer && bart.attackSpeedDebuffTimer > 0) { bart.attackSpeedDebuffTimer--; if (bart.attackSpeedDebuffTimer <= 0) { bart.fireRate = bart.originalFireRate; // Restore Bart's normal weapon visual bart.updateWeaponVisual(selectedWeapon); } } shootBullet(); spawnTimer--; if (spawnTimer <= 0) { if (!isGiantMutantRush) { spawnEnemy(); // Dynamic spawn rate that gets faster but never too overwhelming var baseSpawnRate = 120 - wave * 4; if (wave >= 10) baseSpawnRate -= 20; // Faster spawning for waves 10+ if (wave >= 15) baseSpawnRate += 30; // Slower spawning for waves 15+ to reduce difficulty spawnTimer = Math.max(20, baseSpawnRate); } else { // Giant Mutant Rush mode - no regular spawning spawnTimer = 60; } } for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (bullet.shouldDestroy || bullet.y < -50 || bullet.y > 2782) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check for reflection by Samurai Mutant's katana var reflected = false; for (var s = 0; s < enemies.length; s++) { if (enemies[s] instanceof SamuraiMutant && !enemies[s].invincible) { var samurai = enemies[s]; var dx = bullet.x - samurai.x; var dy = bullet.y - samurai.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < samurai.reflectRadius) { // Reflect the bullet back towards Bart reflected = true; if (bart) { bullet.target = bart; // Reverse bullet direction var newDx = bart.x - bullet.x; var newDy = bart.y - bullet.y; var newDist = Math.sqrt(newDx * newDx + newDy * newDy); if (newDist > 0) { bullet.velocityX = newDx / newDist * bullet.speed; bullet.velocityY = newDy / newDist * bullet.speed; } } // Visual effect for reflection LK.effects.flashObject(samurai.katana, 0xFFFFFF, 200); LK.getSound('hit').play(); break; } } } if (reflected) continue; for (var j = enemies.length - 1; j >= 0; j--) { if (bullet.intersects(enemies[j])) { // Handle spray stun if (bullet instanceof Spray) { enemies[j].takeDamage(bullet.damage, bullet.stunDuration); } else { enemies[j].takeDamage(bullet.damage); } // Handle rubber arrow - no longer pierces if (bullet instanceof RubberArrow) { bullet.destroy(); bullets.splice(i, 1); break; } // Handle pot bomb explosion if (bullet instanceof PotBomb) { bullet.explode(); bullets.splice(i, 1); break; } // Handle peanut splitting if (bullet instanceof Peanut && !bullet.hasSplit) { bullet.hasSplit = true; // Create 3 small nuts for (var k = 0; k < 3; k++) { var nut = new SmallNut(); nut.x = bullet.x; nut.y = bullet.y; // Spread nuts in different directions var angle = (k - 1) * 0.8; // -0.8, 0, 0.8 radians nut.velocityX = Math.sin(angle) * 8; nut.velocityY = Math.cos(angle) * -8; bullets.push(nut); game.addChild(nut); } } bullet.destroy(); bullets.splice(i, 1); break; } } // Check if reflected bullet hits Bart if (bullet.target === bart && bullet.intersects(bart)) { bart.takeDamage(bullet.damage); bullet.destroy(); bullets.splice(i, 1); break; } // Check collision with alien meals for (var j = alienMeals.length - 1; j >= 0; j--) { if (bullet.intersects(alienMeals[j])) { alienMeals[j].destroy(); alienMeals.splice(j, 1); bullet.destroy(); bullets.splice(i, 1); LK.effects.flashObject(bullet, 0xFF0000, 200); break; } } } var bartTookDamage = false; for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; if (enemy.intersects(bart)) { if (enemy instanceof MutantLeader || enemy instanceof Concert || enemy instanceof UFOStriker) { // Instant kill for Giant Mutants (UFO Striker starts kidnapping instead) if (enemy instanceof UFOStriker) { // UFO Striker starts kidnapping on touch continue; // Skip normal damage, UFO handles it } bart.health = 0; bart.takeDamage(0); // Trigger game over } else { var damage = 10; if (enemy instanceof VocalMutant) { damage = enemy.getDamage(); } else if (enemy.damageMultiplier) { damage = Math.floor(10 * enemy.damageMultiplier); } bart.takeDamage(damage); enemy.shouldDestroy = true; } bartTookDamage = true; } if (enemy.y > 2832) { enemy.destroy(); enemies.splice(i, 1); } } // Handle speed boost timers for (var i = 0; i < enemies.length; i++) { if (enemies[i].speedBoosted && enemies[i].speedBoostTimer) { enemies[i].speedBoostTimer--; if (enemies[i].speedBoostTimer <= 0) { enemies[i].speed = enemies[i].originalSpeed; enemies[i].speedBoosted = false; } } } // Only process enemy destruction and XP gain if Bart didn't take damage this frame if (!bartTookDamage) { for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; if (enemy.shouldDestroy) { var xpToGain = enemy.xpValue; // Double XP for Toy Bow weapon if (selectedWeapon === 'bow') { xpToGain = enemy.xpValue * 2; } bart.gainXP(xpToGain); LK.setScore(LK.getScore() + enemy.xpValue); scoreText.setText('Score: ' + LK.getScore()); enemiesKilled++; // Automatic 350 coins for Giant Mutants in Giant Mutant Rush mode if (isGiantMutantRush && (enemy instanceof MutantLeader || enemy instanceof Concert || enemy instanceof UFOStriker)) { bart.coins += 350; coinText.setText('Coins: ' + bart.coins); try { storage.coins = bart.coins; } catch (e) { console.log('Could not save coins for Giant Mutant:', e); } } if (Math.random() < enemy.coinChance) { if (enemy instanceof MutantLeader) { // Drop tons of coins for Mutant Leader for (var c = 0; c < 20; c++) { spawnItem(enemy.x + (Math.random() - 0.5) * 200, enemy.y + (Math.random() - 0.5) * 200, 'coin'); } } else { spawnItem(enemy.x, enemy.y, 'coin'); } } if (Math.random() < enemy.powerupChance) { spawnItem(enemy.x, enemy.y, 'powerup'); } // Check if this was a Giant Mutant in Giant Mutant Rush mode if (isGiantMutantRush && (enemy instanceof MutantLeader || enemy instanceof Concert || enemy instanceof UFOStriker)) { // Victory! try { storage.coins = bart.coins; } catch (e) { console.log('Could not save coins on victory:', e); } LK.showYouWin(); } enemy.destroy(); enemies.splice(i, 1); // Dynamic enemy count per wave - starts at 10, increases every 5 waves var enemiesNeeded = 10 + Math.floor((wave - 1) / 5) * 5; if (enemiesKilled >= enemiesNeeded) { wave++; enemiesKilled = 0; // Infinite waves - no win condition waveText.setText('Wave ' + wave); // Special celebration for milestone waves if (wave % 5 === 0) { LK.effects.flashScreen(0xFFD700, 1000); waveText.tint = 0xFFD700; } else { waveText.tint = 0xFFFFFF; } tween(waveText, { scaleX: 2, scaleY: 2 }, { duration: 500, easing: tween.elasticOut }); tween(waveText, { scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.elasticIn }); } continue; } } } else { // If Bart took damage, still clean up destroyed enemies but don't give XP for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; if (enemy.shouldDestroy) { enemy.destroy(); enemies.splice(i, 1); } } } for (var i = items.length - 1; i >= 0; i--) { var item = items[i]; if (item.shouldDestroy) { item.destroy(); items.splice(i, 1); continue; } if (item.intersects(bart)) { if (item instanceof Coin) { bart.coins += item.value; coinText.setText('Coins: ' + bart.coins); try { storage.coins = bart.coins; } catch (e) { console.log('Could not save coins:', e); } LK.getSound('pickup').play(); } else if (item instanceof PowerUp) { if (item.type === 'damage') { bart.damage += 5; } else { bart.fireRate = Math.max(5, bart.fireRate - 5); } LK.getSound('powerup_pickup').play(); } item.destroy(); items.splice(i, 1); } } for (var i = enemyProjectiles.length - 1; i >= 0; i--) { var projectile = enemyProjectiles[i]; if (projectile.shouldDestroy || projectile.y < -50 || projectile.y > 2832 || projectile.x < -50 || projectile.x > 2098) { projectile.destroy(); enemyProjectiles.splice(i, 1); continue; } if (projectile.intersects(bart)) { // Handle StunRay stunning effect if (projectile instanceof StunRay) { bart.takeDamage(projectile.damage); if (!bart.stunned) { bart.stunned = true; bart.stunnedTimer = projectile.stunDuration; } } else { bart.takeDamage(projectile.damage); } projectile.destroy(); enemyProjectiles.splice(i, 1); } } for (var i = alienMeals.length - 1; i >= 0; i--) { var meal = alienMeals[i]; if (meal.shouldDestroy) { meal.destroy(); alienMeals.splice(i, 1); } } levelText.setText('Level ' + bart.level); xpBarFill.scaleX = bart.xp / bart.xpToNext; }; LK.playMusic('battle');
===================================================================
--- original.js
+++ change.js
@@ -964,8 +964,17 @@
content: "Spawns powerups periodically.\nSpawn Rate: Every 15 seconds\nPowerup Types: Damage/Fire Rate\nCost: 1200 coins"
}, {
title: "SNOWBALL II",
content: "Sneaky cat that distracts enemies.\nDistraction Range: 600 pixels\nReduces invincibility by 50%\nSpeed: 8\nCost: 900 coins"
+ }, {
+ title: "MAGGIE'S PACIFIER",
+ content: "Shoots pacifiers at random enemies.\nDamage: 20 per hit\nFire Rate: Every 1.5 seconds\nSleep Effect: 2 seconds in 150px radius\nCost: 1000 coins"
+ }, {
+ title: "LISA'S SAXOPHONE",
+ content: "Creates protective sound barriers.\nBarrier Health: 150 HP\nBarrier Duration: 10 seconds\nBlocks enemy projectiles\nSlows enemies by 70%\nCost: 1500 coins"
+ }, {
+ title: "MARGE'S VACUUM",
+ content: "Sucks in items automatically.\nSuction Range: 400 pixels\nCleanup Blast: Every 5 seconds\nBlast Damage: 25 to nearby enemies\nCost: 1100 coins"
},
// Game Features
{
title: "POWER-UPS",
@@ -1054,8 +1063,23 @@
LK.getSound('hit').play();
}
};
self.update = function () {
+ // Handle sleep effect
+ if (self.sleeping) {
+ self.sleepTimer--;
+ if (self.sleepTimer <= 0) {
+ self.sleeping = false;
+ self.speed = self.originalSpeed;
+ tween(self, {
+ alpha: 1
+ }, {
+ duration: 200,
+ easing: tween.easeIn
+ });
+ }
+ return; // Don't move when sleeping
+ }
if (self.invincible) {
self.invincibilityTimer--;
mutantGraphics.alpha = 0.5 + Math.sin(LK.ticks * 0.3) * 0.3; // Flashing effect
if (self.invincibilityTimer <= 0) {
@@ -1171,8 +1195,229 @@
self.rotation += 0.15;
};
return self;
});
+var LisaSaxophone = Container.expand(function () {
+ var self = Container.call(this);
+ var saxGraphics = self.attachAsset('sound_wave', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.8,
+ scaleY: 0.8,
+ tint: 0xFFD700 // Gold color for saxophone
+ });
+ self.barrierTimer = 0;
+ self.barrierInterval = 480; // 8 seconds
+ self.barriers = [];
+ self.update = function () {
+ self.barrierTimer--;
+ // Gentle swaying animation
+ self.rotation = Math.sin(LK.ticks * 0.05) * 0.1;
+ if (self.barrierTimer <= 0) {
+ // Create sound barrier
+ var barrier = new SoundBarrier();
+ barrier.x = self.x;
+ barrier.y = self.y - 100;
+ self.barriers.push(barrier);
+ game.addChild(barrier);
+ self.barrierTimer = self.barrierInterval;
+ // Visual effect when creating barrier
+ LK.effects.flashObject(self, 0xFFD700, 500);
+ tween(saxGraphics, {
+ scaleX: 1.5,
+ scaleY: 1.5
+ }, {
+ duration: 300,
+ easing: tween.easeOut
+ });
+ tween(saxGraphics, {
+ scaleX: 0.8,
+ scaleY: 0.8
+ }, {
+ duration: 300,
+ easing: tween.easeIn
+ });
+ }
+ // Clean up destroyed barriers
+ self.barriers = self.barriers.filter(function (barrier) {
+ return !barrier.destroyed && !barrier.shouldDestroy;
+ });
+ };
+ return self;
+});
+var MaggiePacifier = Container.expand(function () {
+ var self = Container.call(this);
+ var pacifierGraphics = self.attachAsset('powerup', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ tint: 0xFF69B4 // Pink tint for pacifier
+ });
+ self.shootTimer = 0;
+ self.shootInterval = 90; // 1.5 seconds
+ self.projectileSpeed = 8;
+ self.projectileDamage = 20;
+ self.update = function () {
+ self.shootTimer--;
+ // Bobbing animation
+ self.y += Math.sin(LK.ticks * 0.1) * 0.5;
+ if (self.shootTimer <= 0 && enemies.length > 0) {
+ // Find random enemy to shoot at
+ var targetEnemy = enemies[Math.floor(Math.random() * enemies.length)];
+ if (targetEnemy) {
+ var pacifier = new PacifierProjectile();
+ pacifier.x = self.x;
+ pacifier.y = self.y;
+ pacifier.target = targetEnemy;
+ pacifier.damage = self.projectileDamage;
+ bullets.push(pacifier);
+ game.addChild(pacifier);
+ self.shootTimer = self.shootInterval;
+ // Visual effect when shooting
+ tween(pacifierGraphics, {
+ scaleX: 1.3,
+ scaleY: 1.3
+ }, {
+ duration: 100,
+ easing: tween.easeOut
+ });
+ tween(pacifierGraphics, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 100,
+ easing: tween.easeIn
+ });
+ }
+ }
+ };
+ return self;
+});
+var MargeVacuum = Container.expand(function () {
+ var self = Container.call(this);
+ var vacuumGraphics = self.attachAsset('healthbar_bg', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.8,
+ scaleY: 1.2,
+ tint: 0x4B0082 // Indigo color for vacuum
+ });
+ // Vacuum nozzle
+ var nozzle = self.attachAsset('healthbar_fill', {
+ anchorX: 0,
+ anchorY: 0.5,
+ x: 40,
+ y: 0,
+ scaleX: 0.4,
+ scaleY: 0.3,
+ tint: 0x808080
+ });
+ self.suctionRadius = 400;
+ self.suctionPower = 8;
+ self.cleanupTimer = 0;
+ self.cleanupInterval = 300; // 5 seconds
+ self.isActive = false;
+ self.update = function () {
+ // Vacuum animation
+ vacuumGraphics.rotation = Math.sin(LK.ticks * 0.1) * 0.05;
+ nozzle.scaleY = 0.3 + Math.sin(LK.ticks * 0.2) * 0.05;
+ // Suck in items
+ for (var i = 0; i < items.length; i++) {
+ var item = items[i];
+ var dx = self.x - item.x;
+ var dy = self.y - item.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < self.suctionRadius && dist > 20) {
+ // Pull items towards vacuum
+ item.x += dx / dist * self.suctionPower;
+ item.y += dy / dist * self.suctionPower;
+ // Speed up spinning when being sucked
+ item.rotation += 0.3;
+ if (!self.isActive) {
+ self.isActive = true;
+ // Start vacuum sound effect
+ tween(vacuumGraphics, {
+ scaleX: 1,
+ scaleY: 1.4
+ }, {
+ duration: 200,
+ easing: tween.easeOut
+ });
+ }
+ }
+ }
+ // Also pull in pottery shards from destroyed pots
+ for (var i = 0; i < bullets.length; i++) {
+ if (bullets[i] instanceof PotteryShard) {
+ var shard = bullets[i];
+ var dx = self.x - shard.x;
+ var dy = self.y - shard.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < self.suctionRadius && dist > 20) {
+ shard.x += dx / dist * (self.suctionPower * 0.5);
+ shard.y += dy / dist * (self.suctionPower * 0.5);
+ }
+ }
+ }
+ if (self.isActive && items.length === 0) {
+ self.isActive = false;
+ tween(vacuumGraphics, {
+ scaleX: 0.8,
+ scaleY: 1.2
+ }, {
+ duration: 200,
+ easing: tween.easeIn
+ });
+ }
+ // Periodic cleanup blast
+ self.cleanupTimer--;
+ if (self.cleanupTimer <= 0) {
+ self.performCleanupBlast();
+ self.cleanupTimer = self.cleanupInterval;
+ }
+ };
+ self.performCleanupBlast = function () {
+ // Visual effect
+ LK.effects.flashObject(self, 0xFFFFFF, 500);
+ // Create expanding ring effect
+ var ring = game.attachAsset('sound_wave', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: self.x,
+ y: self.y,
+ scaleX: 0.1,
+ scaleY: 0.1,
+ tint: 0x4B0082,
+ alpha: 0.8
+ });
+ tween(ring, {
+ scaleX: 6,
+ scaleY: 6,
+ alpha: 0
+ }, {
+ duration: 500,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ ring.destroy();
+ }
+ });
+ // Damage and push back nearby enemies
+ for (var i = 0; i < enemies.length; i++) {
+ var enemy = enemies[i];
+ var dx = enemy.x - self.x;
+ var dy = enemy.y - self.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < 300) {
+ enemy.takeDamage(25);
+ // Push enemies away
+ if (dist > 0) {
+ enemy.x += dx / dist * 100;
+ enemy.y += dy / dist * 100;
+ }
+ }
+ }
+ };
+ return self;
+});
var Mutant = Container.expand(function () {
var self = Container.call(this);
var mutantGraphics = self.attachAsset('mutant', {
anchorX: 0.5,
@@ -1201,8 +1446,23 @@
LK.getSound('hit').play();
}
};
self.update = function () {
+ // Handle sleep effect
+ if (self.sleeping) {
+ self.sleepTimer--;
+ if (self.sleepTimer <= 0) {
+ self.sleeping = false;
+ self.speed = self.originalSpeed;
+ tween(self, {
+ alpha: 1
+ }, {
+ duration: 200,
+ easing: tween.easeIn
+ });
+ }
+ return; // Don't move when sleeping
+ }
if (self.stunned) {
self.stunnedTimer--;
mutantGraphics.tint = 0x00FF00; // Green tint when stunned
if (self.stunnedTimer <= 0) {
@@ -1394,8 +1654,63 @@
}
};
return self;
});
+var PacifierProjectile = Container.expand(function () {
+ var self = Container.call(this);
+ var projectileGraphics = self.attachAsset('powerup', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.6,
+ scaleY: 0.6,
+ tint: 0xFF69B4
+ });
+ self.damage = 20;
+ self.speed = 8;
+ self.target = null;
+ self.lifetime = 120;
+ self.sleepRadius = 150;
+ self.update = function () {
+ self.lifetime--;
+ if (self.lifetime <= 0) {
+ self.shouldDestroy = true;
+ return;
+ }
+ if (self.target && !self.target.destroyed) {
+ var dx = self.target.x - self.x;
+ var dy = self.target.y - self.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist > 0) {
+ self.x += dx / dist * self.speed;
+ self.y += dy / dist * self.speed;
+ }
+ // Apply sleep effect to nearby enemies
+ for (var i = 0; i < enemies.length; i++) {
+ var enemy = enemies[i];
+ var eDx = enemy.x - self.x;
+ var eDy = enemy.y - self.y;
+ var eDist = Math.sqrt(eDx * eDx + eDy * eDy);
+ if (eDist < self.sleepRadius && !enemy.sleeping) {
+ enemy.sleeping = true;
+ enemy.sleepTimer = 120; // 2 seconds of sleep
+ enemy.originalSpeed = enemy.speed;
+ enemy.speed = 0;
+ // Visual effect for sleeping
+ tween(enemy, {
+ alpha: 0.5
+ }, {
+ duration: 200,
+ easing: tween.easeOut
+ });
+ }
+ }
+ } else {
+ self.y -= self.speed;
+ }
+ self.rotation += 0.15;
+ };
+ return self;
+});
var Peanut = Container.expand(function () {
var self = Container.call(this);
var peanutGraphics = self.attachAsset('peanut', {
anchorX: 0.5,
@@ -1995,8 +2310,77 @@
catGraphics.rotation = Math.atan2(self.velocityY, self.velocityX) * 0.2; // Face movement direction
};
return self;
});
+var SoundBarrier = Container.expand(function () {
+ var self = Container.call(this);
+ // Create a wide barrier using multiple sound waves
+ self.waves = [];
+ for (var i = 0; i < 5; i++) {
+ var wave = self.attachAsset('sound_wave', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: (i - 2) * 80,
+ y: 0,
+ scaleX: 1.2,
+ scaleY: 0.8,
+ tint: 0xFFD700,
+ alpha: 0.6
+ });
+ self.waves.push(wave);
+ }
+ self.health = 150;
+ self.lifetime = 600; // 10 seconds
+ self.width = 400;
+ self.height = 80;
+ self.takeDamage = function (damage) {
+ self.health -= damage;
+ LK.effects.flashObject(self, 0xFF0000, 200);
+ if (self.health <= 0) {
+ self.shouldDestroy = true;
+ }
+ };
+ self.update = function () {
+ self.lifetime--;
+ if (self.lifetime <= 0) {
+ self.shouldDestroy = true;
+ return;
+ }
+ // Pulsing effect
+ for (var i = 0; i < self.waves.length; i++) {
+ self.waves[i].alpha = 0.4 + Math.sin(LK.ticks * 0.1 + i * 0.5) * 0.2;
+ self.waves[i].scaleY = 0.8 + Math.sin(LK.ticks * 0.15 + i * 0.3) * 0.1;
+ }
+ // Block enemy projectiles
+ for (var i = enemyProjectiles.length - 1; i >= 0; i--) {
+ var projectile = enemyProjectiles[i];
+ var dx = Math.abs(projectile.x - self.x);
+ var dy = Math.abs(projectile.y - self.y);
+ if (dx < self.width / 2 && dy < self.height / 2) {
+ self.takeDamage(projectile.damage || 10);
+ projectile.destroy();
+ enemyProjectiles.splice(i, 1);
+ }
+ }
+ // Slow down enemies passing through
+ for (var i = 0; i < enemies.length; i++) {
+ var enemy = enemies[i];
+ var dx = Math.abs(enemy.x - self.x);
+ var dy = Math.abs(enemy.y - self.y);
+ if (dx < self.width / 2 && dy < self.height / 2) {
+ if (!enemy.barrierSlowed) {
+ enemy.barrierSlowed = true;
+ enemy.originalBarrierSpeed = enemy.speed;
+ enemy.speed *= 0.3; // 70% speed reduction
+ }
+ } else if (enemy.barrierSlowed) {
+ enemy.speed = enemy.originalBarrierSpeed;
+ enemy.barrierSlowed = false;
+ }
+ }
+ };
+ return self;
+});
var SoundWave = Container.expand(function () {
var self = Container.call(this);
var waveGraphics = self.attachAsset('sound_wave', {
anchorX: 0.5,
@@ -2621,9 +3005,12 @@
var unlockedSubweapons = [];
var subweaponPrices = {
santa_helper: 750,
krusty_shop: 1200,
- snowball_cat: 900
+ snowball_cat: 900,
+ maggie_pacifier: 1000,
+ lisa_saxophone: 1500,
+ marge_vacuum: 1100
};
var activeSubweapon = null;
var encyclopediaScreen;
// Create title screen
@@ -3125,8 +3512,23 @@
id: 'snowball_cat',
name: 'Snowball II',
desc: 'Distracts enemies & reduces invincibility',
y: 700
+}, {
+ id: 'maggie_pacifier',
+ name: "Maggie's Pacifier",
+ desc: 'Shoots pacifiers that make enemies sleep',
+ y: 850
+}, {
+ id: 'lisa_saxophone',
+ name: "Lisa's Saxophone",
+ desc: 'Creates sound barriers that block projectiles',
+ y: 1000
+}, {
+ id: 'marge_vacuum',
+ name: "Marge's Vacuum",
+ desc: 'Sucks in items & blasts enemies away',
+ y: 1150
}];
subweaponData.forEach(function (subweapon) {
// Subweapon button background
var subweaponBg = subweaponsContainer.attachAsset('healthbar_bg', {
@@ -3382,8 +3784,23 @@
activeSubweapon = new SnowballCat();
activeSubweapon.x = bart.x - 150;
activeSubweapon.y = bart.y;
game.addChild(activeSubweapon);
+ } else if (selectedSubweapon === 'maggie_pacifier') {
+ activeSubweapon = new MaggiePacifier();
+ activeSubweapon.x = bart.x - 100;
+ activeSubweapon.y = bart.y - 150;
+ game.addChild(activeSubweapon);
+ } else if (selectedSubweapon === 'lisa_saxophone') {
+ activeSubweapon = new LisaSaxophone();
+ activeSubweapon.x = bart.x + 100;
+ activeSubweapon.y = bart.y - 100;
+ game.addChild(activeSubweapon);
+ } else if (selectedSubweapon === 'marge_vacuum') {
+ activeSubweapon = new MargeVacuum();
+ activeSubweapon.x = bart.x;
+ activeSubweapon.y = bart.y + 100;
+ game.addChild(activeSubweapon);
}
}
// Show initial wave text
waveText.setText('Wave 1');
Bart holding a slingshot. In-Game asset. 2d. High contrast. No shadows
Alien mutant from the Simpsons. In-Game asset. 2d. High contrast. No shadows
Make my character purple
Krusty Burger. In-Game asset. 2d. High contrast. No shadows
Remove Krusty burger
Make my character red
Make my character turquoise and make him hold a bowling ball
Bart holding a plasma gun. In-Game asset. 2d. High contrast. No shadows
Bart holding a shotgun with 2 duck heads instead of barrels and make sure that Bart's body is fully visible In-Game asset. 2d. High contrast. No shadows
Bart in a fighting pose with a flower's head in his shirt. In-Game asset. 2d. High contrast. No shadows
Plasma projectile. In-Game asset. 2d. High contrast. No shadows
Red bowling ball. In-Game asset. 2d. High contrast. No shadows
Santa's Little Helper the Simpsons In-Game asset. 2d. High contrast. No shadows
Make my character have White Classical hair and make him hold a poem
Make my character orange, have a chef's hat and make him hold some Alien Jelly
Alien food: Some green, oozing jelly and some purple shrimp with blue Human eyes all on a plate In-Game asset. 2d. High contrast. No shadows.
Bart holding a light brown slingshot shaped like a peanut. Make him be in a fighting stance In-Game asset. 2d. High contrast. No shadows
Bart holding a purple Spraycan while he is wearing purple shoes and shorts. Show all of his body in a fighting stance In-Game asset. 2d. High contrast. No shadows
Peanut. In-Game asset. 2d. High contrast. No shadows
Chestnut. In-Game asset. 2d. High contrast. No shadows
Add outlines
Make my character dark yellow and have a red samurai helmet
Katana. In-Game asset. 2d. High contrast. No shadows
Make my character have more tentacle based hands and make him have dark black hair with a ponytail (make my character's background white)
Make my character have cute white hair and make him hold a microphone
Make my character pink and make him have rock hair and a rock guitar
Make my character have a brown mustache, hold a gun and have a sergeant's hat
Bart is tired. In-Game asset. 2d. High contrast. No shadows
Bullet. In-Game asset. 2d. High contrast. No shadows
Topdown stageplay design no instruments or crowd, only the base. In-Game asset. 2d. High contrast. No shadows
Bart holding a toy bow and has a quiver full of toy arrows. In-Game asset. 2d. High contrast. No shadows
Bart holding a pot with a plant and is about to throw it. In-Game asset. 2d. High contrast. No shadows
Potted plant. In-Game asset. 2d. High contrast. No shadows
Pottery sherd. In-Game asset. 2d. High contrast. No shadows
Make my character inside an UFO armed with a laser cannon and make him drive it
Itchy's head. In-Game asset. 2d. High contrast. No shadows. Simpsons
Scratchy's head. In-Game asset. 2d. High contrast. No shadows. Simpsons
Itchy and scratchy show!. In-Game asset. 2d. High contrast. No shadows