User prompt
Make when leveling up the game pauses and 3 show and can only pick one and then the game continues
User prompt
Make xp orbs be worth 1 xp and level need 10 xp and increses by 1.5x every level
User prompt
Make enemys have 1.2x more health every wave
User prompt
Make player regen 1 hp every second
User prompt
Make the health bar a little smaller
User prompt
Make so the player have a health bar and 100 hp and enemys deal 10
User prompt
Make so the player have a health bar and 100 hp and enemys deal 10
User prompt
make so the player moves with wasd keys
User prompt
make enemys drop xp orbs that when collected adds to a level ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make enemy hp bar drain when hit
User prompt
make bow shoot 50% slower and deal 50% less damage
User prompt
make enemys have hp and hp bar
User prompt
remove the power ups and make the bow shoot slower
User prompt
player starts with a arrow weapon
Code edit (1 edits merged)
Please save this source code
User prompt
Shadow Survivor
Initial prompt
rougelite survival
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Arrow = Container.expand(function () {
var self = Container.call(this);
var arrowGraphics = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.damage = 12.5;
self.directionX = 0;
self.directionY = 0;
self.lastEnemyCollisions = [];
self.setDirection = function (dx, dy) {
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.directionX = dx / distance;
self.directionY = dy / distance;
self.rotation = Math.atan2(dy, dx);
}
};
self.update = function () {
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
// Check collisions with enemies
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var currentCollision = self.intersects(enemy);
var lastCollision = self.lastEnemyCollisions[i] || false;
if (!lastCollision && currentCollision) {
// Hit enemy
LK.getSound('enemyHit').play();
LK.effects.flashObject(enemy, 0xFFFFFF, 200);
// Damage enemy
var isDead = enemy.takeDamage(self.damage);
if (isDead) {
// Remove enemy
enemies.splice(i, 1);
enemy.destroy();
}
// Remove arrow
if (arrows.indexOf(self) !== -1) {
arrows.splice(arrows.indexOf(self), 1);
self.destroy();
}
return;
}
self.lastEnemyCollisions[i] = currentCollision;
}
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1;
self.damage = 10;
self.targetX = 0;
self.targetY = 0;
self.lastPlayerCollision = false;
self.maxHealth = 50;
self.health = self.maxHealth;
// Create health bar background
var healthBarBg = self.attachAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.15,
scaleY: 0.3
});
healthBarBg.y = -40;
// Create health bar
var healthBar = self.attachAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.15,
scaleY: 0.3
});
healthBar.y = -40;
self.healthBar = healthBar;
self.healthBarBg = healthBarBg;
self.update = function () {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
var currentCollision = self.intersects(player);
if (!self.lastPlayerCollision && currentCollision) {
player.takeDamage(self.damage);
}
self.lastPlayerCollision = currentCollision;
};
self.takeDamage = function (damage) {
self.health -= damage;
self.updateHealthBar();
if (self.health <= 0) {
self.health = 0;
// Drop XP orb
var xpOrb = new XPOrb();
xpOrb.x = self.x;
xpOrb.y = self.y;
xpOrbs.push(xpOrb);
game.addChild(xpOrb);
// Add tween animation for orb spawn
tween(xpOrb, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(xpOrb, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeIn
});
}
});
return true; // Enemy is dead
}
return false; // Enemy is still alive
};
self.updateHealthBar = function () {
var healthPercentage = self.health / self.maxHealth;
self.healthBar.scaleX = 0.15 * healthPercentage;
if (healthPercentage > 0.6) {
self.healthBar.tint = 0x4CAF50;
} else if (healthPercentage > 0.3) {
self.healthBar.tint = 0xFFEB3B;
} else {
self.healthBar.tint = 0xFF5722;
}
};
return self;
});
var FastEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('fastEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.damage = 10;
self.targetX = 0;
self.targetY = 0;
self.lastPlayerCollision = false;
self.maxHealth = 30;
self.health = self.maxHealth;
// Create health bar background
var healthBarBg = self.attachAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.12,
scaleY: 0.25
});
healthBarBg.y = -35;
// Create health bar
var healthBar = self.attachAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.12,
scaleY: 0.25
});
healthBar.y = -35;
self.healthBar = healthBar;
self.healthBarBg = healthBarBg;
self.update = function () {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
var currentCollision = self.intersects(player);
if (!self.lastPlayerCollision && currentCollision) {
player.takeDamage(self.damage);
}
self.lastPlayerCollision = currentCollision;
};
self.takeDamage = function (damage) {
self.health -= damage;
self.updateHealthBar();
if (self.health <= 0) {
self.health = 0;
// Drop XP orb
var xpOrb = new XPOrb();
xpOrb.x = self.x;
xpOrb.y = self.y;
xpOrbs.push(xpOrb);
game.addChild(xpOrb);
// Add tween animation for orb spawn
tween(xpOrb, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(xpOrb, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeIn
});
}
});
return true; // Enemy is dead
}
return false; // Enemy is still alive
};
self.updateHealthBar = function () {
var healthPercentage = self.health / self.maxHealth;
self.healthBar.scaleX = 0.12 * healthPercentage;
if (healthPercentage > 0.6) {
self.healthBar.tint = 0x4CAF50;
} else if (healthPercentage > 0.3) {
self.healthBar.tint = 0xFFEB3B;
} else {
self.healthBar.tint = 0xFF5722;
}
};
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.maxHealth = 100;
// Create player health bar background
var playerHealthBarBg = self.attachAsset('playerHealthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
playerHealthBarBg.y = -60;
// Create player health bar
var playerHealthBar = self.attachAsset('playerHealthBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
playerHealthBar.y = -60;
self.playerHealthBar = playerHealthBar;
self.playerHealthBarBg = playerHealthBarBg;
self.speed = 1;
self.invulnerable = false;
self.invulnerableTime = 0;
self.takeDamage = function (damage) {
if (self.invulnerable) {
return;
}
self.health -= damage;
self.updatePlayerHealthBar();
self.invulnerable = true;
self.invulnerableTime = 60; // 1 second of invulnerability
LK.getSound('playerDamage').play();
LK.effects.flashObject(self, 0xFF0000, 500);
if (self.health <= 0) {
self.health = 0;
gameOver = true;
}
};
self.heal = function (amount) {
self.health = Math.min(self.maxHealth, self.health + amount);
self.updatePlayerHealthBar();
};
self.updatePlayerHealthBar = function () {
var healthPercentage = self.health / self.maxHealth;
self.playerHealthBar.scaleX = 0.8 * healthPercentage;
if (healthPercentage > 0.6) {
self.playerHealthBar.tint = 0x4CAF50;
} else if (healthPercentage > 0.3) {
self.playerHealthBar.tint = 0xFFEB3B;
} else {
self.playerHealthBar.tint = 0xFF5722;
}
};
self.update = function () {
if (self.invulnerable) {
self.invulnerableTime--;
if (self.invulnerableTime <= 0) {
self.invulnerable = false;
}
}
};
return self;
});
var XPOrb = Container.expand(function () {
var self = Container.call(this);
var orbGraphics = self.attachAsset('xpOrb', {
anchorX: 0.5,
anchorY: 0.5
});
self.xpValue = 10;
self.attractDistance = 100;
self.attractSpeed = 4;
self.lastPlayerCollision = false;
self.update = function () {
// Check distance to player for attraction
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Attract to player if within range
if (distance < self.attractDistance && distance > 0) {
var moveSpeed = Math.min(self.attractSpeed, distance);
self.x += dx / distance * moveSpeed;
self.y += dy / distance * moveSpeed;
}
// Check collision with player
var currentCollision = self.intersects(player);
if (!self.lastPlayerCollision && currentCollision) {
// Collect XP
playerXP += self.xpValue;
checkLevelUp();
LK.getSound('xpCollect').play();
// Remove orb
if (xpOrbs.indexOf(self) !== -1) {
xpOrbs.splice(xpOrbs.indexOf(self), 1);
self.destroy();
}
}
self.lastPlayerCollision = currentCollision;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
var player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
player.updatePlayerHealthBar();
var enemies = [];
var arrows = [];
var xpOrbs = [];
var gameOver = false;
var lastShootTime = 0;
var shootCooldown = 90; // 50% slower shooting rate
var waveNumber = 1;
var enemiesSpawned = 0;
var enemiesPerWave = 5;
var spawnTimer = 0;
var survivalTime = 0;
var dragNode = null;
var playerXP = 0;
var playerLevel = 1;
var xpToNextLevel = 100;
// Keyboard input state
var keys = {
w: false,
a: false,
s: false,
d: false
};
// UI Elements
var healthBarBg = LK.getAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0
});
var healthBar = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0
});
LK.gui.top.addChild(healthBarBg);
LK.gui.top.addChild(healthBar);
var waveText = new Text2('Wave: 1', {
size: 80,
fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0);
LK.gui.top.addChild(waveText);
var timeText = new Text2('Time: 0s', {
size: 60,
fill: 0xFFFFFF
});
timeText.anchor.set(1, 0);
LK.gui.topRight.addChild(timeText);
var levelText = new Text2('Level: 1', {
size: 70,
fill: 0xFFD700
});
levelText.anchor.set(0, 0);
LK.gui.topLeft.addChild(levelText);
var xpText = new Text2('XP: 0/100', {
size: 50,
fill: 0x00BCD4
});
xpText.anchor.set(0, 0);
LK.gui.topLeft.addChild(xpText);
// Position UI elements
healthBarBg.y = 120;
healthBar.y = 120;
waveText.y = 200;
timeText.y = 280;
timeText.x = -20;
levelText.x = 120;
levelText.y = 20;
xpText.x = 120;
xpText.y = 100;
function checkLevelUp() {
if (playerXP >= xpToNextLevel) {
playerLevel++;
playerXP -= xpToNextLevel;
xpToNextLevel = Math.floor(xpToNextLevel * 1.5);
// Level up effects
LK.effects.flashScreen(0xFFD700, 800);
player.heal(20);
// Show level up with tween
var levelUpText = new Text2('LEVEL UP!', {
size: 120,
fill: 0xFFD700
});
levelUpText.anchor.set(0.5, 0.5);
levelUpText.x = 1024;
levelUpText.y = 1366;
levelUpText.alpha = 0;
game.addChild(levelUpText);
tween(levelUpText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(levelUpText, {
alpha: 0,
y: levelUpText.y - 100
}, {
duration: 1000,
easing: tween.easeIn,
onFinish: function onFinish() {
levelUpText.destroy();
}
});
}
});
}
}
function spawnEnemy() {
var enemy;
if (waveNumber > 3 && Math.random() < 0.3) {
enemy = new FastEnemy();
} else {
enemy = new Enemy();
}
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
enemy.x = Math.random() * 2048;
enemy.y = -50;
break;
case 1:
// Right
enemy.x = 2098;
enemy.y = Math.random() * 2732;
break;
case 2:
// Bottom
enemy.x = Math.random() * 2048;
enemy.y = 2782;
break;
case 3:
// Left
enemy.x = -50;
enemy.y = Math.random() * 2732;
break;
}
enemy.targetX = player.x;
enemy.targetY = player.y;
enemy.speed += Math.floor(waveNumber / 3) * 0.5;
enemies.push(enemy);
game.addChild(enemy);
enemiesSpawned++;
}
function updateHealthBar() {
var healthPercentage = player.health / player.maxHealth;
healthBar.width = 400 * healthPercentage;
if (healthPercentage > 0.6) {
healthBar.tint = 0x4CAF50;
} else if (healthPercentage > 0.3) {
healthBar.tint = 0xFFEB3B;
} else {
healthBar.tint = 0xFF5722;
}
}
function handleMove(x, y, obj) {
if (dragNode && !gameOver) {
var newX = Math.max(40, Math.min(2008, x));
var newY = Math.max(40, Math.min(2692, y));
var dx = newX - dragNode.x;
var dy = newY - dragNode.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var moveDistance = Math.min(distance, 8 * dragNode.speed);
dragNode.x += dx / distance * moveDistance;
dragNode.y += dy / distance * moveDistance;
}
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (!gameOver) {
dragNode = player;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Keyboard event listeners
LK.on('keydown', function (event) {
switch (event.key.toLowerCase()) {
case 'w':
keys.w = true;
break;
case 'a':
keys.a = true;
break;
case 's':
keys.s = true;
break;
case 'd':
keys.d = true;
break;
}
});
LK.on('keyup', function (event) {
switch (event.key.toLowerCase()) {
case 'w':
keys.w = false;
break;
case 'a':
keys.a = false;
break;
case 's':
keys.s = false;
break;
case 'd':
keys.d = false;
break;
}
});
game.update = function () {
if (gameOver) return;
survivalTime++;
// Handle WASD movement
var moveSpeed = 5;
if (keys.w) {
player.y = Math.max(40, player.y - moveSpeed);
}
if (keys.s) {
player.y = Math.min(2692, player.y + moveSpeed);
}
if (keys.a) {
player.x = Math.max(40, player.x - moveSpeed);
}
if (keys.d) {
player.x = Math.min(2008, player.x + moveSpeed);
}
// Update UI
updateHealthBar();
waveText.setText('Wave: ' + waveNumber);
timeText.setText('Time: ' + Math.floor(survivalTime / 60) + 's');
levelText.setText('Level: ' + playerLevel);
xpText.setText('XP: ' + playerXP + '/' + xpToNextLevel);
// Enemy spawning
spawnTimer++;
var spawnRate = Math.max(30, 120 - waveNumber * 5);
if (spawnTimer >= spawnRate && enemiesSpawned < enemiesPerWave) {
spawnEnemy();
spawnTimer = 0;
}
// Auto-shoot arrows at nearest enemy
lastShootTime++;
if (lastShootTime >= shootCooldown && enemies.length > 0) {
var nearestEnemy = null;
var nearestDistance = Infinity;
for (var e = 0; e < enemies.length; e++) {
var enemy = enemies[e];
var dx = enemy.x - player.x;
var dy = enemy.y - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestEnemy = enemy;
}
}
if (nearestEnemy) {
var arrow = new Arrow();
arrow.x = player.x;
arrow.y = player.y;
var dx = nearestEnemy.x - player.x;
var dy = nearestEnemy.y - player.y;
arrow.setDirection(dx, dy);
arrows.push(arrow);
game.addChild(arrow);
LK.getSound('arrowShoot').play();
lastShootTime = 0;
}
}
// Update arrows
for (var a = arrows.length - 1; a >= 0; a--) {
var arrow = arrows[a];
// Remove arrows that are off screen
if (arrow.x < -100 || arrow.x > 2148 || arrow.y < -100 || arrow.y > 2832) {
arrows.splice(a, 1);
arrow.destroy();
}
}
// Update XP orbs
for (var x = xpOrbs.length - 1; x >= 0; x--) {
var xpOrb = xpOrbs[x];
// Remove orbs that are too far off screen
if (xpOrb.x < -200 || xpOrb.x > 2248 || xpOrb.y < -200 || xpOrb.y > 2932) {
xpOrbs.splice(x, 1);
xpOrb.destroy();
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
enemy.targetX = player.x;
enemy.targetY = player.y;
// Remove enemies that are too far off screen
if (enemy.x < -200 || enemy.x > 2248 || enemy.y < -200 || enemy.y > 2932) {
enemies.splice(i, 1);
enemy.destroy();
}
}
// Check wave completion
if (enemiesSpawned >= enemiesPerWave && enemies.length === 0) {
waveNumber++;
enemiesSpawned = 0;
enemiesPerWave = Math.min(20, 5 + waveNumber * 2);
// Bonus health for completing wave
player.heal(10);
LK.effects.flashScreen(0x4CAF50, 500);
}
// Game over check
if (player.health <= 0) {
gameOver = true;
// Save best survival time
var bestTime = storage.bestTime || 0;
if (survivalTime > bestTime) {
storage.bestTime = survivalTime;
}
// Save total waves completed
var totalWaves = storage.totalWaves || 0;
storage.totalWaves = totalWaves + (waveNumber - 1);
LK.setScore(Math.floor(survivalTime / 60) + (waveNumber - 1) * 10);
LK.effects.flashScreen(0xFF0000, 1000);
LK.setTimeout(function () {
LK.showGameOver();
}, 1500);
}
}; ===================================================================
--- original.js
+++ change.js
@@ -244,29 +244,29 @@
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
- self.speed = 1;
- self.invulnerable = false;
- self.invulnerableTime = 0;
// Create player health bar background
var playerHealthBarBg = self.attachAsset('playerHealthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
- scaleX: 0.4,
+ scaleX: 0.8,
scaleY: 0.8
});
playerHealthBarBg.y = -60;
// Create player health bar
var playerHealthBar = self.attachAsset('playerHealthBar', {
anchorX: 0.5,
anchorY: 0.5,
- scaleX: 0.4,
+ scaleX: 0.8,
scaleY: 0.8
});
playerHealthBar.y = -60;
self.playerHealthBar = playerHealthBar;
self.playerHealthBarBg = playerHealthBarBg;
+ self.speed = 1;
+ self.invulnerable = false;
+ self.invulnerableTime = 0;
self.takeDamage = function (damage) {
if (self.invulnerable) {
return;
}
@@ -286,9 +286,9 @@
self.updatePlayerHealthBar();
};
self.updatePlayerHealthBar = function () {
var healthPercentage = self.health / self.maxHealth;
- self.playerHealthBar.scaleX = 0.4 * healthPercentage;
+ self.playerHealthBar.scaleX = 0.8 * healthPercentage;
if (healthPercentage > 0.6) {
self.playerHealthBar.tint = 0x4CAF50;
} else if (healthPercentage > 0.3) {
self.playerHealthBar.tint = 0xFFEB3B;