User prompt
Oyunun ilk haline çevir yolu
User prompt
Yolu virajlarda yap 4 tane biris sağa biris sol biridaha sağ biridaha sol
User prompt
Yolu değiştir 3 tane kıvrım olsun
User prompt
Toplamda 12 tane unit koyalım ve yolları daha çok kıvrımlı yap
User prompt
15 wawe 20 wawe arası sadece kırmızı zombş gelsin
User prompt
Yeşil zombi oldurdunde 1 para kırmızı zombş oldurdunde 2 para gelsin
User prompt
4. Upraded değiştir 1 rer 1 rer vursun hasarı 8 olsun 5. Upgraded 2 tane aynanda atsın her birisi 7.25şar 7.25 şar vursun toplam hasar 15 4. Upgraded fiyatı 50 5. Upgraded fiyatı 100
User prompt
add 3rd upgraded to units, red unit should be added to right and left arm and should hit with its arm and hit 2 times in a row, its damage should be 10, its money should be 30, the price of 2nd upgraded should be 20, the price of 1st upgraded should be 10
User prompt
10 waves, 1 red zombie comes. 11 waves, 2 red zombies come. 1 red zombie comes every round until 20 waves.
User prompt
After the 5th wave, both green and red zombies will come mixed. From wave 10 to wave 20, only red will come.
User prompt
Red zombş heatlh 10
User prompt
Green zombşe health 5
User prompt
Upgraded ettiniz zaman unitlerin tipi değişsin görselleri değişsin
User prompt
Wawe 5 getir zaman 1 kırmızı zombi gelsin sonra wawe 6 2 tane sonra 3 tane sen kafam random ama ilk 5 ile 8 tur arasında en fazla 4 kırmızı zombi gelsin
User prompt
Wawe 5 ten sonra kırmızı zombiler gelsin normal yeşil zombilerin 2x canı olsun
User prompt
Üstlerinde can barı olsun
User prompt
Upgraded 1 fiyat 5 upgraded 2 fiyatı 10
User prompt
Asker koydunuz zaman bidaha ustune tınladımız zaman upgraded cıksın upgraded edince daha çok hasar versin
Code edit (1 edits merged)
Please save this source code
User prompt
Curvy Path Defense
Initial prompt
Towet defense Birtane yol olsun kıvrımlı her tur daha güçlü daha cok canı olan zom iler gelsin yolu takip etsinler yolu en sonunda base olsun eyeri base canı 100 0 ulaşırsa defeay diye bir yazı cıksın bizimde duvarların üstünde asker koyalım sol alta askerler olsun 4 tane 1. Si para 10 olsun oyuna 10 parayla basliyalım her zombi ayrı puan versin daha güçlüler daha çok puan versin 1. 10 para hasarı 20 2. Para 25 hasarı 50 3. Para 50 hasarı 100 4. Son olarak para 250 hasarı 125
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Bullet class var Bullet = Container.expand(function () { var self = Container.call(this); self.target = null; self.speed = 18; self.damage = 1; self.type = 1; self.active = true; self.shooter = null; self.setType = function (type) { self.type = type; var assetId = 'bullet' + type; self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); }; self.update = function () { if (!self.active || !self.target || self.target.dead) { self.destroy(); return; } // Move toward target var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 30) { // Hit self.target.takeDamage(self.damage); self.destroy(); return; } var step = self.speed / (dist || 1); self.x += dx * step; self.y += dy * step; }; return self; }); // Soldier class var Soldier = Container.expand(function () { var self = Container.call(this); self.type = 1; self.fireRate = 60; // ticks between shots self.damage = 1; self.range = 350; self.cooldown = 0; self.level = 1; self.wallSpot = null; self.setType = function (type) { self.type = type; // Remove all previous children (visuals) while (self.children && self.children.length > 0) { self.removeChild(self.children[0]); } var assetId = 'soldier' + type; self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // Set stats if (type === 1) { self.fireRate = 60; self.damage = 1; self.range = 350; self.dualHit = false; self.money = 3; } if (type === 2) { self.fireRate = 40; self.damage = 1; self.range = 300; self.dualHit = false; self.money = 10; } if (type === 3) { self.fireRate = 90; self.damage = 3; self.range = 320; self.dualHit = false; self.money = 20; } if (type === 4) { self.fireRate = 60; self.damage = 8; self.range = 400; self.dualHit = false; // 4th upgrade: single hit self.money = 50; } if (type === 5) { self.fireRate = 60; self.damage = 7.25; self.range = 400; self.dualHit = true; // 5th upgrade: dual shot self.money = 100; } }; self.update = function () { if (self.cooldown > 0) { self.cooldown--; return; } // Find nearest zombie in range var nearest = null; var minDist = 99999; for (var i = 0; i < zombies.length; ++i) { var z = zombies[i]; if (z.dead) continue; var dx = z.x - self.x; var dy = z.y - self.y; var d = Math.sqrt(dx * dx + dy * dy); if (d < self.range && d < minDist) { minDist = d; nearest = z; } } if (nearest) { // Shoot if (self.type === 5 && self.dualHit) { // 5th upgrade: dual shot, each 7.25 dmg, total 15 for (var i = 0; i < 2; ++i) { var bullet = new Bullet(); bullet.setType(self.type); // Offset for left/right arm bullet.x = self.x + (i === 0 ? -30 : 30); bullet.y = self.y; bullet.target = nearest; bullet.damage = self.damage; bullet.shooter = self; bullets.push(bullet); game.addChild(bullet); } self.cooldown = self.fireRate; } else if (self.type === 4 && !self.dualHit) { // 4th upgrade: single hit, 8 dmg var bullet = new Bullet(); bullet.setType(self.type); bullet.x = self.x; bullet.y = self.y; bullet.target = nearest; bullet.damage = self.damage; bullet.shooter = self; bullets.push(bullet); game.addChild(bullet); self.cooldown = self.fireRate; } else if (self.type === 4 && self.dualHit) { // (legacy, should not occur, but keep for safety) for (var i = 0; i < 2; ++i) { var bullet = new Bullet(); bullet.setType(self.type); bullet.x = self.x + (i === 0 ? -30 : 30); bullet.y = self.y; bullet.target = nearest; bullet.damage = self.damage; bullet.shooter = self; bullets.push(bullet); game.addChild(bullet); } self.cooldown = self.fireRate; } else { var bullet = new Bullet(); bullet.setType(self.type); bullet.x = self.x; bullet.y = self.y; bullet.target = nearest; bullet.damage = self.damage; bullet.shooter = self; bullets.push(bullet); game.addChild(bullet); self.cooldown = self.fireRate; } } }; return self; }); // Zombie class var Zombie = Container.expand(function () { var self = Container.call(this); self.isRed = false; // Will be set after construction if needed var sprite = self.attachAsset('zombie', { anchorX: 0.5, anchorY: 0.5 }); // Health bar background var hpBarBg = LK.getAsset('pathnode', { anchorX: 0.5, anchorY: 0.5, width: 60, height: 14, y: -60, alpha: 0.25, color: 0x000000 }); self.setRed = function () { if (!self.isRed) { self.isRed = true; // Remove old sprite if (sprite && sprite.parent === self) self.removeChild(sprite); // Attach red zombie asset var redSprite = self.attachAsset('zombieRed', { anchorX: 0.5, anchorY: 0.5 }); } }; self.addChild(hpBarBg); // Health bar foreground var hpBar = LK.getAsset('pathnode', { anchorX: 0.5, anchorY: 0.5, width: 56, height: 10, y: -60, color: 0xff2222, alpha: 0.85 }); self.addChild(hpBar); self.speed = 1.2; self.maxHp = 5; self.hp = 5; self.reward = 1; self.pathIndex = 0; self.progress = 0; // 0-1 between path[pathIndex] and path[pathIndex+1] self.targetX = 0; self.targetY = 0; self.dead = false; self.setStats = function (hp, speed, reward) { self.maxHp = hp; self.hp = hp; self.speed = speed; self.reward = reward; // Update health bar on spawn if (hpBar) { hpBar.width = 56; } }; self.setPathIndex = function (idx) { self.pathIndex = idx; self.progress = 0; }; self.update = function () { if (self.dead) return; // Move along path if (self.pathIndex >= path.length - 1) return; var from = path[self.pathIndex]; var to = path[self.pathIndex + 1]; var dx = to.x - from.x; var dy = to.y - from.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist === 0) dist = 1; var step = self.speed / dist; self.progress += step; if (self.progress >= 1) { self.pathIndex++; self.progress = 0; if (self.pathIndex >= path.length - 1) { // At base self.x = to.x; self.y = to.y; self.reachedBase = true; return; } } var from = path[self.pathIndex]; var to = path[self.pathIndex + 1]; self.x = from.x + (to.x - from.x) * self.progress; self.y = from.y + (to.y - from.y) * self.progress; // Update health bar position and width if (hpBar && hpBarBg) { hpBarBg.x = 0; hpBarBg.y = -60; hpBar.x = 0; hpBar.y = -60; var ratio = Math.max(0, Math.min(1, self.hp / self.maxHp)); hpBar.width = 56 * ratio; if (ratio > 0.6) { hpBar.color = 0x44ff44; } else if (ratio > 0.3) { hpBar.color = 0xffe680; } else { hpBar.color = 0xff2222; } } }; self.takeDamage = function (dmg) { self.hp -= dmg; if (self.hp <= 0 && !self.dead) { self.dead = true; // Animate fade out tween(self, { alpha: 0 }, { duration: 200, onFinish: function onFinish() { self.destroy(); } }); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Path and wall spot colors // Path definition (original, less curvy/straight path for the first version of the game) var path = [{ x: 200, y: 400 }, // Start { x: 200, y: 1000 }, { x: 600, y: 1400 }, { x: 1000, y: 1800 }, { x: 1024, y: 2450 } // Base ]; // Wall spot positions (original, fewer and simpler positions) var wallSpots = [{ x: 200, y: 700 }, { x: 200, y: 1200 }, { x: 400, y: 1500 }, { x: 800, y: 1600 }, { x: 900, y: 2000 }, { x: 1200, y: 2200 }]; // Wall spot state var wallSpotStates = []; for (var i = 0; i < wallSpots.length; ++i) wallSpotStates[i] = null; // Game state var zombies = []; var bullets = []; var soldiers = []; var coins = 10; var baseHp = 10; var wave = 1; var spawnTimer = 0; var spawnIdx = 0; var zombiesToSpawn = 0; var waveInProgress = false; var baseNode = null; var selectedSoldierType = 1; var placingSoldier = false; var placingSoldierIdx = -1; var gameOver = false; // GUI var coinTxt = new Text2('Coins: 10', { size: 80, fill: 0xFFE680 }); coinTxt.anchor.set(0, 0); LK.gui.top.addChild(coinTxt); var baseHpTxt = new Text2('Base: 10', { size: 80, fill: 0xFFAAAA }); baseHpTxt.anchor.set(1, 0); LK.gui.topRight.addChild(baseHpTxt); var waveTxt = new Text2('Wave: 1', { size: 80, fill: 0xAAFFAA }); waveTxt.anchor.set(0.5, 0); LK.gui.top.addChild(waveTxt); var soldierBtns = []; var soldierCosts = [3, 10, 20, 50, 100]; var soldierNames = ['Basic', 'Rapid', 'Heavy', 'Red Arm', 'Dual Arm']; var soldierBtnY = 0; for (var i = 0; i < 4; ++i) { var btn = new Text2(soldierNames[i] + "\n" + soldierCosts[i] + "c", { size: 60, fill: "#fff" }); btn.anchor.set(0.5, 0); btn.x = 300 + i * 300; btn.y = 0; LK.gui.bottom.addChild(btn); soldierBtns.push(btn); } // Note: Only 4 buttons shown, but 5 upgrades available via upgrade // Draw path (as faint nodes) for (var i = 0; i < path.length; ++i) { var node = LK.getAsset('pathnode', { anchorX: 0.5, anchorY: 0.5, x: path[i].x, y: path[i].y, alpha: 0.18 }); game.addChild(node); // Connect lines (not possible, so just nodes) } // Draw wall spots var wallSpotNodes = []; for (var i = 0; i < wallSpots.length; ++i) { var ws = LK.getAsset('wallspot', { anchorX: 0.5, anchorY: 0.5, x: wallSpots[i].x, y: wallSpots[i].y, alpha: 0.5 }); ws.idx = i; wallSpotNodes.push(ws); game.addChild(ws); } // Draw base baseNode = LK.getAsset('base', { anchorX: 0.5, anchorY: 0.5, x: path[path.length - 1].x, y: path[path.length - 1].y }); game.addChild(baseNode); // Handle soldier button selection for (var i = 0; i < soldierBtns.length; ++i) { (function (idx) { soldierBtns[idx].down = function (x, y, obj) { selectedSoldierType = idx + 1; for (var j = 0; j < soldierBtns.length; ++j) { soldierBtns[j].setStyle({ fill: j === idx ? "#ffff00" : "#fff" }); } }; })(i); } soldierBtns[0].setStyle({ fill: 0xFFFF00 }); // Place soldier on wall spot for (var i = 0; i < wallSpotNodes.length; ++i) { (function (idx) { wallSpotNodes[idx].down = function (x, y, obj) { if (gameOver) return; if (wallSpotStates[idx] === null) { // Place soldier if empty var cost = soldierCosts[selectedSoldierType - 1]; if (coins < cost) { // Flash red tween(wallSpotNodes[idx], { tint: 0xff0000 }, { duration: 200, onFinish: function onFinish() { tween(wallSpotNodes[idx], { tint: 0x888888 }, { duration: 200 }); } }); return; } coins -= cost; coinTxt.setText('Coins: ' + coins); // Place soldier var s = new Soldier(); s.setType(selectedSoldierType); s.x = wallSpots[idx].x; s.y = wallSpots[idx].y; s.wallSpot = idx; wallSpotStates[idx] = s; soldiers.push(s); game.addChild(s); // Add upgrade text overlay var upgradeTxt = new Text2('Upgrade', { size: 40, fill: 0x00FF00 }); upgradeTxt.anchor.set(0.5, 1); upgradeTxt.x = s.x; upgradeTxt.y = s.y - 60; upgradeTxt.visible = false; s.upgradeTxt = upgradeTxt; game.addChild(upgradeTxt); // Add tap handler for upgrade s.down = function (x, y, obj) { if (gameOver) return; // Show upgrade text if not max level if (s.level < 5) { s.upgradeTxt.visible = true; // Hide after 1s LK.setTimeout(function () { if (s.upgradeTxt) s.upgradeTxt.visible = false; }, 1000); } // If already at max, do nothing }; // Add tap handler for upgrade text upgradeTxt.down = function (x, y, obj) { if (gameOver) return; if (s.level >= 5) return; // Upgrade cost: Level 2 = 10, Level 3 = 20, Level 4 = 50, Level 5 = 100 var upgradeCost = 0; if (s.level === 1) upgradeCost = 10;else if (s.level === 2) upgradeCost = 20;else if (s.level === 3) upgradeCost = 50;else if (s.level === 4) upgradeCost = 100; if (coins < upgradeCost) { // Flash red tween(upgradeTxt, { fill: 0xff0000 }, { duration: 200, onFinish: function onFinish() { tween(upgradeTxt, { fill: 0x00ff00 }, { duration: 200 }); } }); return; } coins -= upgradeCost; coinTxt.setText('Coins: ' + coins); s.level += 1; // Change type and visuals on upgrade if (s.level === 2) { s.setType(2); } if (s.level === 3) { s.setType(3); } if (s.level === 4) { s.setType(4); } if (s.level === 5) { s.setType(5); } // Show upgraded text upgradeTxt.setText('Upgraded!'); upgradeTxt.fill = "#ffff00"; LK.setTimeout(function () { if (upgradeTxt) { upgradeTxt.setText('Upgrade'); upgradeTxt.fill = "#00ff00"; upgradeTxt.visible = false; } }, 1000); }; } else { // If already a soldier, tap to show upgrade var s = wallSpotStates[idx]; if (s && s.upgradeTxt && s.level < 5) { s.upgradeTxt.visible = true; LK.setTimeout(function () { if (s.upgradeTxt) s.upgradeTxt.visible = false; }, 1000); } } }; })(i); } // Start first wave // Red zombie spawn plan: wave 10-20, 1 red per wave; wave 11, 2 reds; otherwise, 1 red per wave 1-10 var redZombiePlan = {}; // wave number -> array of 0/1 (1=red) function setupRedZombiePlan() { // For waves 1-9: 1 red per wave for (var w = 1; w <= 9; ++w) { var arr = []; var totalZ = 5 + w * 2; for (var i = 0; i < totalZ; ++i) arr.push(0); arr[0] = 1; // Always first zombie is red (could randomize if desired) // Shuffle so red is not always first for (var i = arr.length - 1; i > 0; --i) { var j = Math.floor(Math.random() * (i + 1)); var tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } redZombiePlan[w] = arr; } // Wave 10: 1 red var arr10 = []; var totalZ10 = 5 + 10 * 2; for (var i = 0; i < totalZ10; ++i) arr10.push(0); arr10[0] = 1; for (var i = arr10.length - 1; i > 0; --i) { var j = Math.floor(Math.random() * (i + 1)); var tmp = arr10[i]; arr10[i] = arr10[j]; arr10[j] = tmp; } redZombiePlan[10] = arr10; // Wave 11: 2 reds var arr11 = []; var totalZ11 = 5 + 11 * 2; for (var i = 0; i < totalZ11; ++i) arr11.push(0); arr11[0] = 1; arr11[1] = 1; for (var i = arr11.length - 1; i > 0; --i) { var j = Math.floor(Math.random() * (i + 1)); var tmp = arr11[i]; arr11[i] = arr11[j]; arr11[j] = tmp; } redZombiePlan[11] = arr11; // Waves 12-20: 1 red per wave for (var w = 12; w <= 20; ++w) { var arr = []; var totalZ = 5 + w * 2; for (var i = 0; i < totalZ; ++i) arr.push(0); arr[0] = 1; for (var i = arr.length - 1; i > 0; --i) { var j = Math.floor(Math.random() * (i + 1)); var tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } redZombiePlan[w] = arr; } } setupRedZombiePlan(); function startWave() { waveInProgress = true; spawnIdx = 0; zombiesToSpawn = 5 + wave * 2; spawnTimer = 0; waveTxt.setText('Wave: ' + wave); } startWave(); // Spawn zombie function spawnZombie() { var z = new Zombie(); // Stats scale with wave var hp = 5; // Green zombie health is always 5 var speed = 1.2 + 0.08 * wave; var reward = 1 + Math.floor(wave / 2); // Red zombie logic var makeRed = false; if (wave >= 15 && wave <= 20) { // Only red zombies between wave 15 and 20 makeRed = true; } else if (wave >= 1 && wave <= 20 && redZombiePlan[wave]) { if (spawnIdx < redZombiePlan[wave].length && redZombiePlan[wave][spawnIdx] === 1) { makeRed = true; } } else if (wave > 20) { // After wave 20, only green zombies makeRed = false; } if (makeRed) { z.setRed(); hp = 10; // Red zombie health is always 10 reward = reward * 2; } z.setStats(hp, speed, reward); z.setPathIndex(0); z.x = path[0].x; z.y = path[0].y; zombies.push(z); game.addChild(z); } // Main game update game.update = function () { if (gameOver) return; // Spawn zombies for wave if (waveInProgress && spawnIdx < zombiesToSpawn) { if (spawnTimer <= 0) { spawnZombie(); spawnIdx++; spawnTimer = 40 - Math.min(wave * 2, 30); // Faster spawns later } else { spawnTimer--; } } // Update zombies for (var i = zombies.length - 1; i >= 0; --i) { var z = zombies[i]; z.update(); if (z.dead) { // Reward coins if (z.isRed) { coins += 2; } else { coins += 1; } coinTxt.setText('Coins: ' + coins); zombies.splice(i, 1); continue; } if (z.pathIndex >= path.length - 1 && !z.dead) { // Reached base baseHp--; baseHpTxt.setText('Base: ' + baseHp); LK.effects.flashObject(baseNode, 0xff0000, 400); z.dead = true; z.destroy(); zombies.splice(i, 1); if (baseHp <= 0) { gameOver = true; LK.effects.flashScreen(0xff0000, 1200); LK.showGameOver(); return; } } } // Update bullets for (var i = bullets.length - 1; i >= 0; --i) { var b = bullets[i]; b.update(); if (!b.parent) { bullets.splice(i, 1); } } // Update soldiers for (var i = 0; i < soldiers.length; ++i) { soldiers[i].update(); } // Check if wave is over if (waveInProgress && spawnIdx >= zombiesToSpawn && zombies.length === 0) { waveInProgress = false; // Next wave after short delay LK.setTimeout(function () { wave++; startWave(); }, 1200); } }; // Allow dragging soldiers to swap positions (optional, MVP skips this) // Prevent placing elements in top left 100x100 (already handled by GUI placement) // No background, music, or sound per requirements // No pause, leaderboard, or game over handling (LK does this)
===================================================================
--- original.js
+++ change.js
@@ -317,99 +317,47 @@
/****
* Game Code
****/
// Path and wall spot colors
-// Path definition with 4 distinct curves (4 kıvrım): right, left, right, left, for iPad Pro 2048x2732
-var path = [
-// Start
-{
+// Path definition (original, less curvy/straight path for the first version of the game)
+var path = [{
x: 200,
y: 400
-}, {
- x: 400,
- y: 600
},
-// 1st curve: right
+// Start
{
- x: 900,
- y: 800
-},
-// right curve
-{
- x: 1400,
+ x: 200,
y: 1000
-},
-// right curve peak
-// 2nd curve: left
-{
- x: 900,
- y: 1300
-},
-// left curve
-{
- x: 400,
- y: 1600
-},
-// left curve peak
-// 3rd curve: right
-{
- x: 900,
- y: 1900
-},
-// right curve
-{
- x: 1400,
- y: 2200
-},
-// right curve peak
-// 4th curve: left
-{
+}, {
+ x: 600,
+ y: 1400
+}, {
+ x: 1000,
+ y: 1800
+}, {
x: 1024,
y: 2450
-},
-// left curve
-{
- x: 700,
- y: 2650
-} // base (left end)
+} // Base
];
-// Wall spot positions (12, hand-picked along the new path, not on path nodes)
+// Wall spot positions (original, fewer and simpler positions)
var wallSpots = [{
- x: 275,
- y: 500
-}, {
- x: 425,
+ x: 200,
y: 700
}, {
- x: 600,
- y: 900
+ x: 200,
+ y: 1200
}, {
- x: 850,
- y: 1050
+ x: 400,
+ y: 1500
}, {
- x: 1050,
- y: 1250
+ x: 800,
+ y: 1600
}, {
- x: 1250,
- y: 1350
+ x: 900,
+ y: 2000
}, {
- x: 1450,
- y: 1450
-}, {
- x: 1650,
- y: 1550
-}, {
- x: 1750,
- y: 1800
-}, {
- x: 1550,
- y: 2050
-}, {
x: 1200,
- y: 2250
-}, {
- x: 950,
- y: 2350
+ y: 2200
}];
// Wall spot state
var wallSpotStates = [];
for (var i = 0; i < wallSpots.length; ++i) wallSpotStates[i] = null;
Soilder. In-Game asset. 2d. High contrast. No shadows
one-gun soldier. In-Game asset. 2d. High contrast. No shadows
soldier with 2 kate ak47 in his hand. In-Game asset. 2d. High contrast. No shadows
soldier with rifle. In-Game asset. 2d. High contrast. No shadows
Zombie. In-Game asset. 2d. High contrast. No shadows
Zombie. In-Game asset. 2d. High contrast. No shadows