User prompt
20 seviyede bitmesin, 20 ve 50 seviye arası düşman askerleri rastgele doğsun ve 50 seviye son seviye olarak belirle.
User prompt
Fast Enemy Spawn özelliğinin yazı fontunu, panele sığacak şekilde ayarla. Alt satıra geçmesin.
User prompt
Fast Enemy Spawn özelliğinin yazı fontunu, panele sığacak şekilde ayarla.
User prompt
Bu yeni özelliklerin Lv. Undefined yazıyor düzelt.
User prompt
Store paneline 3 farklı özellik daha ekle.
User prompt
Store paneli içinde ki, yazı fontunu %5 oranında küçült. Alt satıra geçmesin.
User prompt
Store paneli içinde ki yazı fontunu %5 oranında küçült.
User prompt
Store panelini, hizalı ve düz şekilde görünmesini sağla.
User prompt
Store paneli yazı fontunu %5 oranında küçült.
User prompt
Store panelinin içeriğini %10 oranında küçült.
User prompt
Store yazı fontunu, reset butonu ile aynı yap. Ayrıca içeriğini %20 oranında büyüt.
User prompt
Ana ekranda bulunan özellik yükseltmelerini gizle.
User prompt
Slingshot resminin 3 satır yukarısına "Store" isminde buton oluştur. Açılan pencereye, özellik yükseltmelerini ekle.
User prompt
Arkaplan resmini aşağı doğru %30 oranında büyüt. Kapat butonu da arkaplan resminin alt ortasına yeniden yerleştir.
User prompt
Panelin arkaplan resmini, içeriğine sığacak şekilde büyüt.
User prompt
Müzik iconunu alt satırına "How to play?" butonu oluştur ve açılan pencereye oyun hakkında bilgi ve nasıl oynanır konusunda bilgi yaz.
User prompt
Bütün yazıları Türkçe'den İngilizce'ye çevir.
User prompt
Anabase canını %30 oranında yükselt.
User prompt
Bizim askerlerin mermi saldırı gücünü %20 arttır.
User prompt
Bizim askerimiz de mermi atsınlar.
User prompt
Düşmanlar neden mermi atmıyorlar? Düzelt.
User prompt
Ses dosya iconunun özel resim dosyasını oluştur
User prompt
Reset butonu 2 satır altına arkaplan müziği açıp kapatmak için ses iconu ekle.
User prompt
Birimlerin tamamı, resimlerinin herhangi bir yerine mermi değdiğinde mermi hasarı alabilsin.
User prompt
Birimlerin tamamı, resimleri boyunca mermi etkisine sahip olsunlar.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // AnaBase (player base) var AnaBase = Container.expand(function () { var self = Container.call(this); var base = self.attachAsset('anaBase', { anchorX: 0.5, anchorY: 0.5 }); self.hp = 100; self.maxHp = 100; self.hpBar = self.addChild(new HealthBar()); self.hpBar.y = 120; self.hpBar.set(1); return self; }); // EnemyBase (enemy base) var EnemyBase = Container.expand(function () { var self = Container.call(this); var base = self.attachAsset('enemyBase', { anchorX: 0.5, anchorY: 0.5 }); self.hp = 100; self.maxHp = 100; self.hpBar = self.addChild(new HealthBar()); self.hpBar.y = 120; self.hpBar.set(1); return self; }); // Enemy Gunner Bullet var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bullet = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); self.vx = 0; self.vy = 0; self.damage = 14; self.update = function () { if (self.lastX === undefined) self.lastX = self.x; if (self.lastY === undefined) self.lastY = self.y; self.x += self.vx; self.y += self.vy; self.lastX = self.x; self.lastY = self.y; }; return self; }); // Enemy soldier (Araba) var EnemyCar = Container.expand(function () { var self = Container.call(this); var body = self.attachAsset('enemyCar', { anchorX: 0.5, anchorY: 1 }); self.hp = 50; self.maxHp = 50; self.atk = 20; self.speed = 5; self.hpBar = self.addChild(new HealthBar()); self.hpBar.y = -60; self.hpBar.set(1); self.update = function () { self.x -= self.speed; }; return self; }); // Enemy Car Bullet var EnemyCarBullet = Container.expand(function () { var self = Container.call(this); var bullet = self.attachAsset('enemyCarBullet', { anchorX: 0.5, anchorY: 0.5 }); self.vx = 0; self.vy = 0; self.damage = 20; self.update = function () { if (self.lastX === undefined) self.lastX = self.x; if (self.lastY === undefined) self.lastY = self.y; self.x += self.vx; self.y += self.vy; self.lastX = self.x; self.lastY = self.y; }; return self; }); // Enemy soldier (Mermi sıkan) var EnemyGunner = Container.expand(function () { var self = Container.call(this); var body = self.attachAsset('enemySoldier2', { anchorX: 0.5, anchorY: 1 }); self.hp = 30; self.maxHp = 30; self.atk = 14; self.speed = 3.5; self.hpBar = self.addChild(new HealthBar()); self.hpBar.y = -90; self.hpBar.set(1); self.update = function () { self.x -= self.speed; // --- EnemyGunner Firing Logic --- if (!self.fireTimer) self.fireTimer = 0; self.fireTimer++; var fireInterval = 60; if (self.fireTimer >= fireInterval) { // Find closest player soldier, else aim at anaBase var target = null; var minDist = 99999; if (typeof playerSoldiers !== "undefined") { for (var ps = 0; ps < playerSoldiers.length; ps++) { var p = playerSoldiers[ps]; var dx = p.x - self.x; var dy = p.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < minDist) { minDist = dist; target = p; } } } if (!target && typeof anaBase !== "undefined") { target = anaBase; } if (target) { var b = new EnemyBullet(); b.x = self.x; b.y = self.y - 70; var tx = target.x; var ty = target.y; var dx = tx - b.x; var dy = ty - b.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist === 0) dist = 1; b.vx = dx / dist * 18; b.vy = dy / dist * 18; b.damage = self.atk || 14; if (typeof enemyBullets !== "undefined" && typeof game !== "undefined") { enemyBullets.push(b); game.addChild(b); } self.fireTimer = 0; } } }; return self; }); // Enemy soldier (Jet) var EnemyJet = Container.expand(function () { var self = Container.call(this); var body = self.attachAsset('enemyJet', { anchorX: 0.5, anchorY: 1 }); self.hp = 80; self.maxHp = 80; self.atk = 60; self.speed = 8; self.hpBar = self.addChild(new HealthBar()); self.hpBar.y = -40; self.hpBar.set(1); self.update = function () { self.x -= self.speed; }; return self; }); // Enemy Jet Missile var EnemyJetMissile = Container.expand(function () { var self = Container.call(this); var missile = self.attachAsset('enemyJetMissile', { anchorX: 0.5, anchorY: 0.5 }); self.vx = 0; self.vy = 0; self.damage = 60; self.update = function () { if (self.lastX === undefined) self.lastX = self.x; if (self.lastY === undefined) self.lastY = self.y; self.x += self.vx; self.y += self.vy; self.lastX = self.x; self.lastY = self.y; }; return self; }); // Enemy StoneThrower Bullet var EnemyStone = Container.expand(function () { var self = Container.call(this); var stone = self.attachAsset('enemyStone', { anchorX: 0.5, anchorY: 0.5 }); self.vx = 0; self.vy = 0; self.damage = 10; self.update = function () { if (self.lastX === undefined) self.lastX = self.x; if (self.lastY === undefined) self.lastY = self.y; self.x += self.vx; self.y += self.vy; self.lastX = self.x; self.lastY = self.y; }; return self; }); // Enemy soldier (Taş atan) var EnemyStoneThrower = Container.expand(function () { var self = Container.call(this); var body = self.attachAsset('enemySoldier1', { anchorX: 0.5, anchorY: 1 }); self.hp = 20; self.maxHp = 20; self.atk = 8; self.speed = 3; self.hpBar = self.addChild(new HealthBar()); self.hpBar.y = -80; self.hpBar.set(1); self.update = function () { self.x -= self.speed; }; return self; }); // Enemy soldier (Tank) var EnemyTank = Container.expand(function () { var self = Container.call(this); var body = self.attachAsset('enemyTank', { anchorX: 0.5, anchorY: 1 }); self.hp = 120; self.maxHp = 120; self.atk = 40; self.speed = 2.2; self.hpBar = self.addChild(new HealthBar()); self.hpBar.y = -70; self.hpBar.set(1); self.update = function () { self.x -= self.speed; }; return self; }); // Enemy Tank Shell var EnemyTankShell = Container.expand(function () { var self = Container.call(this); var shell = self.attachAsset('enemyTankShell', { anchorX: 0.5, anchorY: 0.5 }); self.vx = 0; self.vy = 0; self.damage = 40; self.update = function () { if (self.lastX === undefined) self.lastX = self.x; if (self.lastY === undefined) self.lastY = self.y; self.x += self.vx; self.y += self.vy; self.lastX = self.x; self.lastY = self.y; }; return self; }); // FireEffect animation (short-lived fire burst) var FireEffect = Container.expand(function () { var self = Container.call(this); // Use fireBurst image as fire burst var fire = self.attachAsset('fireBurst', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7 + Math.random() * 0.5, scaleY: 0.7 + Math.random() * 0.5, alpha: 0.85 }); // Animate: scale up and fade out quickly var duration = 320 + Math.random() * 120; tween(self, { scaleX: fire.scaleX * 1.5, scaleY: fire.scaleY * 1.5, alpha: 0 }, { duration: duration, easing: tween.easeOut, onComplete: function onComplete() { self.destroy(); } }); return self; }); // HealthBar class for bases and soldiers var HealthBar = Container.expand(function () { var self = Container.call(this); var bg = self.attachAsset('hpBarBg', { anchorX: 0.5, anchorY: 0.5 }); var fg = self.attachAsset('hpBarFg', { anchorX: 0.5, anchorY: 0.5 }); self.set = function (percent) { if (percent < 0) percent = 0; if (percent > 1) percent = 1; fg.width = 120 * percent; }; return self; }); // Player soldier bullet var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bullet = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); self.vx = 0; self.vy = 0; self.damage = 12; self.update = function () { if (self.lastX === undefined) self.lastX = self.x; if (self.lastY === undefined) self.lastY = self.y; self.x += self.vx; self.y += self.vy; self.lastX = self.x; self.lastY = self.y; }; return self; }); // Player soldier var PlayerSoldier = Container.expand(function () { var self = Container.call(this); var body = self.attachAsset('playerSoldier', { anchorX: 0.5, anchorY: 1 }); self.hp = 20; self.maxHp = 20; self.atk = 8; self.speed = 3; self.hpBar = self.addChild(new HealthBar()); self.hpBar.y = -80; self.hpBar.set(1); self.update = function () { self.x += self.speed; }; return self; }); // Slingshot (player control) var Slingshot = Container.expand(function () { var self = Container.call(this); var sling = self.attachAsset('slingshot', { anchorX: 0.5, anchorY: 1 }); sling.x -= GAME_WIDTH * 0.03; sling.y += GAME_HEIGHT * 0.05; self.stoneReady = true; self.stone = null; self.aimLine = null; self.aimStart = { x: 0, y: 0 }; self.aimEnd = { x: 0, y: 0 }; return self; }); // Stone (slingshot projectile) var Stone = Container.expand(function () { var self = Container.call(this); var stone = self.attachAsset('stone', { anchorX: 0.5, anchorY: 0.5 }); self.vx = 0; self.vy = 0; self.damage = 20; self.update = function () { // Gravity effect if (self.lastY === undefined) self.lastY = self.y; if (self.lastVy === undefined) self.lastVy = self.vy; var gravity = 2.2 * 0.5 * 0.9; // %50 azaltıldı, ardından %10 daha azaltıldı self.vy += gravity; self.x += self.vx; self.y += self.vy; self.lastY = self.y; self.lastVy = self.vy; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xf7f7f7 }); /**** * Game Code ****/ // Music icon image asset (80x80, transparent background, music note icon) // Ateş efekti için özel resim dosyası // Arkaplan resmi (2048x2732, tam ekran) // Savaş uçağı // Tank // Araba // Mermi sıkan // Taş atan // Health bar foreground // Health bar background // Slingshot // Stone (slingshot projectile) // Enemy soldier // Player soldier // EnemyBase (enemy base) // AnaBase (player base) // --- Arkaplan resmi ekle --- var backgroundImg = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChild(backgroundImg); // Game constants // StoneThrower bullet // Gunner bullet // Car bullet // Tank shell // Jet missile var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var BASE_OFFSET_X = 220; var BASE_OFFSET_Y = 200; var GROUND_Y = GAME_HEIGHT - 300; var SLING_X = BASE_OFFSET_X; var SLING_Y = GROUND_Y - 110; var ENEMY_BASE_X = GAME_WIDTH - BASE_OFFSET_X; var ENEMY_BASE_Y = GROUND_Y; var MAX_LEVEL = 50; // Game state // Game state var anaBase, enemyBase, slingshot; var playerSoldiers = []; var enemySoldiers = []; var stones = []; var enemyBullets = []; // All enemy bullets (all types) var playerBullets = []; // All player bullets var level = storage.level || 1; var score = storage.score || 0; var upgradePoints = storage.upgradePoints || 0; // --- Freeze logic for firing phase --- var freezeAllSoldiers = false; var freezeWho = null; // "player" or "enemy" or null function isFiringPhase() { // If there are any playerBullets or enemyBullets, or stones, freeze all soldiers // But only if both sides still have soldiers var playerAlive = playerSoldiers.length > 0; var enemyAlive = enemySoldiers.length > 0; var firingObjects = playerBullets.length > 0 || enemyBullets.length > 0 || stones.length > 0; return firingObjects && playerAlive && enemyAlive; } var isDraggingSling = false; var dragStart = { x: 0, y: 0 }; var dragEnd = { x: 0, y: 0 }; var lastTouchId = null; var spawnTimers = { player: 0, enemy: 0 }; var enemySpawnInterval = 120; var playerSpawnInterval = 120; var enemySoldierStats = { hp: 20, atk: 8, speed: 3 }; var playerSoldierStats = { hp: 20, atk: 9.6, speed: 3 }; var enemyBaseStats = { hp: 100 }; var anaBaseStats = { hp: 130 }; var levelTxt, scoreTxt, upgradeTxt; // UI levelTxt = new Text2('Level: ' + level, { size: 80, fill: "#fff", shadow: true, shadowColor: "#222", shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 2 }); levelTxt.anchor.set(0.5, 0); // Add Reset button to the left of levelTxt var resetBtn = new Text2('Reset', { size: 70, fill: "#fff", shadow: true, shadowColor: "#222", shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 2 }); resetBtn.anchor.set(0.5, 0); resetBtn.x = -260 - GAME_WIDTH * 0.05; // Shifted 5% to the left resetBtn.y = 0; levelTxt.addChild(resetBtn); // Reset handler resetBtn.interactive = true; resetBtn.buttonMode = true; resetBtn.down = function (x, y, obj) { // Reset all game state level = 1; score = 0; upgradePoints = 0; enemyBaseStats.hp = 100; anaBaseStats.hp = 130; playerSoldierStats.hp = 20; playerSoldierStats.atk = 9.6; playerSoldierStats.speed = 3; enemySoldierStats.hp = 20; enemySoldierStats.atk = 8; enemySoldierStats.speed = 3; enemySpawnInterval = 120; playerSpawnInterval = 120; // Remove all soldiers and stones for (var i = 0; i < playerSoldiers.length; i++) playerSoldiers[i].destroy(); for (var i = 0; i < enemySoldiers.length; i++) enemySoldiers[i].destroy(); for (var i = 0; i < stones.length; i++) stones[i].destroy(); playerSoldiers = []; enemySoldiers = []; stones = []; // Reset bases anaBase.hp = anaBaseStats.hp; anaBase.maxHp = anaBaseStats.hp; enemyBase.hp = enemyBaseStats.hp; enemyBase.maxHp = enemyBaseStats.hp; // Save progress storage.level = level; storage.score = score; storage.upgradePoints = upgradePoints; // Update UI immediately levelTxt.setText('Level: ' + level); scoreTxt.setText('Score: ' + score); anaBase.hpBar.set(anaBase.hp / anaBase.maxHp); enemyBase.hpBar.set(enemyBase.hp / enemyBase.maxHp); showUpgradeMsg("Game Reset!"); }; LK.gui.top.addChild(levelTxt); scoreTxt = new Text2('Score: ' + score, { size: 80, fill: "#fff", shadow: true, shadowColor: "#222", shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 2 }); scoreTxt.anchor.set(0.5, 0); scoreTxt.x = GAME_WIDTH * 0.25; // Shifted 25% to the right LK.gui.top.addChild(scoreTxt); upgradeTxt = new Text2('', { size: 60, fill: "#fff", shadow: true, shadowColor: "#222", shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 2 }); upgradeTxt.anchor.set(0.5, 0); LK.gui.bottom.addChild(upgradeTxt); // --- 10 Upgrade Features UI --- var upgradeFeatures = [{ name: "AnaBase HP +20", cost: Math.round(30 * 1.2), apply: function apply() { anaBaseStats.hp += 20; anaBase.maxHp = anaBaseStats.hp; anaBase.hp = anaBaseStats.hp; } }, { name: "Soldier HP +6", cost: Math.round(20 * 1.2), apply: function apply() { playerSoldierStats.hp += 6; } }, { name: "Soldier Atk +2", cost: Math.round(20 * 1.2), apply: function apply() { playerSoldierStats.atk += 2; } }, { name: "Soldier Speed +0.5", cost: Math.round(20 * 1.2), apply: function apply() { playerSoldierStats.speed += 0.5; } }, { name: "Enemy Soldier HP -4", cost: Math.round(25 * 1.2), apply: function apply() { enemySoldierStats.hp = Math.max(4, enemySoldierStats.hp - 4); } }, { name: "Enemy Soldier Atk -1", cost: Math.round(25 * 1.2), apply: function apply() { enemySoldierStats.atk = Math.max(1, enemySoldierStats.atk - 1); } }, { name: "Slingshot Stone Dmg +5", cost: Math.round(20 * 1.2), apply: function apply() { Stone.prototype.damage = (Stone.prototype.damage || 20) + 5; } }, { name: "Slingshot Stone Speed +4", cost: Math.round(20 * 1.2), apply: function apply() { _fireStone.stoneSpeed = (_fireStone.stoneSpeed || 32) + 4; } }, { name: "Soldier Limit +1", cost: Math.round(40 * 1.2), apply: function apply() { if (!game.maxPlayerSoldiers) game.maxPlayerSoldiers = 6; game.maxPlayerSoldiers++; } }, { name: "Base HP Restore +10", cost: Math.round(30 * 1.2), apply: function apply() { anaBase.hp = Math.min(anaBase.maxHp, anaBase.hp + 10); } }, // --- NEW UPGRADE FEATURES --- { name: "Faster Soldier Spawn", cost: Math.round(50 * 1.2), apply: function apply() { playerSpawnInterval = Math.max(30, playerSpawnInterval - 10); } }, { name: "Faster Enemy Spawn (for challenge!)", cost: Math.round(40 * 1.2), apply: function apply() { enemySpawnInterval = Math.max(30, enemySpawnInterval - 10); } }, { name: "Stone Gravity -10%", cost: Math.round(35 * 1.2), apply: function apply() { if (!Stone.prototype.gravity) Stone.prototype.gravity = 2.2 * 0.5 * 0.9; Stone.prototype.gravity *= 0.9; } }]; // Track upgrades purchased and levels var upgradesPurchased = []; var upgradesLevel = []; // new: track level for each upgrade for (var i = 0; i < 10; i++) { upgradesPurchased[i] = 0; upgradesLevel[i] = 0; } // UI: Create upgrade buttons below the reset button, aligned to the left edge var upgradeButtons = []; var musicOn = true; var musicIcon = LK.getAsset('musicIcon', { width: 80, height: 80, anchorX: 0.5, anchorY: 0, x: resetBtn.x, y: resetBtn.y + resetBtn.height + 40 // Reset butonunun 2 satır altı }); musicIcon.interactive = true; musicIcon.buttonMode = true; musicIcon.tint = 0x00ccff; // Açık mavi: müzik açık musicIcon.down = function (x, y, obj) { musicOn = !musicOn; if (musicOn) { LK.playMusic('Backgroundmusic'); musicIcon.tint = 0x00ccff; } else { LK.stopMusic(); musicIcon.tint = 0x888888; } }; LK.gui.top.addChild(musicIcon); // --- How to play? button and popup --- var howToPlayBtn = new Text2('How to play?', { size: 54, fill: "#fff", shadow: true, shadowColor: "#222", shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 2 }); howToPlayBtn.anchor.set(0.5, 0); howToPlayBtn.x = musicIcon.x; howToPlayBtn.y = musicIcon.y + musicIcon.height + 18; howToPlayBtn.interactive = true; howToPlayBtn.buttonMode = true; var howToPlayPopup = null; howToPlayBtn.down = function (x, y, obj) { if (howToPlayPopup) { howToPlayPopup.destroy(); howToPlayPopup = null; return; } // Create popup container howToPlayPopup = new Container(); // Background // Dynamically size the background to fit the content var popupContentWidth = 1200; var popupContentHeight = 900; // Calculate content bounds (title + info + closeBtn) var titleHeight = 120; var infoHeight = 480; var closeBtnHeight = 100; var verticalPadding = 120; popupContentHeight = titleHeight + infoHeight + closeBtnHeight + verticalPadding; // Increase background height by 30% popupContentHeight = Math.round(popupContentHeight * 1.3); popupContentWidth = 1200; var popupBg = LK.getAsset('hpBarBg', { width: popupContentWidth, height: popupContentHeight, anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_HEIGHT / 2, tint: 0x222222, alpha: 0.98 }); howToPlayPopup.addChild(popupBg); // Title var title = new Text2('How to Play', { size: 90, fill: "#fff", shadow: true, shadowColor: "#222", shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 2 }); title.anchor.set(0.5, 0); title.x = GAME_WIDTH / 2; title.y = GAME_HEIGHT / 2 - popupContentHeight / 2 + 40; howToPlayPopup.addChild(title); // Instructions var info = new Text2("Defend your base and defeat the enemy!\n\n" + "- Drag the slingshot to launch stones at enemies and the enemy base.\n" + "- Tap the bottom left to spawn your soldiers (max 6).\n" + "- Your soldiers will automatically move and attack.\n" + "- Upgrade your base and soldiers using your score points.\n" + "- Defeat all enemy soldiers and destroy the enemy base to win the level.\n" + "- If your base is destroyed, you lose!\n\n" + "Good luck, Commander!", { size: 54, fill: "#fff", wordWrap: true, wordWrapWidth: 1100, align: "left", shadow: true, shadowColor: "#222", shadowBlur: 6, shadowOffsetX: 2, shadowOffsetY: 2 }); info.anchor.set(0.5, 0); info.x = GAME_WIDTH / 2; info.y = title.y + title.height + 40; howToPlayPopup.addChild(info); // Close button var closeBtn = new Text2('Close', { size: 60, fill: "#fff", shadow: true, shadowColor: "#222", shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 2 }); closeBtn.anchor.set(0.5, 0); // Place close button at the bottom center of the background closeBtn.x = GAME_WIDTH / 2; closeBtn.y = GAME_HEIGHT / 2 + popupContentHeight / 2 - closeBtn.height - 40; closeBtn.interactive = true; closeBtn.buttonMode = true; closeBtn.down = function (x, y, obj) { if (howToPlayPopup) { howToPlayPopup.destroy(); howToPlayPopup = null; } }; howToPlayPopup.addChild(closeBtn); game.addChild(howToPlayPopup); }; LK.gui.top.addChild(howToPlayBtn); var upgradeStartY = resetBtn.y + resetBtn.height + 20; // Reset butonunun hemen altına hizala var upgradeLeftX = 0; // Tam sol kenara hizalı (platform menüsüne çakışmaz, 0'dan başlat) // Upgrade feature buttons are hidden from the main screen UI as requested. // Patch fireStone to use upgradeable speed var origFireStone = _fireStone; _fireStone = function fireStone(fromX, fromY, toX, toY) { var s = new Stone(); s.x = fromX; s.y = fromY; var dx = fromX - toX; var dy = fromY - toY; var dist = Math.sqrt(dx * dx + dy * dy); var speed = _fireStone.stoneSpeed || 32; s.vx = dx / dist * speed; s.vy = dy / dist * speed; // Patch damage if upgraded if (typeof Stone.prototype.damage === "number") s.damage = Stone.prototype.damage; stones.push(s); game.addChild(s); }; // Start background music by default LK.playMusic('Backgroundmusic'); // Add bases anaBase = new AnaBase(); anaBase.x = BASE_OFFSET_X; anaBase.y = GROUND_Y; game.addChild(anaBase); enemyBase = new EnemyBase(); enemyBase.x = ENEMY_BASE_X; enemyBase.y = ENEMY_BASE_Y; game.addChild(enemyBase); // Add slingshot slingshot = new Slingshot(); slingshot.x = SLING_X; slingshot.y = SLING_Y; game.addChild(slingshot); // --- Store button and popup --- var storeBtn = new Text2('Store', { size: 84, // 70 (resetBtn) * 1.2 = 84 fill: "#fff", shadow: true, shadowColor: "#222", shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 2 }); storeBtn.anchor.set(0.5, 1); // Place 3 lines (approx 3x 60px) above slingshot storeBtn.x = slingshot.x; storeBtn.y = slingshot.y - 236 - 60 * 3; // slingshot.height + 3 lines above storeBtn.interactive = true; storeBtn.buttonMode = true; var storePopup = null; storeBtn.down = function (x, y, obj) { if (storePopup) { storePopup.destroy(); storePopup = null; return; } // Create popup container storePopup = new Container(); // Background var popupContentWidth = 1200 * 0.9; var popupContentHeight = 900 * 0.9; var titleHeight = 120 * 0.9; var btnHeight = 80 * 0.9; var btnSpacing = 24; // vertical space between buttons var infoHeight = (btnHeight + btnSpacing) * upgradeFeatures.length; var closeBtnHeight = 100 * 0.9; var verticalPadding = 120 * 0.9; popupContentHeight = titleHeight + infoHeight + closeBtnHeight + verticalPadding; popupContentHeight = Math.round(popupContentHeight * 1.2); var popupBg = LK.getAsset('hpBarBg', { width: popupContentWidth, height: popupContentHeight, anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_HEIGHT / 2, tint: 0x222222, alpha: 0.98 }); storePopup.addChild(popupBg); // Title var title = new Text2('Store', { size: 108 * 0.9 * 0.95 * 0.95 * 0.95, fill: "#fff", shadow: true, shadowColor: "#222", shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 2 }); title.anchor.set(0.5, 0); title.x = GAME_WIDTH / 2; title.y = GAME_HEIGHT / 2 - popupContentHeight / 2 + 40 * 0.9; storePopup.addChild(title); // Upgrade buttons (centered, evenly spaced) var startY = title.y + title.height + 40 * 0.9; var btnWidth = popupContentWidth * 0.82; for (var i = 0; i < upgradeFeatures.length; i++) { (function (idx) { var upg = upgradeFeatures[idx]; var btnLevel = typeof upgradesLevel[idx] === "number" ? upgradesLevel[idx] : 0; var btnFontSize = 84 * 0.9 * 0.95 * 0.95 * 0.95; var btnWordWrap = false; var btnWordWrapWidth = btnWidth; if (upg.name.indexOf("Faster Enemy Spawn") !== -1) { btnFontSize = btnFontSize * 0.75; // Further reduce font size to fit panel btnWordWrap = false; // Prevent line wrapping btnWordWrapWidth = btnWidth; // Use full width, but no wrap } var btn = new Text2("Lv. " + btnLevel + " " + upg.name + " (" + upg.cost + ")", { size: btnFontSize, fill: "#fff", shadow: true, shadowColor: "#222", shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 2, wordWrap: btnWordWrap, wordWrapWidth: btnWordWrapWidth, align: "center" }); btn.anchor.set(0.5, 0); btn.x = GAME_WIDTH / 2; btn.y = startY + idx * (btnHeight + btnSpacing); btn.interactive = true; btn.buttonMode = true; btn.down = function (x, y, obj) { if (score >= upg.cost) { score -= upg.cost; upg.apply(); upgradesLevel[idx] = (upgradesLevel[idx] || 0) + 1; upgradesPurchased[idx] = 1; upg.cost = upg.cost * 2; btn.setText("Lv. " + upgradesLevel[idx] + " " + upg.name + " (" + upg.cost + ")"); if (upgradeButtons[idx]) { upgradeButtons[idx].setText("Lv. " + upgradesLevel[idx] + " " + upg.name + " (" + upg.cost + ")"); } showUpgradeMsg(upg.name + " level " + upgradesLevel[idx] + "!"); scoreTxt.setText('Score: ' + score); storage.score = score; } else { showUpgradeMsg("Not enough points!"); } }; storePopup.addChild(btn); })(i); } // Close button var closeBtn = new Text2('Close', { size: 60, fill: "#fff", shadow: true, shadowColor: "#222", shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 2 }); closeBtn.anchor.set(0.5, 0); closeBtn.x = GAME_WIDTH / 2; closeBtn.y = GAME_HEIGHT / 2 + popupContentHeight / 2 - closeBtn.height - 40 * 0.9; closeBtn.interactive = true; closeBtn.buttonMode = true; closeBtn.down = function (x, y, obj) { if (storePopup) { storePopup.destroy(); storePopup = null; } }; storePopup.addChild(closeBtn); game.addChild(storePopup); }; game.addChild(storeBtn); // Helper: spawn player soldier function spawnPlayerSoldier() { var s = new PlayerSoldier(); s.hp = playerSoldierStats.hp; s.maxHp = playerSoldierStats.hp; s.atk = playerSoldierStats.atk; s.speed = playerSoldierStats.speed; s.x = anaBase.x + 100; s.y = GROUND_Y + 10; playerSoldiers.push(s); game.addChild(s); } // Helper: spawn enemy soldier function spawnEnemySoldier() { var s; // 1-4: StoneThrower, 5-10: Gunner, 11-15: Car, 16-20: Tank, 21-30: Jet if (level >= 1 && level <= 4) { s = new EnemyStoneThrower(); } else if (level >= 5 && level <= 10) { s = new EnemyGunner(); } else if (level >= 11 && level <= 15) { s = new EnemyCar(); } else if (level >= 16 && level <= 20) { s = new EnemyTank(); } else if (level >= 21 && level < 50) { // Randomly pick one of the enemy types for levels 21-49 var enemyTypes = [EnemyStoneThrower, EnemyGunner, EnemyCar, EnemyTank, EnemyJet]; var idx = Math.floor(Math.random() * enemyTypes.length); s = new enemyTypes[idx](); } else if (level === 50) { // Final level: only Jet for extra challenge s = new EnemyJet(); } else { s = new EnemyStoneThrower(); } s.x = enemyBase.x - 100; s.y = GROUND_Y + 10; enemySoldiers.push(s); game.addChild(s); } // Helper: fire stone function _fireStone(fromX, fromY, toX, toY) { var s = new Stone(); s.x = fromX; s.y = fromY; // Atış yönünü tersine çevir: sapanı geriye çek, taş ileri fırlasın var dx = fromX - toX; var dy = fromY - toY; var dist = Math.sqrt(dx * dx + dy * dy); var speed = 32; // Daha yavaş gitmesi için azaltıldı s.vx = dx / dist * speed; s.vy = dy / dist * speed; stones.push(s); game.addChild(s); } // Helper: show upgrade message function showUpgradeMsg(msg) { upgradeTxt.setText(msg); tween(upgradeTxt, { alpha: 1 }, { duration: 0 }); tween(upgradeTxt, { alpha: 0 }, { duration: 1200, easing: tween.easeOut }); } // Touch/drag logic for slingshot game.down = function (x, y, obj) { // Only allow drag if touch is near slingshot if (Math.abs(x - slingshot.x) < 120 && Math.abs(y - slingshot.y) < 160) { isDraggingSling = true; dragStart.x = x; dragStart.y = y; dragEnd.x = x; dragEnd.y = y; } }; game.move = function (x, y, obj) { if (isDraggingSling) { dragEnd.x = x; dragEnd.y = y; } }; game.up = function (x, y, obj) { if (isDraggingSling) { // Fire stone if drag is long enough var dx = dragEnd.x - slingshot.x; var dy = dragEnd.y - slingshot.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 80 && stones.length < 2) { _fireStone(slingshot.x, slingshot.y - 60, dragEnd.x, dragEnd.y); // fireStone fonksiyonu artık ters vektörle çalışıyor } } isDraggingSling = false; }; // Tap to spawn player soldier (bottom left, not on slingshot) game.on('down', function (x, y, obj) { if (x < 300 && y > GROUND_Y + 60) { if (playerSoldiers.length < 6) { spawnPlayerSoldier(); } } }); // Upgrade logic (tap bottom right) game.on('down', function (x, y, obj) { if (x > GAME_WIDTH - 300 && y > GROUND_Y + 60) { if (upgradePoints > 0) { // Cycle upgrades: base hp, soldier hp, soldier atk, soldier speed var upg = (score + level) % 4; if (upg === 0) { anaBaseStats.hp += 20; anaBase.maxHp = anaBaseStats.hp; anaBase.hp = anaBaseStats.hp; showUpgradeMsg("AnaBase HP +20"); } else if (upg === 1) { playerSoldierStats.hp += 6; showUpgradeMsg("Soldier HP +6"); } else if (upg === 2) { playerSoldierStats.atk += 2; showUpgradeMsg("Soldier Atk +2"); } else { playerSoldierStats.speed += 0.5; showUpgradeMsg("Soldier Speed +0.5"); } upgradePoints--; } } }); // Main update loop game.update = function () { // Update UI levelTxt.setText('Level: ' + level); scoreTxt.setText('Score: ' + score); // Update health bars anaBase.hpBar.set(anaBase.hp / anaBase.maxHp); enemyBase.hpBar.set(enemyBase.hp / enemyBase.maxHp); // Draw slingshot pulled band and stone visual if (isDraggingSling) { // Remove previous drag visuals if any if (slingshot.dragStone) { slingshot.dragStone.destroy(); slingshot.dragStone = null; } if (slingshot.bandLeft) { slingshot.bandLeft.destroy(); slingshot.bandLeft = null; } if (slingshot.bandRight) { slingshot.bandRight.destroy(); slingshot.bandRight = null; } // Calculate band anchor points (left/right of slingshot top) var slingTopX = slingshot.x; var slingTopY = slingshot.y - 110; var bandOffset = 22; var leftX = slingTopX - bandOffset; var rightX = slingTopX + bandOffset; var bandY = slingTopY + 10; // Place a thin rectangle as band (left) slingshot.bandLeft = LK.getAsset('hpBarFg', { width: Math.max(8, Math.sqrt((dragEnd.x - leftX) * (dragEnd.x - leftX) + (dragEnd.y - bandY) * (dragEnd.y - bandY))), height: 8, anchorX: 0, anchorY: 0.5, x: leftX, y: bandY, rotation: Math.atan2(dragEnd.y - bandY, dragEnd.x - leftX) }); game.addChild(slingshot.bandLeft); // Place a thin rectangle as band (right) slingshot.bandRight = LK.getAsset('hpBarFg', { width: Math.max(8, Math.sqrt((dragEnd.x - rightX) * (dragEnd.x - rightX) + (dragEnd.y - bandY) * (dragEnd.y - bandY))), height: 8, anchorX: 0, anchorY: 0.5, x: rightX, y: bandY, rotation: Math.atan2(dragEnd.y - bandY, dragEnd.x - rightX) }); game.addChild(slingshot.bandRight); // Place the stone at dragEnd slingshot.dragStone = LK.getAsset('stone', { anchorX: 0.5, anchorY: 0.5, x: dragEnd.x, y: dragEnd.y }); game.addChild(slingshot.dragStone); } else { // Remove drag visuals if not dragging if (slingshot.dragStone) { slingshot.dragStone.destroy(); slingshot.dragStone = null; } if (slingshot.bandLeft) { slingshot.bandLeft.destroy(); slingshot.bandLeft = null; } if (slingshot.bandRight) { slingshot.bandRight.destroy(); slingshot.bandRight = null; } } // Spawn player soldiers automatically spawnTimers.player++; if (spawnTimers.player >= playerSpawnInterval) { if (playerSoldiers.length < 6) { spawnPlayerSoldier(); } spawnTimers.player = 0; } // Spawn enemy soldiers automatically spawnTimers.enemy++; if (spawnTimers.enemy >= enemySpawnInterval) { if (enemySoldiers.length < 6) { spawnEnemySoldier(); } spawnTimers.enemy = 0; } // --- Freeze logic: check if firing phase is active --- freezeAllSoldiers = isFiringPhase(); // Update player soldiers for (var i = playerSoldiers.length - 1; i >= 0; i--) { var s = playerSoldiers[i]; // --- Freeze all player soldiers if firing phase is active --- if (freezeAllSoldiers) { // No movement, no firing, no attacking base, but still allow dying from bullets continue; } // Asker dondurma: eğer bir düşmanla çarpışıyorsa hareket etmesin var frozen = false; for (var j = enemySoldiers.length - 1; j >= 0; j--) { var e = enemySoldiers[j]; if (Math.abs(s.x - e.x) < 80 && Math.abs(s.y - e.y) < 60) { // Fight! s.hp -= e.atk * 0.03; e.hp -= s.atk * 0.03; s.hpBar.set(s.hp / s.maxHp); e.hpBar.set(e.hp / e.maxHp); frozen = true; if (e.hp <= 0) { score += 10; enemySoldiers.splice(j, 1); e.destroy(); } if (s.hp <= 0) { playerSoldiers.splice(i, 1); s.destroy(); break; } // Eğer ikisi de hayattaysa, dondurulmuş kalmaya devam etsin if (s.hp > 0 && e.hp > 0) { frozen = true; } } } // Hareketi engelle: Eğer çarpışıyorsa update çağrılmasın, çarpışmıyorsa hareket etsin if (!frozen) { // Çarpışma kontrolü: Önümüzde bir düşman var mı? var blocked = false; // Önce kendi askerlerimizi kontrol et, öndekiyle çakışıyorsak ilerleme for (var j = 0; j < playerSoldiers.length; j++) { var s2 = playerSoldiers[j]; if (s2 === s) continue; if (Math.abs(s.y - s2.y) < 60 && s2.x > s.x && s2.x - s.x < 80 && s2.x - s.x > 0 // 80px mesafeden yakınsa ) { blocked = true; break; } } // Sonra düşman askerlerini kontrol et if (!blocked) { for (var j = 0; j < enemySoldiers.length; j++) { var e = enemySoldiers[j]; if (e === s) continue; // Sadece ileriye doğru olan ve çakışan askerleri engelle if (Math.abs(s.y - e.y) < 60 && e.x > s.x && // Sadece önündeki düşman e.x - s.x < 80 && e.x - s.x > 0 // 80px mesafeden yakınsa ) { blocked = true; break; } } } if (!blocked) { s.update(); // Clamp to not go past enemy base if (s.x > enemyBase.x - 120) s.x = enemyBase.x - 120; // --- Player Firing Logic --- if (!s.fireTimer) s.fireTimer = 0; s.fireTimer++; var fireInterval = 60; if (s.fireTimer >= fireInterval) { // En yakın düşman askeri bul, yoksa enemyBase'e ateş et var target = null; var minDist = 99999; for (var es = 0; es < enemySoldiers.length; es++) { var e = enemySoldiers[es]; var dx = e.x - s.x; var dy = e.y - s.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < minDist) { minDist = dist; target = e; } } if (!target) { target = enemyBase; } // Mermi oluştur ve ateşle var b = new PlayerBullet(); b.x = s.x; b.y = s.y - 70 - GAME_HEIGHT * 0.05; // %5 yukarı kaldırıldı // Hedefe yönel var tx = target.x; var ty = target.y; var dx = tx - b.x; var dy = ty - b.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist === 0) dist = 1; b.vx = dx / dist * 22; b.vy = dy / dist * 22; b.damage = s.atk || 8; playerBullets.push(b); game.addChild(b); s.fireTimer = 0; } } } // If at enemy base, attack base if (s.lastAtEnemyBase === undefined) s.lastAtEnemyBase = false; var atEnemyBase = Math.abs(s.x - enemyBase.x) < 120; if (!s.lastAtEnemyBase && atEnemyBase) { // Just arrived at enemy base s.attackedBase = false; } if (!s.attackedBase && atEnemyBase) { enemyBase.hp -= s.atk * 0.15; if (enemyBase.hp < 0) enemyBase.hp = 0; s.attackedBase = true; } s.lastAtEnemyBase = atEnemyBase; } // Update enemy soldiers for (var i = enemySoldiers.length - 1; i >= 0; i--) { var e = enemySoldiers[i]; // --- Freeze all enemy soldiers if firing phase is active --- if (freezeAllSoldiers) { // No movement, no firing, no attacking base, but still allow dying from bullets continue; } // Asker dondurma: eğer bir oyuncu askeriyle çarpışıyorsa hareket etmesin var frozen = false; for (var j = playerSoldiers.length - 1; j >= 0; j--) { var s = playerSoldiers[j]; if (Math.abs(e.x - s.x) < 80 && Math.abs(e.y - s.y) < 60) { // Fight! e.hp -= s.atk * 0.03; s.hp -= e.atk * 0.03; e.hpBar.set(e.hp / e.maxHp); s.hpBar.set(s.hp / s.maxHp); frozen = true; if (s.hp <= 0) { playerSoldiers.splice(j, 1); s.destroy(); } if (e.hp <= 0) { score += 10; enemySoldiers.splice(i, 1); e.destroy(); break; } // Eğer ikisi de hayattaysa, dondurulmuş kalmaya devam etsin if (e.hp > 0 && s.hp > 0) { frozen = true; } } } // Hareketi engelle: Eğer çarpışıyorsa update çağrılmasın, çarpışmıyorsa hareket etsin if (!frozen) { // Çarpışma kontrolü: Önümüzde bir oyuncu askeri var mı? var blocked = false; // Önce kendi düşman askerlerini kontrol et, öndekiyle çakışıyorsak ilerleme for (var j = 0; j < enemySoldiers.length; j++) { var e2 = enemySoldiers[j]; if (e2 === e) continue; if (Math.abs(e.y - e2.y) < 60 && e2.x < e.x && e.x - e2.x < 80 && e.x - e2.x > 0 // 80px mesafeden yakınsa ) { blocked = true; break; } } // Sonra oyuncu askerlerini kontrol et if (!blocked) { for (var j = 0; j < playerSoldiers.length; j++) { var s = playerSoldiers[j]; if (Math.abs(e.y - s.y) < 60 && s.x > e.x && s.x - e.x < 80 && s.x - e.x > 0 // 80px mesafeden yakınsa ) { blocked = true; break; } } } if (!blocked) { e.update(); // Clamp to not go past anaBase if (e.x < anaBase.x + 120) e.x = anaBase.x + 120; } // --- Enemy Firing Logic --- if (!e.fireTimer) e.fireTimer = 0; e.fireTimer++; var fireInterval = 90; // default var BulletClass = null; var bulletSpeed = 0; var bulletDamage = 0; var bulletYOffset = 0; if (e.constructor === EnemyStoneThrower) { fireInterval = 120; BulletClass = EnemyStone; bulletSpeed = 12; bulletDamage = 10; bulletYOffset = -60; } else if (e.constructor === EnemyGunner) { fireInterval = 60; BulletClass = EnemyBullet; bulletSpeed = 18; bulletDamage = 14; bulletYOffset = -70; } else if (e.constructor === EnemyCar) { fireInterval = 80; BulletClass = EnemyCarBullet; bulletSpeed = 20; bulletDamage = 20; bulletYOffset = -40; } else if (e.constructor === EnemyTank) { fireInterval = 100; BulletClass = EnemyTankShell; bulletSpeed = 14; bulletDamage = 40; bulletYOffset = -50; } else if (e.constructor === EnemyJet) { fireInterval = 70; BulletClass = EnemyJetMissile; bulletSpeed = 28; bulletDamage = 60; bulletYOffset = -20; } if (BulletClass && e.fireTimer >= fireInterval) { // Find closest player soldier, else aim at anaBase var target = null; var minDist = 99999; for (var ps = 0; ps < playerSoldiers.length; ps++) { var p = playerSoldiers[ps]; var dx = p.x - e.x; var dy = p.y - e.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < minDist) { minDist = dist; target = p; } } if (!target) { target = anaBase; } // Fire bullet var b = new BulletClass(); b.x = e.x; b.y = e.y + bulletYOffset; // Calculate direction var tx = target.x; var ty = target.y; var dx = tx - b.x; var dy = ty - b.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist === 0) dist = 1; b.vx = dx / dist * bulletSpeed; b.vy = dy / dist * bulletSpeed; b.damage = bulletDamage; enemyBullets.push(b); game.addChild(b); e.fireTimer = 0; } } // If at anaBase, attack base if (e.lastAtAnaBase === undefined) e.lastAtAnaBase = false; var atAnaBase = Math.abs(e.x - anaBase.x) < 120; if (!e.lastAtAnaBase && atAnaBase) { // Just arrived at ana base e.attackedBase = false; } if (!e.attackedBase && atAnaBase) { anaBase.hp -= e.atk * 0.05; // Her asker %5 oranında base canı azaltır if (anaBase.hp < 0) anaBase.hp = 0; e.attackedBase = true; } e.lastAtAnaBase = atAnaBase; } // Update stones (slingshot projectiles) for (var i = stones.length - 1; i >= 0; i--) { var st = stones[i]; st.update(); // Remove if out of bounds if (st.x < 0 || st.x > GAME_WIDTH || st.y < 0 || st.y > GAME_HEIGHT) { stones.splice(i, 1); st.destroy(); continue; } // Hit enemy soldiers var hit = false; for (var j = enemySoldiers.length - 1; j >= 0; j--) { var e = enemySoldiers[j]; if (st.intersects(e)) { e.hp -= st.damage; e.hpBar.set(e.hp / e.maxHp); // Fire effect at collision point var fireFx = new FireEffect(); fireFx.x = st.x; fireFx.y = st.y; game.addChild(fireFx); if (e.hp <= 0) { score += 10; enemySoldiers.splice(j, 1); e.destroy(); } hit = true; break; } } // Hit enemy base if (!hit && Math.abs(st.x - enemyBase.x) < 120 && Math.abs(st.y - enemyBase.y) < 120) { enemyBase.hp -= st.damage; if (enemyBase.hp < 0) enemyBase.hp = 0; // Fire effect at base hit var fireFx = new FireEffect(); fireFx.x = st.x; fireFx.y = st.y; game.addChild(fireFx); hit = true; } if (hit) { stones.splice(i, 1); st.destroy(); } } // --- Enemy Bullets update --- for (var i = enemyBullets.length - 1; i >= 0; i--) { var b = enemyBullets[i]; b.update(); // Remove if out of bounds if (b.x < 0 || b.x > GAME_WIDTH || b.y < 0 || b.y > GAME_HEIGHT) { enemyBullets.splice(i, 1); b.destroy(); continue; } // Hit player soldiers var hit = false; for (var j = playerSoldiers.length - 1; j >= 0; j--) { var s = playerSoldiers[j]; if (b.intersects(s)) { s.hp -= b.damage; s.hpBar.set(s.hp / s.maxHp); // Fire effect at collision point var fireFx = new FireEffect(); fireFx.x = b.x; fireFx.y = b.y; game.addChild(fireFx); if (s.hp <= 0) { playerSoldiers.splice(j, 1); s.destroy(); } hit = true; break; } } // Hit anaBase if (!hit && Math.abs(b.x - anaBase.x) < 120 && Math.abs(b.y - anaBase.y) < 120) { anaBase.hp -= b.damage; if (anaBase.hp < 0) anaBase.hp = 0; // Fire effect at base hit var fireFx = new FireEffect(); fireFx.x = b.x; fireFx.y = b.y; game.addChild(fireFx); hit = true; } if (hit) { enemyBullets.splice(i, 1); b.destroy(); } } // --- Player Bullets update --- for (var i = playerBullets.length - 1; i >= 0; i--) { var b = playerBullets[i]; b.update(); // Remove if out of bounds if (b.x < 0 || b.x > GAME_WIDTH || b.y < 0 || b.y > GAME_HEIGHT) { playerBullets.splice(i, 1); b.destroy(); continue; } // Hit enemy soldiers var hit = false; for (var j = enemySoldiers.length - 1; j >= 0; j--) { var e = enemySoldiers[j]; if (b.intersects(e)) { e.hp -= b.damage; e.hpBar.set(e.hp / e.maxHp); // Fire effect at collision point var fireFx = new FireEffect(); fireFx.x = b.x; fireFx.y = b.y; game.addChild(fireFx); if (e.hp <= 0) { score += 10; enemySoldiers.splice(j, 1); e.destroy(); } hit = true; break; } } // Hit enemy base if (!hit && Math.abs(b.x - enemyBase.x) < 120 && Math.abs(b.y - enemyBase.y) < 120) { enemyBase.hp -= b.damage; if (enemyBase.hp < 0) enemyBase.hp = 0; // Fire effect at base hit var fireFx = new FireEffect(); fireFx.x = b.x; fireFx.y = b.y; game.addChild(fireFx); hit = true; } if (hit) { playerBullets.splice(i, 1); b.destroy(); } } // Check lose condition if (anaBase.hp <= 0) { // Flash and show game over LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); // --- FULL RESET: clear all arrays and state --- // Remove all player soldiers for (var i = 0; i < playerSoldiers.length; i++) playerSoldiers[i].destroy(); for (var i = 0; i < enemySoldiers.length; i++) enemySoldiers[i].destroy(); for (var i = 0; i < stones.length; i++) stones[i].destroy(); for (var i = 0; i < enemyBullets.length; i++) enemyBullets[i].destroy(); for (var i = 0; i < playerBullets.length; i++) playerBullets[i].destroy(); playerSoldiers = []; enemySoldiers = []; stones = []; enemyBullets = []; playerBullets = []; // Reset stats and progress level = 1; score = 0; upgradePoints = 0; enemyBaseStats.hp = 100; anaBaseStats.hp = 130; playerSoldierStats.hp = 20; playerSoldierStats.atk = 9.6; playerSoldierStats.speed = 3; enemySoldierStats.hp = 20; enemySoldierStats.atk = 8; enemySoldierStats.speed = 3; enemySpawnInterval = 120; playerSpawnInterval = 120; // Reset bases anaBase.hp = anaBaseStats.hp; anaBase.maxHp = anaBaseStats.hp; enemyBase.hp = enemyBaseStats.hp; enemyBase.maxHp = enemyBaseStats.hp; // Save progress storage.level = level; storage.score = score; storage.upgradePoints = upgradePoints; // Update UI immediately levelTxt.setText('Level: ' + level); scoreTxt.setText('Score: ' + score); anaBase.hpBar.set(anaBase.hp / anaBase.maxHp); enemyBase.hpBar.set(enemyBase.hp / enemyBase.maxHp); showUpgradeMsg("Game Reset!"); return; } // Check win/level up if (enemyBase.lastWasDead === undefined) enemyBase.lastWasDead = false; var enemyBaseIsDead = enemyBase.hp <= 0; if (!enemyBase.lastWasDead && enemyBaseIsDead) { level++; if (level > MAX_LEVEL) { LK.showYouWin(); return; } // Increase difficulty enemyBaseStats.hp = Math.round(enemyBaseStats.hp * 1.3); enemySoldierStats.hp = Math.round(enemySoldierStats.hp * 1.3); enemySoldierStats.atk = Math.round(enemySoldierStats.atk * 1.3); enemySoldierStats.speed = Math.round(enemySoldierStats.speed * 1.3 * 100) / 100; enemySpawnInterval = Math.max(60, enemySpawnInterval - 4); playerSpawnInterval = Math.max(60, playerSpawnInterval - 2); upgradePoints++; showUpgradeMsg("Level " + level + "! Upgrade Point +1"); // Reset enemyBase.hp = enemyBaseStats.hp; enemyBase.maxHp = enemyBaseStats.hp; anaBase.hp = anaBaseStats.hp; anaBase.maxHp = anaBaseStats.hp; for (var i = 0; i < playerSoldiers.length; i++) playerSoldiers[i].destroy(); for (var i = 0; i < enemySoldiers.length; i++) enemySoldiers[i].destroy(); for (var i = 0; i < stones.length; i++) stones[i].destroy(); playerSoldiers = []; enemySoldiers = []; stones = []; } enemyBase.lastWasDead = enemyBaseIsDead; // Save progress storage.level = level; storage.score = score; storage.upgradePoints = upgradePoints; };
===================================================================
--- original.js
+++ change.js
@@ -452,9 +452,9 @@
var SLING_X = BASE_OFFSET_X;
var SLING_Y = GROUND_Y - 110;
var ENEMY_BASE_X = GAME_WIDTH - BASE_OFFSET_X;
var ENEMY_BASE_Y = GROUND_Y;
-var MAX_LEVEL = 20;
+var MAX_LEVEL = 50; // Game state
// Game state
var anaBase, enemyBase, slingshot;
var playerSoldiers = [];
var enemySoldiers = [];
@@ -1020,9 +1020,15 @@
} else if (level >= 11 && level <= 15) {
s = new EnemyCar();
} else if (level >= 16 && level <= 20) {
s = new EnemyTank();
- } else if (level >= 21 && level <= 30) {
+ } else if (level >= 21 && level < 50) {
+ // Randomly pick one of the enemy types for levels 21-49
+ var enemyTypes = [EnemyStoneThrower, EnemyGunner, EnemyCar, EnemyTank, EnemyJet];
+ var idx = Math.floor(Math.random() * enemyTypes.length);
+ s = new enemyTypes[idx]();
+ } else if (level === 50) {
+ // Final level: only Jet for extra challenge
s = new EnemyJet();
} else {
s = new EnemyStoneThrower();
}
Yukarda gece gökyüzü, aşağıda çölün sadeliği, gerçekçi, uzaktan görünüm, yazısız, background, yüksek boyutta. In-Game asset. High contrast. No shadows
Askeri üs - gerçekçi, yazısız, yandan görünüm. In-Game asset. 2d. High contrast. No shadows
Ateş, gerçekçi, yazısız. In-Game asset. 2d. High contrast. No shadows
Mermi, gerçekçi, yazısız. In-Game asset. High contrast. No shadows
Taş çağında asker, yazısız, gerçekçi, yandan görünüm. In-Game asset. High contrast. No shadows
Komando, yazısız, gerçekçi, yandan görünüm. In-Game asset. 2d. High contrast. No shadows
Komando, yazısız, gerçekçi, yandan görünüm, bütün vücudu görünsün. In-Game asset. High contrast. No shadows
Zırhlı savaş arabası, gerçekçi, yazısız, yandan görümüm. In-Game asset. High contrast. No shadows
Sapan, yandan görünüm, gerçekçi, yazısız. In-Game asset. High contrast. No shadows
Savaş uçağı, gerçekçi, yazısız, yandan görünüm. In-Game asset. High contrast. No shadows
Füze, gerçekçi, yandan görünüm, yazısız. In-Game asset. High contrast. No shadows
Savaş tankı, gerçekçi, yandan görünüm, yazısız. In-Game asset. High contrast. No shadows
Bomba, gerçekçi, yandan görünüm, yazısız. In-Game asset. High contrast. No shadows
Music, icon, yazısız, gerçekçi. In-Game asset. High contrast. No shadows