User prompt
Fix Bug: 'ReferenceError: sqrt is not defined' in this line: 'var distance = sqrt(distance);' Line Number: 317
Code edit (6 edits merged)
Please save this source code
User prompt
Here's a list of things to do: 1) set enemy health bar offset from 50 to -50. 2) Increase enemy attack range from 100. 3) Add a setFill function to the BorderText, which sets the fill of the last element of textList. 4) Reduce healingpickup limit from 5 to 3.
Code edit (2 edits merged)
Please save this source code
User prompt
Fix Bug: 'TypeError: weapons is undefined' in this line: 'weapons.push(new CrossWeapon(self));' Line Number: 700
Code edit (1 edits merged)
Please save this source code
User prompt
Create a DoubleLinkedList class with Node class for linked list elements
Code edit (4 edits merged)
Please save this source code
User prompt
add a function that creates a generic linkedlist
Code edit (1 edits merged)
Please save this source code
Code edit (6 edits merged)
Please save this source code
User prompt
Fix Bug: 'TypeError: t.setStageReference is not a function' in this line: 'parent.addChild(self);' Line Number: 12
Code edit (1 edits merged)
Please save this source code
Code edit (3 edits merged)
Please save this source code
User prompt
Fix Bug: 'ReferenceError: heroGraphics is not defined' in this line: 'LK.effects.flashObject(heroGraphics, 0xaa0000, 1000);' Line Number: 474
Code edit (8 edits merged)
Please save this source code
User prompt
Fix Bug: 'ReferenceError: projectileCount is not defined' in this line: 'var angleIncrement = Math.PI * 2 / projectileCount;' Line Number: 376
Code edit (6 edits merged)
Please save this source code
User prompt
do not destroy healthpickups when collecting a crucifix
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
Fix Bug: 'TypeError: self.getAsset is not a function' in this line: 'var arrowGraphics = self.getAsset('arrow', 'Directional Arrow', -1.0, 0.5);' Line Number: 394
Code edit (10 edits merged)
Please save this source code
User prompt
add an arrow asset to the hero that points towards the shootPos
User prompt
create an arrow asset for the hero that points towards from the hero to the shootPos with an offset of 100 units
function updateIteration(container, vars) {
for (var i = 0; i < container.length; i++) {
if (container[i].update(vars)) {
container[i].destroy();
container.splice(i, 1);
i--;
}
}
}
var Arrow = Container.expand(function (parent, offset, angle) {
var self = Container.call(this);
parent.addChild(self);
var arrowGraphics = self.createAsset('arrow', 'Directional Arrow', 0.5, 0.5);
self.updatePosition = function (heroX, heroY, shootPosX, shootPosY) {
var arrowAngle = Math.atan2(shootPosY - heroY, shootPosX - heroX);
self.rotation = arrowAngle;
self.x = heroX + Math.cos(arrowAngle) * offset;
self.y = heroY + Math.sin(arrowAngle) * offset;
};
self.updatePosition(parent.x, parent.y, angle.x, angle.y);
});
var HealthBar = Container.expand(function (parent, x, y, args) {
var self = Container.call(this);
parent.addChild(self);
self.x = x;
self.y = y;
var border = self.createAsset('blank', 'Health Bar Border', .5, .5);
var bar = LK.getAsset('blank', 'Health Bar', .5, .5);
var defaultFill = '#ffffff';
var defaultWidth = 100;
var defaultHeight = 10;
var defaultWeight = 4;
self.addChild(bar);
bar.width = args.width || defaultWidth;
bar.height = args.height || defaultHeight;
border.width = bar.width + 2 * (args.weight || defaultWeight);
border.height = bar.height + 2 * (args.weight || defaultWeight);
border.tint = '#000000';
self.updatePercentage = updatePercentage;
function updatePercentage(percentage) {
bar.scale.x = Math.max(0, percentage);
}
});
var SectionalContainer = Container.expand(function (parent) {
var self = Container.call(this);
self.x = 0;
self.y = 0;
parent.addChild(self);
});
var BorderedText = Container.expand(function (string, settings) {
var self = Container.call(this);
var textList = [];
var defaultFill = '#ffffff';
var defaultBorder = '#000000';
var defaultFont = 'bold monospace';
var defaultSize = 50;
var defaultWeight = 2;
var offsets = [[-1, -1], [-1, 1], [1, 1], [1, -1], [0, 0]];
var borderSettings = {
fill: settings.border || defaultBorder,
font: settings.font || defaultFont,
size: settings.size || defaultSize
};
var textSettings = {
fill: settings.fill || defaultFill,
font: settings.font || defaultFont,
size: settings.size || defaultSize
};
self.x = settings.x;
self.y = settings.y;
for (var i = 0; i < offsets.length; i++) {
var localSettings = i === offsets.length - 1 ? textSettings : borderSettings;
var text = new Text2(string, localSettings);
text.x += offsets[i][0] * defaultWeight;
text.y += offsets[i][1] * defaultWeight;
if (settings.anchor) {
text.anchor.set(settings.anchor.x, settings.anchor.y);
}
textList.push(text);
self.addChild(text);
}
self.setText = function (string) {
for (var i = 0; i < textList.length; i++) {
textList[i].setText(string);
}
};
});
var CountdownTimer = Container.expand(function (initialCountdown) {
var self = Container.call(this);
var countdown = initialCountdown;
var ticker = 60;
var countdownTxt = new BorderedText('', {
size: 60,
anchor: {
x: .5,
y: 0
}
});
self.update = update;
self.addChild(countdownTxt);
adjustLabel();
function update() {
ticker -= 1;
if (ticker <= 0) {
ticker = 60;
countdown--;
if (countdown >= 0) {
adjustLabel();
}
}
return 1 - countdown / initialCountdown;
}
function adjustLabel() {
var minutes = Math.floor(countdown / 60);
var seconds = countdown % 60;
var minutesString = (minutes < 10 ? '0' : '') + minutes;
var secondsString = (seconds < 10 ? '0' : '') + seconds;
countdownTxt.setText(minutesString + ':' + secondsString);
}
});
var ExperiencePickup = Container.expand(function (parent, x, y, experience) {
var self = Container.call(this);
parent.addChild(self);
self.x = x;
self.y = y;
var pickupGraphics = self.createAsset('experiencePickup', 'Experience Pickup', .5, .5);
var active = false;
self.update = update;
function update(vars) {
var hero = vars.hero;
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 250) {
self.active = true;
if (self.intersects(hero)) {
hero.addExperience(experience);
return true;
}
}
if (self.active) {
self.x += dx / distance * 20;
self.y += dy / distance * 20;
}
}
});
var CrucifixPickup = Container.expand(function (parent, x, y) {
var self = Container.call(this);
parent.addChild(self);
self.x = x;
self.y = y;
var pickupGraphics = self.createAsset('crucifixPickup', 'Crucifix Pickup', .5, .5);
});
var HealingPickup = Container.expand(function (parent, x, y) {
var self = Container.call(this);
parent.addChild(self);
self.x = x;
self.y = y;
var pickupGraphics = self.createAsset('healingPickup', 'Healing Pickup', .5, .5);
var healPercentage = 0.1;
self.update = update;
function update(args) {
var hero = args.hero;
if (self.intersects(hero)) {
hero.health = Math.min(hero.healthMax, hero.health + hero.healthMax * healPercentage);
return true;
}
}
});
var BasicBloodSplatter = Container.expand(function (parent, x, y) {
var self = Container.call(this);
parent.addChild(self);
self.x = x;
self.y = y;
var splatterGraphics = self.createAsset('bloodSplatter', 'Blood Splatter', .5, .5);
var initialLifetime = Math.floor(0.2 * 60);
var remainingLifetime = initialLifetime;
self.update = update;
function update() {
if (--remainingLifetime <= 0) {
return true;
}
var lifetime = remainingLifetime / initialLifetime;
var newScale = 2 - lifetime;
splatterGraphics.alpha = lifetime;
splatterGraphics.scale = {
x: newScale,
y: newScale
};
}
});
var BasicEnemy = Container.expand(function (parent, x, y, args) {
var self = Container.call(this);
self.id = args.id;
parent.addChild(self);
self.x = x;
self.y = y;
var enemyGraphics = self.createAsset('enemy', 'Basic Enemy', .5, .5);
var healthBar = null;
var damageDistance = 100;
var speed = 2.5;
var damage = 10;
var initialCooldown = 10;
var cooldown = initialCooldown;
var bobMagnitude = 2;
var bobPeriod = 10;
var creationTick = LK.ticks;
var parent = parent;
var healthMax = 5 + 25 * args.difficultyScale;
var health = healthMax;
self.update = update;
self.onTakeDamage = onTakeDamage;
function update(args) {
if (health <= 0) {
kill(args);
return true;
}
var hero = args.hero;
var game = args.game;
var backgroundContainer = args.backgroundContainer;
var foregroundContainer = args.foregroundContainer;
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > damageDistance) {
self.x += dx / distance * speed;
self.y += dy / distance * speed + Math.sin((LK.ticks - creationTick) / bobPeriod) * bobMagnitude;
cooldown = initialCooldown;
} else {
cooldown -= 1;
if (cooldown <= 0) {
cooldown = initialCooldown;
hero.onTakeDamage(damage);
}
}
var newParent;
if (self.y <= hero.y) {
newParent = backgroundContainer;
} else {
newParent = foregroundContainer;
}
if (parent !== newParent) {
newParent.addChild(self);
parent = newParent;
}
}
function kill(args) {
var hero = args.hero;
var game = args.game;
var effects = args.effects;
var healthPickups = args.healthPickups;
var crucifixPickups = args.crucifixPickups;
var experiencePickups = args.experiencePickups;
if (crucifixPickups.length < 1 && Math.random() < Math.sqrt(hero.minorBoonLevels['Luck']) / 100) {
crucifixPickups.push(new CrucifixPickup(game, self.x, self.y));
} else if (healthPickups.length < 5) {
for (var k = 0; k <= hero.minorBoonLevels['Luck']; k++) {
if (Math.random() < 0.02) {
healthPickups.push(new HealingPickup(game, self.x, self.y));
break;
}
}
}
var droppedExperience = 0;
for (var k = 0; k <= hero.minorBoonLevels['Luck'] + 1; k++) {
if (Math.random() < 0.3) {
droppedExperience++;
}
}
if (droppedExperience > 0) {
var x = self.x + Math.random() * 100 - 50;
var y = self.y + Math.random() * 100 - 50;
experiencePickups.push(new ExperiencePickup(game, x, y, droppedExperience));
}
effects.push(new BasicBloodSplatter(game, self.x, self.y));
}
function onTakeDamage(takenDamage) {
health -= takenDamage;
if (health > 0) {
if (!healthBar) {
healthBar = new HealthBar(self, 0, -enemyGraphics.height / 2 - 10, {
fill: '#aa0000'
});
}
healthBar.updatePercentage(health / healthMax);
LK.effects.flashObject(enemyGraphics, 0xaa0000, 1000);
}
}
});
var CrossProjectile = Container.expand(function (parent, x, y, args) {
var self = Container.call(this);
parent.addChild(self);
self.x = x;
self.y = y;
var projectileAsset = self.createAsset('crossProjectile', 'Projectile Asset', .5, .5);
var hitMap = {};
var initialSpeed = 30;
var speed = initialSpeed;
var speedDecrement = 1;
var destroyRange = -1200;
var growth = 1;
var growthRate = args.growthRate;
var initialScale = args.scale;
var range = args.range;
var damage = args.damage;
var linger = args.linger;
var angle = args.angle;
self.rotation = Math.random() * Math.PI * 2;
self.scale = {
x: initialScale,
y: initialScale
};
self.update = update;
function update(args) {
var hero = args.hero;
var enemies = args.enemies;
self.x += speed * Math.cos(angle);
self.y += speed * Math.sin(angle);
self.rotation += 0.2;
if (growthRate > 0) {
growth += growthRate;
var newScale = initialScale * growth;
self.scale = {
x: newScale,
y: newScale
};
}
if (range <= 0) {
if (speed > -initialSpeed) {
if (speed <= 0 && linger > 0) {
speed = 0;
linger--;
} else {
speed -= speedDecrement;
}
} else {
speed = -initialSpeed;
}
}
range -= Math.abs(speed);
var tick = LK.ticks;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (self.intersects(enemy)) {
var lastHitTick = hitMap[enemy.id];
if (!lastHitTick || tick - lastHitTick > 10) {
hitMap[enemy.id] = tick;
enemy.onTakeDamage(damage);
}
}
}
return (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) && range < destroyRange || self.intersects(hero) && speed < 0;
}
});
var CrossWeapon = Container.expand(function (parent) {
var self = Container.call(this);
parent.addChild(self);
self.x = 0;
self.y = 0;
var initialCooldown = 120;
var cooldown = self.initialCooldown;
self.update = update;
function update(args) {
var hero = args.hero;
if (cooldown > 0) {
cooldown--;
} else {
launch(args);
var attackSpeed = 1 + 0.25 * hero.minorBoonLevels['Rearm'];
cooldown = initialCooldown / attackSpeed;
}
}
function launch(args) {
var hero = args.hero;
var game = args.game;
var projectiles = args.projectiles;
var dx = hero.shootPos.x - hero.x;
var dy = hero.shootPos.y - hero.y;
var angle = Math.atan2(dy, dx);
var growthRate = 0.25 * hero.majorBoonLevels['Growth'] / 60;
var scale = 1 + 0.2 * hero.minorBoonLevels['Scale'];
var range = 200 + 50 * hero.minorBoonLevels['Range'];
var damage = 10 + 5 * hero.minorBoonLevels['Damage'];
var linger = 0 + 10 * hero.minorBoonLevels['Linger'];
var projectileCount = 1 + hero.majorBoonLevels['Extra'];
var angleIncrement = Math.PI * 2 / projectileCount;
for (var i = 0; i < projectileCount; i++) {
var currentAngle = angle + i * angleIncrement;
projectiles.push(new CrossProjectile(game, hero.x, hero.y, {
angle: currentAngle,
growthRate,
scale,
range,
damage,
linger
}));
}
}
});
var Hero = Container.expand(function (parent, x, y, args) {
var self = Container.call(this);
parent.addChild(self);
self.x = x;
self.y = y;
var heroGraphics = self.createAsset('hero', 'Hero character', .5, .5);
var progressBar = args.progressBar;
var onLevelUp = args.onLevelUp;
var baseMaxHealth = 100;
var experience = 0;
var level = 1;
var levelRequirement = 20;
self.minorBoonLevels = {
'Luck': 0,
'Scale': 0,
'Range': 0,
'Damage': 0,
'Rearm': 0,
'Linger': 0,
'Health': 0
};
self.majorBoonLevels = {
'Growth': 0,
'Spread': 0,
'Extra': 0
};
self.shootPos = {
x,
y
};
self.healthMax = baseMaxHealth;
self.health = baseMaxHealth;
var healthBar = new HealthBar(self, 0, -self.height / 2 - 10, {
fill: '#0fa0ff'
});
self.update = update;
self.addExperience = addExperience;
self.onTakeDamage = onTakeDamage;
function update(args) {
var game = args.game;
var newMaxHealth = baseMaxHealth + 20 * self.minorBoonLevels['Health'];
if (self.healthMax < newMaxHealth) {
self.maxHealth = newMaxHealth;
self.health = newMaxHealth;
healthBar.updatePercentage(self.health / self.healthMax);
}
if (self.targetPos) {
var dx = self.targetPos.x - self.x;
var dy = self.targetPos.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * 10;
self.y += dy / distance * 10;
} else {
self.x = self.targetPos.x;
self.y = self.targetPos.y;
self.targetPos = null;
}
}
var arrowOffset = 100;
if (!self.arrow) {
self.arrow = new Arrow(self, arrowOffset, self.shootPos);
} else {
self.arrow.updatePosition(self.x, self.y, self.shootPos.x, self.shootPos.y);
}
if (self.shootPos.x < self.x) {
self.scale.x = -1;
self.arrow.scale.x = -1;
} else {
self.scale.x = 1;
self.arrow.scale.x = 1;
}
}
function addExperience(amount) {
experience += amount;
if (experience >= levelRequirement) {
level++;
experience -= levelRequirement;
levelRequirement = Math.floor(levelRequirement * 1.2);
onLevelUp(level);
}
progressBar.scale.x = experience / levelRequirement;
}
function onTakeDamage(amount) {
self.health -= amount;
healthBar.updatePercentage(self.health / self.healthMax);
if (self.health <= 0) {
LK.effects.flashScreen(0xaa0000, 1000);
LK.showGameOver();
} else {
LK.effects.flashObject(heroGraphics, 0xaa0000, 1000);
}
}
});
var BoonSelection = Container.expand(function (boons, type, count, callback) {
var self = Container.call(this);
var availableBoons = Object.keys(boons).filter(function (boon) {
return boons[boon] < 5;
});
if (!availableBoons.length) {
self.destroy();
callback();
}
var selectedBoons = [];
while (selectedBoons.length < 3 && availableBoons.length > 0) {
var boonIndex = Math.floor(Math.random() * availableBoons.length);
selectedBoons.push(availableBoons.splice(boonIndex, 1)[0]);
}
var background = self.createAsset('boonBackground', 'Boon Selection Popup', 0.5, 0.5);
var boonMessageTitle = new BorderedText('Choose ' + count, {
y: -220,
size: 60,
anchor: {
x: .5,
y: 0
}
});
background.y = 50;
self.addChild(boonMessageTitle);
var boonMessageSubtitle = new BorderedText(type + ' Boon' + (count === 1 ? '' : 's'), {
y: -150,
anchor: {
x: .5,
y: 0
}
});
self.addChild(boonMessageSubtitle);
for (var i = 0; i < selectedBoons.length; i++) {
var boon = selectedBoons[i];
var boonButton = self.createAsset('boonButton', 'Boon Button', 0.5, 0.5);
boonButton.y = i * 120;
boonButton.x = -100;
boonButton.boon = boon;
boonButton.on('down', function () {
self.destroy();
callback(this.boon);
});
var boonLevel = new BorderedText(boons[boon], {
x: boonButton.x,
y: boonButton.y,
anchor: {
x: .5,
y: .5
}
});
var boonName = new BorderedText(boon, {
x: boonButton.x + 60,
y: boonButton.y,
anchor: {
x: 0,
y: .5
}
});
self.addChild(boonLevel);
self.addChild(boonName);
}
});
var Game = Container.expand(function () {
var self = Container.call(this);
var isPaused = false;
var minorBoonCount = 0;
var majorBoonCount = 0;
var grass = self.createAsset('grass', 'Grass Background', 0, 0);
var canMove = false;
var difficultyScale = 0;
var availableBoonsTxt = new BorderedText('0', {
x: -70,
y: 70,
fill: '#ff0000',
anchor: {
x: .5,
y: .5
}
});
var upgradeButton = LK.gui.topRight.createAsset('upgradeButton', 'Upgrade Button', 0.5, 0.5);
LK.gui.topRight.addChild(availableBoonsTxt);
grass.width = 2048;
grass.height = 2732;
upgradeButton.x = -70;
upgradeButton.y = 70;
upgradeButton.on('down', function () {
if (minorBoonCount + majorBoonCount > 0) {
showBoonSelection();
}
});
var levelTxt = new BorderedText('Level 1 • XP', {
anchor: {
x: 1.0,
y: 0
},
size: 80
});
var selectingBoon = false;
var progressBarBorder = LK.getAsset('progressBarBorder', 'Progress Bar Border', 0, .5);
var progressBar = LK.getAsset('progressBar', 'Progress Bar', 0, .5);
var enemyIdCounter = -1;
var heroProjectiles = [];
var enemyProjectiles = [];
var weapons = [];
var enemies = [];
var healthPickups = [];
var crucifixPickups = [];
var experiencePickups = [];
var effects = [];
var countdownTimer = new CountdownTimer(300);
LK.gui.topCenter.addChild(countdownTimer);
LK.gui.topCenter.addChild(progressBarBorder);
LK.gui.topCenter.addChild(progressBar);
LK.gui.topCenter.addChild(levelTxt);
countdownTimer.y = levelTxt.height + 10;
progressBarBorder.x = 20;
progressBarBorder.y = levelTxt.y + levelTxt.height / 2;
progressBar.x = 24;
progressBar.y = levelTxt.y + levelTxt.height / 2;
progressBar.scale.x = 0;
self.targetPos = null;
self.addChild(grass);
var backgroundContainer = new SectionalContainer(self);
var hero = new Hero(self, 2048 / 2, 2732 / 2, {
progressBar,
onLevelUp
});
weapons.push(new CrossWeapon(self));
var foregroundContainer = new SectionalContainer(self);
refreshBoonUpgradeButton();
stage.on('down', function (obj) {
canMove = true;
hero.targetPos = obj.event.getLocalPosition(self);
});
stage.on('up', function (obj) {
canMove = false;
hero.targetPos = null;
});
stage.on('move', function (obj) {
if (!isPaused) {
if (canMove) {
hero.targetPos = obj.event.getLocalPosition(self);
}
hero.shootPos = obj.event.getLocalPosition(self);
if (hero.shootPos.x < hero.x) {
hero.scale.x = -1;
} else {
hero.scale.x = 1;
}
}
});
LK.on('tick', function () {
if (!isPaused) {
difficultyScale = countdownTimer.update();
hero.update({
game: self
});
updateIteration(weapons, {
projectiles: heroProjectiles,
game: self,
hero
});
updateIteration(heroProjectiles, {
enemies,
hero
});
updateIteration(enemyProjectiles);
updateIteration(enemies, {
game: self,
backgroundContainer,
foregroundContainer,
experiencePickups,
crucifixPickups,
healthPickups,
effects,
hero
});
updateIteration(effects);
updateIteration(experiencePickups, {
hero
});
updateIteration(healthPickups, {
hero
});
for (var i = 0; i < crucifixPickups.length; i++) {
if (hero.intersects(crucifixPickups[i])) {
for (var j = 0; j < enemies.length; j++) {
enemies[j].destroy();
}
enemies = [];
for (var j = 0; j < enemyProjectiles.length; j++) {
enemyProjectiles[j].destroy();
}
enemyProjectiles = [];
for (var j = 0; j < healthPickups.length; j++) {
healthPickups[j].destroy();
}
healthPickups = [];
for (var j = 0; j < crucifixPickups.length; j++) {
crucifixPickups[j].destroy();
}
crucifixPickups = [];
for (var j = 0; j < experiencePickups.length; j++) {
experiencePickups[j].active = true;
}
LK.effects.flashScreen(0xffffff, 1000);
break;
}
}
if (LK.ticks % (60 - Math.floor(50 * difficultyScale)) === 0) {
spawnEnemy();
}
}
});
function refreshBoonUpgradeButton() {
var bool = !selectingBoon && minorBoonCount + majorBoonCount > 0;
upgradeButton.visible = bool;
availableBoonsTxt.visible = bool;
availableBoonsTxt.setText(minorBoonCount + majorBoonCount);
}
function showBoonSelection() {
if (!selectingBoon) {
var boonSelection;
if (minorBoonCount) {
selectingBoon = true;
boonSelection = new BoonSelection(hero.minorBoonLevels, 'Minor', minorBoonCount, function (boon) {
if (boon) {
hero.minorBoonLevels[boon]++;
minorBoonCount--;
selectingBoon = false;
refreshBoonUpgradeButton();
showBoonSelection();
}
});
} else if (majorBoonCount) {
selectingBoon = true;
boonSelection = new BoonSelection(hero.majorBoonLevels, 'Major', majorBoonCount, function (boon) {
if (boon) {
hero.majorBoonLevels[boon]++;
majorBoonCount--;
selectingBoon = false;
refreshBoonUpgradeButton();
showBoonSelection();
}
});
}
if (boonSelection) {
isPaused = true;
LK.gui.center.addChild(boonSelection);
} else {
isPaused = false;
}
refreshBoonUpgradeButton();
}
}
function spawnEnemy() {
var side = Math.floor(Math.random() * 4);
var distance = Math.random();
var x, y;
switch (side) {
case 0:
x = 2048 * distance;
y = 0;
break;
case 1:
x = 2048;
y = 2732 * distance;
break;
case 2:
x = 2048 * distance;
y = 2732;
break;
case 3:
x = 0;
y = 2732 * distance;
break;
}
enemies.push(new BasicEnemy(self, x, y, {
id: (++enemyIdCounter).toString(),
difficultyScale
}));
}
function onLevelUp(level) {
levelTxt.setText('Level ' + level + ' • XP');
if (level % 5) {
minorBoonCount++;
} else {
majorBoonCount++;
}
refreshBoonUpgradeButton();
}
});
pixel art cross with blue accents Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of a white orb. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of a white orb with a halo. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of a pulsating white heart with a halo. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of a dark goo projectile with red highlights. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art tall blue fireball. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of an evil fantasy sword facing downward. Minor red details. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
backgroundAmbient
Sound effect
heroHealed
Sound effect
pickupExperience
Sound effect
heroLeveled
Sound effect
weaponCrossImpact
Sound effect
heroImpact
Sound effect
enemyDeath
Sound effect
pickupWeapon
Sound effect
pickupCrucifix
Sound effect
weaponCrossLaunch
Sound effect
heroDeath
Sound effect
enemyRoar
Sound effect
clockChime
Sound effect