User prompt
musuh mati setelah kena tembak 4 kali
User prompt
musih mati setelah 5 kali kena tembak
User prompt
musuh mati setelah 6 kali tembak
User prompt
musuh matih setelah 8 kali kena tembak
User prompt
musuh setelah sepuluh kali tembak
User prompt
musuh mati setelah 6 kali kena tembak
User prompt
maksimal healt adalah 100
User prompt
perbaiki music
User prompt
perbaiki respo tap saat build tower
User prompt
ubah text buy health menjadi Health support
User prompt
ubah katau build tower menjadi summon fairy guardian
User prompt
tower hanya bisa di bangun 3
User prompt
buy health 50g sama dengan 15 hp
User prompt
add asset background
User prompt
tower destroyer muncul setiap satu menit
User prompt
kurangi kecepatan peluru
User prompt
buat random enemy yang kebal senjata. tugasnya menghancurkan tower
User prompt
musuh memiliki kecerdasan dan bisa cari celah
User prompt
musuh mati setelah 3 kali kena tembak
User prompt
bisa beli health 50 g sama dengan 30 health
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'buildButton.style.fill = 0x00FF00; // Green when available' Line Number: 555
User prompt
maksimal hanya lima tower bisa di buat
User prompt
musuh 2 kali kena tembak baru mati
User prompt
tower can destroy if enemy explode near tower ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add enemy can destroy tower
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Projectile = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('projectile', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.target = null; self.direction = null; self.damage = 20; self.update = function () { if (self.target && !self.target.destroyed) { // Move towards target 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) { self.target.takeDamage(self.damage); self.destroy(); return; } else { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } } else if (self.direction) { // Move in fixed direction self.x += self.direction.x * self.speed; self.y += self.direction.y * self.speed; // Check if we hit any spirit along the way for (var i = 0; i < spirits.length; i++) { var spirit = spirits[i]; var dx = spirit.x - self.x; var dy = spirit.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 30) { spirit.takeDamage(self.damage); self.destroy(); return; } } // Destroy if projectile goes too far if (Math.abs(self.x) > 1000 || Math.abs(self.y) > 1000) { self.destroy(); return; } } else { // No target and no direction, destroy self.destroy(); return; } }; self.destroy = function () { for (var i = projectiles.length - 1; i >= 0; i--) { if (projectiles[i] === self) { projectiles.splice(i, 1); break; } } if (self.parent) { self.parent.removeChild(self); } }; return self; }); var Spirit = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('spirit', { anchorX: 0.5, anchorY: 0.5 }); self.health = 50; self.maxHealth = 50; self.speed = 1; self.gold = 10; self.targetX = villageX; self.targetY = villageY; self.hitsToKill = 2; self.hitsTaken = 0; 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 > 5) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } else { self.reachVillage(); } // Check collision with towers for (var i = towers.length - 1; i >= 0; i--) { var tower = towers[i]; var tdx = tower.x - self.x; var tdy = tower.y - self.y; var towerDistance = Math.sqrt(tdx * tdx + tdy * tdy); if (towerDistance < 50) { // Destroy tower towers.splice(i, 1); if (tower.parent) { tower.parent.removeChild(tower); } buildButton.setText('Build Tower (50g) ' + towers.length + '/5'); // Destroy spirit too self.die(); break; } } }; self.takeDamage = function (damage) { self.hitsTaken++; LK.getSound('spirit_hit').play(); if (self.hitsTaken >= self.hitsToKill) { self.die(); } }; self.die = function () { gold += self.gold; goldText.setText('Gold: ' + gold); LK.getSound('spirit_death').play(); // Check for towers within explosion range and destroy them var explosionRange = 100; for (var i = towers.length - 1; i >= 0; i--) { var tower = towers[i]; var dx = tower.x - self.x; var dy = tower.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= explosionRange) { // Destroy tower towers.splice(i, 1); if (tower.parent) { tower.parent.removeChild(tower); } buildButton.setText('Build Tower (50g) ' + towers.length + '/5'); // Add explosion effect to destroyed tower tween(tower, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 200, easing: tween.easeOut }); } } // Create explosion effect - scale up and fade out tween(self, { scaleX: 3, scaleY: 3, alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Remove from spirits array and destroy after explosion for (var i = spirits.length - 1; i >= 0; i--) { if (spirits[i] === self) { spirits.splice(i, 1); break; } } self.destroy(); } }); // Flash red effect tween(self, { tint: 0xFF0000 }, { duration: 100 }); tween(self, { tint: 0xFFFFFF }, { duration: 200 }); // Flash screen red LK.effects.flashScreen(0xFF0000, 200); }; self.reachVillage = function () { villageHealth -= 10; healthText.setText('Health: ' + villageHealth); if (villageHealth <= 0) { LK.showGameOver(); } for (var i = spirits.length - 1; i >= 0; i--) { if (spirits[i] === self) { spirits.splice(i, 1); break; } } self.destroy(); }; return self; }); var Tower = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('tower', { anchorX: 0.5, anchorY: 0.5 }); self.range = 150; self.damage = 20; self.fireRate = 60; // frames between shots self.lastShot = 0; self.level = 1; self.update = function () { self.lastShot++; if (self.lastShot >= self.fireRate) { // Shoot continuously if there are any spirits on the map if (spirits.length > 0) { self.shoot(null); // Pass null since we're shooting in all directions self.lastShot = 0; } } }; self.findTarget = function () { var closestSpirit = null; var closestDistance = self.range; for (var i = 0; i < spirits.length; i++) { var spirit = spirits[i]; var dx = spirit.x - self.x; var dy = spirit.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= self.range && distance < closestDistance) { closestDistance = distance; closestSpirit = spirit; } } return closestSpirit; }; self.shoot = function (target) { // Fire projectiles in all 8 compass directions var directions = [{ x: 0, y: -1 }, // North { x: 0.707, y: -0.707 }, // Northeast { x: 1, y: 0 }, // East { x: 0.707, y: 0.707 }, // Southeast { x: 0, y: 1 }, // South { x: -0.707, y: 0.707 }, // Southwest { x: -1, y: 0 }, // West { x: -0.707, y: -0.707 } // Northwest ]; for (var d = 0; d < directions.length; d++) { var projectile = new Projectile(); projectile.x = self.x; projectile.y = self.y; // Always find closest spirit in this direction for targeting var dirTarget = self.findTargetInDirection(directions[d]); if (dirTarget) { projectile.target = dirTarget; } else { // Always shoot in the direction even if no specific target projectile.direction = directions[d]; } projectile.damage = self.damage; projectiles.push(projectile); gameWorld.addChild(projectile); } }; self.findTargetInDirection = function (direction) { var bestTarget = null; var bestDistance = self.range; for (var i = 0; i < spirits.length; i++) { var spirit = spirits[i]; var dx = spirit.x - self.x; var dy = spirit.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); // Check if spirit is within range if (distance <= self.range && distance < bestDistance) { // Check if spirit is roughly in the desired direction var normalizedDx = dx / distance; var normalizedDy = dy / distance; // Calculate dot product to see if spirit aligns with direction var dot = normalizedDx * direction.x + normalizedDy * direction.y; // If dot product > 0.3, spirit is in this general direction (wider angle for 8 directions) if (dot > 0.3) { bestDistance = distance; bestTarget = spirit; } } } return bestTarget; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2F4F2F }); /**** * Game Code ****/ var gameWorld = new Container(); game.addChild(gameWorld); var gameWorldX = 1024; // Center horizontally (2048/2) var gameWorldY = 1366; // Center vertically (2732/2) gameWorld.x = gameWorldX; gameWorld.y = gameWorldY; var isDragging = false; var lastDragX = 0; var lastDragY = 0; var villageX = 0; var villageY = 0; var villageHealth = 100; var gold = 100; var wave = 1; var spiritsToSpawn = 5; var spiritsSpawned = 0; var spawnTimer = 0; var towers = []; var spirits = []; var projectiles = []; var placementMode = false; var placementPreview = null; var maxTowers = 5; // Create village at center var village = gameWorld.attachAsset('village', { anchorX: 0.5, anchorY: 0.5, x: villageX, y: villageY }); // UI Elements var goldText = new Text2('Gold: ' + gold, { size: 80, fill: 0xFFD700 }); goldText.anchor.set(1, 0); goldText.x = -20; goldText.y = 120; LK.gui.topRight.addChild(goldText); var healthText = new Text2('Health: ' + villageHealth, { size: 80, fill: 0xFF0000 }); healthText.anchor.set(1, 0); healthText.x = -20; healthText.y = 220; LK.gui.topRight.addChild(healthText); var waveText = new Text2('Wave: ' + wave, { size: 100, fill: 0xFFFFFF }); waveText.anchor.set(0.5, 0); waveText.y = 120; LK.gui.top.addChild(waveText); var buildButton = new Text2('Build Tower (50g) 0/5', { size: 80, fill: 0x00FF00 }); buildButton.anchor.set(0.5, 1); buildButton.y = -50; LK.gui.bottom.addChild(buildButton); function canPlaceTower(x, y) { // Check tower count limit if (towers.length >= maxTowers) { return false; } // Check distance from village var dx = x - villageX; var dy = y - villageY; var distanceFromVillage = Math.sqrt(dx * dx + dy * dy); if (distanceFromVillage < 150) { return false; } // Check distance from other towers for (var i = 0; i < towers.length; i++) { var tower = towers[i]; var tdx = x - tower.x; var tdy = y - tower.y; var distanceFromTower = Math.sqrt(tdx * tdx + tdy * tdy); if (distanceFromTower < 80) { return false; } } return true; } function spawnSpirit() { if (spiritsSpawned >= spiritsToSpawn) { return; } var spirit = new Spirit(); // Spawn from random edge var edge = Math.floor(Math.random() * 4); var mapSize = 1500; switch (edge) { case 0: // Top spirit.x = Math.random() * mapSize - mapSize / 2; spirit.y = -mapSize / 2; break; case 1: // Right spirit.x = mapSize / 2; spirit.y = Math.random() * mapSize - mapSize / 2; break; case 2: // Bottom spirit.x = Math.random() * mapSize - mapSize / 2; spirit.y = mapSize / 2; break; case 3: // Left spirit.x = -mapSize / 2; spirit.y = Math.random() * mapSize - mapSize / 2; break; } spirits.push(spirit); gameWorld.addChild(spirit); spiritsSpawned++; } function nextWave() { if (spirits.length === 0 && spiritsSpawned >= spiritsToSpawn) { wave++; spiritsToSpawn = 5 + wave * 2; spiritsSpawned = 0; spawnTimer = 0; waveText.setText('Wave: ' + wave); // Bonus gold for completing wave gold += 20; goldText.setText('Gold: ' + gold); } } game.down = function (x, y, obj) { var localPos = gameWorld.toLocal(game.toGlobal({ x: x, y: y })); if (placementMode) { if (canPlaceTower(localPos.x, localPos.y) && gold >= 50) { var tower = new Tower(); tower.x = localPos.x; tower.y = localPos.y; towers.push(tower); gameWorld.addChild(tower); gold -= 50; goldText.setText('Gold: ' + gold); buildButton.setText('Build Tower (50g) ' + towers.length + '/5'); LK.getSound('place_tower').play(); placementMode = false; if (placementPreview) { placementPreview.destroy(); placementPreview = null; } } } }; game.move = function (x, y, obj) { var localPos = gameWorld.toLocal(game.toGlobal({ x: x, y: y })); if (placementMode) { if (placementPreview) { placementPreview.destroy(); } if (canPlaceTower(localPos.x, localPos.y)) { placementPreview = gameWorld.attachAsset('validPlacement', { anchorX: 0.5, anchorY: 0.5, x: localPos.x, y: localPos.y, alpha: 0.5 }); } else { placementPreview = gameWorld.attachAsset('invalidPlacement', { anchorX: 0.5, anchorY: 0.5, x: localPos.x, y: localPos.y, alpha: 0.5 }); } } }; game.up = function (x, y, obj) { // No dragging functionality needed }; buildButton.down = function (x, y, obj) { if (gold >= 50 && towers.length < maxTowers) { placementMode = !placementMode; if (!placementMode && placementPreview) { placementPreview.destroy(); placementPreview = null; } } }; game.update = function () { // Spawn spirits spawnTimer++; if (spawnTimer >= 120) { // Spawn every 2 seconds spawnSpirit(); spawnTimer = 0; } // Check for next wave nextWave(); // Update build button color based on availability if (towers.length >= maxTowers || gold < 50) { buildButton.style.fill = 0xFF0000; // Red when unavailable } else { buildButton.style.fill = 0x00FF00; // Green when available } // Update all game objects for (var i = 0; i < towers.length; i++) { towers[i].update(); } for (var i = 0; i < spirits.length; i++) { spirits[i].update(); } for (var i = 0; i < projectiles.length; i++) { projectiles[i].update(); } };
===================================================================
--- original.js
+++ change.js
@@ -105,8 +105,9 @@
towers.splice(i, 1);
if (tower.parent) {
tower.parent.removeChild(tower);
}
+ buildButton.setText('Build Tower (50g) ' + towers.length + '/5');
// Destroy spirit too
self.die();
break;
}
@@ -135,8 +136,9 @@
towers.splice(i, 1);
if (tower.parent) {
tower.parent.removeChild(tower);
}
+ buildButton.setText('Build Tower (50g) ' + towers.length + '/5');
// Add explosion effect to destroyed tower
tween(tower, {
scaleX: 2,
scaleY: 2,
@@ -349,8 +351,9 @@
var spirits = [];
var projectiles = [];
var placementMode = false;
var placementPreview = null;
+var maxTowers = 5;
// Create village at center
var village = gameWorld.attachAsset('village', {
anchorX: 0.5,
anchorY: 0.5,
@@ -380,16 +383,20 @@
});
waveText.anchor.set(0.5, 0);
waveText.y = 120;
LK.gui.top.addChild(waveText);
-var buildButton = new Text2('Build Tower (50g)', {
+var buildButton = new Text2('Build Tower (50g) 0/5', {
size: 80,
fill: 0x00FF00
});
buildButton.anchor.set(0.5, 1);
buildButton.y = -50;
LK.gui.bottom.addChild(buildButton);
function canPlaceTower(x, y) {
+ // Check tower count limit
+ if (towers.length >= maxTowers) {
+ return false;
+ }
// Check distance from village
var dx = x - villageX;
var dy = y - villageY;
var distanceFromVillage = Math.sqrt(dx * dx + dy * dy);
@@ -467,8 +474,9 @@
towers.push(tower);
gameWorld.addChild(tower);
gold -= 50;
goldText.setText('Gold: ' + gold);
+ buildButton.setText('Build Tower (50g) ' + towers.length + '/5');
LK.getSound('place_tower').play();
placementMode = false;
if (placementPreview) {
placementPreview.destroy();
@@ -508,9 +516,9 @@
game.up = function (x, y, obj) {
// No dragging functionality needed
};
buildButton.down = function (x, y, obj) {
- if (gold >= 50) {
+ if (gold >= 50 && towers.length < maxTowers) {
placementMode = !placementMode;
if (!placementMode && placementPreview) {
placementPreview.destroy();
placementPreview = null;
@@ -526,8 +534,14 @@
spawnTimer = 0;
}
// Check for next wave
nextWave();
+ // Update build button color based on availability
+ if (towers.length >= maxTowers || gold < 50) {
+ buildButton.style.fill = 0xFF0000; // Red when unavailable
+ } else {
+ buildButton.style.fill = 0x00FF00; // Green when available
+ }
// Update all game objects
for (var i = 0; i < towers.length; i++) {
towers[i].update();
}
image top down hutan pinus luas yang ditengahnya terdapat kerajaan peri daun. 2d anime. In-Game asset. 2d. High contrast. No shadows
kesatria peri pria seluruh badan bercahaya melayang dengan tangan merengggang keatas. In-Game asset. 2d. High contrast. No shadows
roh jahat berbentuk orb gelap. In-Game asset. 2d. High contrast. No shadows
roh jahat bentuk orb api. In-Game asset. 2d. High contrast. No shadows