User prompt
quiero que el texto de las torres sean un poco mas grandes y un poco mas abajo
User prompt
el texto de las torres
User prompt
el texto un poquito mas abajo y mas grande
User prompt
un poco mas a la izquierda
User prompt
mas separados
User prompt
ahora mas grandes
User prompt
mas a la derecha, bien a la derecha
User prompt
quiero que los botones de las torres se hagan mas a las izquierda
User prompt
un poco mas a la izquierda, pero bien poco
User prompt
un poco mas a la izquierda
User prompt
un poquito mas a la derecha
User prompt
ahora el texto que dice: Tap the place Tower BUtton, then tap empty space to build en la parte de arriba
User prompt
un poco mas a la izquierda
User prompt
ahora haz las letras un poco mas grandes y ponlas un poco mas arriba
User prompt
mas
User prompt
maas
User prompt
dije: currency, base heath, y el otro
User prompt
ahora lo que incluye la base y los 2 demas que vayan a la izquierda
User prompt
okey ahora encojelo por arriba
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Bullet = Container.expand(function (startX, startY, target, damage) { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.x = startX; self.y = startY; self.target = target; self.damage = damage; self.speed = 8; self.update = function () { if (!self.target || self.target.parent === null) { // Target destroyed, remove bullet self.destroy(); var index = bullets.indexOf(self); if (index > -1) bullets.splice(index, 1); return; } var dx = self.target.x - self.x; var dy = self.target.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 20) { // Hit target self.target.takeDamage(self.damage); self.destroy(); var index = bullets.indexOf(self); if (index > -1) bullets.splice(index, 1); } else { // Move towards target var moveX = dx / distance * self.speed; var moveY = dy / distance * self.speed; self.x += moveX; self.y += moveY; } }; return self; }); var Noob = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'basic'; var assetId = 'noob'; self.maxHealth = 100; self.speed = 2; self.reward = 10; if (self.type === 'fast') { assetId = 'fastNoob'; self.maxHealth = 60; self.speed = 4; self.reward = 15; } else if (self.type === 'strong') { assetId = 'strongNoob'; self.maxHealth = 200; self.speed = 1.5; self.reward = 25; } var noobGraphics = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.health = self.maxHealth; self.pathIndex = 0; self.targetX = pathPoints[0].x; self.targetY = pathPoints[0].y; self.update = function () { // Move towards current target var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 10) { // Reached current target, move to next self.pathIndex++; if (self.pathIndex >= pathPoints.length) { // Reached base baseHealth -= 20; self.destroy(); var index = noobs.indexOf(self); if (index > -1) noobs.splice(index, 1); return; } self.targetX = pathPoints[self.pathIndex].x; self.targetY = pathPoints[self.pathIndex].y; } else { // Move towards target var moveX = dx / distance * self.speed; var moveY = dy / distance * self.speed; self.x += moveX; self.y += moveY; } }; self.takeDamage = function (damage) { self.health -= damage; LK.getSound('enemyHit').play(); // Flash red when hit tween(noobGraphics, { tint: 0xFF0000 }, { duration: 100, onFinish: function onFinish() { tween(noobGraphics, { tint: 0xFFFFFF }, { duration: 100 }); } }); if (self.health <= 0) { currency += self.reward; LK.getSound('enemyDeath').play(); self.destroy(); var index = noobs.indexOf(self); if (index > -1) noobs.splice(index, 1); } }; return self; }); var Tower = Container.expand(function (gridX, gridY, towerType) { var self = Container.call(this); self.gridX = gridX; self.gridY = gridY; self.level = 1; self.towerType = towerType || 'basic'; var typeData = towerTypes[self.towerType]; self.damage = typeData.damage; self.range = typeData.range; self.attackSpeed = self.towerType === 'rapid' ? 30 : 60; // frames between attacks self.cost = typeData.cost; self.upgradeCost = Math.floor(typeData.cost * 1.5); self.lastAttack = 0; var towerGraphics = self.attachAsset(typeData.asset, { anchorX: 0.5, anchorY: 0.5 }); self.x = gridX * 128 + 64; self.y = gridY * 128 + 64; self.update = function () { self.lastAttack++; if (self.lastAttack >= self.attackSpeed) { // Look for enemies in range var target = null; var closestDistance = self.range; for (var i = 0; i < noobs.length; i++) { var noob = noobs[i]; var dx = noob.x - self.x; var dy = noob.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= self.range && distance < closestDistance) { target = noob; closestDistance = distance; } } if (target) { self.shoot(target); self.lastAttack = 0; } } }; self.shoot = function (target) { var bullet = new Bullet(self.x, self.y, target, self.damage); game.addChild(bullet); bullets.push(bullet); LK.getSound('shoot').play(); }; self.upgrade = function () { if (self.level < 3 && currency >= self.upgradeCost) { currency -= self.upgradeCost; self.level++; self.damage += 15; self.range += 50; self.upgradeCost = Math.floor(self.upgradeCost * 1.5); if (self.level >= 2) { towerGraphics.removeChild(); towerGraphics = self.attachAsset('upgradedTower', { anchorX: 0.5, anchorY: 0.5 }); } // Visual upgrade effect tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 200 }); } }); } }; self.down = function (x, y, obj) { if (selectedTower !== self) { selectedTower = self; updateUI(); } else { self.upgrade(); updateUI(); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2F3542 }); /**** * Game Code ****/ // Sounds // UI Elements // Base // Projectiles // Towers // Noobs // Path tiles // Game variables var pathPoints = [{ x: 0, y: 1366 }, { x: 600, y: 1366 }, { x: 600, y: 800 }, { x: 1400, y: 800 }, { x: 1400, y: 1900 }, { x: 600, y: 1900 }, { x: 600, y: 1366 }, { x: 1500, y: 1366 }, { x: 2048, y: 1366 }]; var noobs = []; var towers = []; var bullets = []; var currency = 100; var baseHealth = 100; var wave = 1; var enemiesInWave = 5; var enemiesSpawned = 0; var waveComplete = true; var spawnTimer = 0; var selectedTower = null; // Create path visualization function createPath() { for (var i = 0; i < pathPoints.length - 1; i++) { var start = pathPoints[i]; var end = pathPoints[i + 1]; // Create tiles between points var steps = Math.max(Math.abs(end.x - start.x), Math.abs(end.y - start.y)) / 128; for (var j = 0; j <= steps; j++) { var x = start.x + (end.x - start.x) * (j / steps); var y = start.y + (end.y - start.y) * (j / steps); var pathTile = LK.getAsset('pathTile', { anchorX: 0.5, anchorY: 0.5 }); pathTile.x = x; pathTile.y = y; game.addChild(pathTile); } } // Initialize path tiles data for tower placement checking createPathTiles(); } // Create grass background function createBackground() { for (var x = 0; x < 16; x++) { for (var y = 0; y < 22; y++) { var grassTile = LK.getAsset('grassTile', { anchorX: 0, anchorY: 0 }); grassTile.x = x * 128; grassTile.y = y * 128; game.addChild(grassTile); } } } // Create base var base = LK.getAsset('base', { anchorX: 0.5, anchorY: 0.5 }); base.x = pathPoints[pathPoints.length - 1].x; base.y = pathPoints[pathPoints.length - 1].y; // UI Elements var currencyText = new Text2('Currency: 100', { size: 60, fill: 0xFFD700 }); currencyText.anchor.set(0, 1); currencyText.x = 20; currencyText.y = -20; var healthText = new Text2('Base Health: 100', { size: 60, fill: 0xFF6B6B }); healthText.anchor.set(0, 1); healthText.x = 20; healthText.y = -90; var waveText = new Text2('Wave: 1', { size: 60, fill: 0x4ECDC4 }); waveText.anchor.set(0, 1); waveText.x = 20; waveText.y = -160; var towerInfoText = new Text2('Tap the PLACE TOWER button, then tap empty space to build', { size: 40, fill: 0xFFFFFF }); towerInfoText.anchor.set(0.5, 1); towerInfoText.y = -230; // Tower selection variables var selectedTowerType = null; var towerTypes = { basic: { cost: 50, damage: 25, range: 250, asset: 'basicTower', name: 'Basic Tower' }, cannon: { cost: 100, damage: 50, range: 220, asset: 'upgradedTower', name: 'Cannon Tower' }, rapid: { cost: 75, damage: 15, range: 280, asset: 'basicTower', name: 'Rapid Tower' } }; // Tower selection variables var canPlaceTowers = false; // Tower selection UI var towerSelectionContainer = new Container(); var towerButtons = []; var towerTypeNames = ['basic', 'cannon', 'rapid']; // Create horizontal background panel for all tower buttons var verticalBackground = LK.getAsset('pathTile', { anchorX: 0.5, anchorY: 0 }); verticalBackground.x = 200; // Moved even more to the left verticalBackground.y = -470; // Position relative to top of expanded panel verticalBackground.width = 1900; // Increase width just a little bit more for horizontal layout extending further left verticalBackground.height = 620; // Increased height further downward for vertical expansion verticalBackground.alpha = 0.9; towerSelectionContainer.addChild(verticalBackground); // Create darker border for the vertical background panel var borderThickness = 8; // Top border var topBorder = LK.getAsset('pathTile', { anchorX: 0.5, anchorY: 0 }); topBorder.x = verticalBackground.x; topBorder.y = verticalBackground.y; topBorder.width = verticalBackground.width + borderThickness * 2; topBorder.height = borderThickness; topBorder.tint = 0x3d2914; // Darker brown color towerSelectionContainer.addChild(topBorder); // Bottom border var bottomBorder = LK.getAsset('pathTile', { anchorX: 0.5, anchorY: 0 }); bottomBorder.x = verticalBackground.x; bottomBorder.y = verticalBackground.y + verticalBackground.height; bottomBorder.width = verticalBackground.width + borderThickness * 2; bottomBorder.height = borderThickness; bottomBorder.tint = 0x3d2914; // Darker brown color towerSelectionContainer.addChild(bottomBorder); // Left border var leftBorder = LK.getAsset('pathTile', { anchorX: 0.5, anchorY: 0 }); leftBorder.x = verticalBackground.x - verticalBackground.width / 2 - borderThickness / 2; leftBorder.y = verticalBackground.y; leftBorder.width = borderThickness; leftBorder.height = verticalBackground.height; leftBorder.tint = 0x3d2914; // Darker brown color towerSelectionContainer.addChild(leftBorder); // Right border var rightBorder = LK.getAsset('pathTile', { anchorX: 0.5, anchorY: 0 }); rightBorder.x = verticalBackground.x + verticalBackground.width / 2 + borderThickness / 2; rightBorder.y = verticalBackground.y; rightBorder.width = borderThickness; rightBorder.height = verticalBackground.height; rightBorder.tint = 0x3d2914; // Darker brown color towerSelectionContainer.addChild(rightBorder); // Create tower selection buttons for (var i = 0; i < towerTypeNames.length; i++) { var towerType = towerTypeNames[i]; var button = LK.getAsset('towerButton', { anchorX: 0.5, anchorY: 0.5 }); button.x = 50 + i * 160; // Position horizontally from left to right, starting from the slightly more extended left edge button.y = -200; // Fixed vertical position at bottom button.towerType = towerType; button.selected = towerType === selectedTowerType; towerButtons.push(button); towerSelectionContainer.addChild(button); // Add tower type text below button var buttonText = new Text2(towerTypes[towerType].name, { size: 24, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); buttonText.x = button.x; buttonText.y = button.y + 70; towerSelectionContainer.addChild(buttonText); // Add cost text below button var costText = new Text2('$' + towerTypes[towerType].cost, { size: 20, fill: 0xFFD700 }); costText.anchor.set(0.5, 0.5); costText.x = button.x; costText.y = button.y + 95; towerSelectionContainer.addChild(costText); } // Add event handlers to tower buttons after they are created for (var i = 0; i < towerButtons.length; i++) { var button = towerButtons[i]; button.interactive = true; // Create a closure to capture the correct towerType for each button (function (btn, type) { btn.down = function (x, y, obj) { // Check if player can afford this tower type if (currency >= towerTypes[type].cost) { selectedTowerType = type; selectedTower = null; updateUI(); } }; })(button, button.towerType); } // Position UI elements at bottom LK.gui.bottom.addChild(towerSelectionContainer); LK.gui.bottom.addChild(currencyText); LK.gui.bottom.addChild(healthText); LK.gui.bottom.addChild(waveText); LK.gui.bottom.addChild(towerInfoText); function updateUI() { currencyText.setText('Currency: ' + currency); healthText.setText('Base Health: ' + baseHealth); waveText.setText('Wave: ' + wave); if (selectedTower) { towerInfoText.setText('Tower Level ' + selectedTower.level + ' | Upgrade Cost: ' + selectedTower.upgradeCost + ' | Tap again to upgrade'); } else if (selectedTowerType) { towerInfoText.setText('Selected: ' + towerTypes[selectedTowerType].name + ' (Cost: ' + towerTypes[selectedTowerType].cost + ') - Tap empty space to build'); } else { towerInfoText.setText('Tap the PLACE TOWER button, then tap empty space to build'); } updateTowerSelectionUI(); } function updateTowerSelectionUI() { for (var i = 0; i < towerButtons.length; i++) { var button = towerButtons[i]; if (selectedTowerType && button.towerType === selectedTowerType) { button.tint = 0x00FF00; // Green for selected } else if (currency >= towerTypes[button.towerType].cost) { button.tint = 0xFFFFFF; // White for affordable } else { button.tint = 0x666666; // Gray for unaffordable } } } function startNextWave() { wave++; enemiesInWave = Math.floor(5 + wave * 1.5); enemiesSpawned = 0; waveComplete = false; spawnTimer = 0; selectedTower = null; updateUI(); } function spawnEnemy() { var enemyType = 'basic'; if (wave > 3 && Math.random() < 0.3) { enemyType = 'fast'; } if (wave > 5 && Math.random() < 0.2) { enemyType = 'strong'; } var noob = new Noob(enemyType); noob.x = pathPoints[0].x; noob.y = pathPoints[0].y; noobs.push(noob); game.addChild(noob); enemiesSpawned++; } // Create a set to store all path grid positions var pathTiles = []; function createPathTiles() { pathTiles = []; for (var i = 0; i < pathPoints.length - 1; i++) { var start = pathPoints[i]; var end = pathPoints[i + 1]; // Create tiles between points var steps = Math.max(Math.abs(end.x - start.x), Math.abs(end.y - start.y)) / 128; for (var j = 0; j <= steps; j++) { var x = start.x + (end.x - start.x) * (j / steps); var y = start.y + (end.y - start.y) * (j / steps); var gridX = Math.floor(x / 128); var gridY = Math.floor(y / 128); // Add to path tiles if not already added var found = false; for (var k = 0; k < pathTiles.length; k++) { if (pathTiles[k].x === gridX && pathTiles[k].y === gridY) { found = true; break; } } if (!found) { pathTiles.push({ x: gridX, y: gridY }); } } } } function canPlaceTower(gridX, gridY) { // Check if position is on path or too close to path for (var i = 0; i < pathTiles.length; i++) { var pathTileX = pathTiles[i].x; var pathTileY = pathTiles[i].y; var distance = Math.sqrt((gridX - pathTileX) * (gridX - pathTileX) + (gridY - pathTileY) * (gridY - pathTileY)); // Prevent placement if within 1.0 grid units of path if (distance < 1.0) { return false; } } // Check if tower already exists for (var i = 0; i < towers.length; i++) { if (towers[i].gridX === gridX && towers[i].gridY === gridY) { return false; } } return true; } // Initialize game elements createBackground(); createPath(); game.addChild(base); // Game event handlers game.down = function (x, y, obj) { // Only handle tower placement if we have a selected tower type and we're clicking on the game area (not UI) if (selectedTowerType && y < 2200) { // Make sure we're not clicking on bottom UI area var gridX = Math.floor(x / 128); var gridY = Math.floor(y / 128); var towerCost = towerTypes[selectedTowerType].cost; if (canPlaceTower(gridX, gridY) && currency >= towerCost) { var tower = new Tower(gridX, gridY, selectedTowerType); towers.push(tower); game.addChild(tower); currency -= towerCost; selectedTower = tower; selectedTowerType = null; // Clear selection after placing updateUI(); } else { selectedTower = null; updateUI(); } } }; game.update = function () { // Check game over if (baseHealth <= 0) { LK.showGameOver(); return; } // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (bullet.parent) { bullet.update(); } } // Spawn enemies if (!waveComplete) { spawnTimer++; if (spawnTimer >= 90 && enemiesSpawned < enemiesInWave) { spawnEnemy(); spawnTimer = 0; } if (enemiesSpawned >= enemiesInWave && noobs.length === 0) { waveComplete = true; currency += 20; // Wave completion bonus updateUI(); } } else if (LK.ticks % 180 === 0) { // Auto-start next wave after 3 seconds startNextWave(); } // Update UI periodically if (LK.ticks % 30 === 0) { updateUI(); } }; // Start first wave updateUI(); startNextWave();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function (startX, startY, target, damage) {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = startX;
self.y = startY;
self.target = target;
self.damage = damage;
self.speed = 8;
self.update = function () {
if (!self.target || self.target.parent === null) {
// Target destroyed, remove bullet
self.destroy();
var index = bullets.indexOf(self);
if (index > -1) bullets.splice(index, 1);
return;
}
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 20) {
// Hit target
self.target.takeDamage(self.damage);
self.destroy();
var index = bullets.indexOf(self);
if (index > -1) bullets.splice(index, 1);
} else {
// Move towards target
var moveX = dx / distance * self.speed;
var moveY = dy / distance * self.speed;
self.x += moveX;
self.y += moveY;
}
};
return self;
});
var Noob = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'basic';
var assetId = 'noob';
self.maxHealth = 100;
self.speed = 2;
self.reward = 10;
if (self.type === 'fast') {
assetId = 'fastNoob';
self.maxHealth = 60;
self.speed = 4;
self.reward = 15;
} else if (self.type === 'strong') {
assetId = 'strongNoob';
self.maxHealth = 200;
self.speed = 1.5;
self.reward = 25;
}
var noobGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.health = self.maxHealth;
self.pathIndex = 0;
self.targetX = pathPoints[0].x;
self.targetY = pathPoints[0].y;
self.update = function () {
// Move towards current target
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 10) {
// Reached current target, move to next
self.pathIndex++;
if (self.pathIndex >= pathPoints.length) {
// Reached base
baseHealth -= 20;
self.destroy();
var index = noobs.indexOf(self);
if (index > -1) noobs.splice(index, 1);
return;
}
self.targetX = pathPoints[self.pathIndex].x;
self.targetY = pathPoints[self.pathIndex].y;
} else {
// Move towards target
var moveX = dx / distance * self.speed;
var moveY = dy / distance * self.speed;
self.x += moveX;
self.y += moveY;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.getSound('enemyHit').play();
// Flash red when hit
tween(noobGraphics, {
tint: 0xFF0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(noobGraphics, {
tint: 0xFFFFFF
}, {
duration: 100
});
}
});
if (self.health <= 0) {
currency += self.reward;
LK.getSound('enemyDeath').play();
self.destroy();
var index = noobs.indexOf(self);
if (index > -1) noobs.splice(index, 1);
}
};
return self;
});
var Tower = Container.expand(function (gridX, gridY, towerType) {
var self = Container.call(this);
self.gridX = gridX;
self.gridY = gridY;
self.level = 1;
self.towerType = towerType || 'basic';
var typeData = towerTypes[self.towerType];
self.damage = typeData.damage;
self.range = typeData.range;
self.attackSpeed = self.towerType === 'rapid' ? 30 : 60; // frames between attacks
self.cost = typeData.cost;
self.upgradeCost = Math.floor(typeData.cost * 1.5);
self.lastAttack = 0;
var towerGraphics = self.attachAsset(typeData.asset, {
anchorX: 0.5,
anchorY: 0.5
});
self.x = gridX * 128 + 64;
self.y = gridY * 128 + 64;
self.update = function () {
self.lastAttack++;
if (self.lastAttack >= self.attackSpeed) {
// Look for enemies in range
var target = null;
var closestDistance = self.range;
for (var i = 0; i < noobs.length; i++) {
var noob = noobs[i];
var dx = noob.x - self.x;
var dy = noob.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.range && distance < closestDistance) {
target = noob;
closestDistance = distance;
}
}
if (target) {
self.shoot(target);
self.lastAttack = 0;
}
}
};
self.shoot = function (target) {
var bullet = new Bullet(self.x, self.y, target, self.damage);
game.addChild(bullet);
bullets.push(bullet);
LK.getSound('shoot').play();
};
self.upgrade = function () {
if (self.level < 3 && currency >= self.upgradeCost) {
currency -= self.upgradeCost;
self.level++;
self.damage += 15;
self.range += 50;
self.upgradeCost = Math.floor(self.upgradeCost * 1.5);
if (self.level >= 2) {
towerGraphics.removeChild();
towerGraphics = self.attachAsset('upgradedTower', {
anchorX: 0.5,
anchorY: 0.5
});
}
// Visual upgrade effect
tween(self, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
}
};
self.down = function (x, y, obj) {
if (selectedTower !== self) {
selectedTower = self;
updateUI();
} else {
self.upgrade();
updateUI();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F3542
});
/****
* Game Code
****/
// Sounds
// UI Elements
// Base
// Projectiles
// Towers
// Noobs
// Path tiles
// Game variables
var pathPoints = [{
x: 0,
y: 1366
}, {
x: 600,
y: 1366
}, {
x: 600,
y: 800
}, {
x: 1400,
y: 800
}, {
x: 1400,
y: 1900
}, {
x: 600,
y: 1900
}, {
x: 600,
y: 1366
}, {
x: 1500,
y: 1366
}, {
x: 2048,
y: 1366
}];
var noobs = [];
var towers = [];
var bullets = [];
var currency = 100;
var baseHealth = 100;
var wave = 1;
var enemiesInWave = 5;
var enemiesSpawned = 0;
var waveComplete = true;
var spawnTimer = 0;
var selectedTower = null;
// Create path visualization
function createPath() {
for (var i = 0; i < pathPoints.length - 1; i++) {
var start = pathPoints[i];
var end = pathPoints[i + 1];
// Create tiles between points
var steps = Math.max(Math.abs(end.x - start.x), Math.abs(end.y - start.y)) / 128;
for (var j = 0; j <= steps; j++) {
var x = start.x + (end.x - start.x) * (j / steps);
var y = start.y + (end.y - start.y) * (j / steps);
var pathTile = LK.getAsset('pathTile', {
anchorX: 0.5,
anchorY: 0.5
});
pathTile.x = x;
pathTile.y = y;
game.addChild(pathTile);
}
}
// Initialize path tiles data for tower placement checking
createPathTiles();
}
// Create grass background
function createBackground() {
for (var x = 0; x < 16; x++) {
for (var y = 0; y < 22; y++) {
var grassTile = LK.getAsset('grassTile', {
anchorX: 0,
anchorY: 0
});
grassTile.x = x * 128;
grassTile.y = y * 128;
game.addChild(grassTile);
}
}
}
// Create base
var base = LK.getAsset('base', {
anchorX: 0.5,
anchorY: 0.5
});
base.x = pathPoints[pathPoints.length - 1].x;
base.y = pathPoints[pathPoints.length - 1].y;
// UI Elements
var currencyText = new Text2('Currency: 100', {
size: 60,
fill: 0xFFD700
});
currencyText.anchor.set(0, 1);
currencyText.x = 20;
currencyText.y = -20;
var healthText = new Text2('Base Health: 100', {
size: 60,
fill: 0xFF6B6B
});
healthText.anchor.set(0, 1);
healthText.x = 20;
healthText.y = -90;
var waveText = new Text2('Wave: 1', {
size: 60,
fill: 0x4ECDC4
});
waveText.anchor.set(0, 1);
waveText.x = 20;
waveText.y = -160;
var towerInfoText = new Text2('Tap the PLACE TOWER button, then tap empty space to build', {
size: 40,
fill: 0xFFFFFF
});
towerInfoText.anchor.set(0.5, 1);
towerInfoText.y = -230;
// Tower selection variables
var selectedTowerType = null;
var towerTypes = {
basic: {
cost: 50,
damage: 25,
range: 250,
asset: 'basicTower',
name: 'Basic Tower'
},
cannon: {
cost: 100,
damage: 50,
range: 220,
asset: 'upgradedTower',
name: 'Cannon Tower'
},
rapid: {
cost: 75,
damage: 15,
range: 280,
asset: 'basicTower',
name: 'Rapid Tower'
}
};
// Tower selection variables
var canPlaceTowers = false;
// Tower selection UI
var towerSelectionContainer = new Container();
var towerButtons = [];
var towerTypeNames = ['basic', 'cannon', 'rapid'];
// Create horizontal background panel for all tower buttons
var verticalBackground = LK.getAsset('pathTile', {
anchorX: 0.5,
anchorY: 0
});
verticalBackground.x = 200; // Moved even more to the left
verticalBackground.y = -470; // Position relative to top of expanded panel
verticalBackground.width = 1900; // Increase width just a little bit more for horizontal layout extending further left
verticalBackground.height = 620; // Increased height further downward for vertical expansion
verticalBackground.alpha = 0.9;
towerSelectionContainer.addChild(verticalBackground);
// Create darker border for the vertical background panel
var borderThickness = 8;
// Top border
var topBorder = LK.getAsset('pathTile', {
anchorX: 0.5,
anchorY: 0
});
topBorder.x = verticalBackground.x;
topBorder.y = verticalBackground.y;
topBorder.width = verticalBackground.width + borderThickness * 2;
topBorder.height = borderThickness;
topBorder.tint = 0x3d2914; // Darker brown color
towerSelectionContainer.addChild(topBorder);
// Bottom border
var bottomBorder = LK.getAsset('pathTile', {
anchorX: 0.5,
anchorY: 0
});
bottomBorder.x = verticalBackground.x;
bottomBorder.y = verticalBackground.y + verticalBackground.height;
bottomBorder.width = verticalBackground.width + borderThickness * 2;
bottomBorder.height = borderThickness;
bottomBorder.tint = 0x3d2914; // Darker brown color
towerSelectionContainer.addChild(bottomBorder);
// Left border
var leftBorder = LK.getAsset('pathTile', {
anchorX: 0.5,
anchorY: 0
});
leftBorder.x = verticalBackground.x - verticalBackground.width / 2 - borderThickness / 2;
leftBorder.y = verticalBackground.y;
leftBorder.width = borderThickness;
leftBorder.height = verticalBackground.height;
leftBorder.tint = 0x3d2914; // Darker brown color
towerSelectionContainer.addChild(leftBorder);
// Right border
var rightBorder = LK.getAsset('pathTile', {
anchorX: 0.5,
anchorY: 0
});
rightBorder.x = verticalBackground.x + verticalBackground.width / 2 + borderThickness / 2;
rightBorder.y = verticalBackground.y;
rightBorder.width = borderThickness;
rightBorder.height = verticalBackground.height;
rightBorder.tint = 0x3d2914; // Darker brown color
towerSelectionContainer.addChild(rightBorder);
// Create tower selection buttons
for (var i = 0; i < towerTypeNames.length; i++) {
var towerType = towerTypeNames[i];
var button = LK.getAsset('towerButton', {
anchorX: 0.5,
anchorY: 0.5
});
button.x = 50 + i * 160; // Position horizontally from left to right, starting from the slightly more extended left edge
button.y = -200; // Fixed vertical position at bottom
button.towerType = towerType;
button.selected = towerType === selectedTowerType;
towerButtons.push(button);
towerSelectionContainer.addChild(button);
// Add tower type text below button
var buttonText = new Text2(towerTypes[towerType].name, {
size: 24,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = button.x;
buttonText.y = button.y + 70;
towerSelectionContainer.addChild(buttonText);
// Add cost text below button
var costText = new Text2('$' + towerTypes[towerType].cost, {
size: 20,
fill: 0xFFD700
});
costText.anchor.set(0.5, 0.5);
costText.x = button.x;
costText.y = button.y + 95;
towerSelectionContainer.addChild(costText);
}
// Add event handlers to tower buttons after they are created
for (var i = 0; i < towerButtons.length; i++) {
var button = towerButtons[i];
button.interactive = true;
// Create a closure to capture the correct towerType for each button
(function (btn, type) {
btn.down = function (x, y, obj) {
// Check if player can afford this tower type
if (currency >= towerTypes[type].cost) {
selectedTowerType = type;
selectedTower = null;
updateUI();
}
};
})(button, button.towerType);
}
// Position UI elements at bottom
LK.gui.bottom.addChild(towerSelectionContainer);
LK.gui.bottom.addChild(currencyText);
LK.gui.bottom.addChild(healthText);
LK.gui.bottom.addChild(waveText);
LK.gui.bottom.addChild(towerInfoText);
function updateUI() {
currencyText.setText('Currency: ' + currency);
healthText.setText('Base Health: ' + baseHealth);
waveText.setText('Wave: ' + wave);
if (selectedTower) {
towerInfoText.setText('Tower Level ' + selectedTower.level + ' | Upgrade Cost: ' + selectedTower.upgradeCost + ' | Tap again to upgrade');
} else if (selectedTowerType) {
towerInfoText.setText('Selected: ' + towerTypes[selectedTowerType].name + ' (Cost: ' + towerTypes[selectedTowerType].cost + ') - Tap empty space to build');
} else {
towerInfoText.setText('Tap the PLACE TOWER button, then tap empty space to build');
}
updateTowerSelectionUI();
}
function updateTowerSelectionUI() {
for (var i = 0; i < towerButtons.length; i++) {
var button = towerButtons[i];
if (selectedTowerType && button.towerType === selectedTowerType) {
button.tint = 0x00FF00; // Green for selected
} else if (currency >= towerTypes[button.towerType].cost) {
button.tint = 0xFFFFFF; // White for affordable
} else {
button.tint = 0x666666; // Gray for unaffordable
}
}
}
function startNextWave() {
wave++;
enemiesInWave = Math.floor(5 + wave * 1.5);
enemiesSpawned = 0;
waveComplete = false;
spawnTimer = 0;
selectedTower = null;
updateUI();
}
function spawnEnemy() {
var enemyType = 'basic';
if (wave > 3 && Math.random() < 0.3) {
enemyType = 'fast';
}
if (wave > 5 && Math.random() < 0.2) {
enemyType = 'strong';
}
var noob = new Noob(enemyType);
noob.x = pathPoints[0].x;
noob.y = pathPoints[0].y;
noobs.push(noob);
game.addChild(noob);
enemiesSpawned++;
}
// Create a set to store all path grid positions
var pathTiles = [];
function createPathTiles() {
pathTiles = [];
for (var i = 0; i < pathPoints.length - 1; i++) {
var start = pathPoints[i];
var end = pathPoints[i + 1];
// Create tiles between points
var steps = Math.max(Math.abs(end.x - start.x), Math.abs(end.y - start.y)) / 128;
for (var j = 0; j <= steps; j++) {
var x = start.x + (end.x - start.x) * (j / steps);
var y = start.y + (end.y - start.y) * (j / steps);
var gridX = Math.floor(x / 128);
var gridY = Math.floor(y / 128);
// Add to path tiles if not already added
var found = false;
for (var k = 0; k < pathTiles.length; k++) {
if (pathTiles[k].x === gridX && pathTiles[k].y === gridY) {
found = true;
break;
}
}
if (!found) {
pathTiles.push({
x: gridX,
y: gridY
});
}
}
}
}
function canPlaceTower(gridX, gridY) {
// Check if position is on path or too close to path
for (var i = 0; i < pathTiles.length; i++) {
var pathTileX = pathTiles[i].x;
var pathTileY = pathTiles[i].y;
var distance = Math.sqrt((gridX - pathTileX) * (gridX - pathTileX) + (gridY - pathTileY) * (gridY - pathTileY));
// Prevent placement if within 1.0 grid units of path
if (distance < 1.0) {
return false;
}
}
// Check if tower already exists
for (var i = 0; i < towers.length; i++) {
if (towers[i].gridX === gridX && towers[i].gridY === gridY) {
return false;
}
}
return true;
}
// Initialize game elements
createBackground();
createPath();
game.addChild(base);
// Game event handlers
game.down = function (x, y, obj) {
// Only handle tower placement if we have a selected tower type and we're clicking on the game area (not UI)
if (selectedTowerType && y < 2200) {
// Make sure we're not clicking on bottom UI area
var gridX = Math.floor(x / 128);
var gridY = Math.floor(y / 128);
var towerCost = towerTypes[selectedTowerType].cost;
if (canPlaceTower(gridX, gridY) && currency >= towerCost) {
var tower = new Tower(gridX, gridY, selectedTowerType);
towers.push(tower);
game.addChild(tower);
currency -= towerCost;
selectedTower = tower;
selectedTowerType = null; // Clear selection after placing
updateUI();
} else {
selectedTower = null;
updateUI();
}
}
};
game.update = function () {
// Check game over
if (baseHealth <= 0) {
LK.showGameOver();
return;
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (bullet.parent) {
bullet.update();
}
}
// Spawn enemies
if (!waveComplete) {
spawnTimer++;
if (spawnTimer >= 90 && enemiesSpawned < enemiesInWave) {
spawnEnemy();
spawnTimer = 0;
}
if (enemiesSpawned >= enemiesInWave && noobs.length === 0) {
waveComplete = true;
currency += 20; // Wave completion bonus
updateUI();
}
} else if (LK.ticks % 180 === 0) {
// Auto-start next wave after 3 seconds
startNextWave();
}
// Update UI periodically
if (LK.ticks % 30 === 0) {
updateUI();
}
};
// Start first wave
updateUI();
startNextWave();