User prompt
Make it so upgrade button works ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'ReferenceError: Can't find variable: ammoBar' in or related to this line: 'ammoBar.scale.x = player.ammo / player.maxAmmo * 3;' Line Number: 580
User prompt
Make a ammo bar at the top left corner
User prompt
Make a meter that says how much ammo you have
User prompt
Make the enemy bigger
User prompt
Make it so you can click the upgrade button
User prompt
Please fix the bug: 'storage.get is not a function. (In 'storage.get('upgrade_' + upgradeTypes[i])', 'storage.get' is undefined)' in or related to this line: 'var savedLevel = storage.get('upgrade_' + upgradeTypes[i]);' Line Number: 430 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add upgrades
Code edit (1 edits merged)
Please save this source code
User prompt
Shotout Frenzy
User prompt
How about a shotout frenzy
Initial prompt
Hey
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var AmmoUI = Container.expand(function () { var self = Container.call(this); var ammoGraphics = self.attachAsset('ammo', { anchorX: 0.5, anchorY: 0.5 }); var ammoText = new Text2('0', { size: 40, fill: 0xFFFFFF }); ammoText.anchor.set(0.5, 0.5); ammoText.y = 60; self.addChild(ammoText); self.update = function (currentAmmo, maxAmmo) { ammoText.setText(currentAmmo + '/' + maxAmmo); }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 15; self.damage = 1; // Default damage, will be set by player self.update = function () { self.y -= self.speed; }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.health = 1; self.speed = 3; self.scoreValue = 10; self.movePattern = 'direct'; // Can be 'direct', 'zigzag', 'circular' self.moveCounter = 0; self.takeDamage = function (amount) { self.health -= amount; if (self.health <= 0) { return true; // Enemy is destroyed } // Flash white when hit LK.effects.flashObject(self, 0xffffff, 200); return false; }; self.setType = function (type) { if (type === 'basic') { enemyGraphics.tint = 0xe74c3c; // Red self.health = 1; self.speed = 3; self.scoreValue = 10; self.movePattern = 'direct'; } else if (type === 'fast') { enemyGraphics.tint = 0xe67e22; // Orange self.health = 1; self.speed = 6; self.scoreValue = 15; self.movePattern = 'zigzag'; } else if (type === 'tank') { enemyGraphics.tint = 0x7f8c8d; // Gray self.health = 3; self.speed = 2; self.scoreValue = 25; self.movePattern = 'direct'; // Make it bigger enemyGraphics.scale.set(2.0, 2.0); } }; self.update = function () { self.moveCounter++; if (self.movePattern === 'direct') { self.y += self.speed; } else if (self.movePattern === 'zigzag') { self.y += self.speed; self.x += Math.sin(self.moveCounter * 0.1) * 3; } else if (self.movePattern === 'circular') { self.y += self.speed * 0.8; self.x += Math.sin(self.moveCounter * 0.05) * 4; } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100; self.ammo = 30; self.maxAmmo = 30; self.fireRate = 10; self.damage = 1; self.lastFired = 0; self.inFrenzyMode = false; self.frenzyTimeLeft = 0; self.frenzyDuration = 300; // Initial frenzy duration (5 seconds at 60fps) self.takeDamage = function (amount) { self.health -= amount; if (self.health <= 0) { self.health = 0; } // Flash red when taking damage LK.effects.flashObject(self, 0xff0000, 300); }; self.shoot = function () { if (LK.ticks - self.lastFired < 60 / self.fireRate) { return null; } if (self.ammo <= 0 && !self.inFrenzyMode) { return null; } if (!self.inFrenzyMode) { self.ammo--; } self.lastFired = LK.ticks; var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y - 40; bullet.damage = self.damage; LK.getSound('shoot').play(); return bullet; }; self.activateFrenzy = function () { self.inFrenzyMode = true; self.frenzyTimeLeft = self.frenzyDuration; playerGraphics.tint = 0xf39c12; // Change color to orange in frenzy mode }; self.reloadAmmo = function (amount) { self.ammo = Math.min(self.maxAmmo, self.ammo + amount); }; self.update = function () { if (self.inFrenzyMode) { self.frenzyTimeLeft--; if (self.frenzyTimeLeft <= 0) { self.inFrenzyMode = false; playerGraphics.tint = 0xffffff; // Reset color } } }; 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 = 'ammo'; // Can be 'ammo', 'frenzy', 'health' self.speed = 2; self.setType = function (newType) { self.type = newType; if (newType === 'ammo') { powerupGraphics.tint = 0x2ecc71; // Green } else if (newType === 'frenzy') { powerupGraphics.tint = 0xf39c12; // Orange } else if (newType === 'health') { powerupGraphics.tint = 0x3498db; // Blue } }; self.update = function () { self.y += self.speed; // Slight wobble effect self.x += Math.sin(LK.ticks * 0.05) * 0.5; }; return self; }); var Upgrade = Container.expand(function () { var self = Container.call(this); var upgradeGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); upgradeGraphics.tint = 0xFFD700; // Gold color for upgrades // Text to display upgrade info var nameText = new Text2('', { size: 30, fill: 0xFFFFFF }); nameText.anchor.set(0.5, 0); nameText.y = -50; self.addChild(nameText); var levelText = new Text2('', { size: 24, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0); levelText.y = -20; self.addChild(levelText); var costText = new Text2('', { size: 24, fill: 0xFFD700 }); costText.anchor.set(0.5, 0); costText.y = 10; self.addChild(costText); self.type = ''; self.level = 1; self.maxLevel = 5; self.cost = 100; self.name = ''; self.description = ''; self.setType = function (type) { self.type = type; if (type === 'fireRate') { self.name = 'Fire Rate'; self.description = 'Increase firing speed'; upgradeGraphics.tint = 0xFF5500; // Orange-red } else if (type === 'damage') { self.name = 'Damage'; self.description = 'Increase bullet damage'; upgradeGraphics.tint = 0xFF0000; // Red } else if (type === 'maxAmmo') { self.name = 'Max Ammo'; self.description = 'Increase ammo capacity'; upgradeGraphics.tint = 0x00FF00; // Green } else if (type === 'frenzyTime') { self.name = 'Frenzy Time'; self.description = 'Extend frenzy duration'; upgradeGraphics.tint = 0xFFFF00; // Yellow } self.updateText(); }; self.updateText = function () { nameText.setText(self.name); levelText.setText('Level: ' + self.level + '/' + self.maxLevel); costText.setText(self.cost + ' pts'); }; self.purchase = function () { if (self.level >= self.maxLevel) { return false; } self.level++; self.cost = Math.floor(self.cost * 1.5); self.updateText(); return true; }; self.down = function (x, y, obj) { // Handle clicking on this upgrade LK.effects.flashObject(self, 0xFFFFFF, 200); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ // Game state variables var player; var bullets = []; var enemies = []; var powerups = []; var score = 0; var wave = 1; var enemiesKilled = 0; var enemiesThisWave = 10; var enemySpawnRate = 120; // Frames between enemy spawns var lastEnemySpawn = 0; var isGameOver = false; var isPaused = false; var showingUpgradeMenu = false; var upgrades = []; // UI elements var scoreText; var waveText; var healthBar; var ammoUI; var frenzyMeter; var upgradeButton; var upgradeMenu; // Game boundaries var gameBounds = { left: 100, right: 2048 - 100, top: 100, bottom: 2732 - 200 }; // Initialize player function initPlayer() { player = new Player(); player.x = 2048 / 2; player.y = 2732 - 300; game.addChild(player); } // Initialize UI function initUI() { // Score display scoreText = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); scoreText.x = 120; scoreText.y = 50; LK.gui.addChild(scoreText); // Wave display waveText = new Text2('Wave 1', { size: 60, fill: 0xFFFFFF }); waveText.anchor.set(1, 0); waveText.x = 2048 - 120; waveText.y = 50; LK.gui.addChild(waveText); // Health bar healthBar = game.addChild(LK.getAsset('player', { anchorX: 0, anchorY: 0.5, scaleX: 3, scaleY: 0.3, x: 120, y: 130, tint: 0x3498db })); // Ammo UI ammoUI = new AmmoUI(); ammoUI.x = 200; ammoUI.y = 200; game.addChild(ammoUI); ammoUI.update(player.ammo, player.maxAmmo); // Initialize with current ammo values // Ammo Bar var ammoBarBackground = game.addChild(LK.getAsset('bullet', { anchorX: 0, anchorY: 0.5, scaleX: 3, scaleY: 0.3, x: 120, y: 200, tint: 0x333333 })); ammoBar = game.addChild(LK.getAsset('bullet', { anchorX: 0, anchorY: 0.5, scaleX: 3, scaleY: 0.3, x: 120, y: 200, tint: 0x2ecc71 })); // Frenzy indicator frenzyMeter = game.addChild(LK.getAsset('powerup', { anchorX: 0.5, anchorY: 0.5, x: 2048 - 150, y: 150, alpha: 0.3, tint: 0xf39c12 })); // Upgrade button upgradeButton = new Text2('UPGRADES', { size: 50, fill: 0xFFD700 }); upgradeButton.anchor.set(0.5, 0.5); upgradeButton.x = 2048 - 200; upgradeButton.y = 250; game.addChild(upgradeButton); // Upgrade menu container (initially hidden) upgradeMenu = new Container(); upgradeMenu.visible = false; game.addChild(upgradeMenu); // Semi-transparent background var menuBg = LK.getAsset('bullet', { anchorX: 0, anchorY: 0, scaleX: 20, scaleY: 25, tint: 0x000000, alpha: 0.7 }); upgradeMenu.addChild(menuBg); // Menu title var menuTitle = new Text2('UPGRADES', { size: 80, fill: 0xFFD700 }); menuTitle.anchor.set(0.5, 0); menuTitle.x = 2048 / 2; menuTitle.y = 100; upgradeMenu.addChild(menuTitle); // Close button var closeButton = new Text2('CLOSE', { size: 60, fill: 0xFFFFFF }); closeButton.anchor.set(0.5, 0.5); closeButton.x = 2048 / 2; closeButton.y = 2732 - 200; closeButton.down = function () { toggleUpgradeMenu(); }; upgradeMenu.addChild(closeButton); // Create upgrade options initUpgrades(); } // Initialize upgrades function initUpgrades() { // Clear previous upgrades if any for (var i = 0; i < upgrades.length; i++) { upgrades[i].destroy(); } upgrades = []; // Create new upgrades var upgradeTypes = ['fireRate', 'damage', 'maxAmmo', 'frenzyTime']; var baseX = 2048 / 2; var baseY = 600; var spacing = 300; for (var i = 0; i < upgradeTypes.length; i++) { var upgrade = new Upgrade(); upgrade.setType(upgradeTypes[i]); upgrade.x = baseX; upgrade.y = baseY + i * spacing; // Load saved level if exists var upgradeKey = 'upgrade_' + upgradeTypes[i]; var savedLevel = storage[upgradeKey]; if (savedLevel !== undefined) { upgrade.level = savedLevel; upgrade.cost = Math.floor(100 * Math.pow(1.5, upgrade.level - 1)); upgrade.updateText(); } upgrade.down = function () { if (score >= this.cost && this.level < this.maxLevel) { score -= this.cost; scoreText.setText('Score: ' + score); this.purchase(); // Apply upgrade effect applyUpgrade(this.type, this.level); // Save upgrade level var upgradeKey = 'upgrade_' + this.type; storage[upgradeKey] = this.level; // Flash to indicate purchase LK.effects.flashObject(this, 0x00FF00, 300); } else { // Flash red if can't afford LK.effects.flashObject(this, 0xFF0000, 300); } }; upgradeMenu.addChild(upgrade); upgrades.push(upgrade); } // Apply saved upgrades to player for (var i = 0; i < upgrades.length; i++) { applyUpgrade(upgrades[i].type, upgrades[i].level); } } // Apply upgrade effects to player function applyUpgrade(type, level) { if (!player) { return; } var baseValue, increment; if (type === 'fireRate') { baseValue = 10; increment = 2; player.fireRate = baseValue + (level - 1) * increment; } else if (type === 'damage') { baseValue = 1; increment = 0.5; player.damage = baseValue + (level - 1) * increment; } else if (type === 'maxAmmo') { baseValue = 30; increment = 10; var newMaxAmmo = baseValue + (level - 1) * increment; player.ammo += newMaxAmmo - player.maxAmmo; player.maxAmmo = newMaxAmmo; } else if (type === 'frenzyTime') { baseValue = 300; increment = 60; player.frenzyDuration = baseValue + (level - 1) * increment; } } // Toggle upgrade menu visibility function toggleUpgradeMenu() { showingUpgradeMenu = !showingUpgradeMenu; upgradeMenu.visible = showingUpgradeMenu; } // Spawn enemy function spawnEnemy() { var enemy = new Enemy(); // Randomize initial position (along top of screen) enemy.x = gameBounds.left + Math.random() * (gameBounds.right - gameBounds.left); enemy.y = -50; // Determine enemy type based on wave and randomness var rand = Math.random(); if (wave < 3) { enemy.setType('basic'); } else if (wave < 5) { if (rand < 0.7) { enemy.setType('basic'); } else if (rand < 0.9) { enemy.setType('fast'); } else { enemy.setType('tank'); } } else { if (rand < 0.5) { enemy.setType('basic'); } else if (rand < 0.8) { enemy.setType('fast'); } else { enemy.setType('tank'); } } game.addChild(enemy); enemies.push(enemy); } // Spawn powerup function spawnPowerup(x, y) { // 20% chance to spawn a powerup when enemy dies if (Math.random() > 0.2) { return; } var powerup = new PowerUp(); powerup.x = x; powerup.y = y; // Determine powerup type var rand = Math.random(); if (rand < 0.6) { powerup.setType('ammo'); } else if (rand < 0.9) { powerup.setType('health'); } else { powerup.setType('frenzy'); } game.addChild(powerup); powerups.push(powerup); } // Handle player shooting function handlePlayerShoot() { var bullet = player.shoot(); if (bullet) { game.addChild(bullet); bullets.push(bullet); } } // Update game state function updateGameState() { // Update player player.update(); ammoUI.update(player.ammo, player.maxAmmo); // Update health bar healthBar.scale.x = player.health / 100 * 3; // Update ammo bar ammoBar.scale.x = player.ammo / player.maxAmmo * 3; // Update frenzy meter if (player.inFrenzyMode) { frenzyMeter.alpha = 0.5 + Math.sin(LK.ticks * 0.2) * 0.5; } else { frenzyMeter.alpha = 0.3; } // Spawn enemies if (LK.ticks - lastEnemySpawn >= enemySpawnRate && enemies.length < enemiesThisWave) { spawnEnemy(); lastEnemySpawn = LK.ticks; } // Next wave logic if (enemiesKilled >= enemiesThisWave) { wave++; enemiesKilled = 0; enemiesThisWave = Math.min(50, 10 + wave * 5); enemySpawnRate = Math.max(30, 120 - wave * 10); waveText.setText('Wave ' + wave); // Flash screen green for new wave LK.effects.flashScreen(0x2ecc71, 500); } // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; bullet.update(); // Remove bullets that go off screen if (bullet.y < -50) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check for bullet collisions with enemies for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (bullet.intersects(enemy)) { // Enemy takes damage var destroyed = enemy.takeDamage(bullet.damage); if (destroyed) { // Add score score += enemy.scoreValue; scoreText.setText('Score: ' + score); // Increment kill counter enemiesKilled++; // Spawn powerup spawnPowerup(enemy.x, enemy.y); // Remove enemy enemy.destroy(); enemies.splice(j, 1); } // Remove bullet bullet.destroy(); bullets.splice(i, 1); // Play hit sound LK.getSound('enemyHit').play(); // Break since bullet is gone break; } } } // Update enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; enemy.update(); // Remove enemies that go off bottom of screen if (enemy.y > gameBounds.bottom + 50) { // Player takes damage when enemy passes player.takeDamage(10); // Remove enemy enemy.destroy(); enemies.splice(i, 1); // Play hit sound LK.getSound('playerHit').play(); continue; } // Check collision with player if (enemy.intersects(player)) { // Player takes damage player.takeDamage(20); // Remove enemy enemy.destroy(); enemies.splice(i, 1); // Play hit sound LK.getSound('playerHit').play(); } } // Update powerups for (var i = powerups.length - 1; i >= 0; i--) { var powerup = powerups[i]; powerup.update(); // Remove powerups that go off bottom of screen if (powerup.y > gameBounds.bottom + 50) { powerup.destroy(); powerups.splice(i, 1); continue; } // Check collision with player if (powerup.intersects(player)) { if (powerup.type === 'ammo') { player.reloadAmmo(15); } else if (powerup.type === 'health') { player.health = Math.min(100, player.health + 20); } else if (powerup.type === 'frenzy') { player.activateFrenzy(); } // Play powerup sound LK.getSound('powerupCollect').play(); // Remove powerup powerup.destroy(); powerups.splice(i, 1); } } // Check for game over if (player.health <= 0 && !isGameOver) { isGameOver = true; LK.showGameOver(); } // Auto-shoot in frenzy mode if (player.inFrenzyMode && LK.ticks % 5 === 0) { handlePlayerShoot(); } } // Initialize game function initGame() { // Reset game state bullets = []; enemies = []; powerups = []; showingUpgradeMenu = false; score = 0; wave = 1; enemiesKilled = 0; enemiesThisWave = 10; enemySpawnRate = 120; lastEnemySpawn = 0; isGameOver = false; // Set score LK.setScore(0); // Init player and UI initPlayer(); initUI(); // Play music LK.playMusic('gameMusic', { fade: { start: 0, end: 1, duration: 1000 } }); } // Initialize the game initGame(); // Touch/mouse handlers for player movement var isDragging = false; game.down = function (x, y, obj) { // Check if upgrade button was clicked if (obj.target === upgradeButton) { toggleUpgradeMenu(); return; } // If upgrade menu is showing, don't process player movement/shooting if (showingUpgradeMenu) { return; } isDragging = true; player.x = x; // Constrain player to game bounds player.x = Math.max(gameBounds.left, Math.min(gameBounds.right, player.x)); // Shoot on tap handlePlayerShoot(); }; game.up = function (x, y, obj) { isDragging = false; }; game.move = function (x, y, obj) { if (isDragging && !showingUpgradeMenu) { player.x = x; // Constrain player to game bounds player.x = Math.max(gameBounds.left, Math.min(gameBounds.right, player.x)); } }; // Main game loop game.update = function () { if (!isGameOver && !showingUpgradeMenu) { updateGameState(); } // Update score LK.setScore(score); };
===================================================================
--- original.js
+++ change.js
@@ -434,10 +434,10 @@
upgrade.y = baseY + i * spacing;
// Load saved level if exists
var upgradeKey = 'upgrade_' + upgradeTypes[i];
var savedLevel = storage[upgradeKey];
- if (savedLevel) {
- upgrade.level = parseInt(savedLevel);
+ if (savedLevel !== undefined) {
+ upgrade.level = savedLevel;
upgrade.cost = Math.floor(100 * Math.pow(1.5, upgrade.level - 1));
upgrade.updateText();
}
upgrade.down = function () {
@@ -448,9 +448,9 @@
// Apply upgrade effect
applyUpgrade(this.type, this.level);
// Save upgrade level
var upgradeKey = 'upgrade_' + this.type;
- storage[upgradeKey] = this.level.toString();
+ storage[upgradeKey] = this.level;
// Flash to indicate purchase
LK.effects.flashObject(this, 0x00FF00, 300);
} else {
// Flash red if can't afford