User prompt
75 coıne can yenıleme ekleyelım
User prompt
kulenın canını arttıralım ve parasını 30 yapıp otyuncu her silah guceldirdiginde kulenınde silahı guçlensın
User prompt
ve ondan sonrada 2 nın katları şeklinde gitsin ve her deferinde 100 coın daha pahalı olsun
User prompt
oyuncu 1.5 x parayı adlıktan sonra onun yerine 2x para gelsin ve o da 100 coin olsun
User prompt
checkpoint i kaldıralım
User prompt
oyundakı tum yazıları ingilizce yapalım
User prompt
arkaplana bir orman çiz
User prompt
arka plan resmini ortala
User prompt
arkaplana bir askeriye koy
User prompt
arkaplanı siyah yerine zombi salgınına ugramış ve terk edilmiş bir askeriye yapalım
User prompt
butonlardaki mavı rengi kaldır
User prompt
yon tusları ve satın alma kutularınn rengini gri yap
User prompt
yön tuşlarının arkasını gri yap
User prompt
kutulardaki resimleri eski haline getir aam duvar kalsın
User prompt
kalpleri iraz daha küçültelim mobil için
User prompt
karakterin hareketi için sanal sag sol on arka tusları ekliyelim
User prompt
mausenın 3. tuşu ile hareket ettirelim
User prompt
karakteri masuenın sol tuşu ile hareket ettirelim
User prompt
kalpleri biraz küçültelim
User prompt
kalpleri ortaya alalım
User prompt
kalpleri sola alalım
User prompt
en sola alalım
User prompt
biraz daha sola alalım
User prompt
en sol uste alalım
User prompt
biraz daha sola
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // BossZombie class var BossZombie = Container.expand(function () { var self = Container.call(this); var bossSprite = self.attachAsset('zombie', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.7, scaleY: 1.7, color: 0x8e44ad // purple tint for boss }); self.radius = bossSprite.width / 2; var bossPowerLevel = Math.floor((currentWave - 1) / 3); self.speed = 1.5 + bossPowerLevel * 0.5; self.hp = 10 + bossPowerLevel * 5; self.maxHp = self.hp; self.target = null; self.lastHitTick = 0; self.update = function () { // Move towards player var tx = player.x; var ty = player.y; // If wall/trap/tower is closer, target that var minDist = Math.sqrt((self.x - tx) * (self.x - tx) + (self.y - ty) * (self.y - ty)); var targetObj = player; for (var i = 0; i < defenses.length; i++) { var d = defenses[i]; var dist = Math.sqrt((self.x - d.x) * (self.x - d.x) + (self.y - d.y) * (self.y - d.y)); if (dist < minDist) { minDist = dist; targetObj = d; } } self.target = targetObj; var dx = targetObj.x - self.x; var dy = targetObj.y - self.y; var len = Math.sqrt(dx * dx + dy * dy); if (len > 0) { dx /= len; dy /= len; self.x += dx * self.speed; self.y += dy * self.speed; } // Attack if close if (len < self.radius + targetObj.radius + 10) { if (LK.ticks - self.lastHitTick > 30) { if (targetObj === player) { player.takeDamage(2); // Boss does more damage } else if (targetObj.takeDamage) { targetObj.takeDamage(2); } self.lastHitTick = LK.ticks; } } }; self.takeDamage = function (amount) { self.hp -= amount; if (self.hp <= 0) { self.die(); } else { LK.effects.flashObject(self, 0xff00ff, 300); } }; self.die = function () { LK.getSound('zombie_die').play(); // Drop 5 coins var coinCount = 5; if (typeof coinMultiplierEnabled !== "undefined" && coinMultiplierEnabled) { coinCount = Math.round(5 * 1.5); } for (var i = 0; i < coinCount; i++) { var coin = new Coin(); // Spread coins a bit var angle = Math.PI * 2 * i / coinCount; coin.x = self.x + Math.cos(angle) * 60; coin.y = self.y + Math.sin(angle) * 60; coins.push(coin); game.addChild(coin); } self.destroy(); var idx = zombies.indexOf(self); if (idx !== -1) zombies.splice(idx, 1); zombiesKilledThisWave++; }; return self; }); // Bullet class var Bullet = Container.expand(function () { var self = Container.call(this); var bulletSprite = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.radius = bulletSprite.width / 2; self.vx = 0; self.vy = 0; self.damage = 1; self.update = function () { self.x += self.vx; self.y += self.vy; }; return self; }); // Coin class var Coin = Container.expand(function () { var self = Container.call(this); var coinSprite = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.radius = coinSprite.width * 1.5; // Even further increase hitbox radius for much easier collection // Remove vy and falling logic so coin stays at spawn position self.collected = false; self.update = function () { // No falling, coin stays at its spawn position }; self.collect = function () { if (self.collected) return; self.collected = true; LK.getSound('coin').play(); // Animate to coinText var guiPos = LK.gui.topRight.toLocal(game.toGlobal({ x: self.x, y: self.y })); var startX = self.x, startY = self.y; var endX = 2048 - 200, endY = 80; tween(self, { x: endX, y: endY, alpha: 0 }, { duration: 400, easing: tween.cubicIn, onFinish: function onFinish() { self.destroy(); var idx = coins.indexOf(self); if (idx !== -1) coins.splice(idx, 1); if (typeof coinMultiplierLevel !== "undefined" && coinMultiplierLevel > 0) { coinsCollected += Math.pow(2, coinMultiplierLevel); } else { coinsCollected++; } coinsCollected = Math.floor(coinsCollected); updateCoinText(); } }); }; return self; }); // Player class var Player = Container.expand(function () { var self = Container.call(this); var playerSprite = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.radius = playerSprite.width / 2; self.hp = 10; self.maxHp = 10; self.shootCooldown = 0; self.shootDelay = 20; // frames self.weaponLevel = 1; self.lastShotTick = 0; // For drag self.down = function (x, y, obj) {}; self.up = function (x, y, obj) {}; self.update = function () { if (self.shootCooldown > 0) self.shootCooldown--; }; // Shoot method self.shoot = function (targetX, targetY) { if (self.shootCooldown > 0) return; var dx = targetX - self.x; var dy = targetY - self.y; var len = Math.sqrt(dx * dx + dy * dy); if (len === 0) return; dx /= len; dy /= len; var bullet = new Bullet(); bullet.x = self.x + dx * (self.radius + 30); bullet.y = self.y + dy * (self.radius + 30); bullet.vx = dx * (22 + self.weaponLevel * 2); bullet.vy = dy * (22 + self.weaponLevel * 2); bullet.damage = self.weaponLevel; // Set bullet rotation so the tip faces the direction of movement if (bullet.children && bullet.children.length > 0) { bullet.children[0].rotation = Math.atan2(bullet.vy, bullet.vx); } bullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); self.shootCooldown = self.shootDelay; }; // Take damage self.takeDamage = function (amount) { self.hp -= amount; if (self.hp < 0) self.hp = 0; LK.effects.flashObject(self, 0xff0000, 300); updateHpBar(); if (self.hp <= 0) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } }; return self; }); // Tower class var Tower = Container.expand(function () { var self = Container.call(this); var towerSprite = self.attachAsset('tower', { anchorX: 0.5, anchorY: 0.5 }); self.radius = Math.max(towerSprite.width, towerSprite.height) / 2; self.hp = 20; self.maxHp = 20; self.shootCooldown = 0; self.shootDelay = 40; self.takeDamage = function (amount) { self.hp -= amount; LK.effects.flashObject(self, 0xff0000, 200); if (self.hp <= 0) { self.destroy(); var idx = defenses.indexOf(self); if (idx !== -1) defenses.splice(idx, 1); } }; self.update = function () { if (self.shootCooldown > 0) self.shootCooldown--; // Find nearest zombie var nearest = null, minDist = 99999; for (var i = 0; i < zombies.length; i++) { var z = zombies[i]; var dx = z.x - self.x; var dy = z.y - self.y; var dist = dx * dx + dy * dy; if (dist < minDist) { minDist = dist; nearest = z; } } if (nearest && self.shootCooldown <= 0) { // Shoot at nearest zombie var dx = nearest.x - self.x; var dy = nearest.y - self.y; var len = Math.sqrt(dx * dx + dy * dy); if (len > 0) { dx /= len; dy /= len; var bullet = new Bullet(); bullet.x = self.x + dx * (self.radius + 20); bullet.y = self.y + dy * (self.radius + 20); var towerWeaponLevel = typeof self.weaponLevel !== "undefined" ? self.weaponLevel : 1; bullet.vx = dx * (18 + towerWeaponLevel * 2); bullet.vy = dy * (18 + towerWeaponLevel * 2); bullet.damage = towerWeaponLevel; // Set bullet rotation so the tip faces the direction of movement if (bullet.children && bullet.children.length > 0) { bullet.children[0].rotation = Math.atan2(bullet.vy, bullet.vx); } bullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); self.shootCooldown = self.shootDelay; } } }; return self; }); // Trap class var Trap = Container.expand(function () { var self = Container.call(this); var trapSprite = self.attachAsset('trap', { anchorX: 0.5, anchorY: 0.5 }); self.radius = Math.max(trapSprite.width, trapSprite.height) / 2; self.hp = 2; self.maxHp = 2; self.takeDamage = function (amount) { self.hp -= amount; LK.effects.flashObject(self, 0xff0000, 200); if (self.hp <= 0) { self.destroy(); var idx = defenses.indexOf(self); if (idx !== -1) defenses.splice(idx, 1); } }; return self; }); // Wall class var Wall = Container.expand(function () { var self = Container.call(this); var wallSprite = self.attachAsset('wall', { anchorX: 0.5, anchorY: 0.5 }); self.radius = Math.max(wallSprite.width, wallSprite.height) / 2; self.hp = 6; self.maxHp = 6; self.takeDamage = function (amount) { self.hp -= amount; LK.effects.flashObject(self, 0xff0000, 200); if (self.hp <= 0) { self.destroy(); var idx = defenses.indexOf(self); if (idx !== -1) defenses.splice(idx, 1); } }; return self; }); // Zombie class var Zombie = Container.expand(function () { var self = Container.call(this); var zombieSprite = self.attachAsset('zombie', { anchorX: 0.5, anchorY: 0.5 }); self.radius = zombieSprite.width / 2; // Zombies get stronger only every 3 waves var zombiePowerLevel = Math.floor((currentWave - 1) / 3); self.speed = 2 + zombiePowerLevel * 0.9; self.hp = 1 + zombiePowerLevel; self.maxHp = self.hp; self.target = null; self.lastHitTick = 0; self.update = function () { // Move towards player var tx = player.x; var ty = player.y; // If wall/trap/tower is closer, target that var minDist = Math.sqrt((self.x - tx) * (self.x - tx) + (self.y - ty) * (self.y - ty)); var targetObj = player; for (var i = 0; i < defenses.length; i++) { var d = defenses[i]; var dist = Math.sqrt((self.x - d.x) * (self.x - d.x) + (self.y - d.y) * (self.y - d.y)); if (dist < minDist) { minDist = dist; targetObj = d; } } self.target = targetObj; var dx = targetObj.x - self.x; var dy = targetObj.y - self.y; var len = Math.sqrt(dx * dx + dy * dy); if (len > 0) { dx /= len; dy /= len; self.x += dx * self.speed; self.y += dy * self.speed; } // Attack if close if (len < self.radius + targetObj.radius + 10) { if (LK.ticks - self.lastHitTick > 30) { if (targetObj === player) { player.takeDamage(1); } else if (targetObj.takeDamage) { targetObj.takeDamage(1); } self.lastHitTick = LK.ticks; } } }; self.takeDamage = function (amount) { self.hp -= amount; if (self.hp <= 0) { self.die(); } else { LK.effects.flashObject(self, 0xff0000, 200); } }; self.die = function () { LK.getSound('zombie_die').play(); // Drop coin var coin = new Coin(); coin.x = self.x; coin.y = self.y; coins.push(coin); game.addChild(coin); self.destroy(); var idx = zombies.indexOf(self); if (idx !== -1) zombies.splice(idx, 1); zombiesKilledThisWave++; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Sounds // Tower // Trap // Wall // Coin // Bullet // Zombie // Character (player) // Global variables var player; var zombies = []; var bullets = []; var coins = []; var defenses = []; var coinsCollected = 0; var autoCollectEnabled = false; var coinMultiplierEnabled = false; var coinMultiplier2Enabled = false; var currentWave = 1; var zombiesToSpawn = 0; var zombiesSpawnedThisWave = 0; var zombiesKilledThisWave = 0; var waveInProgress = false; var dragNode = null; var buildMode = null; // 'wall', 'trap', 'tower', 'upgrade', 'autocollect', 'coinmult' var buildPreview = null; var buildCost = { wall: 5, trap: 7, tower: 30, upgrade: 10, autocollect: 20, coinmult: 50 }; var buildNames = { wall: "Duvar", trap: "Tuzak", tower: "Kule", upgrade: "Silah+", autocollect: "Oto-Para", coinmult: "Para x2" }; // Track current coin multiplier and its cost var coinMultiplierLevel = 1; // 1 means 2x, 2 means 4x, etc. var coinMultiplierCost = 100; // Cost for next multiplier (starts at 100 for 2x) // buildDesc removed var hpBar, coinText, waveText, buildPanel, buildButtons = []; var lastTouchX = 0, lastTouchY = 0; // UI: HP Bar function updateHpBar() { if (!hpBar) return; var txt = ""; for (var i = 0; i < player.maxHp; i++) { txt += i < player.hp ? "♥ " : "♡ "; } hpBar.setText(txt); } // UI: Coin Text function updateCoinText() { if (coinText) coinText.setText("₺ " + coinsCollected); // Rebuild build panel to update overlays/locks if it exists if (typeof buildPanel !== "undefined" && buildPanel) { buildPanel.destroy(); buildButtons = []; createBuildPanel(); } } // UI: Wave Text function updateWaveText() { if (waveText) waveText.setText("Dalga: " + currentWave); } // UI: Build Panel function createBuildPanel() { buildPanel = new Container(); buildPanel.y = 0; buildPanel.x = 0; var btnW = 140, btnH = 56, gap = 18; // Dynamically build types array based on upgrade state var types = ['wall', 'trap', 'tower', 'upgrade', 'heal']; if (!autoCollectEnabled) { types.push('autocollect'); } else { types.push('coinmult'); } // If coinmult is present, we will handle its label and cost dynamically below for (var i = 0; i < types.length; i++) { (function (type, idx) { var btn = new Container(); // Use original images for each type except for upgrade/autocollect/coinmult/checkpoint var assetId = 'wall'; if (type === 'trap') assetId = 'trap';else if (type === 'tower') assetId = 'tower'; // Remove blue color, always use gray for button backgrounds var bg = LK.getAsset(assetId, { width: btnW, height: btnH, color: 0x888888, anchorX: 0, anchorY: 0 }); btn.addChild(bg); var label, cost; if (type === 'coinmult') { // Show next multiplier (2x, 4x, 8x, ...) and its cost var nextMult = Math.pow(2, coinMultiplierLevel + 1); label = "Para x" + nextMult; cost = coinMultiplierCost; } else if (type === 'heal') { label = "Can +1"; cost = 75; } else { label = buildNames[type] ? buildNames[type] : type; cost = buildCost[type] ? buildCost[type] : 0; } var txt = new Text2(label + "\n₺" + cost, { size: 32, fill: "#fff" }); txt.x = btnW / 2; txt.y = 12; txt.anchor.set(0.5, 0); btn.addChild(txt); btn.x = idx * (btnW + gap) - 10; // Move each button 10px to the left (was 100px) btn.y = 0; btn.type = type; // Check if player can afford this item var canAfford = coinsCollected >= cost; if (!canAfford) { // Add a semi-transparent black overlay // Remove blue color, always use gray for lock overlays var overlay = LK.getAsset('wall', { width: btnW, height: btnH, color: 0x888888, anchorX: 0, anchorY: 0 }); overlay.alpha = 0.45; btn.addChild(overlay); // Add a lock icon (use a Text2 lock emoji for simplicity) var lockIcon = new Text2("🔒", { size: 38, fill: "#fff" }); lockIcon.x = btnW / 2; lockIcon.y = btnH / 2 - 18; lockIcon.anchor.set(0.5, 0.5); btn.addChild(lockIcon); // Disable interaction btn.down = function () {}; } else { btn.down = function (x, y, obj) { setBuildMode(type); }; } buildPanel.addChild(btn); buildButtons.push(btn); })(types[i], i); } buildPanel.y = -120; // Move the build panel further up by 120px (closer to bottom) buildPanel.x = -320; // Move the build panel to the right (was -540) LK.gui.bottom.addChild(buildPanel); } // Set build mode function setBuildMode(type) { buildMode = type; if (buildPreview) { buildPreview.destroy(); buildPreview = null; } if (type === 'wall') { buildPreview = new Wall(); } else if (type === 'trap') { buildPreview = new Trap(); } else if (type === 'tower') { buildPreview = new Tower(); } else if (type === 'upgrade' || type === 'autocollect') { buildPreview = null; } if (buildPreview) { buildPreview.alpha = 0.5; game.addChild(buildPreview); } } // Remove build preview function clearBuildPreview() { if (buildPreview) { buildPreview.destroy(); buildPreview = null; } buildMode = null; } // Start new wave function startWave() { zombiesToSpawn = 5 + currentWave * 2; zombiesSpawnedThisWave = 0; zombiesKilledThisWave = 0; waveInProgress = true; updateWaveText(); // Spawn boss every 3 waves if (currentWave % 3 === 0) { // Boss will be spawned after all regular zombies zombiesToSpawn += 1; } } // Spawn zombie function spawnZombie() { // Spawn at random edge var edge = Math.floor(Math.random() * 4); var zx, zy; if (edge === 0) { // top zx = 200 + Math.random() * (2048 - 400); zy = -60; } else if (edge === 1) { // right zx = 2048 + 60; zy = 200 + Math.random() * (2732 - 400); } else if (edge === 2) { // bottom zx = 200 + Math.random() * (2048 - 400); zy = 2732 + 60; } else { // left zx = -60; zy = 200 + Math.random() * (2732 - 400); } // If this is a boss wave and this is the last zombie, spawn boss var isBossWave = currentWave % 3 === 0; var isLastZombie = zombiesSpawnedThisWave === zombiesToSpawn - 1 && isBossWave; var z; if (isLastZombie) { z = new BossZombie(); } else { z = new Zombie(); } z.x = zx; z.y = zy; zombies.push(z); game.addChild(z); zombiesSpawnedThisWave++; } // Build defense function buildDefense(type, x, y) { if (coinsCollected < buildCost[type]) return false; var obj; if (type === 'wall') { obj = new Wall(); } else if (type === 'trap') { obj = new Trap(); } else if (type === 'tower') { obj = new Tower(); } if (obj) { obj.x = x; obj.y = y; defenses.push(obj); game.addChild(obj); coinsCollected -= buildCost[type]; updateCoinText(); LK.getSound('build').play(); return true; } return false; } // Upgrade weapon function upgradeWeapon() { if (coinsCollected < buildCost.upgrade) return false; player.weaponLevel++; // Upgrade all towers' shoot power for (var i = 0; i < defenses.length; i++) { if (defenses[i] && defenses[i] instanceof Tower) { // Increase tower bullet damage and speed with each upgrade if (typeof defenses[i].weaponLevel === "undefined") { defenses[i].weaponLevel = 1; } defenses[i].weaponLevel++; } } coinsCollected -= buildCost.upgrade; updateCoinText(); LK.effects.flashObject(player, 0xffff00, 600); LK.getSound('build').play(); return true; } // Handle move (drag, build preview, collect coin) function handleMove(x, y, obj) { lastTouchX = x; lastTouchY = y; // Drag player if (dragNode === player) { // Clamp to game area var r = player.radius + 10; player.x = Math.max(r, Math.min(2048 - r, x)); player.y = Math.max(r, Math.min(2732 - r, y)); } // Build preview follows finger if (buildPreview) { buildPreview.x = x; buildPreview.y = y; } // Coin collection for (var i = coins.length - 1; i >= 0; i--) { var c = coins[i]; var dx = c.x - x, dy = c.y - y; if (!c.collected && dx * dx + dy * dy < c.radius * c.radius + 1200) { c.collect(); } } } // Handle down (start drag, build, upgrade) game.down = function (x, y, obj) { // If build mode is active if (buildMode) { if (buildMode === 'upgrade') { if (upgradeWeapon()) { clearBuildPreview(); } } else if (buildMode === 'autocollect') { if (!autoCollectEnabled && coinsCollected >= buildCost.autocollect) { coinsCollected -= buildCost.autocollect; updateCoinText(); autoCollectEnabled = true; LK.effects.flashObject(player, 0x00ffcc, 600); LK.getSound('build').play(); clearBuildPreview(); // Recreate build panel to remove autocollect and add coinmult if (buildPanel) { buildPanel.destroy(); buildButtons = []; createBuildPanel(); } } } else if (buildMode === 'coinmult') { if (coinsCollected >= coinMultiplierCost) { coinsCollected -= coinMultiplierCost; updateCoinText(); coinMultiplierLevel++; coinMultiplierCost += 100; LK.effects.flashObject(player, 0xffe066, 600); LK.getSound('build').play(); clearBuildPreview(); // Recreate build panel to update multiplier label/cost if (buildPanel) { buildPanel.destroy(); buildButtons = []; createBuildPanel(); } } } else if (buildMode === 'heal') { if (coinsCollected >= 75 && player.hp < player.maxHp) { coinsCollected -= 75; player.hp += 1; if (player.hp > player.maxHp) player.hp = player.maxHp; updateCoinText(); updateHpBar(); LK.effects.flashObject(player, 0x00ff44, 600); LK.getSound('build').play(); clearBuildPreview(); } } else { // Place defense if possible if (buildPreview) { // Don't allow build on player or on top of other defenses var canBuild = true; var dx = player.x - x, dy = player.y - y; if (dx * dx + dy * dy < (player.radius + buildPreview.radius + 40) * (player.radius + buildPreview.radius + 40)) { canBuild = false; } for (var i = 0; i < defenses.length; i++) { var d = defenses[i]; var ddx = d.x - x, ddy = d.y - y; if (ddx * ddx + ddy * ddy < (d.radius + buildPreview.radius + 30) * (d.radius + buildPreview.radius + 30)) { canBuild = false; break; } } if (canBuild && buildDefense(buildMode, x, y)) { clearBuildPreview(); } } } return; } // Only handle mouse/touch events with event object var event = obj && obj.event ? obj.event : null; var isLeftClick = false; var isMiddleClick = false; // Mouse events if (event && typeof event.button !== "undefined") { // 0: left, 1: middle if (event.button === 0) isLeftClick = true; if (event.button === 1) isMiddleClick = true; } else { // Touch events: treat as left click (drag/shoot) isLeftClick = true; } if (isMiddleClick) { // Teleport player to clicked position, clamp to game area var r = player.radius + 10; player.x = Math.max(r, Math.min(2048 - r, x)); player.y = Math.max(r, Math.min(2732 - r, y)); } else if (isLeftClick) { // If click/touch is on player, start drag var dx = player.x - x, dy = player.y - y; if (dx * dx + dy * dy < player.radius * player.radius + 2000) { dragNode = player; } else { // Otherwise, shoot player.shoot(x, y); } } handleMove(x, y, obj); }; // Prevent context menu on right click for the canvas if (typeof window !== "undefined" && typeof document !== "undefined") { var canvas = document.querySelector('canvas'); if (canvas) { canvas.oncontextmenu = function (e) { e.preventDefault(); return false; }; } } // Handle up (stop drag, clear build preview) game.up = function (x, y, obj) { dragNode = null; // If build preview exists, clear it if not placed if (buildPreview && buildMode) { clearBuildPreview(); } }; // Handle move game.move = handleMove; // Game update game.update = function () { // --- Virtual Joystick Movement --- var moveSpeed = 18 + player.weaponLevel * 2; if (typeof vbtns !== "undefined") { var dx = 0, dy = 0; if (vbtns.up && vbtns.up.isDown) dy -= 1; if (vbtns.down && vbtns.down.isDown) dy += 1; if (vbtns.left && vbtns.left.isDown) dx -= 1; if (vbtns.right && vbtns.right.isDown) dx += 1; if (dx !== 0 || dy !== 0) { var len = Math.sqrt(dx * dx + dy * dy); if (len > 0) { dx /= len; dy /= len; // Clamp to game area var r = player.radius + 10; player.x = Math.max(r, Math.min(2048 - r, player.x + dx * moveSpeed)); player.y = Math.max(r, Math.min(2732 - r, player.y + dy * moveSpeed)); } } } // Player update player.update(); // Zombies update for (var i = zombies.length - 1; i >= 0; i--) { zombies[i].update(); } // Bullets update for (var i = bullets.length - 1; i >= 0; i--) { var b = bullets[i]; b.update(); // Remove if out of bounds if (b.x < -100 || b.x > 2148 || b.y < -100 || b.y > 2832) { b.destroy(); bullets.splice(i, 1); continue; } // Check collision with zombies for (var j = zombies.length - 1; j >= 0; j--) { var z = zombies[j]; var dx = z.x - b.x, dy = z.y - b.y; if (dx * dx + dy * dy < (z.radius + b.radius) * (z.radius + b.radius)) { z.takeDamage(b.damage); b.destroy(); bullets.splice(i, 1); break; } } } // Coins update for (var i = coins.length - 1; i >= 0; i--) { coins[i].update(); if (autoCollectEnabled && !coins[i].collected) { coins[i].collect(); } } // Defenses update for (var i = defenses.length - 1; i >= 0; i--) { if (defenses[i].update) defenses[i].update(); } // Wave logic if (waveInProgress) { // Spawn zombies if (zombiesSpawnedThisWave < zombiesToSpawn && LK.ticks % Math.max(20, 60 - currentWave * 2) === 0) { spawnZombie(); } // Check wave end if (zombiesKilledThisWave >= zombiesToSpawn && zombies.length === 0) { waveInProgress = false; // Give 5 coins every 5 waves at the end of the wave if (currentWave % 5 === 0) { coinsCollected += 5; updateCoinText(); } // Next wave after 4 seconds (4000 ms) LK.setTimeout(function () { currentWave++; startWave(); }, 4000); } } }; // --- Game Initialization --- // Add forest background (drawn as a large green rectangle with tree-like ellipses) var forestBg = new Container(); var bgRect = LK.getAsset('military_bg', { width: 2048, height: 2732, color: 0x2e4d1a, // deep forest green anchorX: 0, anchorY: 0, x: 0, y: 0 }); forestBg.addChild(bgRect); // Add some tree ellipses for a forest look for (var i = 0; i < 18; i++) { var tree = LK.getAsset('military_bg', { width: 180 + Math.floor(Math.random() * 80), height: 320 + Math.floor(Math.random() * 60), color: 0x3e7d2a + Math.floor(Math.random() * 0x002000), shape: 'ellipse', anchorX: 0.5, anchorY: 1, x: 120 + Math.random() * 1800, y: 400 + Math.random() * 2100 }); tree.alpha = 0.22 + Math.random() * 0.18; forestBg.addChild(tree); } game.addChild(forestBg); // Place player at center player = new Player(); player.x = 2048 / 2; player.y = 2732 / 2; game.addChild(player); // --- Virtual Joystick Buttons --- // Button size and margin var vbtnSize = 160; var vbtnMargin = 40; var vbtnAlpha = 0.45; var vbtnColor = 0x888888; var vbtns = {}; // Helper to create a button function createVBtn(label, x, y, dir) { var btn = new Container(); // Remove blue color, always use gray for joystick button backgrounds var bg = LK.getAsset('wall', { width: vbtnSize, height: vbtnSize, color: 0x888888, anchorX: 0.5, anchorY: 0.5 }); bg.alpha = vbtnAlpha; btn.addChild(bg); var txt = new Text2(label, { size: 80, fill: "#fff" }); txt.anchor.set(0.5, 0.5); txt.x = 0; txt.y = 0; btn.addChild(txt); btn.x = x; btn.y = y; btn.dir = dir; btn.isDown = false; btn.down = function () { btn.isDown = true; }; btn.up = function () { btn.isDown = false; }; LK.gui.bottomLeft.addChild(btn); return btn; } // Positioning for bottom left corner var baseX = vbtnSize + vbtnMargin; var baseY = -vbtnSize - vbtnMargin; // Up vbtns.up = createVBtn("▲", baseX, baseY - vbtnSize, "up"); // Down vbtns.down = createVBtn("▼", baseX, baseY + vbtnSize, "down"); // Left vbtns.left = createVBtn("◀", baseX - vbtnSize, baseY, "left"); // Right vbtns.right = createVBtn("▶", baseX + vbtnSize, baseY, "right"); // UI: HP Bar hpBar = new Text2("", { size: 38, fill: 0xFF4444 }); // Move hearts to the absolute left (x=0), keep y=20 hpBar.anchor.set(0, 0); LK.gui.top.addChild(hpBar); hpBar.x = 0; hpBar.y = 20; updateHpBar(); // UI: Coin Text coinText = new Text2("₺ 0", { size: 70, fill: 0xFFE066 }); coinText.anchor.set(1, 0); LK.gui.topRight.addChild(coinText); coinText.x = -40; coinText.y = 20; // UI: Wave Text waveText = new Text2("Dalga: 1", { size: 60, fill: "#fff" }); waveText.anchor.set(0, 0); LK.gui.top.addChild(waveText); waveText.x = 60; waveText.y = 120; // UI: Build Panel createBuildPanel(); // Start first wave startWave(); updateCoinText(); updateWaveText();
===================================================================
--- original.js
+++ change.js
@@ -491,9 +491,9 @@
var btnW = 140,
btnH = 56,
gap = 18;
// Dynamically build types array based on upgrade state
- var types = ['wall', 'trap', 'tower', 'upgrade'];
+ var types = ['wall', 'trap', 'tower', 'upgrade', 'heal'];
if (!autoCollectEnabled) {
types.push('autocollect');
} else {
types.push('coinmult');
@@ -519,8 +519,11 @@
// Show next multiplier (2x, 4x, 8x, ...) and its cost
var nextMult = Math.pow(2, coinMultiplierLevel + 1);
label = "Para x" + nextMult;
cost = coinMultiplierCost;
+ } else if (type === 'heal') {
+ label = "Can +1";
+ cost = 75;
} else {
label = buildNames[type] ? buildNames[type] : type;
cost = buildCost[type] ? buildCost[type] : 0;
}
@@ -759,8 +762,19 @@
buildButtons = [];
createBuildPanel();
}
}
+ } else if (buildMode === 'heal') {
+ if (coinsCollected >= 75 && player.hp < player.maxHp) {
+ coinsCollected -= 75;
+ player.hp += 1;
+ if (player.hp > player.maxHp) player.hp = player.maxHp;
+ updateCoinText();
+ updateHpBar();
+ LK.effects.flashObject(player, 0x00ff44, 600);
+ LK.getSound('build').play();
+ clearBuildPreview();
+ }
} else {
// Place defense if possible
if (buildPreview) {
// Don't allow build on player or on top of other defenses
9mm ammo. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
içinde c yazan sarı renkli bir madeni para. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
clash of clans klan kalesi. In-Game asset. 2d. High contrast. No shadows
the zombie. In-Game asset. 2d. High contrast. No shadows
gray block. In-Game asset. 2d. High contrast. No shadows
trap. In-Game asset. 2d. High contrast. No shadows
arazi pxelart sadece yeşillikle dolu. In-Game asset. 2d. High contrast. No shadows
elinde silahı olan bir asker. In-Game asset. 2d. High contrast. No shadows