User prompt
There is no reload bar make a asset
User prompt
Devam et
User prompt
Hala gözükmüyor (zaten mermş değiştirmeden kastım bu değildi) 7 defa ateş ettikten sonra 1,5 sn cooldown girecek ve mermi yeniliyeceğiz
User prompt
Gözden geçir mermi değiştirme tuşu gözükmüyor
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'if (storage.get("currentBulletType") !== undefined && storage.get("currentBulletType") !== null) {' Line Number: 328
User prompt
Please fix the bug: 'storage.getItem is not a function' in or related to this line: 'if (storage.getItem("currentBulletType") !== undefined && storage.getItem("currentBulletType") !== null) {' Line Number: 328
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'if (storage.get("currentBulletType") !== undefined) {' Line Number: 328
User prompt
Devam et
User prompt
Mermi değiştirme mekaniği ekle
User prompt
Çok yavaşlatmışsın biraz arttır
User prompt
Karakterim yürüme hızını azalt
User prompt
Please fix the bug: 'tween.to is not a function' in or related to this line: 'tween.to(zoneGraphics, {' Line Number: 208 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Bölge resimlerinin parlaklığını arttır
User prompt
Ekle
User prompt
Her bölge farklı bir assete sahip olsun örn bölge 1 bölge 2 şeklinde
User prompt
Karakterimiz tıkladığımız yere doğru gitmesin nereye doğru kaydırıyorsak orayq gitsin
User prompt
Rakipler benim ele geçirdiğim bölgelerde doğamasın
User prompt
Rakipler sadece bölge başında doğsun
User prompt
Rakipler belli bir yakınlıkta iken bize saldırsın
User prompt
Can barı oluştur karakterimiz hasar yediğinde üzerinde belirsin (can değerimiz 10 mermi olsun)
User prompt
Oyuna rakip ekle
Code edit (1 edits merged)
Please save this source code
User prompt
Territory Takeover
Initial prompt
Bana gta1 isimli bir oyun yap oyun şöyle olacak:karakterimiz mermi atabilecek yakınımızda aynı gta san andreas daki gibi bölge ele geçirbileceğiz bunun için bölgede bir süre durmamız gerekecek
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 15; self.vx = 0; self.vy = 0; self.lifetime = 120; self.update = function () { self.x += self.vx; self.y += self.vy; self.lifetime--; }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3; self.shootCooldown = 0; self.moveTimer = 0; // Enemy magazine/reload system self.magazine = 7; self.maxMagazine = 7; self.reloading = false; self.reloadTime = 1500; // ms self.reloadTimeout = null; // Start at a random non-captured zone position var availableZones = []; for (var k = 0; k < zones.length; k++) { if (!zones[k].captured) { availableZones.push(k); } } if (availableZones.length > 0) { var randomIndex = Math.floor(Math.random() * availableZones.length); var zoneIndex = availableZones[randomIndex]; self.targetX = [512, 1536, 512, 1536][zoneIndex]; self.targetY = [683, 683, 2049, 2049][zoneIndex]; } else { // If all zones are captured, default to center self.targetX = 1024; self.targetY = 1366; } self.update = function () { // Move towards target position var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 20) { // Store previous position var prevX = self.x; var prevY = self.y; self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; // Prevent enemy from moving through walls for (var w = 0; w < walls.length; w++) { if (self.intersects(walls[w])) { self.x = prevX; self.y = prevY; break; } } } // Change target position periodically self.moveTimer++; // Find available (uncaptured) zones var availableZones = []; for (var k = 0; k < zones.length; k++) { if (!zones[k].captured) { availableZones.push(k); } } // If only one zone left, allow random movement within that zone's area if (availableZones.length === 1) { if (self.moveTimer > 120 || dist < 20) { self.moveTimer = 0; var zoneIndex = availableZones[0]; // Pick a random point within the zone's bounds (±180px from center) var zx = [512, 1536, 512, 1536][zoneIndex]; var zy = [683, 683, 2049, 2049][zoneIndex]; var offsetX = (Math.random() - 0.5) * 360; var offsetY = (Math.random() - 0.5) * 360; self.targetX = zx + offsetX; self.targetY = zy + offsetY; } } else if (self.moveTimer > 180 || dist < 20) { self.moveTimer = 0; // Move to a random non-captured zone position if (availableZones.length > 0) { var randomIndex = Math.floor(Math.random() * availableZones.length); var zoneIndex = availableZones[randomIndex]; self.targetX = [512, 1536, 512, 1536][zoneIndex]; self.targetY = [683, 683, 2049, 2049][zoneIndex]; } } // Shoot at player if (self.shootCooldown > 0) { self.shootCooldown--; } else if (player) { var pdx = player.x - self.x; var pdy = player.y - self.y; var pdist = Math.sqrt(pdx * pdx + pdy * pdy); // Only attack when within 500 pixel proximity if (pdist < 500) { self.shoot(player.x, player.y); } } }; self.shoot = function (targetX, targetY) { // Only shoot if not reloading and magazine > 0 if (self.reloading) { return; } if (self.magazine <= 0) { // Start reload if not already if (!self.reloading) { self.reloading = true; self.reloadTimeout = LK.setTimeout(function () { self.magazine = self.maxMagazine; self.reloading = false; }, self.reloadTime); } return; } var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; var dx = targetX - self.x; var dy = targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); bullet.vx = dx / dist * bullet.speed; bullet.vy = dy / dist * bullet.speed; bullet.isEnemyBullet = true; enemyBullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); self.shootCooldown = 60; self.magazine--; if (self.magazine <= 0) { // Start reload self.reloading = true; self.reloadTimeout = LK.setTimeout(function () { self.magazine = self.maxMagazine; self.reloading = false; }, self.reloadTime); } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); // Stylized, highly visible gun: colored barrel, body, handle, and sight // Gun barrel (long, thick, bright yellow) var gunBarrelLength = 70; var gunBarrel = self.attachAsset('zone', { width: gunBarrelLength, height: 18, tint: 0xffe066, anchorX: 0.1, anchorY: 0.5, alpha: 1 }); gunBarrel.x = 54; gunBarrel.y = 0; // Gun body (short, thick, black) var gunBody = self.attachAsset('zone', { width: 38, height: 28, tint: 0x222222, anchorX: 0.1, anchorY: 0.5, alpha: 1 }); gunBody.x = 38; gunBody.y = 0; // Gun handle (angled, orange) var gunHandle = self.attachAsset('zone', { width: 18, height: 36, tint: 0xff9900, anchorX: 0.1, anchorY: 0.1, alpha: 1 }); gunHandle.x = 38 + 20; gunHandle.y = 16; gunHandle.rotation = Math.PI / 2.1; // Gun trigger guard (small, black ellipse) var gunTrigger = self.attachAsset('bullet', { width: 12, height: 10, color: 0x111111, anchorX: 0.5, anchorY: 0.5, alpha: 0.9 }); gunTrigger.x = 38 + 10; gunTrigger.y = 13; // Gun sight (small, red dot at barrel tip) var gunSight = self.attachAsset('bullet', { width: 10, height: 10, color: 0xff2222, anchorX: 0.5, anchorY: 0.5, alpha: 1 }); gunSight.x = gunBarrel.x + gunBarrelLength - 10; gunSight.y = 0; // Group all as the gun self.gun = gunBarrel; self.gunBody = gunBody; self.gunHandle = gunHandle; self.gunTrigger = gunTrigger; self.gunSight = gunSight; self.gunAngle = 0; // Track current gun angle self.speed = 8; self.shootCooldown = 0; self.health = 12; self.maxHealth = 12; // Create health bar container var healthBar = self.addChild(new Container()); healthBar.y = -playerGraphics.height / 2 - 50; healthBar.visible = false; // Health bar background var healthBg = healthBar.attachAsset('zone', { width: 260, height: 28, tint: 0x333333, anchorX: 0.5, anchorY: 0.5 }); // Health bar fill var healthFill = healthBar.attachAsset('zone', { width: 252, height: 22, tint: 0x00ff00, anchorX: 0, anchorY: 0.5 }); healthFill.x = -130; self.healthBar = healthBar; self.healthFill = healthFill; self.healthBg = healthBg; self.takeDamage = function () { self.health--; self.healthBar.visible = true; // Update health bar width self.healthFill.width = self.health / self.maxHealth * 252; // Update health bar color based on health if (self.health <= 3) { self.healthFill.tint = 0xff0000; } else if (self.health <= 6) { self.healthFill.tint = 0xffaa00; } else { self.healthFill.tint = 0x00ff00; } // Flash effect LK.effects.flashObject(self, 0xff0000, 300); if (self.health <= 0) { LK.showGameOver({ text: "Wasted" }); } }; // Override intersects to use a smaller hitbox for the player self.intersects = function (other) { // Use a smaller hitbox (60% of width/height, centered) var scale = 0.6; var px = self.x, py = self.y; var pw = playerGraphics.width * scale, ph = playerGraphics.height * scale; var pLeft = px - pw / 2, pRight = px + pw / 2, pTop = py - ph / 2, pBottom = py + ph / 2; // Get other's bounds (assume center anchor) var ox = other.x, oy = other.y; var ow = typeof other.width !== "undefined" ? other.width : other.graphics && other.graphics.width ? other.graphics.width : 0; var oh = typeof other.height !== "undefined" ? other.height : other.graphics && other.graphics.height ? other.graphics.height : 0; if (ow === 0 && typeof other.children !== "undefined" && other.children.length > 0 && typeof other.children[0].width !== "undefined") { ow = other.children[0].width; oh = other.children[0].height; } var oLeft = ox - ow / 2, oRight = ox + ow / 2, oTop = oy - oh / 2, oBottom = oy + oh / 2; // AABB collision return !(pRight < oLeft || pLeft > oRight || pBottom < oTop || pTop > oBottom); }; self.update = function () { if (self.shootCooldown > 0) { self.shootCooldown--; } }; self.shoot = function (targetX, targetY) { // Magazine/cooldown logic if (typeof playerMagazine !== "undefined" && typeof playerReloading !== "undefined") { if (playerReloading) { // Can't shoot while reloading return; } if (playerMagazine <= 0) { // Start reload if not already if (!playerReloading) { playerReloading = true; // Track reload bar timing if (typeof Date !== "undefined") { reloadStartTime = Date.now(); reloadEndTime = reloadStartTime + playerReloadTime; } // Animate reload bar fill and bullet icons if (typeof reloadBar !== "undefined") { reloadBar.visible = true; reloadFill.width = 0; // Clear all bullet icons (hide them) when magazine is empty for (var i = 0; i < reloadBar.bulletIcons.length; i++) { reloadBar.bulletIcons[i].alpha = 0; reloadBar.bulletIcons[i].color = 0x888888; } } playerReloadTimeout = LK.setTimeout(function () { playerMagazine = playerMaxMagazine; playerReloading = false; reloadStartTime = 0; reloadEndTime = 0; // On reload complete, show all bullets as filled if (typeof reloadBar !== "undefined") { for (var i = 0; i < reloadBar.bulletIcons.length; i++) { reloadBar.bulletIcons[i].alpha = 1; reloadBar.bulletIcons[i].color = 0xffff00; } reloadFill.width = 200; } }, playerReloadTime); } return; } } if (self.shootCooldown <= 0) { // Use selected bullet type var type = bulletTypes[currentBulletType]; var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; // Change bullet asset and speed if (type.id !== 'bullet') { bullet.removeChild(bullet.children[0]); var bulletGraphics = bullet.attachAsset(type.id, { anchorX: 0.5, anchorY: 0.5 }); bullet.speed = type.speed; } else { bullet.speed = type.speed; } var dx = targetX - self.x; var dy = targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); bullet.vx = dx / dist * bullet.speed; bullet.vy = dy / dist * bullet.speed; // Rotate the gun towards the shooting direction if (self.gun) { var angle = Math.atan2(dy, dx); // If shooting to the left (targetX < self.x), teleport gun to left side if (targetX < self.x) { // Place gun on left side self.gun.x = -54; self.gunBody.x = -38; self.gunHandle.x = -38 - 20; self.gunTrigger.x = -38 - 10; // Sight will be repositioned below } else { // Place gun on right side (default) self.gun.x = 54; self.gunBody.x = 38; self.gunHandle.x = 38 + 20; self.gunTrigger.x = 38 + 10; // Sight will be repositioned below } self.gun.rotation = angle; self.gunAngle = angle; // Rotate the body and trigger to match the barrel if (self.gunBody) { self.gunBody.rotation = angle; } if (self.gunTrigger) { self.gunTrigger.rotation = angle; } // Rotate the handle with a slight offset to look like a real gun if (self.gunHandle) { self.gunHandle.rotation = angle + Math.PI / 2.1; } // Rotate and reposition the sight to always be at the barrel tip if (self.gunSight) { self.gunSight.rotation = angle; // Place at the tip of the barrel var barrelLen = 70; self.gunSight.x = self.gun.x + Math.cos(angle) * (barrelLen - 10); self.gunSight.y = self.gun.y + Math.sin(angle) * (barrelLen - 10); } } bullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); self.shootCooldown = 15; // Decrement magazine if (typeof playerMagazine !== "undefined") { playerMagazine--; // Immediately update reload bar bullet icons after shooting if (typeof reloadBar !== "undefined" && reloadBar.bulletIcons) { for (var i = 0; i < reloadBar.bulletIcons.length; i++) { if (i < playerMagazine && !playerReloading) { reloadBar.bulletIcons[i].alpha = 1; reloadBar.bulletIcons[i].color = 0xffff00; } else { reloadBar.bulletIcons[i].alpha = 0.3; reloadBar.bulletIcons[i].color = 0x888888; } } } if (playerMagazine <= 0) { playerReloading = true; playerReloadTimeout = LK.setTimeout(function () { playerMagazine = playerMaxMagazine; playerReloading = false; }, playerReloadTime); } } } }; return self; }); // Wall class for bullet-blocking cover var Wall = Container.expand(function () { var self = Container.call(this); self.wallGraphics = self.attachAsset('wall', { anchorX: 0.5, anchorY: 0.5 }); self.isCapturedVisual = false; // Method to change wall visual to captured self.setCapturedVisual = function () { if (!self.isCapturedVisual) { self.removeChild(self.wallGraphics); self.wallGraphics = self.attachAsset('wall_captured', { anchorX: 0.5, anchorY: 0.5 }); self.isCapturedVisual = true; } }; // No update needed, static return self; }); var Zone = Container.expand(function (zoneIndex) { var self = Container.call(this); var zoneAssetId = 'zone' + (zoneIndex + 1); var zoneGraphics = self.attachAsset(zoneAssetId, { anchorX: 0.5, anchorY: 0.5, alpha: 0.3 }); // Increase brightness using tween color effect (tint to a lighter color) tween(zoneGraphics, { tint: 0xffffff }, { duration: 500 }); self.graphics = zoneGraphics; self.captureProgress = 0; self.captureTime = 180; self.captured = false; self.playerInside = false; var progressBar = self.addChild(new Container()); progressBar.y = -zoneGraphics.height / 2 - 30; var progressBg = progressBar.attachAsset('zone', { width: 300, height: 20, tint: 0x333333, anchorX: 0.5, anchorY: 0.5 }); var progressFill = progressBar.attachAsset('zone', { width: 0, height: 16, tint: 0x00ff00, anchorX: 0, anchorY: 0.5 }); progressFill.x = -148; self.progressFill = progressFill; progressBar.visible = false; self.progressBar = progressBar; self.update = function () { if (self.playerInside && !self.captured) { self.captureProgress++; self.progressBar.visible = true; self.progressFill.width = self.captureProgress / self.captureTime * 296; if (self.captureProgress >= self.captureTime) { self.captured = true; self.graphics.tint = 0x00ff00; self.graphics.alpha = 0.5; self.progressBar.visible = false; LK.getSound('capture').play(); capturedZones++; updateScore(); // Change visual of only the nearest wall to this zone var nearestWall = null; var minDist = Infinity; for (var w = 0; w < walls.length; w++) { var wx = walls[w].x; var wy = walls[w].y; var dx = wx - self.x; var dy = wy - self.y; var distSq = dx * dx + dy * dy; if (distSq < minDist) { minDist = distSq; nearestWall = walls[w]; } } if (nearestWall && typeof nearestWall.setCapturedVisual === "function") { nearestWall.setCapturedVisual(); } // If all zones are captured, set all walls to captured visual if (capturedZones >= totalZones) { for (var w = 0; w < walls.length; w++) { if (typeof walls[w].setCapturedVisual === "function") { walls[w].setCapturedVisual(); } } } // No reload bar or magazine logic here; zone capture does not affect reload bar } } else if (!self.playerInside && self.captureProgress > 0 && !self.captured) { self.captureProgress = Math.max(0, self.captureProgress - 2); if (self.captureProgress === 0) { self.progressBar.visible = false; } else { self.progressFill.width = self.captureProgress / self.captureTime * 296; } } }; self.checkPlayerInside = function (player) { var halfWidth = self.graphics.width / 2; var halfHeight = self.graphics.height / 2; var dx = Math.abs(player.x - self.x); var dy = Math.abs(player.y - self.y); self.playerInside = dx < halfWidth && dy < halfHeight; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Wall asset for small cover/wall (cephé) var player; var bullets = []; var enemyBullets = []; var enemies = []; var zones = []; var walls = []; // Array for wall objects var capturedZones = 0; var totalZones = 4; var isDragging = false; var lastShootX = 0; var lastShootY = 0; // Bullet type switching var bulletTypes = [{ id: 'bullet', color: 0xffff00, speed: 15, size: 20 }, // normal { id: 'bullet_red', color: 0xff4444, speed: 10, size: 32 }, // slow, big { id: 'bullet_blue', color: 0x44aaff, speed: 22, size: 14 } // fast, small ]; var currentBulletType = 0; if (typeof storage.getItem === "function" && storage.getItem("currentBulletType") !== undefined && storage.getItem("currentBulletType") !== null) { currentBulletType = parseInt(storage.getItem("currentBulletType")); } // Dynamically create bullet assets if not already present for (var i = 1; i < bulletTypes.length; i++) { if (!LK.getAsset(bulletTypes[i].id, {})) {} } // UI for bullet type var bulletTypeTxt = new Text2('Bullet: Normal', { size: 60, fill: 0xffffff }); bulletTypeTxt.anchor.set(0.5, 0); bulletTypeTxt.y = 120; bulletTypeTxt.x = 1024; LK.gui.top.addChild(bulletTypeTxt); // Button to switch bullet type (simple text button) var switchBtn = new Text2('Change Bullet', { size: 60, fill: 0x00ffcc }); switchBtn.anchor.set(0.5, 0); switchBtn.y = 210; switchBtn.x = 1024; LK.gui.top.addChild(switchBtn); // Touch/click event for switchBtn switchBtn.down = function (x, y, obj) { currentBulletType = (currentBulletType + 1) % bulletTypes.length; storage.set("currentBulletType", currentBulletType); var names = ['Normal', 'Big', 'Fast']; bulletTypeTxt.setText('Bullet: ' + names[currentBulletType]); }; var scoreTxt = new Text2('Zones: 0/4', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); function updateScore() { scoreTxt.setText('Zones: ' + capturedZones + '/' + totalZones); if (capturedZones >= totalZones) { LK.showYouWin({ text: "Mission Passed" }); } ; // Update reload bar position and progress, animate fill and update bullet icons if (typeof reloadBar !== "undefined" && typeof player !== "undefined") { reloadBar.x = player.x; reloadBar.y = player.y - 170; // Update bullet icons: show filled for each bullet in magazine, empty for spent if (typeof playerMagazine !== "undefined" && reloadBar.bulletIcons) { for (var i = 0; i < reloadBar.bulletIcons.length; i++) { if (i < playerMagazine && !playerReloading) { reloadBar.bulletIcons[i].alpha = 1; reloadBar.bulletIcons[i].color = 0xffff00; } else { reloadBar.bulletIcons[i].alpha = 0.3; reloadBar.bulletIcons[i].color = 0x888888; } } } if (typeof playerReloading !== "undefined" && playerReloading) { reloadBar.visible = true; // Animate fill: (playerReloadTime - remaining) / playerReloadTime if (typeof reloadStartTime !== "undefined" && typeof reloadEndTime !== "undefined" && reloadStartTime > 0 && reloadEndTime > reloadStartTime) { var now = Date.now(); var progress = Math.min(1, Math.max(0, (now - reloadStartTime) / (reloadEndTime - reloadStartTime))); reloadFill.width = 200 * progress; // Animate bullet icons: fill them as reload progresses var bulletsToShow = Math.floor(progress * 10); for (var i = 0; i < reloadBar.bulletIcons.length; i++) { if (i < bulletsToShow) { reloadBar.bulletIcons[i].alpha = 1; reloadBar.bulletIcons[i].color = 0xffff00; } else { reloadBar.bulletIcons[i].alpha = 0.3; reloadBar.bulletIcons[i].color = 0x888888; } } } else { reloadFill.width = 0; } } else if (typeof playerReloading !== "undefined" && !playerReloading) { reloadBar.visible = true; reloadFill.width = 200; } } } ; // Magazine and cooldown for player shooting var playerMagazine = 10; var playerMaxMagazine = 10; var playerReloading = false; var playerReloadTimeout = null; var playerReloadTime = 1500; // ms // Track reload progress for bar var reloadStartTime = 0; var reloadEndTime = 0; player = game.addChild(new Player()); player.x = 1024; player.y = 1366; // Reload progress bar UI above player, with 7 bullet icons and animated fill var reloadBar = new Container(); // Background bar var reloadBg = reloadBar.attachAsset('reloadBarBg', { anchorX: 0.5, anchorY: 0.5 }); // Animated fill (for reload progress) var reloadFill = reloadBar.attachAsset('reloadBarFill', { width: 0, anchorX: 0, anchorY: 0.5 }); reloadFill.x = -100; reloadFill.y = 0; // 10 bullet icons (small ellipses) spaced evenly on the bar reloadBar.bulletIcons = []; var bulletIconSpacing = 20; var bulletIconStartX = -90; for (var i = 0; i < 10; i++) { var icon = reloadBar.attachAsset('bullet', { width: 18, height: 18, anchorX: 0.5, anchorY: 0.5, color: 0xffff00 }); icon.x = bulletIconStartX + i * bulletIconSpacing; icon.y = 0; reloadBar.bulletIcons.push(icon); } reloadBar.visible = true; game.addChild(reloadBar); var zonePositions = [{ x: 512, y: 683 }, { x: 1536, y: 683 }, { x: 512, y: 2049 }, { x: 1536, y: 2049 }]; for (var i = 0; i < zonePositions.length; i++) { var zone = new Zone(i); zone.x = zonePositions[i].x; zone.y = zonePositions[i].y; zones.push(zone); game.addChild(zone); } // Place walls (cephé) at strategic locations var wallPositions = [{ x: 1024, y: 500, rotation: 0 }, // Top center { x: 1024, y: 2200, rotation: 0 }, // Bottom center { x: 400, y: 1366, rotation: Math.PI / 2 }, // Left center { x: 1648, y: 1366, rotation: Math.PI / 2 }, // Right center { x: 800, y: 900, rotation: 0.3 }, // Near zone 1 { x: 1300, y: 1800, rotation: -0.3 } // Near zone 4 ]; for (var i = 0; i < wallPositions.length; i++) { var wall = new Wall(); wall.x = wallPositions[i].x; wall.y = wallPositions[i].y; if (wallPositions[i].rotation) wall.rotation = wallPositions[i].rotation; walls.push(wall); game.addChild(wall); } // Spawn enemies at zone positions for (var i = 0; i < 3; i++) { var enemy = new Enemy(); var zoneIndex = i % zonePositions.length; enemy.x = zonePositions[zoneIndex].x; enemy.y = zonePositions[zoneIndex].y; enemies.push(enemy); game.addChild(enemy); } game.down = function (x, y, obj) { isDragging = true; lastShootX = x; lastShootY = y; }; game.move = function (x, y, obj) { if (isDragging) { // Calculate drag direction from last position var dx = x - lastShootX; var dy = y - lastShootY; var dist = Math.sqrt(dx * dx + dy * dy); // Move player in the direction of the drag, but slower if (dist > 0) { var moveScale = 0.5; // Increase speed to 50% of drag // Store previous position var prevX = player.x; var prevY = player.y; player.x += dx * moveScale; player.y += dy * moveScale; player.x = Math.max(30, Math.min(2018, player.x)); player.y = Math.max(30, Math.min(2702, player.y)); // Check collision with walls, revert if colliding for (var w = 0; w < walls.length; w++) { if (player.intersects(walls[w])) { player.x = prevX; player.y = prevY; break; } } } lastShootX = x; lastShootY = y; } }; game.up = function (x, y, obj) { if (isDragging) { player.shoot(x, y); isDragging = false; } }; game.update = function () { // Update reload bar position to follow player if (typeof reloadBar !== "undefined" && typeof player !== "undefined") { reloadBar.x = player.x; reloadBar.y = player.y - 170; } // Update zones for (var i = zones.length - 1; i >= 0; i--) { zones[i].checkPlayerInside(player); } // Update player bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; // Block by wall var hitWall = false; for (var w = 0; w < walls.length; w++) { if (bullet.intersects(walls[w])) { hitWall = true; break; } } if (hitWall || bullet.lifetime <= 0 || bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check collision with enemies for (var j = enemies.length - 1; j >= 0; j--) { if (bullet.intersects(enemies[j])) { bullet.destroy(); bullets.splice(i, 1); // Mini explosion effect at enemy position var explosion = new Container(); var expAsset = explosion.attachAsset('bullet', { width: 80, height: 80, color: 0xffaa00, anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); explosion.x = enemies[j].x; explosion.y = enemies[j].y; game.addChild(explosion); // Animate explosion: scale up and fade out, then destroy tween(expAsset, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 350, onComplete: function onComplete() { explosion.destroy(); } }); enemies[j].destroy(); enemies.splice(j, 1); // Spawn new enemy at a random non-captured zone position // Recalculate availableZones at spawn time to ensure accuracy if (zones.filter(function (z) { return !z.captured; }).length > 0) { // Delay enemy spawn by 2 seconds (2000ms) LK.setTimeout(function () { var availableZones = []; for (var k = 0; k < zones.length; k++) { if (!zones[k].captured) { availableZones.push(k); } } if (availableZones.length > 0) { var newEnemy = new Enemy(); var randomIndex = Math.floor(Math.random() * availableZones.length); var zoneIndex = availableZones[randomIndex]; newEnemy.x = zonePositions[zoneIndex].x; newEnemy.y = zonePositions[zoneIndex].y; enemies.push(newEnemy); game.addChild(newEnemy); } }, 2000); } break; } } } // Update enemy bullets for (var i = enemyBullets.length - 1; i >= 0; i--) { var bullet = enemyBullets[i]; // Block by wall var hitWall = false; for (var w = 0; w < walls.length; w++) { if (bullet.intersects(walls[w])) { hitWall = true; break; } } if (hitWall || bullet.lifetime <= 0 || bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) { bullet.destroy(); enemyBullets.splice(i, 1); continue; } // Check collision with player if (bullet.intersects(player)) { bullet.destroy(); enemyBullets.splice(i, 1); player.takeDamage(); } // Example: Restart the game if you want to force a full reset (uncomment to use) // LK.showGameOver(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 15;
self.vx = 0;
self.vy = 0;
self.lifetime = 120;
self.update = function () {
self.x += self.vx;
self.y += self.vy;
self.lifetime--;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.shootCooldown = 0;
self.moveTimer = 0;
// Enemy magazine/reload system
self.magazine = 7;
self.maxMagazine = 7;
self.reloading = false;
self.reloadTime = 1500; // ms
self.reloadTimeout = null;
// Start at a random non-captured zone position
var availableZones = [];
for (var k = 0; k < zones.length; k++) {
if (!zones[k].captured) {
availableZones.push(k);
}
}
if (availableZones.length > 0) {
var randomIndex = Math.floor(Math.random() * availableZones.length);
var zoneIndex = availableZones[randomIndex];
self.targetX = [512, 1536, 512, 1536][zoneIndex];
self.targetY = [683, 683, 2049, 2049][zoneIndex];
} else {
// If all zones are captured, default to center
self.targetX = 1024;
self.targetY = 1366;
}
self.update = function () {
// Move towards target position
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 20) {
// Store previous position
var prevX = self.x;
var prevY = self.y;
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
// Prevent enemy from moving through walls
for (var w = 0; w < walls.length; w++) {
if (self.intersects(walls[w])) {
self.x = prevX;
self.y = prevY;
break;
}
}
}
// Change target position periodically
self.moveTimer++;
// Find available (uncaptured) zones
var availableZones = [];
for (var k = 0; k < zones.length; k++) {
if (!zones[k].captured) {
availableZones.push(k);
}
}
// If only one zone left, allow random movement within that zone's area
if (availableZones.length === 1) {
if (self.moveTimer > 120 || dist < 20) {
self.moveTimer = 0;
var zoneIndex = availableZones[0];
// Pick a random point within the zone's bounds (±180px from center)
var zx = [512, 1536, 512, 1536][zoneIndex];
var zy = [683, 683, 2049, 2049][zoneIndex];
var offsetX = (Math.random() - 0.5) * 360;
var offsetY = (Math.random() - 0.5) * 360;
self.targetX = zx + offsetX;
self.targetY = zy + offsetY;
}
} else if (self.moveTimer > 180 || dist < 20) {
self.moveTimer = 0;
// Move to a random non-captured zone position
if (availableZones.length > 0) {
var randomIndex = Math.floor(Math.random() * availableZones.length);
var zoneIndex = availableZones[randomIndex];
self.targetX = [512, 1536, 512, 1536][zoneIndex];
self.targetY = [683, 683, 2049, 2049][zoneIndex];
}
}
// Shoot at player
if (self.shootCooldown > 0) {
self.shootCooldown--;
} else if (player) {
var pdx = player.x - self.x;
var pdy = player.y - self.y;
var pdist = Math.sqrt(pdx * pdx + pdy * pdy);
// Only attack when within 500 pixel proximity
if (pdist < 500) {
self.shoot(player.x, player.y);
}
}
};
self.shoot = function (targetX, targetY) {
// Only shoot if not reloading and magazine > 0
if (self.reloading) {
return;
}
if (self.magazine <= 0) {
// Start reload if not already
if (!self.reloading) {
self.reloading = true;
self.reloadTimeout = LK.setTimeout(function () {
self.magazine = self.maxMagazine;
self.reloading = false;
}, self.reloadTime);
}
return;
}
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var dx = targetX - self.x;
var dy = targetY - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
bullet.vx = dx / dist * bullet.speed;
bullet.vy = dy / dist * bullet.speed;
bullet.isEnemyBullet = true;
enemyBullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
self.shootCooldown = 60;
self.magazine--;
if (self.magazine <= 0) {
// Start reload
self.reloading = true;
self.reloadTimeout = LK.setTimeout(function () {
self.magazine = self.maxMagazine;
self.reloading = false;
}, self.reloadTime);
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Stylized, highly visible gun: colored barrel, body, handle, and sight
// Gun barrel (long, thick, bright yellow)
var gunBarrelLength = 70;
var gunBarrel = self.attachAsset('zone', {
width: gunBarrelLength,
height: 18,
tint: 0xffe066,
anchorX: 0.1,
anchorY: 0.5,
alpha: 1
});
gunBarrel.x = 54;
gunBarrel.y = 0;
// Gun body (short, thick, black)
var gunBody = self.attachAsset('zone', {
width: 38,
height: 28,
tint: 0x222222,
anchorX: 0.1,
anchorY: 0.5,
alpha: 1
});
gunBody.x = 38;
gunBody.y = 0;
// Gun handle (angled, orange)
var gunHandle = self.attachAsset('zone', {
width: 18,
height: 36,
tint: 0xff9900,
anchorX: 0.1,
anchorY: 0.1,
alpha: 1
});
gunHandle.x = 38 + 20;
gunHandle.y = 16;
gunHandle.rotation = Math.PI / 2.1;
// Gun trigger guard (small, black ellipse)
var gunTrigger = self.attachAsset('bullet', {
width: 12,
height: 10,
color: 0x111111,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.9
});
gunTrigger.x = 38 + 10;
gunTrigger.y = 13;
// Gun sight (small, red dot at barrel tip)
var gunSight = self.attachAsset('bullet', {
width: 10,
height: 10,
color: 0xff2222,
anchorX: 0.5,
anchorY: 0.5,
alpha: 1
});
gunSight.x = gunBarrel.x + gunBarrelLength - 10;
gunSight.y = 0;
// Group all as the gun
self.gun = gunBarrel;
self.gunBody = gunBody;
self.gunHandle = gunHandle;
self.gunTrigger = gunTrigger;
self.gunSight = gunSight;
self.gunAngle = 0; // Track current gun angle
self.speed = 8;
self.shootCooldown = 0;
self.health = 12;
self.maxHealth = 12;
// Create health bar container
var healthBar = self.addChild(new Container());
healthBar.y = -playerGraphics.height / 2 - 50;
healthBar.visible = false;
// Health bar background
var healthBg = healthBar.attachAsset('zone', {
width: 260,
height: 28,
tint: 0x333333,
anchorX: 0.5,
anchorY: 0.5
});
// Health bar fill
var healthFill = healthBar.attachAsset('zone', {
width: 252,
height: 22,
tint: 0x00ff00,
anchorX: 0,
anchorY: 0.5
});
healthFill.x = -130;
self.healthBar = healthBar;
self.healthFill = healthFill;
self.healthBg = healthBg;
self.takeDamage = function () {
self.health--;
self.healthBar.visible = true;
// Update health bar width
self.healthFill.width = self.health / self.maxHealth * 252;
// Update health bar color based on health
if (self.health <= 3) {
self.healthFill.tint = 0xff0000;
} else if (self.health <= 6) {
self.healthFill.tint = 0xffaa00;
} else {
self.healthFill.tint = 0x00ff00;
}
// Flash effect
LK.effects.flashObject(self, 0xff0000, 300);
if (self.health <= 0) {
LK.showGameOver({
text: "Wasted"
});
}
};
// Override intersects to use a smaller hitbox for the player
self.intersects = function (other) {
// Use a smaller hitbox (60% of width/height, centered)
var scale = 0.6;
var px = self.x,
py = self.y;
var pw = playerGraphics.width * scale,
ph = playerGraphics.height * scale;
var pLeft = px - pw / 2,
pRight = px + pw / 2,
pTop = py - ph / 2,
pBottom = py + ph / 2;
// Get other's bounds (assume center anchor)
var ox = other.x,
oy = other.y;
var ow = typeof other.width !== "undefined" ? other.width : other.graphics && other.graphics.width ? other.graphics.width : 0;
var oh = typeof other.height !== "undefined" ? other.height : other.graphics && other.graphics.height ? other.graphics.height : 0;
if (ow === 0 && typeof other.children !== "undefined" && other.children.length > 0 && typeof other.children[0].width !== "undefined") {
ow = other.children[0].width;
oh = other.children[0].height;
}
var oLeft = ox - ow / 2,
oRight = ox + ow / 2,
oTop = oy - oh / 2,
oBottom = oy + oh / 2;
// AABB collision
return !(pRight < oLeft || pLeft > oRight || pBottom < oTop || pTop > oBottom);
};
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
};
self.shoot = function (targetX, targetY) {
// Magazine/cooldown logic
if (typeof playerMagazine !== "undefined" && typeof playerReloading !== "undefined") {
if (playerReloading) {
// Can't shoot while reloading
return;
}
if (playerMagazine <= 0) {
// Start reload if not already
if (!playerReloading) {
playerReloading = true;
// Track reload bar timing
if (typeof Date !== "undefined") {
reloadStartTime = Date.now();
reloadEndTime = reloadStartTime + playerReloadTime;
}
// Animate reload bar fill and bullet icons
if (typeof reloadBar !== "undefined") {
reloadBar.visible = true;
reloadFill.width = 0;
// Clear all bullet icons (hide them) when magazine is empty
for (var i = 0; i < reloadBar.bulletIcons.length; i++) {
reloadBar.bulletIcons[i].alpha = 0;
reloadBar.bulletIcons[i].color = 0x888888;
}
}
playerReloadTimeout = LK.setTimeout(function () {
playerMagazine = playerMaxMagazine;
playerReloading = false;
reloadStartTime = 0;
reloadEndTime = 0;
// On reload complete, show all bullets as filled
if (typeof reloadBar !== "undefined") {
for (var i = 0; i < reloadBar.bulletIcons.length; i++) {
reloadBar.bulletIcons[i].alpha = 1;
reloadBar.bulletIcons[i].color = 0xffff00;
}
reloadFill.width = 200;
}
}, playerReloadTime);
}
return;
}
}
if (self.shootCooldown <= 0) {
// Use selected bullet type
var type = bulletTypes[currentBulletType];
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
// Change bullet asset and speed
if (type.id !== 'bullet') {
bullet.removeChild(bullet.children[0]);
var bulletGraphics = bullet.attachAsset(type.id, {
anchorX: 0.5,
anchorY: 0.5
});
bullet.speed = type.speed;
} else {
bullet.speed = type.speed;
}
var dx = targetX - self.x;
var dy = targetY - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
bullet.vx = dx / dist * bullet.speed;
bullet.vy = dy / dist * bullet.speed;
// Rotate the gun towards the shooting direction
if (self.gun) {
var angle = Math.atan2(dy, dx);
// If shooting to the left (targetX < self.x), teleport gun to left side
if (targetX < self.x) {
// Place gun on left side
self.gun.x = -54;
self.gunBody.x = -38;
self.gunHandle.x = -38 - 20;
self.gunTrigger.x = -38 - 10;
// Sight will be repositioned below
} else {
// Place gun on right side (default)
self.gun.x = 54;
self.gunBody.x = 38;
self.gunHandle.x = 38 + 20;
self.gunTrigger.x = 38 + 10;
// Sight will be repositioned below
}
self.gun.rotation = angle;
self.gunAngle = angle;
// Rotate the body and trigger to match the barrel
if (self.gunBody) {
self.gunBody.rotation = angle;
}
if (self.gunTrigger) {
self.gunTrigger.rotation = angle;
}
// Rotate the handle with a slight offset to look like a real gun
if (self.gunHandle) {
self.gunHandle.rotation = angle + Math.PI / 2.1;
}
// Rotate and reposition the sight to always be at the barrel tip
if (self.gunSight) {
self.gunSight.rotation = angle;
// Place at the tip of the barrel
var barrelLen = 70;
self.gunSight.x = self.gun.x + Math.cos(angle) * (barrelLen - 10);
self.gunSight.y = self.gun.y + Math.sin(angle) * (barrelLen - 10);
}
}
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
self.shootCooldown = 15;
// Decrement magazine
if (typeof playerMagazine !== "undefined") {
playerMagazine--;
// Immediately update reload bar bullet icons after shooting
if (typeof reloadBar !== "undefined" && reloadBar.bulletIcons) {
for (var i = 0; i < reloadBar.bulletIcons.length; i++) {
if (i < playerMagazine && !playerReloading) {
reloadBar.bulletIcons[i].alpha = 1;
reloadBar.bulletIcons[i].color = 0xffff00;
} else {
reloadBar.bulletIcons[i].alpha = 0.3;
reloadBar.bulletIcons[i].color = 0x888888;
}
}
}
if (playerMagazine <= 0) {
playerReloading = true;
playerReloadTimeout = LK.setTimeout(function () {
playerMagazine = playerMaxMagazine;
playerReloading = false;
}, playerReloadTime);
}
}
}
};
return self;
});
// Wall class for bullet-blocking cover
var Wall = Container.expand(function () {
var self = Container.call(this);
self.wallGraphics = self.attachAsset('wall', {
anchorX: 0.5,
anchorY: 0.5
});
self.isCapturedVisual = false;
// Method to change wall visual to captured
self.setCapturedVisual = function () {
if (!self.isCapturedVisual) {
self.removeChild(self.wallGraphics);
self.wallGraphics = self.attachAsset('wall_captured', {
anchorX: 0.5,
anchorY: 0.5
});
self.isCapturedVisual = true;
}
};
// No update needed, static
return self;
});
var Zone = Container.expand(function (zoneIndex) {
var self = Container.call(this);
var zoneAssetId = 'zone' + (zoneIndex + 1);
var zoneGraphics = self.attachAsset(zoneAssetId, {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
// Increase brightness using tween color effect (tint to a lighter color)
tween(zoneGraphics, {
tint: 0xffffff
}, {
duration: 500
});
self.graphics = zoneGraphics;
self.captureProgress = 0;
self.captureTime = 180;
self.captured = false;
self.playerInside = false;
var progressBar = self.addChild(new Container());
progressBar.y = -zoneGraphics.height / 2 - 30;
var progressBg = progressBar.attachAsset('zone', {
width: 300,
height: 20,
tint: 0x333333,
anchorX: 0.5,
anchorY: 0.5
});
var progressFill = progressBar.attachAsset('zone', {
width: 0,
height: 16,
tint: 0x00ff00,
anchorX: 0,
anchorY: 0.5
});
progressFill.x = -148;
self.progressFill = progressFill;
progressBar.visible = false;
self.progressBar = progressBar;
self.update = function () {
if (self.playerInside && !self.captured) {
self.captureProgress++;
self.progressBar.visible = true;
self.progressFill.width = self.captureProgress / self.captureTime * 296;
if (self.captureProgress >= self.captureTime) {
self.captured = true;
self.graphics.tint = 0x00ff00;
self.graphics.alpha = 0.5;
self.progressBar.visible = false;
LK.getSound('capture').play();
capturedZones++;
updateScore();
// Change visual of only the nearest wall to this zone
var nearestWall = null;
var minDist = Infinity;
for (var w = 0; w < walls.length; w++) {
var wx = walls[w].x;
var wy = walls[w].y;
var dx = wx - self.x;
var dy = wy - self.y;
var distSq = dx * dx + dy * dy;
if (distSq < minDist) {
minDist = distSq;
nearestWall = walls[w];
}
}
if (nearestWall && typeof nearestWall.setCapturedVisual === "function") {
nearestWall.setCapturedVisual();
}
// If all zones are captured, set all walls to captured visual
if (capturedZones >= totalZones) {
for (var w = 0; w < walls.length; w++) {
if (typeof walls[w].setCapturedVisual === "function") {
walls[w].setCapturedVisual();
}
}
}
// No reload bar or magazine logic here; zone capture does not affect reload bar
}
} else if (!self.playerInside && self.captureProgress > 0 && !self.captured) {
self.captureProgress = Math.max(0, self.captureProgress - 2);
if (self.captureProgress === 0) {
self.progressBar.visible = false;
} else {
self.progressFill.width = self.captureProgress / self.captureTime * 296;
}
}
};
self.checkPlayerInside = function (player) {
var halfWidth = self.graphics.width / 2;
var halfHeight = self.graphics.height / 2;
var dx = Math.abs(player.x - self.x);
var dy = Math.abs(player.y - self.y);
self.playerInside = dx < halfWidth && dy < halfHeight;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Wall asset for small cover/wall (cephé)
var player;
var bullets = [];
var enemyBullets = [];
var enemies = [];
var zones = [];
var walls = []; // Array for wall objects
var capturedZones = 0;
var totalZones = 4;
var isDragging = false;
var lastShootX = 0;
var lastShootY = 0;
// Bullet type switching
var bulletTypes = [{
id: 'bullet',
color: 0xffff00,
speed: 15,
size: 20
},
// normal
{
id: 'bullet_red',
color: 0xff4444,
speed: 10,
size: 32
},
// slow, big
{
id: 'bullet_blue',
color: 0x44aaff,
speed: 22,
size: 14
} // fast, small
];
var currentBulletType = 0;
if (typeof storage.getItem === "function" && storage.getItem("currentBulletType") !== undefined && storage.getItem("currentBulletType") !== null) {
currentBulletType = parseInt(storage.getItem("currentBulletType"));
}
// Dynamically create bullet assets if not already present
for (var i = 1; i < bulletTypes.length; i++) {
if (!LK.getAsset(bulletTypes[i].id, {})) {}
}
// UI for bullet type
var bulletTypeTxt = new Text2('Bullet: Normal', {
size: 60,
fill: 0xffffff
});
bulletTypeTxt.anchor.set(0.5, 0);
bulletTypeTxt.y = 120;
bulletTypeTxt.x = 1024;
LK.gui.top.addChild(bulletTypeTxt);
// Button to switch bullet type (simple text button)
var switchBtn = new Text2('Change Bullet', {
size: 60,
fill: 0x00ffcc
});
switchBtn.anchor.set(0.5, 0);
switchBtn.y = 210;
switchBtn.x = 1024;
LK.gui.top.addChild(switchBtn);
// Touch/click event for switchBtn
switchBtn.down = function (x, y, obj) {
currentBulletType = (currentBulletType + 1) % bulletTypes.length;
storage.set("currentBulletType", currentBulletType);
var names = ['Normal', 'Big', 'Fast'];
bulletTypeTxt.setText('Bullet: ' + names[currentBulletType]);
};
var scoreTxt = new Text2('Zones: 0/4', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
function updateScore() {
scoreTxt.setText('Zones: ' + capturedZones + '/' + totalZones);
if (capturedZones >= totalZones) {
LK.showYouWin({
text: "Mission Passed"
});
}
;
// Update reload bar position and progress, animate fill and update bullet icons
if (typeof reloadBar !== "undefined" && typeof player !== "undefined") {
reloadBar.x = player.x;
reloadBar.y = player.y - 170;
// Update bullet icons: show filled for each bullet in magazine, empty for spent
if (typeof playerMagazine !== "undefined" && reloadBar.bulletIcons) {
for (var i = 0; i < reloadBar.bulletIcons.length; i++) {
if (i < playerMagazine && !playerReloading) {
reloadBar.bulletIcons[i].alpha = 1;
reloadBar.bulletIcons[i].color = 0xffff00;
} else {
reloadBar.bulletIcons[i].alpha = 0.3;
reloadBar.bulletIcons[i].color = 0x888888;
}
}
}
if (typeof playerReloading !== "undefined" && playerReloading) {
reloadBar.visible = true;
// Animate fill: (playerReloadTime - remaining) / playerReloadTime
if (typeof reloadStartTime !== "undefined" && typeof reloadEndTime !== "undefined" && reloadStartTime > 0 && reloadEndTime > reloadStartTime) {
var now = Date.now();
var progress = Math.min(1, Math.max(0, (now - reloadStartTime) / (reloadEndTime - reloadStartTime)));
reloadFill.width = 200 * progress;
// Animate bullet icons: fill them as reload progresses
var bulletsToShow = Math.floor(progress * 10);
for (var i = 0; i < reloadBar.bulletIcons.length; i++) {
if (i < bulletsToShow) {
reloadBar.bulletIcons[i].alpha = 1;
reloadBar.bulletIcons[i].color = 0xffff00;
} else {
reloadBar.bulletIcons[i].alpha = 0.3;
reloadBar.bulletIcons[i].color = 0x888888;
}
}
} else {
reloadFill.width = 0;
}
} else if (typeof playerReloading !== "undefined" && !playerReloading) {
reloadBar.visible = true;
reloadFill.width = 200;
}
}
}
;
// Magazine and cooldown for player shooting
var playerMagazine = 10;
var playerMaxMagazine = 10;
var playerReloading = false;
var playerReloadTimeout = null;
var playerReloadTime = 1500; // ms
// Track reload progress for bar
var reloadStartTime = 0;
var reloadEndTime = 0;
player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
// Reload progress bar UI above player, with 7 bullet icons and animated fill
var reloadBar = new Container();
// Background bar
var reloadBg = reloadBar.attachAsset('reloadBarBg', {
anchorX: 0.5,
anchorY: 0.5
});
// Animated fill (for reload progress)
var reloadFill = reloadBar.attachAsset('reloadBarFill', {
width: 0,
anchorX: 0,
anchorY: 0.5
});
reloadFill.x = -100;
reloadFill.y = 0;
// 10 bullet icons (small ellipses) spaced evenly on the bar
reloadBar.bulletIcons = [];
var bulletIconSpacing = 20;
var bulletIconStartX = -90;
for (var i = 0; i < 10; i++) {
var icon = reloadBar.attachAsset('bullet', {
width: 18,
height: 18,
anchorX: 0.5,
anchorY: 0.5,
color: 0xffff00
});
icon.x = bulletIconStartX + i * bulletIconSpacing;
icon.y = 0;
reloadBar.bulletIcons.push(icon);
}
reloadBar.visible = true;
game.addChild(reloadBar);
var zonePositions = [{
x: 512,
y: 683
}, {
x: 1536,
y: 683
}, {
x: 512,
y: 2049
}, {
x: 1536,
y: 2049
}];
for (var i = 0; i < zonePositions.length; i++) {
var zone = new Zone(i);
zone.x = zonePositions[i].x;
zone.y = zonePositions[i].y;
zones.push(zone);
game.addChild(zone);
}
// Place walls (cephé) at strategic locations
var wallPositions = [{
x: 1024,
y: 500,
rotation: 0
},
// Top center
{
x: 1024,
y: 2200,
rotation: 0
},
// Bottom center
{
x: 400,
y: 1366,
rotation: Math.PI / 2
},
// Left center
{
x: 1648,
y: 1366,
rotation: Math.PI / 2
},
// Right center
{
x: 800,
y: 900,
rotation: 0.3
},
// Near zone 1
{
x: 1300,
y: 1800,
rotation: -0.3
} // Near zone 4
];
for (var i = 0; i < wallPositions.length; i++) {
var wall = new Wall();
wall.x = wallPositions[i].x;
wall.y = wallPositions[i].y;
if (wallPositions[i].rotation) wall.rotation = wallPositions[i].rotation;
walls.push(wall);
game.addChild(wall);
}
// Spawn enemies at zone positions
for (var i = 0; i < 3; i++) {
var enemy = new Enemy();
var zoneIndex = i % zonePositions.length;
enemy.x = zonePositions[zoneIndex].x;
enemy.y = zonePositions[zoneIndex].y;
enemies.push(enemy);
game.addChild(enemy);
}
game.down = function (x, y, obj) {
isDragging = true;
lastShootX = x;
lastShootY = y;
};
game.move = function (x, y, obj) {
if (isDragging) {
// Calculate drag direction from last position
var dx = x - lastShootX;
var dy = y - lastShootY;
var dist = Math.sqrt(dx * dx + dy * dy);
// Move player in the direction of the drag, but slower
if (dist > 0) {
var moveScale = 0.5; // Increase speed to 50% of drag
// Store previous position
var prevX = player.x;
var prevY = player.y;
player.x += dx * moveScale;
player.y += dy * moveScale;
player.x = Math.max(30, Math.min(2018, player.x));
player.y = Math.max(30, Math.min(2702, player.y));
// Check collision with walls, revert if colliding
for (var w = 0; w < walls.length; w++) {
if (player.intersects(walls[w])) {
player.x = prevX;
player.y = prevY;
break;
}
}
}
lastShootX = x;
lastShootY = y;
}
};
game.up = function (x, y, obj) {
if (isDragging) {
player.shoot(x, y);
isDragging = false;
}
};
game.update = function () {
// Update reload bar position to follow player
if (typeof reloadBar !== "undefined" && typeof player !== "undefined") {
reloadBar.x = player.x;
reloadBar.y = player.y - 170;
}
// Update zones
for (var i = zones.length - 1; i >= 0; i--) {
zones[i].checkPlayerInside(player);
}
// Update player bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Block by wall
var hitWall = false;
for (var w = 0; w < walls.length; w++) {
if (bullet.intersects(walls[w])) {
hitWall = true;
break;
}
}
if (hitWall || bullet.lifetime <= 0 || bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check collision with enemies
for (var j = enemies.length - 1; j >= 0; j--) {
if (bullet.intersects(enemies[j])) {
bullet.destroy();
bullets.splice(i, 1);
// Mini explosion effect at enemy position
var explosion = new Container();
var expAsset = explosion.attachAsset('bullet', {
width: 80,
height: 80,
color: 0xffaa00,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
explosion.x = enemies[j].x;
explosion.y = enemies[j].y;
game.addChild(explosion);
// Animate explosion: scale up and fade out, then destroy
tween(expAsset, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 350,
onComplete: function onComplete() {
explosion.destroy();
}
});
enemies[j].destroy();
enemies.splice(j, 1);
// Spawn new enemy at a random non-captured zone position
// Recalculate availableZones at spawn time to ensure accuracy
if (zones.filter(function (z) {
return !z.captured;
}).length > 0) {
// Delay enemy spawn by 2 seconds (2000ms)
LK.setTimeout(function () {
var availableZones = [];
for (var k = 0; k < zones.length; k++) {
if (!zones[k].captured) {
availableZones.push(k);
}
}
if (availableZones.length > 0) {
var newEnemy = new Enemy();
var randomIndex = Math.floor(Math.random() * availableZones.length);
var zoneIndex = availableZones[randomIndex];
newEnemy.x = zonePositions[zoneIndex].x;
newEnemy.y = zonePositions[zoneIndex].y;
enemies.push(newEnemy);
game.addChild(newEnemy);
}
}, 2000);
}
break;
}
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
// Block by wall
var hitWall = false;
for (var w = 0; w < walls.length; w++) {
if (bullet.intersects(walls[w])) {
hitWall = true;
break;
}
}
if (hitWall || bullet.lifetime <= 0 || bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check collision with player
if (bullet.intersects(player)) {
bullet.destroy();
enemyBullets.splice(i, 1);
player.takeDamage();
}
// Example: Restart the game if you want to force a full reset (uncomment to use)
// LK.showGameOver();
}
};
Gangside ghetto Neighbourhood. In-Game asset. 2d. High contrast. No shadows
Tuğladan duvar üzerinde ballas grafitisi var,west side tarzında. In-Game asset. 2d. High contrast. No shadows
Tuğla duvar duvarda CJ's Gang yazacak. In-Game asset. 2d. High contrast. No shadows
CJ. In-Game asset. 2d. High contrast. No shadows
Ballas üyesi gang. In-Game asset. 2d. High contrast. No shadows