User prompt
Make the Sparkling water get gifted when clicking Goosandra secret while Glen's HP is at 0
User prompt
Now gift the player sparkling water if the player clicks on the Goosandra Easter egg while Octo is spawning ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Make the game lose UI for a second, gain it back, ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Now let's add a Boombox (Control your music. Each piece must be listened in their natural environment before getting access.) ↪💡 Consider importing and using the following plugins: @upit/storage.v1 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
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
/****
* Plugins
****/
var tween = LK.import("@upit/tween.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 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 distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
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 = new PlayerBullet();
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;
});
/****
* 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 bossDefeated = false;
var isGameOver = false;
var transitionTimer = 0;
var dragNode = null;
var bossNames = ['Brian The Destroyer', 'Chris The Relentless', 'Martin The Chaos Bringer', 'Kresimir The Code Crusher', 'Anders The Final Boss', 'The Upit Collective'];
// 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);
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: Brian The Destroyer', {
size: 70,
fill: 0xFF6600
});
bossNameText.anchor.set(0.5, 0);
bossNameText.y = 100;
LK.gui.top.addChild(bossNameText);
// Initialize player
player = game.addChild(new Player());
player.x = 1024;
player.y = 2200;
// Start first boss
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);
}
// Spawn appropriate boss
if (currentBossLevel == 1) {
currentBoss = game.addChild(new Boss1());
currentBoss.x = 1024;
currentBoss.y = 400;
levelText.setText('Boss 1: Brian The Destroyer');
bossNameText.setText('Boss 1: Brian The Destroyer');
} else if (currentBossLevel == 2) {
currentBoss = game.addChild(new Boss2());
currentBoss.x = 1024;
currentBoss.y = 600;
levelText.setText('Boss 2: Chris The Relentless');
bossNameText.setText('Boss 2: Chris The Relentless');
} else if (currentBossLevel == 3) {
currentBoss = game.addChild(new Boss3());
currentBoss.x = 1024;
currentBoss.y = 500;
levelText.setText('Boss 3: Martin The Chaos Bringer');
bossNameText.setText('Boss 3: Martin The Chaos Bringer');
} else if (currentBossLevel == 4) {
currentBoss = game.addChild(new Boss4());
currentBoss.x = 1024;
currentBoss.y = 500;
levelText.setText('Boss 4: Kresimir The Code Crusher');
bossNameText.setText('Boss 4: Kresimir The Code Crusher');
} else if (currentBossLevel == 5) {
currentBoss = game.addChild(new Boss5());
currentBoss.x = 1024;
currentBoss.y = 400;
levelText.setText('Boss 5: Anders The Final Boss');
bossNameText.setText('Boss 5: Anders The Final Boss');
} 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');
}
}
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) {
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
// Check collision with boss
if (currentBoss && bullet.intersects(currentBoss)) {
currentBoss.takeDamage(25);
bullet.destroy();
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) {
bullet.destroy();
bossBullets.splice(i, 1);
continue;
}
// Check collision with player
if (bullet.intersects(player)) {
player.takeDamage(15);
bullet.destroy();
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) {
laser.destroy();
bossLasers.splice(i, 1);
continue;
}
// Check collision with player
if (laser.intersects(player)) {
player.takeDamage(2); // Continuous damage
}
}
// Update UI
healthBar.setText('Health: ' + player.health);
if (currentBoss) {
bossHealthBar.setText('Boss Health: ' + currentBoss.health);
}
// Auto-shoot
if (LK.ticks % 15 == 0 && !isGameOver) {
player.shoot();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -452,9 +452,9 @@
var bossDefeated = false;
var isGameOver = false;
var transitionTimer = 0;
var dragNode = null;
-var bossNames = ['The Red Guardian', 'The Spinning Menace', 'The Laser Lord', 'The Spiral Destroyer', 'The Phantom Striker', 'The Upit Overlord'];
+var bossNames = ['Brian The Destroyer', 'Chris The Relentless', 'Martin The Chaos Bringer', 'Kresimir The Code Crusher', 'Anders The Final Boss', 'The Upit Collective'];
// UI Elements
var healthBar;
var bossHealthBar;
var levelText;
@@ -483,9 +483,9 @@
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(instructionText);
-var bossNameText = new Text2('Boss 1: The Red Guardian', {
+var bossNameText = new Text2('Boss 1: Brian The Destroyer', {
size: 70,
fill: 0xFF6600
});
bossNameText.anchor.set(0.5, 0);
@@ -511,40 +511,40 @@
if (currentBossLevel == 1) {
currentBoss = game.addChild(new Boss1());
currentBoss.x = 1024;
currentBoss.y = 400;
- levelText.setText('Boss 1: The Red Guardian');
- bossNameText.setText('Boss 1: The Red Guardian');
+ levelText.setText('Boss 1: Brian The Destroyer');
+ bossNameText.setText('Boss 1: Brian The Destroyer');
} else if (currentBossLevel == 2) {
currentBoss = game.addChild(new Boss2());
currentBoss.x = 1024;
currentBoss.y = 600;
- levelText.setText('Boss 2: The Spinning Menace');
- bossNameText.setText('Boss 2: The Spinning Menace');
+ levelText.setText('Boss 2: Chris The Relentless');
+ bossNameText.setText('Boss 2: Chris The Relentless');
} else if (currentBossLevel == 3) {
currentBoss = game.addChild(new Boss3());
currentBoss.x = 1024;
currentBoss.y = 500;
- levelText.setText('Boss 3: The Laser Lord');
- bossNameText.setText('Boss 3: The Laser Lord');
+ levelText.setText('Boss 3: Martin The Chaos Bringer');
+ bossNameText.setText('Boss 3: Martin The Chaos Bringer');
} else if (currentBossLevel == 4) {
currentBoss = game.addChild(new Boss4());
currentBoss.x = 1024;
currentBoss.y = 500;
- levelText.setText('Boss 4: The Spiral Destroyer');
- bossNameText.setText('Boss 4: The Spiral Destroyer');
+ levelText.setText('Boss 4: Kresimir The Code Crusher');
+ bossNameText.setText('Boss 4: Kresimir The Code Crusher');
} else if (currentBossLevel == 5) {
currentBoss = game.addChild(new Boss5());
currentBoss.x = 1024;
currentBoss.y = 400;
- levelText.setText('Boss 5: The Phantom Striker');
- bossNameText.setText('Boss 5: The Phantom Striker');
+ levelText.setText('Boss 5: Anders The Final Boss');
+ bossNameText.setText('Boss 5: Anders The Final Boss');
} else if (currentBossLevel >= 6) {
currentBoss = game.addChild(new FinalBoss());
currentBoss.x = 1024;
currentBoss.y = 400;
- levelText.setText('Final Boss: The Upit Overlord');
- bossNameText.setText('Final Boss: The Upit Overlord');
+ levelText.setText('Final Boss: The Upit Collective');
+ bossNameText.setText('Final Boss: The Upit Collective');
}
}
spawnBoss();
// Play battle music