User prompt
Add new Thingy: Encyclopedia! tells you stuff about enemies and upgrades/subupgrades and Niche Game features! That homework really paid off then... There is one page for each type of enemy/Upgrade/SubupgradFeature.
User prompt
Add new Thingy: Encyclopedia! Read a book that tells you stuff about enemies and upgrades/subupgrades! That homework really paid off then...
User prompt
Add new Thingy: Encyclopedia! Read a book that tells you stuff about enemies and upgrades/subupgrades! That homework really paid off then
User prompt
Rework the Alien meal so that it gives invincibility for 10 seconds for the first non-cook mutant that touches it ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add new enemies: Poet Mutant (sings poems to summon other Mutants to help him out! Kill him as fast as possible. Starts appearing at wave 8), Cook Mutant (makes some alien dishes that heal Mutants! You can shoot at the meals to stop their healing effect! Starts appearing at wave 6) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Santa's little helper should have a bigger sight range
User prompt
Santa's little helper should be a lot faster and he should follow and bite enemies, and should follow Bart if inactive ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Invincibility is reduced to 1.5 seconds at wave 10 onwards and there's no invincibility at wave 15 onwards
User prompt
Add different pages for weapons and sub weapons in Krusty Burger ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add a page for weapons and sub weapons in Krusty Burger ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add a page for weapons and sub weapons ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add new Thingy: Subweapons! They can be used with the main weapons just fine, making you have essentially 2 weapons! But you can only equip one Subweapon at a time and won't change Bart's appearance! (Subweapons: Santa's Little helper: *note that there is no default Subweapon* He is an ally runs fast and bites enemies to death, he can be used as an ally to deal some extra chip damage; Krusty Burger Shop: this Krusty Burger makes a powerups every 15 seconds! Perfect when you're in trouble!) ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
Flower's beam, Dart gun's projectile should have their own assets
User prompt
Ducky triple's projectiles don't spread: fix that
User prompt
Add assets for Bart when he has equipped different weapons
User prompt
Make it so that coin counter is also on the title screen ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Make spawnrate a little lower for the higher levels (from level 15 onwards)
User prompt
Make it so that coins are always in the UI and are always saved when there's a game over ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Your coins don't get saved when the game ends: fix that ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
You don't get levels if an enemy dies when you get damaged
User prompt
Add a healthbar for Bart
User prompt
Please fix the bug: 'TypeError: storage.set is not a function' in or related to this line: 'storage.set('coins', bart.coins);' Line Number: 1014 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'child.style.fill = selectedWeapon === child.weaponId ? 0x00FFFF : 0x00FF00;' Line Number: 680
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'startsWith')' in or related to this line: 'return child instanceof Text2 && child.text.startsWith('Coins:');' Line Number: 670
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'var savedCoins = storage.get('coins') || 0;' Line Number: 543
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ 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.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 () { 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 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 () { 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 } } 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 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.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 } } 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 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 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; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000080 }); /**** * Game Code ****/ var bart; var enemies = []; var bullets = []; var items = []; var enemyProjectiles = []; 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, ducky: 500, flower: 1000 }; var weaponStats = { slingshot: { damage: 10, fireRate: 30, projectileCount: 1 }, dartgun: { damage: 50, fireRate: 60, projectileCount: 1 }, ducky: { damage: 25, fireRate: 45, projectileCount: 3 }, flower: { damage: 3, fireRate: 6, projectileCount: 1 } }; // 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); // 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; try { savedCoins = storage.coins || 0; savedWeapons = storage.unlockedWeapons; savedSelected = storage.selectedWeapon; } catch (e) { console.log('Storage not available:', e); } if (savedWeapons) { unlockedWeapons = savedWeapons; } if (savedSelected) { selectedWeapon = savedSelected; } 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); // Shop title var shopTitle = new Text2('KRUSTY BURGER WEAPONS', { size: 100, fill: 0xFFFF00 }); shopTitle.anchor.set(0.5, 0.5); shopTitle.x = 1024; shopTitle.y = 200; shopScreen.addChild(shopTitle); // 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); // Weapon buttons var weaponData = [{ id: 'slingshot', name: 'Slingshot', desc: 'The Default Weapon', y: 600 }, { id: 'dartgun', name: 'Dart Gun', desc: 'High damage, slow fire rate', y: 900 }, { id: 'ducky', name: 'Ducky Triple', desc: 'Shoots 3 projectiles', y: 1200 }, { id: 'flower', name: "Krusty's Flower", desc: 'Water beam, rapid fire', y: 1500 }]; weaponData.forEach(function (weapon) { // Weapon button background var weaponBg = shopScreen.attachAsset('healthbar_bg', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: weapon.y, scaleX: 4, scaleY: 1.5 }); 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; shopScreen.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; shopScreen.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; shopScreen.addChild(priceText); }); 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 shopScreen.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); } } }); } 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); // 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 >= 7 && mutantType < 0.2) { 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 >= 2 && mutantType < 0.5) { 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; } // 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 Bullet(); 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 === '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, dartgun) 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 (shopScreen.visible) { // Shop interactions if (x > 100 && x < 300 && y > 100 && y < 300) { // Back button shopScreen.visible = false; titleScreen.visible = true; } // Weapon buttons var weaponY = [600, 900, 1200, 1500]; var weaponIds = ['slingshot', 'dartgun', 'ducky', 'flower']; for (var i = 0; i < weaponY.length; i++) { if (x > 624 && x < 1424 && y > weaponY[i] - 60 && y < weaponY[i] + 60) { 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 { dragTarget = bart; } }; game.up = function (x, y, obj) { dragTarget = null; }; game.move = function (x, y, obj) { if (dragTarget) { 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; } shootBullet(); spawnTimer--; if (spawnTimer <= 0) { 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); } 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; } for (var j = enemies.length - 1; j >= 0; j--) { if (bullet.intersects(enemies[j])) { enemies[j].takeDamage(bullet.damage); bullet.destroy(); bullets.splice(i, 1); break; } } } var bartTookDamage = false; for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; if (enemy.intersects(bart)) { bart.takeDamage(10); enemy.shouldDestroy = true; bartTookDamage = true; } if (enemy.y > 2832) { enemy.destroy(); enemies.splice(i, 1); } } // 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) { bart.gainXP(enemy.xpValue); LK.setScore(LK.getScore() + enemy.xpValue); scoreText.setText('Score: ' + LK.getScore()); enemiesKilled++; if (Math.random() < enemy.coinChance) { spawnItem(enemy.x, enemy.y, 'coin'); } if (Math.random() < enemy.powerupChance) { spawnItem(enemy.x, enemy.y, 'powerup'); } 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)) { bart.takeDamage(projectile.damage); projectile.destroy(); enemyProjectiles.splice(i, 1); } } levelText.setText('Level ' + bart.level); xpBarFill.scaleX = bart.xp / bart.xpToNext; }; LK.playMusic('battle');
===================================================================
--- original.js
+++ change.js
@@ -845,14 +845,27 @@
bullet.speed = 25;
bullets.push(bullet);
game.addChild(bullet);
} else if (selectedWeapon === 'ducky') {
- // Triple shot
+ // 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;
- bullet.target = closestEnemy;
+ // 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);
}
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