User prompt
add a asset for the background, reverse the image for the left turret, remove the bottom ground
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ground is not defined' in or related to this line: 'game.addChild(ground);' Line Number: 216
Code edit (1 edits merged)
Please save this source code
User prompt
add a background for the market
User prompt
remove the hp text and make the hp bar work, showing the remaining health with a green bar inside of the gray one and add a platform ground
User prompt
make hp a bar, visible on the top of the base
User prompt
make the buttons and texts far from each other
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'containsPoint')' in or related to this line: 'if (t && LK.util.containsPoint(t, {' Line Number: 373
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'containsPoint')' in or related to this line: 'if (LK.util.containsPoint(t, {' Line Number: 373
User prompt
Please fix the bug: 'Uncaught TypeError: t.containsPoint is not a function' in or related to this line: 'if (t.containsPoint({' Line Number: 373
Code edit (1 edits merged)
Please save this source code
User prompt
Base Turret Defense: Horde Siege
Initial prompt
a platform, base in the middle, hordes coming from right and left of the map, we are trying to defend our base with turrets, enemy's and our base's health bar, upgrading our base and adding more turrets, gaining gold when clearing waves etc
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Base class
var Base = Container.expand(function () {
var self = Container.call(this);
// Attach base asset (ellipse, blue)
var baseGraphics = self.attachAsset('base', {
anchorX: 0.5,
anchorY: 0.5
});
baseGraphics.width = 180;
baseGraphics.height = 180;
baseGraphics.color = 0x3399ff;
self.maxHp = 20;
self.hp = self.maxHp;
// Flash on hit
self.hit = function () {
LK.effects.flashObject(self, 0xff0000, 400);
};
// Repair
self.repair = function () {
self.hp = Math.min(self.maxHp, self.hp + 5);
};
// Upgrade
self.upgrade = function () {
self.maxHp += 10;
self.hp = self.maxHp;
baseGraphics.scaleX += 0.1;
baseGraphics.scaleY += 0.1;
};
return self;
});
// Bullet class
var Bullet = Container.expand(function () {
var self = Container.call(this);
// Attach bullet asset (box, yellow)
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
bulletGraphics.width = 40;
bulletGraphics.height = 40;
bulletGraphics.color = 0xb8b031;
self.speed = 24;
self.target = null;
self.side = 1;
self.damage = 1;
self.update = function () {
if (!self.target || self.target.destroyed) {
self.destroy();
return;
}
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 40) {
// Hit!
self.target.hp -= self.damage;
LK.effects.flashObject(self.target, 0xffff00, 200);
self.destroy();
return;
}
var step = self.speed;
self.x += dx / dist * step;
self.y += dy / dist * step;
};
return self;
});
// Enemy class
var Enemy = Container.expand(function () {
var self = Container.call(this);
// Attach enemy asset (ellipse, red)
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
// Set size and color
enemyGraphics.width = 90;
enemyGraphics.height = 90;
enemyGraphics.color = 0xd83318;
// Enemy properties
self.speed = 3 + Math.random() * 1.5; // Will be set per wave
self.hp = 1; // Will be set per wave
self.direction = 1; // 1 for right-to-left, -1 for left-to-right
// Update method
self.update = function () {
self.x += self.speed * self.direction;
};
return self;
});
// Turret class
var Turret = Container.expand(function () {
var self = Container.call(this);
// Attach turret asset (box, green)
var turretGraphics = self.attachAsset('turret', {
anchorX: 0.5,
anchorY: 0.5
});
turretGraphics.width = 100;
turretGraphics.height = 100;
turretGraphics.color = 0x83de44;
// Turret properties
self.range = 500;
self.fireRate = 60; // frames between shots
self.cooldown = 0;
self.level = 1;
self.side = 1; // 1 = right, -1 = left
// Upgrade method
self.upgrade = function () {
if (self.level < 3) {
self.level += 1;
self.range += 100;
self.fireRate = Math.max(30, self.fireRate - 10);
turretGraphics.scaleX += 0.1;
turretGraphics.scaleY += 0.1;
}
};
// Update method
self.update = function () {
if (self.cooldown > 0) {
self.cooldown--;
return;
}
// Find closest enemy in range on this side
var closest = null;
var minDist = self.range + 1;
for (var i = 0; i < enemies.length; i++) {
var e = enemies[i];
if (self.side === 1 && e.x > base.x || self.side === -1 && e.x < base.x) {
var dx = e.x - self.x;
var dy = e.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minDist && dist <= self.range) {
minDist = dist;
closest = e;
}
}
}
if (closest) {
// Fire at enemy
var b = new Bullet();
b.x = self.x;
b.y = self.y;
b.target = closest;
b.side = self.side;
b.damage = self.level;
bullets.push(b);
game.addChild(b);
self.cooldown = self.fireRate;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181818
});
/****
* Game Code
****/
// Game state variables
var base = new Base();
base.x = 2048 / 2;
base.y = 2732 / 2;
game.addChild(base);
var turrets = [];
var enemies = [];
var bullets = [];
var gold = 50;
var wave = 1;
var enemiesToSpawn = 0;
var enemiesSpawned = 0;
var enemiesPerWave = 6;
var waveInProgress = false;
var spawnTimer = 0;
var nextWaveTimer = 0;
var baseHealthTxt, goldTxt, waveTxt;
var selectedTurret = null;
// HP Bar for base (gray background, green foreground)
var baseHpBarBg = LK.getAsset('base', {
anchorX: 0.5,
anchorY: 0.5,
x: base.x,
y: base.y - 140,
width: 200,
height: 32,
color: 0x444444
});
var baseHpBar = LK.getAsset('base', {
anchorX: 0,
anchorY: 0.5,
x: base.x - 100,
y: base.y - 140,
width: 200,
height: 32,
color: 0x44ff44
});
// Add ground platform at the bottom of the screen
var ground = LK.getAsset('base', {
anchorX: 0.5,
anchorY: 1,
x: 2048 / 2,
y: 2732,
width: 2048,
height: 80,
color: 0x888888
});
game.addChild(ground);
// GUI
// HP text removed
goldTxt = new Text2("Gold: " + gold, {
size: 80,
fill: 0xFFD700
});
goldTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(goldTxt);
waveTxt = new Text2("Wave: " + wave, {
size: 80,
fill: "#fff"
});
waveTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(waveTxt);
// Turret placement buttons (left and right)
// Space out the buttons and texts at the bottom of the screen for better separation
var bottomY = 2732 - 180;
var leftTurretBtn = LK.getAsset('turret', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 700,
y: bottomY,
scaleX: 1.2,
scaleY: 1.2
});
var rightTurretBtn = LK.getAsset('turret', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 700,
y: bottomY,
scaleX: 1.2,
scaleY: 1.2
});
game.addChild(leftTurretBtn);
game.addChild(rightTurretBtn);
var leftTurretCostTxt = new Text2("Buy: 30", {
size: 60,
fill: "#fff"
});
leftTurretCostTxt.anchor.set(0.5, 0);
leftTurretCostTxt.x = leftTurretBtn.x;
leftTurretCostTxt.y = leftTurretBtn.y + 100;
game.addChild(leftTurretCostTxt);
var rightTurretCostTxt = new Text2("Buy: 30", {
size: 60,
fill: "#fff"
});
rightTurretCostTxt.anchor.set(0.5, 0);
rightTurretCostTxt.x = rightTurretBtn.x;
rightTurretCostTxt.y = rightTurretBtn.y + 100;
game.addChild(rightTurretCostTxt);
// Base repair and upgrade buttons
var repairBtn = LK.getAsset('base', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 350,
y: bottomY,
scaleX: 0.7,
scaleY: 0.7
});
var upgradeBtn = LK.getAsset('base', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 350,
y: bottomY,
scaleX: 0.7,
scaleY: 0.7
});
game.addChild(repairBtn);
game.addChild(upgradeBtn);
var repairCostTxt = new Text2("Repair: 15", {
size: 60,
fill: "#fff"
});
repairCostTxt.anchor.set(0.5, 0);
repairCostTxt.x = repairBtn.x;
repairCostTxt.y = repairBtn.y + 100;
game.addChild(repairCostTxt);
var upgradeCostTxt = new Text2("Upgrade: 40", {
size: 60,
fill: "#fff"
});
upgradeCostTxt.anchor.set(0.5, 0);
upgradeCostTxt.x = upgradeBtn.x;
upgradeCostTxt.y = upgradeBtn.y + 100;
game.addChild(upgradeCostTxt);
// Turret upgrade buttons (appear above turrets)
function showTurretUpgradeBtn(turret) {
if (turret.upgradeBtn) {
return;
}
var btn = LK.getAsset('turret', {
anchorX: 0.5,
anchorY: 0.5,
x: turret.x,
y: turret.y - 120,
scaleX: 0.6,
scaleY: 0.6
});
var txt = new Text2("Upgrade: 25", {
size: 50,
fill: "#fff"
});
txt.anchor.set(0.5, 0);
txt.x = btn.x;
txt.y = btn.y + 50;
btn._upgradeTxt = txt;
game.addChild(btn);
game.addChild(txt);
turret.upgradeBtn = btn;
turret.upgradeTxt = txt;
}
// Remove upgrade button
function hideTurretUpgradeBtn(turret) {
if (turret.upgradeBtn) {
turret.upgradeBtn.destroy();
turret.upgradeTxt.destroy();
turret.upgradeBtn = null;
turret.upgradeTxt = null;
}
}
// Place initial turrets
function placeTurret(side) {
var x = base.x + (side === 1 ? 300 : -300);
var y = base.y;
var t = new Turret();
t.x = x;
t.y = y;
t.side = side;
turrets.push(t);
game.addChild(t);
return t;
}
// Initial turrets
placeTurret(-1);
placeTurret(1);
// Handle turret placement
leftTurretBtn.down = function (x, y, obj) {
if (gold >= 30) {
var t = placeTurret(-1);
gold -= 30;
goldTxt.setText("Gold: " + gold);
}
};
rightTurretBtn.down = function (x, y, obj) {
if (gold >= 30) {
var t = placeTurret(1);
gold -= 30;
goldTxt.setText("Gold: " + gold);
}
};
// Handle base repair/upgrade
repairBtn.down = function (x, y, obj) {
if (gold >= 15 && base.hp < base.maxHp) {
base.repair();
gold -= 15;
goldTxt.setText("Gold: " + gold);
baseHealthTxt.setText("HP: " + base.hp);
}
};
upgradeBtn.down = function (x, y, obj) {
if (gold >= 40) {
base.upgrade();
gold -= 40;
goldTxt.setText("Gold: " + gold);
baseHealthTxt.setText("HP: " + base.hp);
}
};
// Handle turret upgrade
game.down = function (x, y, obj) {
// Check if a turret was tapped
for (var i = 0; i < turrets.length; i++) {
var t = turrets[i];
if (t && LK.util && typeof LK.util.containsPoint === "function" && LK.util.containsPoint(t, {
x: x,
y: y
})) {
selectedTurret = t;
showTurretUpgradeBtn(t);
return;
}
}
// Check if upgrade button was tapped
for (var i = 0; i < turrets.length; i++) {
var t = turrets[i];
if (t && t.upgradeBtn && LK.util && typeof LK.util.containsPoint === "function" && LK.util.containsPoint(t.upgradeBtn, {
x: x,
y: y
})) {
if (gold >= 25 && t.level < 3) {
t.upgrade();
gold -= 25;
goldTxt.setText("Gold: " + gold);
if (t.level >= 3) {
hideTurretUpgradeBtn(t);
}
}
return;
}
}
// Deselect turret if tap elsewhere
for (var i = 0; i < turrets.length; i++) {
hideTurretUpgradeBtn(turrets[i]);
}
selectedTurret = null;
};
// Enemy spawn logic
function startWave() {
waveInProgress = true;
enemiesToSpawn = enemiesPerWave + (wave - 1) * 2;
enemiesSpawned = 0;
spawnTimer = 0;
waveTxt.setText("Wave: " + wave);
}
function endWave() {
waveInProgress = false;
nextWaveTimer = 120; // 2 seconds
gold += 20 + wave * 5;
goldTxt.setText("Gold: " + gold);
enemiesPerWave += 1;
wave += 1;
}
// Main update loop
game.update = function () {
// Update HP bar position and width
baseHpBarBg.x = base.x;
baseHpBarBg.y = base.y - 140;
baseHpBar.x = base.x - 100;
baseHpBar.y = base.y - 140;
baseHpBar.width = 200 * Math.max(0, base.hp) / base.maxHp;
// Update turrets
for (var i = 0; i < turrets.length; i++) {
turrets[i].update();
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var e = enemies[i];
e.update();
// Check if reached base
if (e.direction === 1 && e.x >= base.x - 90 || e.direction === -1 && e.x <= base.x + 90) {
base.hp -= 1;
base.hit();
e.destroy();
enemies.splice(i, 1);
if (base.hp <= 0) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
continue;
}
// Check if dead
if (e.hp <= 0) {
e.destroy();
enemies.splice(i, 1);
gold += 5;
goldTxt.setText("Gold: " + gold);
continue;
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var b = bullets[i];
b.update();
if (b.destroyed) {
b.destroy();
bullets.splice(i, 1);
}
}
// Wave logic
if (waveInProgress) {
if (enemiesSpawned < enemiesToSpawn) {
if (spawnTimer <= 0) {
// Spawn enemy from left or right
var side = Math.random() < 0.5 ? -1 : 1;
var e = new Enemy();
e.direction = side;
e.x = side === 1 ? 0 : 2048;
e.y = base.y - 200 + Math.random() * 400;
e.speed = 3 + wave * 0.3 + Math.random();
e.hp = 1 + Math.floor(wave / 2);
enemies.push(e);
game.addChild(e);
enemiesSpawned++;
spawnTimer = 30 + Math.floor(Math.random() * 20);
} else {
spawnTimer--;
}
} else if (enemies.length === 0) {
endWave();
}
} else {
if (nextWaveTimer > 0) {
nextWaveTimer--;
if (nextWaveTimer === 0) {
startWave();
}
}
}
};
// Start first wave
startWave(); ===================================================================
--- original.js
+++ change.js
@@ -204,8 +204,18 @@
width: 200,
height: 32,
color: 0x44ff44
});
+// Add ground platform at the bottom of the screen
+var ground = LK.getAsset('base', {
+ anchorX: 0.5,
+ anchorY: 1,
+ x: 2048 / 2,
+ y: 2732,
+ width: 2048,
+ height: 80,
+ color: 0x888888
+});
game.addChild(ground);
// GUI
// HP text removed
goldTxt = new Text2("Gold: " + gold, {
2d turret. In-Game asset. 2d. High contrast. No shadows
a 2d turret base. In-Game asset. 2d. High contrast. No shadows
a 2d upgrade button png. In-Game asset. 2d. High contrast. No shadows
purple zombie 2d. In-Game asset. 2d. High contrast. No shadows
add a grass background, empty middle, grass and trees around. In-Game asset. 2d. High contrast. No shadows