User prompt
You have to add a lore button which tells how the game started and the prelogue
User prompt
Add Easter eggs
User prompt
LORE FOR GOOSANDRA: Certified Viggener, responsible for multiple genocides. Pounds sand with geese.
User prompt
Use a different asset for Goosandra
User prompt
Add a theme song and cutscene for Goosandra ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Consider importing storage.v1 so the state of revealing stays in the next game as the game ends when defeating secret boss ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
2: Glen: Haskell god, #########'s friend (Make it reveal Goosandra after defeating the secret boss)
User prompt
CORRECT LORE: Shant: A simple UPIT creator, mostly known for The Last Beat
User prompt
Add lore for each (Just code for now, i can help you get the right lore)
User prompt
Add a guide for each boss
User prompt
Reduce Viggen firerate
User prompt
Add Viggens to the Goosandra boss battle (Smaller but homing lasers)
User prompt
The Goodandra boss starts lagging significantly when activating the second wave
User prompt
Add optimization
User prompt
Add a new secret boss if you click at the health text on Glen's boss (named after me, Goosandra)
User prompt
Rename them into actual Upit usernames (1: Shant, 2: Glen, 3: Octo, 4: Benjaminsen, 5: Upit Developer)
User prompt
Make them named after Upit creators
User prompt
Please fix the bug: 'TypeError: tween.to is not a function' in or related to this line: 'tween.to(self, 0.3, {' Line Number: 143 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Level 4 isn't the final boss yet!
User prompt
Name the bosses
Code edit (1 edits merged)
Please save this source code
User prompt
Boss Rush Arena
Initial prompt
A game where you fight bosses, starting from easy enemies to one of the hardest areas in Upit.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Boss = Container.expand(function () { var self = Container.call(this); self.maxHealth = 100; self.health = self.maxHealth; self.attackCooldown = 0; self.movePattern = 0; self.speed = 2; self.damage = 10; self.takeDamage = function (damage) { self.health -= damage; LK.effects.flashObject(self, 0xffffff, 200); LK.getSound('bossHit').play(); if (self.health <= 0) { self.health = 0; self.onDefeat(); } }; self.onDefeat = function () { LK.getSound('bossDefeat').play(); bossDefeated = true; LK.setScore(LK.getScore() + 100 * currentBossLevel); }; return self; }); var Goosandra = Boss.expand(function () { var self = Boss.call(this); var graphics = self.attachAsset('viggen', { anchorX: 0.5, anchorY: 0.5 }); graphics.tint = 0x800080; // Purple tint for Goosandra graphics.scaleX = 8; // Make Goosandra much larger graphics.scaleY = 8; // Make Goosandra much larger self.maxHealth = 1000; self.health = self.maxHealth; self.speed = 4; self.secretPhase = 1; self.phaseTimer = 0; self.update = function () { self.phaseTimer++; if (self.secretPhase == 1) { // Phase 1: Chaotic movement self.x += Math.sin(self.phaseTimer * 0.03) * 4; self.y += Math.cos(self.phaseTimer * 0.02) * 2; self.attackCooldown--; if (self.attackCooldown <= 0) { self.chaosAttack(); self.attackCooldown = 25; } if (self.health < self.maxHealth * 0.6) { self.secretPhase = 2; self.phaseTimer = 0; } } else if (self.secretPhase == 2) { // Phase 2: Ultimate chaos self.x += Math.sin(self.phaseTimer * 0.05) * 6; self.y += Math.cos(self.phaseTimer * 0.04) * 3; self.attackCooldown--; if (self.attackCooldown <= 0) { self.ultimateAttack(); self.attackCooldown = 25; } } }; self.chaosAttack = function () { // Spiral chaos shot for (var i = 0; i < 6; i++) { var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y; var angle = i / 6 * Math.PI * 2 + self.phaseTimer * 0.1; bullet.targetX = self.x + Math.cos(angle) * 800; bullet.targetY = self.y + Math.sin(angle) * 800; bossBullets.push(bullet); game.addChild(bullet); } // Add 1 Viggen every chaos attack for (var j = 0; j < 1; j++) { var viggen = getPooledViggen(); viggen.x = self.x + (j - 0.5) * 100; viggen.y = self.y + 80; viggen.velocityX = (Math.random() - 0.5) * 2; viggen.velocityY = Math.random() * 2 + 1; viggen.lifetime = 300; viggens.push(viggen); game.addChild(viggen); } }; self.ultimateAttack = function () { // Ultimate chaos burst for (var i = 0; i < 12; i++) { var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y; var angle = i / 12 * Math.PI * 2 + self.phaseTimer * 0.2; bullet.targetX = self.x + Math.cos(angle) * 900; bullet.targetY = self.y + Math.sin(angle) * 900; bossBullets.push(bullet); game.addChild(bullet); } // Random laser bursts if (self.phaseTimer % 120 == 0) { for (var j = 0; j < 2; j++) { var laser = new BossLaser(); laser.x = 200 + Math.random() * 1648; laser.y = 0; bossLasers.push(laser); game.addChild(laser); } } // Add 2 Viggens during ultimate attack for (var k = 0; k < 2; k++) { var viggen = getPooledViggen(); viggen.x = self.x + (k - 0.5) * 80; viggen.y = self.y + 100; viggen.velocityX = (Math.random() - 0.5) * 3; viggen.velocityY = Math.random() * 3 + 2; viggen.lifetime = 300; viggens.push(viggen); game.addChild(viggen); } }; self.onDefeat = function () { LK.getSound('bossDefeat').play(); LK.setScore(LK.getScore() + 2000); secretBossDefeated = true; storage.secretBossDefeated = true; // Update Glen's lore text if currently viewing boss 2 if (currentBossLevel == 2) { bossLoreText.setText(getBossLore(2)); } // Dramatic defeat cutscene LK.effects.flashScreen(0x800080, 2000); // Spin and shrink effect tween(self, { rotation: Math.PI * 8, scaleX: 0, scaleY: 0 }, { duration: 2000, easing: tween.easeIn }); // Fade out all UI elements dramatically tween(levelText, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 1500, easing: tween.easeIn }); tween(bossNameText, { alpha: 0 }, { duration: 1500, easing: tween.easeIn }); // Wait for dramatic effect before showing win LK.setTimeout(function () { LK.showYouWin(); }, 2500); }; return self; }); var FinalBoss = Boss.expand(function () { var self = Boss.call(this); var graphics = self.attachAsset('finalBoss', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 800; self.health = self.maxHealth; self.phase = 1; self.phaseTimer = 0; self.speed = 2; self.update = function () { self.phaseTimer++; if (self.phase == 1) { // Phase 1: Slow movement, regular attacks self.x += Math.sin(self.phaseTimer * 0.01) * 2; self.attackCooldown--; if (self.attackCooldown <= 0) { self.phase1Attack(); self.attackCooldown = 60; } if (self.health < self.maxHealth * 0.5) { self.phase = 2; self.phaseTimer = 0; } } else if (self.phase == 2) { // Phase 2: Aggressive attacks self.attackCooldown--; if (self.attackCooldown <= 0) { self.phase2Attack(); self.attackCooldown = 30; } } }; self.phase1Attack = function () { // Triple spread shot for (var i = -2; i <= 2; i++) { var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y + 150; bullet.targetX = player.x + i * 100; bullet.targetY = player.y; bossBullets.push(bullet); game.addChild(bullet); } }; self.phase2Attack = function () { // Radial burst + laser for (var i = 0; i < 12; i++) { var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y; var angle = i / 12 * Math.PI * 2; bullet.targetX = self.x + Math.cos(angle) * 600; bullet.targetY = self.y + Math.sin(angle) * 600; bossBullets.push(bullet); game.addChild(bullet); } if (self.phaseTimer % 120 == 0) { var laser = new BossLaser(); laser.x = player.x; laser.y = 0; bossLasers.push(laser); game.addChild(laser); } }; self.onDefeat = function () { LK.getSound('bossDefeat').play(); LK.setScore(LK.getScore() + 1000); LK.showYouWin(); }; return self; }); var Boss5 = Boss.expand(function () { var self = Boss.call(this); var graphics = self.attachAsset('boss2', { anchorX: 0.5, anchorY: 0.5 }); graphics.scaleX = 1.5; graphics.scaleY = 1.5; self.maxHealth = 750; self.health = self.maxHealth; self.speed = 3; self.teleportTimer = 0; self.laserWaveTimer = 0; self.update = function () { self.teleportTimer++; self.laserWaveTimer++; // Teleport movement if (self.teleportTimer % 120 == 0) { var newX = 300 + Math.random() * 1448; var newY = 300 + Math.random() * 400; tween(self, { x: newX, y: newY }, { duration: 300 }); LK.effects.flashObject(self, 0xffffff, 300); } // Attack patterns self.attackCooldown--; if (self.attackCooldown <= 0) { self.attack(); self.attackCooldown = 35; } // Laser wave attack if (self.laserWaveTimer % 240 == 0) { self.laserWave(); } }; self.attack = function () { // Homing missiles for (var i = 0; i < 4; i++) { var bullet = new BossBullet(); bullet.x = self.x + (i - 1.5) * 80; bullet.y = self.y + 100; bullet.targetX = player.x + (Math.random() - 0.5) * 200; bullet.targetY = player.y + (Math.random() - 0.5) * 200; bossBullets.push(bullet); game.addChild(bullet); } }; self.laserWave = function () { // Create multiple lasers across the screen for (var i = 0; i < 5; i++) { var laser = new BossLaser(); laser.x = 200 + i * 400; laser.y = 0; bossLasers.push(laser); game.addChild(laser); } }; return self; }); var Boss4 = Boss.expand(function () { var self = Boss.call(this); var graphics = self.attachAsset('boss3', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 600; self.health = self.maxHealth; self.speed = 5; self.spiralAngle = 0; self.burstTimer = 0; self.update = function () { // Spiral movement pattern self.spiralAngle += 0.05; self.x = 1024 + Math.cos(self.spiralAngle) * 400; self.y = 500 + Math.sin(self.spiralAngle * 0.7) * 150; // Multiple attack patterns self.attackCooldown--; self.burstTimer++; if (self.attackCooldown <= 0) { self.attack(); self.attackCooldown = 40; } // Burst attack every 3 seconds if (self.burstTimer % 180 == 0) { self.burstAttack(); } }; self.attack = function () { // Spiral shot pattern for (var i = 0; i < 6; i++) { var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y; var angle = i / 6 * Math.PI * 2 + self.spiralAngle * 2; bullet.targetX = self.x + Math.cos(angle) * 600; bullet.targetY = self.y + Math.sin(angle) * 600; bossBullets.push(bullet); game.addChild(bullet); } }; self.burstAttack = function () { // Massive radial burst for (var i = 0; i < 16; i++) { var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y; var angle = i / 16 * Math.PI * 2; bullet.targetX = self.x + Math.cos(angle) * 700; bullet.targetY = self.y + Math.sin(angle) * 700; bossBullets.push(bullet); game.addChild(bullet); } }; return self; }); var Boss3 = Boss.expand(function () { var self = Boss.call(this); var graphics = self.attachAsset('boss3', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 400; self.health = self.maxHealth; self.speed = 4; self.laserCooldown = 0; self.update = function () { // Aggressive movement toward player var dx = player.x - self.x; var dy = player.y - self.y; var distanceSquared = dx * dx + dy * dy; if (distanceSquared > 0) { var distance = Math.sqrt(distanceSquared); self.x += dx / distance * self.speed * 0.5; self.y += dy / distance * self.speed * 0.3; } // Multiple attack patterns self.attackCooldown--; self.laserCooldown--; if (self.attackCooldown <= 0) { self.attack(); self.attackCooldown = 45; } if (self.laserCooldown <= 0) { self.laserAttack(); self.laserCooldown = 180; } }; self.attack = function () { // Radial shot for (var i = 0; i < 8; i++) { var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y; var angle = i / 8 * Math.PI * 2; bullet.targetX = self.x + Math.cos(angle) * 500; bullet.targetY = self.y + Math.sin(angle) * 500; bossBullets.push(bullet); game.addChild(bullet); } }; self.laserAttack = function () { var laser = new BossLaser(); laser.x = self.x; laser.y = self.y + 100; bossLasers.push(laser); game.addChild(laser); }; return self; }); var Boss2 = Boss.expand(function () { var self = Boss.call(this); var graphics = self.attachAsset('boss2', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 250; self.health = self.maxHealth; self.speed = 3; self.angle = 0; self.update = function () { // Circular movement self.angle += 0.02; self.x = 1024 + Math.cos(self.angle) * 300; self.y = 600 + Math.sin(self.angle) * 200; // Faster shooting self.attackCooldown--; if (self.attackCooldown <= 0) { self.attack(); self.attackCooldown = 60; } }; self.attack = function () { // Spread shot for (var i = -1; i <= 1; i++) { var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y + 90; bullet.targetX = player.x + i * 150; bullet.targetY = player.y; bossBullets.push(bullet); game.addChild(bullet); } }; return self; }); var Boss1 = Boss.expand(function () { var self = Boss.call(this); var graphics = self.attachAsset('boss1', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 150; self.health = self.maxHealth; self.moveDirection = 1; self.update = function () { // Simple horizontal movement self.x += self.speed * self.moveDirection; if (self.x > 1800 || self.x < 250) { self.moveDirection *= -1; } // Simple shooting pattern self.attackCooldown--; if (self.attackCooldown <= 0) { self.attack(); self.attackCooldown = 90; } }; self.attack = function () { var bullet = new BossBullet(); bullet.x = self.x; bullet.y = self.y + 75; bullet.targetX = player.x; bullet.targetY = player.y; bossBullets.push(bullet); game.addChild(bullet); }; return self; }); var BossBullet = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('bossBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 6; self.targetX = 0; self.targetY = 0; self.velocityX = 0; self.velocityY = 0; self.update = function () { if (self.velocityX == 0 && self.velocityY == 0) { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.velocityX = dx / distance * self.speed; self.velocityY = dy / distance * self.speed; } } self.x += self.velocityX; self.y += self.velocityY; }; return self; }); var BossLaser = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('bossLaser', { anchorX: 0.5, anchorY: 0.5 }); self.lifetime = 120; self.update = function () { self.lifetime--; graphics.alpha = self.lifetime / 120; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.maxHealth = 100; self.health = self.maxHealth; self.shootCooldown = 0; self.speed = 8; self.update = function () { if (self.shootCooldown > 0) { self.shootCooldown--; } }; self.takeDamage = function (damage) { self.health -= damage; LK.effects.flashObject(self, 0xff0000, 300); LK.getSound('hit').play(); if (self.health <= 0) { self.health = 0; isGameOver = true; } }; self.shoot = function () { if (self.shootCooldown <= 0) { var bullet = getPooledPlayerBullet(); bullet.x = self.x; bullet.y = self.y - 50; playerBullets.push(bullet); game.addChild(bullet); self.shootCooldown = 10; LK.getSound('shoot').play(); } }; return self; }); var PlayerBullet = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -12; self.update = function () { self.y += self.speed; }; return self; }); var Viggen = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('viggen', { anchorX: 0.5, anchorY: 0.5 }); graphics.tint = 0x00ffff; // Cyan tint for Viggens self.speed = 4; self.homingForce = 0.2; self.velocityX = 0; self.velocityY = 0; self.lifetime = 300; // 5 seconds at 60fps self.update = function () { self.lifetime--; // Homing behavior toward player var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.velocityX += dx / distance * self.homingForce; self.velocityY += dy / distance * self.homingForce; } // Apply velocity with speed limit var currentSpeed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY); if (currentSpeed > self.speed) { self.velocityX = self.velocityX / currentSpeed * self.speed; self.velocityY = self.velocityY / currentSpeed * self.speed; } self.x += self.velocityX; self.y += self.velocityY; // Fade out as lifetime decreases graphics.alpha = Math.min(1, self.lifetime / 60); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000011 }); /**** * Game Code ****/ var player; var currentBoss; var currentBossLevel = 1; var playerBullets = []; var bossBullets = []; var bossLasers = []; var viggens = []; // Object pools for performance optimization var playerBulletPool = []; var bossBulletPool = []; var bossLaserPool = []; var viggenPool = []; function getPooledPlayerBullet() { if (playerBulletPool.length > 0) { return playerBulletPool.pop(); } return new PlayerBullet(); } function getPooledBossBullet() { if (bossBulletPool.length > 0) { return bossBulletPool.pop(); } return new BossBullet(); } function getPooledBossLaser() { if (bossLaserPool.length > 0) { return bossLaserPool.pop(); } return new BossLaser(); } function getPooledViggen() { if (viggenPool.length > 0) { return viggenPool.pop(); } return new Viggen(); } function returnToPool(bullet, pool) { bullet.x = 0; bullet.y = 0; bullet.velocityX = 0; bullet.velocityY = 0; bullet.targetX = 0; bullet.targetY = 0; pool.push(bullet); } var bossDefeated = false; var isGameOver = false; var transitionTimer = 0; var dragNode = null; var bossNames = ['Shant', 'Glen', 'Octo', 'Benjaminsen', 'Upit Developer', 'The Upit Collective']; var secretBossUnlocked = false; var secretBossDefeated = storage.secretBossDefeated || false; // Easter egg variables var konamiCode = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65]; // Up Up Down Down Left Right Left Right B A var konamiProgress = 0; var rapidFireUnlocked = storage.rapidFireUnlocked || false; var rainbowModeUnlocked = storage.rainbowModeUnlocked || false; var clickCounter = 0; var lastClickTime = 0; var easterEggTimer = 0; // UI Elements var healthBar; var bossHealthBar; var levelText; var instructionText; // Initialize UI healthBar = new Text2('Health: 100', { size: 60, fill: 0x00FF00 }); healthBar.anchor.set(0, 0); LK.gui.topLeft.addChild(healthBar); bossHealthBar = new Text2('Boss Health: 0', { size: 60, fill: 0xFF0000 }); bossHealthBar.anchor.set(0.5, 0); LK.gui.top.addChild(bossHealthBar); // Add click handler to boss health bar for secret boss bossHealthBar.down = function (x, y, obj) { if (currentBossLevel == 2 && currentBoss && !secretBossUnlocked) { secretBossUnlocked = true; // Spawn secret boss Goosandra currentBoss.destroy(); currentBoss = game.addChild(new Goosandra()); currentBoss.x = 1024; currentBoss.y = -300; // Start above screen for dramatic entrance levelText.setText('Secret Boss: Goosandra'); bossNameText.setText('Secret Boss: Goosandra'); bossGuideText.setText('CHAOS! Two phases, homing Viggens, ultimate mayhem!'); bossLoreText.setText(getGoosandraLore()); // Play Goosandra's theme song LK.playMusic('goosandraTheme'); // Dramatic entrance cutscene LK.effects.flashScreen(0x800080, 1000); // Easter egg: Extra special effects if both Easter eggs are unlocked if (rapidFireUnlocked && rainbowModeUnlocked) { // Create rainbow particle effect for (var i = 0; i < 20; i++) { var particle = LK.getAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5, x: 1024 + (Math.random() - 0.5) * 400, y: 1366 + (Math.random() - 0.5) * 400, scaleX: 2, scaleY: 2 }); particle.tint = Math.random() * 0xFFFFFF; game.addChild(particle); // Animate particles tween(particle, { x: particle.x + (Math.random() - 0.5) * 800, y: particle.y + (Math.random() - 0.5) * 800, alpha: 0, rotation: Math.PI * 4 }, { duration: 2000, onFinish: function onFinish() { particle.destroy(); } }); } // Special message for Easter egg hunters var easterMsg = new Text2('🥚 TRUE EASTER EGG HUNTER! 🥚', { size: 50, fill: 0xFF69B4 }); easterMsg.anchor.set(0.5, 0.5); easterMsg.x = 1024; easterMsg.y = 1100; game.addChild(easterMsg); tween(easterMsg, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 4000, onFinish: function onFinish() { easterMsg.destroy(); } }); } // Make UI text dramatic entrance tween(levelText, { scaleX: 1.5, scaleY: 1.5 }, { duration: 500, easing: tween.bounceOut }); tween(bossNameText, { scaleX: 1.3, scaleY: 1.3 }, { duration: 600, easing: tween.elasticOut }); // Goosandra dramatic entrance from above tween(currentBoss, { y: 400 }, { duration: 2000, easing: tween.bounceOut }); // Add spinning entrance effect tween(currentBoss, { rotation: Math.PI * 4 }, { duration: 2000, easing: tween.easeOut }); // Pulsing size effect tween(currentBoss, { scaleX: 1.2, scaleY: 1.2 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(currentBoss, { scaleX: 1, scaleY: 1 }, { duration: 1000, easing: tween.easeInOut }); } }); } }; levelText = new Text2('Boss Level: 1', { size: 80, fill: 0xFFFF00 }); levelText.anchor.set(1, 0); LK.gui.topRight.addChild(levelText); instructionText = new Text2('Drag to move, tap to shoot!', { size: 50, fill: 0xFFFFFF }); instructionText.anchor.set(0.5, 1); LK.gui.bottom.addChild(instructionText); var bossNameText = new Text2('Boss 1: Shant', { size: 70, fill: 0xFF6600 }); bossNameText.anchor.set(0.5, 0); bossNameText.y = 100; LK.gui.top.addChild(bossNameText); // Easter egg: Rapid click on boss name for rainbow mode bossNameText.down = function (x, y, obj) { var currentTime = Date.now(); if (currentTime - lastClickTime < 200) { // Clicks within 200ms clickCounter++; if (clickCounter >= 7) { if (!rainbowModeUnlocked) { rainbowModeUnlocked = true; storage.rainbowModeUnlocked = true; LK.effects.flashScreen(0xFFFFFF, 1000); // Show rainbow message var rainbowMsg = new Text2('🌈 RAINBOW MODE ACTIVATED! 🌈', { size: 60, fill: 0xFF00FF }); rainbowMsg.anchor.set(0.5, 0.5); rainbowMsg.x = 1024; rainbowMsg.y = 1366; game.addChild(rainbowMsg); // Animate message tween(rainbowMsg, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 3000, onFinish: function onFinish() { rainbowMsg.destroy(); } }); } clickCounter = 0; } } else { clickCounter = 1; } lastClickTime = currentTime; }; var bossGuideText = new Text2('', { size: 40, fill: 0xAAAAA }); bossGuideText.anchor.set(0.5, 0); bossGuideText.y = 180; LK.gui.top.addChild(bossGuideText); var bossLoreText = new Text2('', { size: 35, fill: 0xCCCCCC }); bossLoreText.anchor.set(0.5, 0); bossLoreText.y = 240; LK.gui.top.addChild(bossLoreText); // Add lore button var loreButton = new Text2('📖 LORE', { size: 50, fill: 0xFFD700 }); loreButton.anchor.set(0, 1); loreButton.x = 50; loreButton.y = -50; LK.gui.bottomLeft.addChild(loreButton); // Lore display overlay var loreOverlay = null; var loreDisplayText = null; var loreCloseButton = null; var showingLore = false; // Lore button click handler loreButton.down = function (x, y, obj) { if (!showingLore) { showingLore = true; // Create dark overlay loreOverlay = LK.getAsset('boss1', { anchorX: 0, anchorY: 0, x: 0, y: 0, scaleX: 13.65, scaleY: 18.21, alpha: 0.8 }); loreOverlay.tint = 0x000000; game.addChild(loreOverlay); // Create lore text var loreContent = getGameLore(); loreDisplayText = new Text2(loreContent, { size: 45, fill: 0xFFFFFF }); loreDisplayText.anchor.set(0.5, 0.5); loreDisplayText.x = 1024; loreDisplayText.y = 1366; game.addChild(loreDisplayText); // Create close button loreCloseButton = new Text2('❌ CLOSE', { size: 60, fill: 0xFF4444 }); loreCloseButton.anchor.set(0.5, 0.5); loreCloseButton.x = 1024; loreCloseButton.y = 2400; game.addChild(loreCloseButton); // Close button handler loreCloseButton.down = function (x, y, obj) { closeLoreDisplay(); }; // Animate entrance tween(loreOverlay, { alpha: 0.9 }, { duration: 500 }); tween(loreDisplayText, { scaleX: 1.1, scaleY: 1.1 }, { duration: 300, easing: tween.bounceOut }); tween(loreCloseButton, { scaleX: 1.2, scaleY: 1.2 }, { duration: 400, easing: tween.elasticOut }); } }; function closeLoreDisplay() { if (showingLore) { showingLore = false; if (loreOverlay) { loreOverlay.destroy(); loreOverlay = null; } if (loreDisplayText) { loreDisplayText.destroy(); loreDisplayText = null; } if (loreCloseButton) { loreCloseButton.destroy(); loreCloseButton = null; } } } function getGameLore() { return "THE UPIT WARS: GENESIS\n\n" + "Long ago, in the digital realm of FRVR,\n" + "the UPIT Collective ruled with algorithms\n" + "and code. But power corrupted their minds,\n" + "transforming them into digital tyrants.\n\n" + "Each member became a Boss, wielding\n" + "their programming skills as weapons:\n\n" + "• Shant - The Beat Master\n" + "• Glen - The Haskell God\n" + "• Octo - The Hunter-Killer\n" + "• Benjaminsen - The Strategist\n" + "• The Upit Developer - Reality Bender\n" + "• The Collective - Merged Consciousness\n\n" + "In the shadows lurks Goosandra,\n" + "the Certified Viggener, responsible\n" + "for multiple digital genocides.\n\n" + "You are humanity's last hope.\n" + "Defeat the UPIT Bosses and restore\n" + "balance to the digital realm!\n\n" + "May the code be with you..."; } // Initialize player player = game.addChild(new Player()); player.x = 1024; player.y = 2200; // Easter egg: Double tap player for rapid fire var playerClickCount = 0; var playerLastClickTime = 0; player.down = function (x, y, obj) { var currentTime = Date.now(); if (currentTime - playerLastClickTime < 300) { // Double tap within 300ms playerClickCount++; if (playerClickCount >= 2 && !rapidFireUnlocked) { rapidFireUnlocked = true; storage.rapidFireUnlocked = true; LK.effects.flashObject(player, 0xFFFF00, 1000); // Show rapid fire message var rapidMsg = new Text2('⚡ RAPID FIRE UNLOCKED! ⚡', { size: 60, fill: 0xFFFF00 }); rapidMsg.anchor.set(0.5, 0.5); rapidMsg.x = 1024; rapidMsg.y = 1500; game.addChild(rapidMsg); // Animate message tween(rapidMsg, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 2000, onFinish: function onFinish() { rapidMsg.destroy(); } }); playerClickCount = 0; } } else { playerClickCount = 1; } playerLastClickTime = currentTime; }; // Start first boss function getBossGuide(bossLevel) { if (bossLevel == 1) { return 'Simple movement, single shots. Stay mobile!'; } else if (bossLevel == 2) { return 'Circular pattern, spread shots. Predict the path!'; } else if (bossLevel == 3) { return 'Homing movement, radial + laser attacks. Keep distance!'; } else if (bossLevel == 4) { return 'Spiral movement, burst attacks. Watch for patterns!'; } else if (bossLevel == 5) { return 'Teleports randomly, homing missiles + laser waves!'; } else if (bossLevel >= 6) { return 'Two phases, radial bursts + targeted lasers!'; } return ''; } function getBossLore(bossLevel) { if (bossLevel == 1) { var baseLore = 'A simple UPIT creator, mostly known for The Last Beat'; if (rapidFireUnlocked && rainbowModeUnlocked) { return baseLore + ' 🎵 *hums The Last Beat* 🎵'; } return baseLore; } else if (bossLevel == 2) { // Check if secret boss has been defeated to reveal Goosandra's name if (secretBossDefeated) { return 'Haskell god, Goosandra\'s friend'; } else { return 'Haskell god, #########\'s friend'; } } else if (bossLevel == 3) { var baseLore = 'An aggressive hunter-killer with advanced targeting.'; if (rainbowModeUnlocked) { return baseLore + ' 🐙 Surprisingly, loves rainbow colors! 🌈'; } return baseLore; } else if (bossLevel == 4) { var baseLore = 'A master strategist who fights with calculated precision.'; if (rapidFireUnlocked) { return baseLore + ' ⚡ Respects your rapid fire skills! ⚡'; } return baseLore; } else if (bossLevel == 5) { return 'The lead developer, wielding reality-bending code.'; } else if (bossLevel >= 6) { var baseLore = 'The merged consciousness of all UPIT minds.'; if (rapidFireUnlocked && rainbowModeUnlocked) { return baseLore + ' 🧠✨ They are impressed by your Easter egg hunting! ✨🧠'; } return baseLore; } return ''; } function getGoosandraLore() { return 'Certified Viggener, responsible for multiple genocides. Pounds sand with geese.'; } function spawnBoss() { if (currentBoss) { currentBoss.destroy(); } bossDefeated = false; transitionTimer = 0; // Clear bullets for (var i = bossBullets.length - 1; i >= 0; i--) { bossBullets[i].destroy(); bossBullets.splice(i, 1); } // Clear viggens for (var i = viggens.length - 1; i >= 0; i--) { viggens[i].destroy(); viggens.splice(i, 1); } // Spawn appropriate boss if (currentBossLevel == 1) { currentBoss = game.addChild(new Boss1()); currentBoss.x = 1024; currentBoss.y = 400; levelText.setText('Boss 1: Shant'); bossNameText.setText('Boss 1: Shant'); bossGuideText.setText(getBossGuide(1)); bossLoreText.setText(getBossLore(1)); } else if (currentBossLevel == 2) { currentBoss = game.addChild(new Boss2()); currentBoss.x = 1024; currentBoss.y = 600; levelText.setText('Boss 2: Glen'); bossNameText.setText('Boss 2: Glen'); bossGuideText.setText(getBossGuide(2)); bossLoreText.setText(getBossLore(2)); } else if (currentBossLevel == 3) { currentBoss = game.addChild(new Boss3()); currentBoss.x = 1024; currentBoss.y = 500; levelText.setText('Boss 3: Octo'); bossNameText.setText('Boss 3: Octo'); bossGuideText.setText(getBossGuide(3)); bossLoreText.setText(getBossLore(3)); } else if (currentBossLevel == 4) { currentBoss = game.addChild(new Boss4()); currentBoss.x = 1024; currentBoss.y = 500; levelText.setText('Boss 4: Benjaminsen'); bossNameText.setText('Boss 4: Benjaminsen'); bossGuideText.setText(getBossGuide(4)); bossLoreText.setText(getBossLore(4)); } else if (currentBossLevel == 5) { currentBoss = game.addChild(new Boss5()); currentBoss.x = 1024; currentBoss.y = 400; levelText.setText('Boss 5: Upit Developer'); bossNameText.setText('Boss 5: Upit Developer'); bossGuideText.setText(getBossGuide(5)); bossLoreText.setText(getBossLore(5)); } else if (currentBossLevel >= 6) { currentBoss = game.addChild(new FinalBoss()); currentBoss.x = 1024; currentBoss.y = 400; levelText.setText('Final Boss: The Upit Collective'); bossNameText.setText('Final Boss: The Upit Collective'); bossGuideText.setText(getBossGuide(6)); bossLoreText.setText(getBossLore(6)); } } spawnBoss(); // Play battle music LK.playMusic('battleMusic'); // Event handlers function handleMove(x, y, obj) { if (dragNode && !isGameOver) { dragNode.x = Math.max(40, Math.min(2008, x)); dragNode.y = Math.max(1000, Math.min(2692, y)); } } game.move = handleMove; game.down = function (x, y, obj) { if (!isGameOver) { dragNode = player; handleMove(x, y, obj); player.shoot(); } }; game.up = function (x, y, obj) { dragNode = null; }; // Main game loop game.update = function () { if (isGameOver) { LK.showGameOver(); return; } // Handle boss transition if (bossDefeated) { transitionTimer++; if (transitionTimer > 120) { currentBossLevel++; if (currentBossLevel > 6) { currentBossLevel = 6; // Stay at final boss } spawnBoss(); // Heal player slightly between bosses player.health = Math.min(player.maxHealth, player.health + 20); } } // Update player bullets for (var i = playerBullets.length - 1; i >= 0; i--) { var bullet = playerBullets[i]; if (bullet.y < -50) { game.removeChild(bullet); returnToPool(bullet, playerBulletPool); playerBullets.splice(i, 1); continue; } // Check collision with boss if (currentBoss && bullet.intersects(currentBoss)) { currentBoss.takeDamage(25); game.removeChild(bullet); returnToPool(bullet, playerBulletPool); playerBullets.splice(i, 1); continue; } } // Update boss bullets for (var i = bossBullets.length - 1; i >= 0; i--) { var bullet = bossBullets[i]; if (bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) { game.removeChild(bullet); returnToPool(bullet, bossBulletPool); bossBullets.splice(i, 1); continue; } // Check collision with player if (bullet.intersects(player)) { player.takeDamage(15); game.removeChild(bullet); returnToPool(bullet, bossBulletPool); bossBullets.splice(i, 1); continue; } } // Update boss lasers for (var i = bossLasers.length - 1; i >= 0; i--) { var laser = bossLasers[i]; if (laser.lifetime <= 0) { game.removeChild(laser); laser.lifetime = 120; // Reset lifetime for pooling returnToPool(laser, bossLaserPool); bossLasers.splice(i, 1); continue; } // Check collision with player if (laser.intersects(player)) { player.takeDamage(2); // Continuous damage } } // Update viggens for (var i = viggens.length - 1; i >= 0; i--) { var viggen = viggens[i]; if (viggen.lifetime <= 0 || viggen.x < -50 || viggen.x > 2098 || viggen.y < -50 || viggen.y > 2782) { game.removeChild(viggen); viggen.lifetime = 300; // Reset lifetime for pooling returnToPool(viggen, viggenPool); viggens.splice(i, 1); continue; } // Check collision with player if (viggen.intersects(player)) { player.takeDamage(20); game.removeChild(viggen); viggen.lifetime = 300; // Reset lifetime for pooling returnToPool(viggen, viggenPool); viggens.splice(i, 1); continue; } } // Update UI (only every 10 frames to reduce text update overhead) if (LK.ticks % 10 === 0) { healthBar.setText('Health: ' + player.health); if (currentBoss) { bossHealthBar.setText('Boss Health: ' + currentBoss.health); } } // Easter egg: Pulsing effect for unlocked features if (rapidFireUnlocked) { var pulseScale = 1 + Math.sin(easterEggTimer * 0.15) * 0.1; player.scaleX = pulseScale; player.scaleY = pulseScale; } // Auto-shoot (with rapid fire Easter egg) var shootInterval = rapidFireUnlocked ? 5 : 15; if (LK.ticks % shootInterval == 0 && !isGameOver) { player.shoot(); } // Easter egg effects easterEggTimer++; // Rainbow mode effect if (rainbowModeUnlocked) { var rainbowColor = Math.sin(easterEggTimer * 0.1) * 0.5 + 0.5; var r = Math.sin(easterEggTimer * 0.1) * 127 + 128; var g = Math.sin(easterEggTimer * 0.1 + 2) * 127 + 128; var b = Math.sin(easterEggTimer * 0.1 + 4) * 127 + 128; var color = (Math.floor(r) << 16) + (Math.floor(g) << 8) + Math.floor(b); // Apply rainbow effect to UI elements if (easterEggTimer % 3 == 0) { bossNameText.tint = color; levelText.tint = color; } } // Easter egg: Hidden developer message appears randomly if (easterEggTimer % 3600 == 0) { // Every 60 seconds var messages = ["The developer is watching... 👁️", "Viggens are secretly plotting...", "Glen approves of your gameplay", "Goosandra whispers your name...", "The code is strong with this one", "FRVR games are the best games! 🎮"]; var randomMsg = messages[Math.floor(Math.random() * messages.length)]; var devMsg = new Text2(randomMsg, { size: 40, fill: 0x00FFFF }); devMsg.anchor.set(0.5, 0.5); devMsg.x = 1024; devMsg.y = 2000; devMsg.alpha = 0; game.addChild(devMsg); // Fade in and out tween(devMsg, { alpha: 1, y: 1800 }, { duration: 1000, onFinish: function onFinish() { tween(devMsg, { alpha: 0, y: 1600 }, { duration: 1000, onFinish: function onFinish() { devMsg.destroy(); } }); } }); } };
===================================================================
--- original.js
+++ change.js
@@ -881,8 +881,103 @@
});
bossLoreText.anchor.set(0.5, 0);
bossLoreText.y = 240;
LK.gui.top.addChild(bossLoreText);
+// Add lore button
+var loreButton = new Text2('📖 LORE', {
+ size: 50,
+ fill: 0xFFD700
+});
+loreButton.anchor.set(0, 1);
+loreButton.x = 50;
+loreButton.y = -50;
+LK.gui.bottomLeft.addChild(loreButton);
+// Lore display overlay
+var loreOverlay = null;
+var loreDisplayText = null;
+var loreCloseButton = null;
+var showingLore = false;
+// Lore button click handler
+loreButton.down = function (x, y, obj) {
+ if (!showingLore) {
+ showingLore = true;
+ // Create dark overlay
+ loreOverlay = LK.getAsset('boss1', {
+ anchorX: 0,
+ anchorY: 0,
+ x: 0,
+ y: 0,
+ scaleX: 13.65,
+ scaleY: 18.21,
+ alpha: 0.8
+ });
+ loreOverlay.tint = 0x000000;
+ game.addChild(loreOverlay);
+ // Create lore text
+ var loreContent = getGameLore();
+ loreDisplayText = new Text2(loreContent, {
+ size: 45,
+ fill: 0xFFFFFF
+ });
+ loreDisplayText.anchor.set(0.5, 0.5);
+ loreDisplayText.x = 1024;
+ loreDisplayText.y = 1366;
+ game.addChild(loreDisplayText);
+ // Create close button
+ loreCloseButton = new Text2('❌ CLOSE', {
+ size: 60,
+ fill: 0xFF4444
+ });
+ loreCloseButton.anchor.set(0.5, 0.5);
+ loreCloseButton.x = 1024;
+ loreCloseButton.y = 2400;
+ game.addChild(loreCloseButton);
+ // Close button handler
+ loreCloseButton.down = function (x, y, obj) {
+ closeLoreDisplay();
+ };
+ // Animate entrance
+ tween(loreOverlay, {
+ alpha: 0.9
+ }, {
+ duration: 500
+ });
+ tween(loreDisplayText, {
+ scaleX: 1.1,
+ scaleY: 1.1
+ }, {
+ duration: 300,
+ easing: tween.bounceOut
+ });
+ tween(loreCloseButton, {
+ scaleX: 1.2,
+ scaleY: 1.2
+ }, {
+ duration: 400,
+ easing: tween.elasticOut
+ });
+ }
+};
+function closeLoreDisplay() {
+ if (showingLore) {
+ showingLore = false;
+ if (loreOverlay) {
+ loreOverlay.destroy();
+ loreOverlay = null;
+ }
+ if (loreDisplayText) {
+ loreDisplayText.destroy();
+ loreDisplayText = null;
+ }
+ if (loreCloseButton) {
+ loreCloseButton.destroy();
+ loreCloseButton = null;
+ }
+ }
+}
+function getGameLore() {
+ return "THE UPIT WARS: GENESIS\n\n" + "Long ago, in the digital realm of FRVR,\n" + "the UPIT Collective ruled with algorithms\n" + "and code. But power corrupted their minds,\n" + "transforming them into digital tyrants.\n\n" + "Each member became a Boss, wielding\n" + "their programming skills as weapons:\n\n" + "• Shant - The Beat Master\n" + "• Glen - The Haskell God\n" + "• Octo - The Hunter-Killer\n" + "• Benjaminsen - The Strategist\n" + "• The Upit Developer - Reality Bender\n" + "• The Collective - Merged Consciousness\n\n" + "In the shadows lurks Goosandra,\n" + "the Certified Viggener, responsible\n" + "for multiple digital genocides.\n\n" + "You are humanity's last hope.\n" + "Defeat the UPIT Bosses and restore\n" + "balance to the digital realm!\n\n" + "May the code be with you...";
+}
// Initialize player
player = game.addChild(new Player());
player.x = 1024;
player.y = 2200;