/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, level: 1 }); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); self.bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); self.speed = 15; self.damage = 20; self.maxRange = 1200; self.distanceTraveled = 0; self.angle = 0; self.active = true; self.update = function () { if (!self.active) { return; } // Move bullet based on angle var vx = Math.cos(self.angle) * self.speed; var vy = Math.sin(self.angle) * self.speed; self.x += vx; self.y += vy; self.distanceTraveled += self.speed; // Check if bullet has reached max range if (self.distanceTraveled >= self.maxRange) { self.active = false; } // Check collision with walls for (var i = 0; i < walls.length; i++) { if (self.intersects(walls[i])) { self.active = false; break; } } // Check collision with enemies if (self.active) { for (var i = 0; i < enemies.length; i++) { if (enemies[i].active && self.intersects(enemies[i])) { enemies[i].takeDamage(self.damage); self.active = false; LK.getSound('hit').play(); break; } } } }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); self.enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.health = 50; self.maxHealth = 50; self.speed = 2; self.active = true; self.fireRate = 1500; // milliseconds between shots self.lastFired = 0; self.detectionRange = 600; self.angle = 0; self.points = 100; self.takeDamage = function (amount) { self.health -= amount; // Flash enemy red when hit LK.effects.flashObject(self, 0xff0000, 300); if (self.health <= 0) { self.active = false; score += self.points; updateScore(); // Check if all enemies are defeated var allDefeated = true; for (var i = 0; i < enemies.length; i++) { if (enemies[i].active) { allDefeated = false; break; } } if (allDefeated && objectives.length === 0) { LK.showYouWin(); } } }; self.update = function () { if (!self.active || !player.active) { return; } // Calculate distance to player var dx = player.x - self.x; var dy = player.y - self.y; var distToPlayer = Math.sqrt(dx * dx + dy * dy); // Calculate angle to player self.angle = Math.atan2(dy, dx); self.enemyGraphics.rotation = self.angle; // If player is within detection range, move towards player and shoot if (distToPlayer < self.detectionRange) { // Check if path to player is clear var canSeePlayer = true; var steps = 10; for (var i = 1; i < steps; i++) { var checkX = self.x + dx * i / steps; var checkY = self.y + dy * i / steps; for (var j = 0; j < walls.length; j++) { var wall = walls[j]; if (checkX > wall.x - wall.width / 2 && checkX < wall.x + wall.width / 2 && checkY > wall.y - wall.height / 2 && checkY < wall.y + wall.height / 2) { canSeePlayer = false; break; } } if (!canSeePlayer) { break; } } if (canSeePlayer) { // Move towards player if not too close if (distToPlayer > 200) { var moveX = Math.cos(self.angle) * self.speed; var moveY = Math.sin(self.angle) * self.speed; var newX = self.x + moveX; var newY = self.y + moveY; // Check for wall collisions var canMove = true; for (var i = 0; i < walls.length; i++) { var wall = walls[i]; if (Math.abs(newX - wall.x) < self.enemyGraphics.width / 2 + wall.width / 2 && Math.abs(newY - wall.y) < self.enemyGraphics.height / 2 + wall.height / 2) { canMove = false; break; } } if (canMove) { self.x = newX; self.y = newY; } } // Try to shoot var currentTime = Date.now(); if (currentTime - self.lastFired > self.fireRate) { self.lastFired = currentTime; var bullet = new EnemyBullet(); bullet.x = self.x; bullet.y = self.y; bullet.angle = self.angle; enemyBullets.push(bullet); game.addChild(bullet); LK.getSound('enemyShoot').play(); } } } }; return self; }); var EnemyBullet = Container.expand(function () { var self = Container.call(this); self.bulletGraphics = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); self.speed = 10; self.damage = 10; self.maxRange = 1000; self.distanceTraveled = 0; self.angle = 0; self.active = true; self.update = function () { if (!self.active) { return; } // Move bullet based on angle var vx = Math.cos(self.angle) * self.speed; var vy = Math.sin(self.angle) * self.speed; self.x += vx; self.y += vy; self.distanceTraveled += self.speed; // Check if bullet has reached max range if (self.distanceTraveled >= self.maxRange) { self.active = false; } // Check collision with walls for (var i = 0; i < walls.length; i++) { if (self.intersects(walls[i])) { self.active = false; break; } } // Check collision with player if (self.active && self.intersects(player) && player.active) { player.takeDamage(self.damage); self.active = false; LK.getSound('hit').play(); } }; return self; }); var Objective = Container.expand(function () { var self = Container.call(this); self.objectiveGraphics = self.attachAsset('objective', { anchorX: 0.5, anchorY: 0.5 }); self.active = true; self.captureProgress = 0; self.captureTime = 3000; // 3 seconds to capture self.isPlayerInRange = false; self.lastCaptureTime = 0; self.points = 500; self.update = function () { if (!self.active) { return; } // Check if player is within capture range var dx = player.x - self.x; var dy = player.y - self.y; var distToPlayer = Math.sqrt(dx * dx + dy * dy); self.isPlayerInRange = distToPlayer < 100; if (self.isPlayerInRange && player.active) { var currentTime = Date.now(); var timeDelta = currentTime - self.lastCaptureTime; self.lastCaptureTime = currentTime; if (timeDelta > 0) { self.captureProgress += timeDelta; // Pulse effect during capture var pulseScale = 1 + 0.1 * Math.sin(currentTime / 200); self.objectiveGraphics.scale.set(pulseScale, pulseScale); } if (self.captureProgress >= self.captureTime) { self.complete(); } } else { // Reset if player leaves self.lastCaptureTime = Date.now(); self.objectiveGraphics.scale.set(1, 1); } }; self.complete = function () { if (!self.active) { return; } self.active = false; score += self.points; updateScore(); LK.getSound('objectiveComplete').play(); LK.effects.flashObject(self, 0x00ff00, 1000); // Remove from objectives array var index = objectives.indexOf(self); if (index !== -1) { objectives.splice(index, 1); } // Check win condition if (objectives.length === 0) { var allEnemiesDefeated = true; for (var i = 0; i < enemies.length; i++) { if (enemies[i].active) { allEnemiesDefeated = false; break; } } if (allEnemiesDefeated) { LK.showYouWin(); } } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); self.playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.aimLine = self.attachAsset('aimLine', { anchorX: 0, anchorY: 0.5, alpha: 0.3 }); self.health = 100; self.maxHealth = 100; self.speed = 5; self.angle = 0; self.fireRate = 300; // milliseconds between shots self.lastFired = 0; self.active = true; self.ammo = 30; self.maxAmmo = 30; self.reloading = false; self.reloadTime = 2000; // 2 seconds to reload self.weaponType = "standard"; // standard, shotgun, rifle self.takeDamage = function (amount) { self.health -= amount; updateHealthBar(); if (self.health <= 0) { self.active = false; LK.showGameOver(); } }; self.shoot = function () { if (!self.active || self.reloading) { return; } var currentTime = Date.now(); if (currentTime - self.lastFired < self.fireRate) { return; } if (self.ammo <= 0) { self.reload(); return; } self.lastFired = currentTime; self.ammo--; updateAmmoBar(); LK.getSound('shoot').play(); if (self.weaponType === "shotgun") { // Create 5 bullets in a spread pattern for (var i = -2; i <= 2; i++) { var spreadAngle = self.angle + i * 0.1; createBullet(self.x, self.y, spreadAngle); } } else if (self.weaponType === "rifle") { // Rifle has higher fire rate and damage self.fireRate = 150; var bullet = createBullet(self.x, self.y, self.angle); bullet.damage = 30; } else { // Standard pistol createBullet(self.x, self.y, self.angle); } }; self.reload = function () { if (self.reloading || self.ammo === self.maxAmmo) { return; } self.reloading = true; LK.getSound('reload').play(); LK.setTimeout(function () { self.ammo = self.maxAmmo; self.reloading = false; updateAmmoBar(); }, self.reloadTime); }; self.updateAim = function (targetX, targetY) { // Calculate angle to target var dx = targetX - self.x; var dy = targetY - self.y; self.angle = Math.atan2(dy, dx); // Rotate player to face aim direction self.playerGraphics.rotation = self.angle; // Update aim line rotation and visibility self.aimLine.rotation = self.angle; }; return self; }); var Wall = Container.expand(function () { var self = Container.call(this); self.wallGraphics = self.attachAsset('wall', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var WeaponPickup = Container.expand(function () { var self = Container.call(this); self.pickupGraphics = self.attachAsset('weaponPickup', { anchorX: 0.5, anchorY: 0.5 }); self.active = true; self.type = "standard"; // standard, shotgun, rifle self.update = function () { if (!self.active) { return; } if (self.intersects(player) && player.active) { self.pickup(); } // Rotate pickup for visual effect self.pickupGraphics.rotation += 0.02; }; self.pickup = function () { if (!self.active) { return; } self.active = false; player.weaponType = self.type; player.ammo = player.maxAmmo; updateAmmoBar(); LK.getSound('pickup').play(); // Adjust player's weapon properties based on type if (self.type === "shotgun") { player.fireRate = 800; player.maxAmmo = 8; } else if (self.type === "rifle") { player.fireRate = 150; player.maxAmmo = 25; } else { player.fireRate = 300; player.maxAmmo = 15; } // Remove from pickups array var index = weaponPickups.indexOf(self); if (index !== -1) { weaponPickups.splice(index, 1); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Game variables var player; var bullets = []; var enemyBullets = []; var enemies = []; var walls = []; var objectives = []; var weaponPickups = []; var score = 0; var level = storage.level || 1; var dragActive = false; var dragStartX = 0; var dragStartY = 0; var moveTargetX = 0; var moveTargetY = 0; var isMoving = false; var lastShootTime = 0; // UI elements var scoreTxt; var healthBar; var healthBarBg; var ammoBar; var ammoBarBg; var levelTxt; // Initialize game function initGame() { // Reset game state bullets = []; enemyBullets = []; enemies = []; walls = []; objectives = []; weaponPickups = []; score = 0; // Create player player = new Player(); player.x = 300; player.y = 300; game.addChild(player); // Create UI createUI(); // Create level based on current level createLevel(level); // Start background music LK.playMusic('bgMusic'); } function createUI() { // Score text scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.top.addChild(scoreTxt); scoreTxt.x = 120; scoreTxt.y = 20; // Level text levelTxt = new Text2('Level: ' + level, { size: 60, fill: 0xFFFFFF }); levelTxt.anchor.set(1, 0); LK.gui.topRight.addChild(levelTxt); levelTxt.x = -20; levelTxt.y = 20; // Health bar background healthBarBg = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0, tint: 0x333333 }); LK.gui.bottom.addChild(healthBarBg); healthBarBg.x = -200; healthBarBg.y = -60; // Health bar healthBar = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0, tint: 0x00cc00 }); LK.gui.bottom.addChild(healthBar); healthBar.x = -200; healthBar.y = -60; // Ammo bar background ammoBarBg = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0, tint: 0x333333 }); LK.gui.bottom.addChild(ammoBarBg); ammoBarBg.x = -200; ammoBarBg.y = -30; // Ammo bar ammoBar = LK.getAsset('ammoBar', { anchorX: 0, anchorY: 0, tint: 0x3366ff }); LK.gui.bottom.addChild(ammoBar); ammoBar.x = -200; ammoBar.y = -30; } function updateScore() { scoreTxt.setText('Score: ' + score); LK.setScore(score); // Update high score if (score > storage.highScore) { storage.highScore = score; } } function updateHealthBar() { var healthPercent = player.health / player.maxHealth; healthBar.scale.x = healthPercent; // Change color based on health if (healthPercent < 0.3) { healthBar.tint = 0xff0000; // Red when low health } else if (healthPercent < 0.6) { healthBar.tint = 0xffcc00; // Yellow when medium health } else { healthBar.tint = 0x00cc00; // Green when high health } } function updateAmmoBar() { var ammoPercent = player.ammo / player.maxAmmo; ammoBar.scale.x = ammoPercent; } function createLevel(levelNum) { // Clear any existing level elements for (var i = walls.length - 1; i >= 0; i--) { game.removeChild(walls[i]); walls.splice(i, 1); } for (var i = enemies.length - 1; i >= 0; i--) { game.removeChild(enemies[i]); enemies.splice(i, 1); } for (var i = objectives.length - 1; i >= 0; i--) { game.removeChild(objectives[i]); objectives.splice(i, 1); } for (var i = weaponPickups.length - 1; i >= 0; i--) { game.removeChild(weaponPickups[i]); weaponPickups.splice(i, 1); } // Create level based on level number if (levelNum === 1) { createLevel1(); } else if (levelNum === 2) { createLevel2(); } else if (levelNum === 3) { createLevel3(); } else { // If no specific level, create a random one createRandomLevel(); } } function createLevel1() { // Create walls for level 1 createWall(400, 400, 300, 50); createWall(800, 400, 300, 50); createWall(600, 600, 50, 400); createWall(600, 1200, 800, 50); createWall(200, 800, 50, 800); createWall(1000, 800, 50, 800); // Create enemies createEnemy(800, 200); createEnemy(1000, 600); createEnemy(400, 1000); // Create objectives createObjective(600, 1000); // Create weapon pickups createWeaponPickup(600, 400, "shotgun"); } function createLevel2() { // Create a more complex level with more enemies and obstacles // Create walls for level 2 createWall(600, 400, 1000, 50); createWall(200, 800, 50, 800); createWall(1000, 800, 50, 800); createWall(400, 800, 200, 200); createWall(800, 800, 200, 200); createWall(600, 1200, 800, 50); // Create enemies createEnemy(300, 200); createEnemy(900, 200); createEnemy(300, 600); createEnemy(900, 600); createEnemy(600, 1000); // Create objectives createObjective(400, 600); createObjective(800, 600); // Create weapon pickups createWeaponPickup(600, 200, "rifle"); createWeaponPickup(600, 800, "shotgun"); } function createLevel3() { // Create an even more complex level with more enemies and obstacles // Create walls for level 3 createWall(600, 400, 1000, 50); createWall(200, 1000, 50, 1200); createWall(1000, 1000, 50, 1200); createWall(400, 800, 100, 100); createWall(800, 800, 100, 100); createWall(400, 1200, 100, 100); createWall(800, 1200, 100, 100); createWall(600, 1500, 800, 50); // Create enemies createEnemy(300, 200); createEnemy(900, 200); createEnemy(300, 600); createEnemy(900, 600); createEnemy(300, 1000); createEnemy(900, 1000); createEnemy(600, 1300); // Create objectives createObjective(400, 600); createObjective(800, 600); createObjective(600, 1000); // Create weapon pickups createWeaponPickup(200, 500, "rifle"); createWeaponPickup(1000, 500, "shotgun"); createWeaponPickup(600, 1300, "rifle"); } function createRandomLevel() { // Create a random level with walls, enemies, and objectives var numWalls = 10 + level * 2; var numEnemies = 5 + level; var numObjectives = 2 + Math.floor(level / 2); var numPickups = 1 + Math.floor(level / 2); // Create boundary walls createWall(600, 100, 1000, 50); createWall(600, 2000, 1000, 50); createWall(100, 1050, 50, 1900); createWall(1100, 1050, 50, 1900); // Create random walls for (var i = 0; i < numWalls; i++) { var x = 200 + Math.random() * 800; var y = 200 + Math.random() * 1600; var width = 50 + Math.random() * 200; var height = 50 + Math.random() * 200; if (Math.random() < 0.5) { // Horizontal wall createWall(x, y, width, 50); } else { // Vertical wall createWall(x, y, 50, height); } } // Create random enemies for (var i = 0; i < numEnemies; i++) { var x = 200 + Math.random() * 800; var y = 300 + Math.random() * 1400; // Make sure enemy is not too close to player if (Math.sqrt(Math.pow(x - player.x, 2) + Math.pow(y - player.y, 2)) > 400) { createEnemy(x, y); } } // Create random objectives for (var i = 0; i < numObjectives; i++) { var x = 200 + Math.random() * 800; var y = 300 + Math.random() * 1400; createObjective(x, y); } // Create random weapon pickups for (var i = 0; i < numPickups; i++) { var x = 200 + Math.random() * 800; var y = 300 + Math.random() * 1400; var type = Math.random() < 0.5 ? "shotgun" : "rifle"; createWeaponPickup(x, y, type); } } function createWall(x, y, width, height) { var wall = new Wall(); wall.x = x; wall.y = y; wall.wallGraphics.width = width; wall.wallGraphics.height = height; walls.push(wall); game.addChild(wall); return wall; } function createEnemy(x, y) { var enemy = new Enemy(); enemy.x = x; enemy.y = y; enemies.push(enemy); game.addChild(enemy); return enemy; } function createObjective(x, y) { var objective = new Objective(); objective.x = x; objective.y = y; objectives.push(objective); game.addChild(objective); return objective; } function createWeaponPickup(x, y, type) { var pickup = new WeaponPickup(); pickup.x = x; pickup.y = y; pickup.type = type; // Change color based on weapon type if (type === "shotgun") { pickup.pickupGraphics.tint = 0xff9900; } else if (type === "rifle") { pickup.pickupGraphics.tint = 0x6699ff; } weaponPickups.push(pickup); game.addChild(pickup); return pickup; } function createBullet(x, y, angle) { var bullet = new Bullet(); bullet.x = x; bullet.y = y; bullet.angle = angle; bullets.push(bullet); game.addChild(bullet); return bullet; } function handlePlayerMovement() { if (!isMoving || !player.active) { return; } var dx = moveTargetX - player.x; var dy = moveTargetY - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < player.speed) { // Arrived at destination isMoving = false; return; } // Normalize direction vector var dirX = dx / distance; var dirY = dy / distance; // Calculate new position var newX = player.x + dirX * player.speed; var newY = player.y + dirY * player.speed; // Check for wall collisions var canMove = true; for (var i = 0; i < walls.length; i++) { var wall = walls[i]; var playerRadius = player.playerGraphics.width / 2; // Simple collision check between circle (player) and rectangle (wall) var testX = newX; var testY = newY; if (newX < wall.x - wall.wallGraphics.width / 2) { testX = wall.x - wall.wallGraphics.width / 2; } else if (newX > wall.x + wall.wallGraphics.width / 2) { testX = wall.x + wall.wallGraphics.width / 2; } if (newY < wall.y - wall.wallGraphics.height / 2) { testY = wall.y - wall.wallGraphics.height / 2; } else if (newY > wall.y + wall.wallGraphics.height / 2) { testY = wall.y + wall.wallGraphics.height / 2; } var distX = newX - testX; var distY = newY - testY; var distance = Math.sqrt(distX * distX + distY * distY); if (distance < playerRadius) { canMove = false; break; } } if (canMove) { player.x = newX; player.y = newY; } else { // Try to slide along walls var canMoveX = true; var canMoveY = true; // Check X movement only for (var i = 0; i < walls.length; i++) { var wall = walls[i]; var playerRadius = player.playerGraphics.width / 2; var testX = player.x + dirX * player.speed; var testY = player.y; var closestX = testX; var closestY = testY; if (testX < wall.x - wall.wallGraphics.width / 2) { closestX = wall.x - wall.wallGraphics.width / 2; } else if (testX > wall.x + wall.wallGraphics.width / 2) { closestX = wall.x + wall.wallGraphics.width / 2; } if (testY < wall.y - wall.wallGraphics.height / 2) { closestY = wall.y - wall.wallGraphics.height / 2; } else if (testY > wall.y + wall.wallGraphics.height / 2) { closestY = wall.y + wall.wallGraphics.height / 2; } var distX = testX - closestX; var distY = testY - closestY; var distance = Math.sqrt(distX * distX + distY * distY); if (distance < playerRadius) { canMoveX = false; break; } } // Check Y movement only for (var i = 0; i < walls.length; i++) { var wall = walls[i]; var playerRadius = player.playerGraphics.width / 2; var testX = player.x; var testY = player.y + dirY * player.speed; var closestX = testX; var closestY = testY; if (testX < wall.x - wall.wallGraphics.width / 2) { closestX = wall.x - wall.wallGraphics.width / 2; } else if (testX > wall.x + wall.wallGraphics.width / 2) { closestX = wall.x + wall.wallGraphics.width / 2; } if (testY < wall.y - wall.wallGraphics.height / 2) { closestY = wall.y - wall.wallGraphics.height / 2; } else if (testY > wall.y + wall.wallGraphics.height / 2) { closestY = wall.y + wall.wallGraphics.height / 2; } var distX = testX - closestX; var distY = testY - closestY; var distance = Math.sqrt(distX * distX + distY * distY); if (distance < playerRadius) { canMoveY = false; break; } } // Apply sliding movement if (canMoveX) { player.x += dirX * player.speed; } if (canMoveY) { player.y += dirY * player.speed; } } } // Game input handlers game.down = function (x, y, obj) { if (!player.active) { return; } dragActive = true; dragStartX = x; dragStartY = y; // Calculate time since last shoot var currentTime = Date.now(); if (currentTime - lastShootTime < 300) { // Double tap detected - shoot player.shoot(); } lastShootTime = currentTime; }; game.up = function (x, y, obj) { dragActive = false; // Set movement target if drag distance is small var dragDistX = x - dragStartX; var dragDistY = y - dragStartY; var dragDist = Math.sqrt(dragDistX * dragDistX + dragDistY * dragDistY); if (dragDist < 20) { // Tap (not drag) - set movement target moveTargetX = x; moveTargetY = y; isMoving = true; } }; game.move = function (x, y, obj) { if (!dragActive || !player.active) { return; } // Update player aim direction player.updateAim(x, y); // Check if drag distance is large enough to be considered a drag rather than a tap var dragDistX = x - dragStartX; var dragDistY = y - dragStartY; var dragDist = Math.sqrt(dragDistX * dragDistX + dragDistY * dragDistY); if (dragDist > 20) { // Long enough drag - shoot player.shoot(); } }; // Game update loop game.update = function () { // Handle player movement handlePlayerMovement(); // Update all bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (!bullet.active) { game.removeChild(bullet); bullets.splice(i, 1); continue; } } // Update all enemy bullets for (var i = enemyBullets.length - 1; i >= 0; i--) { var bullet = enemyBullets[i]; if (!bullet.active) { game.removeChild(bullet); enemyBullets.splice(i, 1); continue; } } // Update all enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; if (!enemy.active) { game.removeChild(enemy); enemies.splice(i, 1); continue; } } // Update all objectives for (var i = objectives.length - 1; i >= 0; i--) { var objective = objectives[i]; if (!objective.active) { game.removeChild(objective); objectives.splice(i, 1); continue; } } // Update all weapon pickups for (var i = weaponPickups.length - 1; i >= 0; i--) { var pickup = weaponPickups[i]; if (!pickup.active) { game.removeChild(pickup); weaponPickups.splice(i, 1); continue; } } // Check for win condition if (objectives.length === 0 && enemies.length === 0) { // Level completed level++; storage.level = level; // Check if we have more levels if (level <= 3) { // Advance to next level LK.showYouWin(); } else { // Game completed LK.showYouWin(); level = 1; // Reset level for next game storage.level = level; } } }; // Initialize the game initGame();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,976 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ highScore: 0,
+ level: 1
+});
+
+/****
+* Classes
+****/
+var Bullet = Container.expand(function () {
+ var self = Container.call(this);
+ self.bulletGraphics = self.attachAsset('bullet', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 1,
+ scaleY: 1
+ });
+ self.speed = 15;
+ self.damage = 20;
+ self.maxRange = 1200;
+ self.distanceTraveled = 0;
+ self.angle = 0;
+ self.active = true;
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ // Move bullet based on angle
+ var vx = Math.cos(self.angle) * self.speed;
+ var vy = Math.sin(self.angle) * self.speed;
+ self.x += vx;
+ self.y += vy;
+ self.distanceTraveled += self.speed;
+ // Check if bullet has reached max range
+ if (self.distanceTraveled >= self.maxRange) {
+ self.active = false;
+ }
+ // Check collision with walls
+ for (var i = 0; i < walls.length; i++) {
+ if (self.intersects(walls[i])) {
+ self.active = false;
+ break;
+ }
+ }
+ // Check collision with enemies
+ if (self.active) {
+ for (var i = 0; i < enemies.length; i++) {
+ if (enemies[i].active && self.intersects(enemies[i])) {
+ enemies[i].takeDamage(self.damage);
+ self.active = false;
+ LK.getSound('hit').play();
+ break;
+ }
+ }
+ }
+ };
+ return self;
+});
+var Enemy = Container.expand(function () {
+ var self = Container.call(this);
+ self.enemyGraphics = self.attachAsset('enemy', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.health = 50;
+ self.maxHealth = 50;
+ self.speed = 2;
+ self.active = true;
+ self.fireRate = 1500; // milliseconds between shots
+ self.lastFired = 0;
+ self.detectionRange = 600;
+ self.angle = 0;
+ self.points = 100;
+ self.takeDamage = function (amount) {
+ self.health -= amount;
+ // Flash enemy red when hit
+ LK.effects.flashObject(self, 0xff0000, 300);
+ if (self.health <= 0) {
+ self.active = false;
+ score += self.points;
+ updateScore();
+ // Check if all enemies are defeated
+ var allDefeated = true;
+ for (var i = 0; i < enemies.length; i++) {
+ if (enemies[i].active) {
+ allDefeated = false;
+ break;
+ }
+ }
+ if (allDefeated && objectives.length === 0) {
+ LK.showYouWin();
+ }
+ }
+ };
+ self.update = function () {
+ if (!self.active || !player.active) {
+ return;
+ }
+ // Calculate distance to player
+ var dx = player.x - self.x;
+ var dy = player.y - self.y;
+ var distToPlayer = Math.sqrt(dx * dx + dy * dy);
+ // Calculate angle to player
+ self.angle = Math.atan2(dy, dx);
+ self.enemyGraphics.rotation = self.angle;
+ // If player is within detection range, move towards player and shoot
+ if (distToPlayer < self.detectionRange) {
+ // Check if path to player is clear
+ var canSeePlayer = true;
+ var steps = 10;
+ for (var i = 1; i < steps; i++) {
+ var checkX = self.x + dx * i / steps;
+ var checkY = self.y + dy * i / steps;
+ for (var j = 0; j < walls.length; j++) {
+ var wall = walls[j];
+ if (checkX > wall.x - wall.width / 2 && checkX < wall.x + wall.width / 2 && checkY > wall.y - wall.height / 2 && checkY < wall.y + wall.height / 2) {
+ canSeePlayer = false;
+ break;
+ }
+ }
+ if (!canSeePlayer) {
+ break;
+ }
+ }
+ if (canSeePlayer) {
+ // Move towards player if not too close
+ if (distToPlayer > 200) {
+ var moveX = Math.cos(self.angle) * self.speed;
+ var moveY = Math.sin(self.angle) * self.speed;
+ var newX = self.x + moveX;
+ var newY = self.y + moveY;
+ // Check for wall collisions
+ var canMove = true;
+ for (var i = 0; i < walls.length; i++) {
+ var wall = walls[i];
+ if (Math.abs(newX - wall.x) < self.enemyGraphics.width / 2 + wall.width / 2 && Math.abs(newY - wall.y) < self.enemyGraphics.height / 2 + wall.height / 2) {
+ canMove = false;
+ break;
+ }
+ }
+ if (canMove) {
+ self.x = newX;
+ self.y = newY;
+ }
+ }
+ // Try to shoot
+ var currentTime = Date.now();
+ if (currentTime - self.lastFired > self.fireRate) {
+ self.lastFired = currentTime;
+ var bullet = new EnemyBullet();
+ bullet.x = self.x;
+ bullet.y = self.y;
+ bullet.angle = self.angle;
+ enemyBullets.push(bullet);
+ game.addChild(bullet);
+ LK.getSound('enemyShoot').play();
+ }
+ }
+ }
+ };
+ return self;
+});
+var EnemyBullet = Container.expand(function () {
+ var self = Container.call(this);
+ self.bulletGraphics = self.attachAsset('enemyBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 1,
+ scaleY: 1
+ });
+ self.speed = 10;
+ self.damage = 10;
+ self.maxRange = 1000;
+ self.distanceTraveled = 0;
+ self.angle = 0;
+ self.active = true;
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ // Move bullet based on angle
+ var vx = Math.cos(self.angle) * self.speed;
+ var vy = Math.sin(self.angle) * self.speed;
+ self.x += vx;
+ self.y += vy;
+ self.distanceTraveled += self.speed;
+ // Check if bullet has reached max range
+ if (self.distanceTraveled >= self.maxRange) {
+ self.active = false;
+ }
+ // Check collision with walls
+ for (var i = 0; i < walls.length; i++) {
+ if (self.intersects(walls[i])) {
+ self.active = false;
+ break;
+ }
+ }
+ // Check collision with player
+ if (self.active && self.intersects(player) && player.active) {
+ player.takeDamage(self.damage);
+ self.active = false;
+ LK.getSound('hit').play();
+ }
+ };
+ return self;
+});
+var Objective = Container.expand(function () {
+ var self = Container.call(this);
+ self.objectiveGraphics = self.attachAsset('objective', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.active = true;
+ self.captureProgress = 0;
+ self.captureTime = 3000; // 3 seconds to capture
+ self.isPlayerInRange = false;
+ self.lastCaptureTime = 0;
+ self.points = 500;
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ // Check if player is within capture range
+ var dx = player.x - self.x;
+ var dy = player.y - self.y;
+ var distToPlayer = Math.sqrt(dx * dx + dy * dy);
+ self.isPlayerInRange = distToPlayer < 100;
+ if (self.isPlayerInRange && player.active) {
+ var currentTime = Date.now();
+ var timeDelta = currentTime - self.lastCaptureTime;
+ self.lastCaptureTime = currentTime;
+ if (timeDelta > 0) {
+ self.captureProgress += timeDelta;
+ // Pulse effect during capture
+ var pulseScale = 1 + 0.1 * Math.sin(currentTime / 200);
+ self.objectiveGraphics.scale.set(pulseScale, pulseScale);
+ }
+ if (self.captureProgress >= self.captureTime) {
+ self.complete();
+ }
+ } else {
+ // Reset if player leaves
+ self.lastCaptureTime = Date.now();
+ self.objectiveGraphics.scale.set(1, 1);
+ }
+ };
+ self.complete = function () {
+ if (!self.active) {
+ return;
+ }
+ self.active = false;
+ score += self.points;
+ updateScore();
+ LK.getSound('objectiveComplete').play();
+ LK.effects.flashObject(self, 0x00ff00, 1000);
+ // Remove from objectives array
+ var index = objectives.indexOf(self);
+ if (index !== -1) {
+ objectives.splice(index, 1);
+ }
+ // Check win condition
+ if (objectives.length === 0) {
+ var allEnemiesDefeated = true;
+ for (var i = 0; i < enemies.length; i++) {
+ if (enemies[i].active) {
+ allEnemiesDefeated = false;
+ break;
+ }
+ }
+ if (allEnemiesDefeated) {
+ LK.showYouWin();
+ }
+ }
+ };
+ return self;
+});
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ self.playerGraphics = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.aimLine = self.attachAsset('aimLine', {
+ anchorX: 0,
+ anchorY: 0.5,
+ alpha: 0.3
+ });
+ self.health = 100;
+ self.maxHealth = 100;
+ self.speed = 5;
+ self.angle = 0;
+ self.fireRate = 300; // milliseconds between shots
+ self.lastFired = 0;
+ self.active = true;
+ self.ammo = 30;
+ self.maxAmmo = 30;
+ self.reloading = false;
+ self.reloadTime = 2000; // 2 seconds to reload
+ self.weaponType = "standard"; // standard, shotgun, rifle
+ self.takeDamage = function (amount) {
+ self.health -= amount;
+ updateHealthBar();
+ if (self.health <= 0) {
+ self.active = false;
+ LK.showGameOver();
+ }
+ };
+ self.shoot = function () {
+ if (!self.active || self.reloading) {
+ return;
+ }
+ var currentTime = Date.now();
+ if (currentTime - self.lastFired < self.fireRate) {
+ return;
+ }
+ if (self.ammo <= 0) {
+ self.reload();
+ return;
+ }
+ self.lastFired = currentTime;
+ self.ammo--;
+ updateAmmoBar();
+ LK.getSound('shoot').play();
+ if (self.weaponType === "shotgun") {
+ // Create 5 bullets in a spread pattern
+ for (var i = -2; i <= 2; i++) {
+ var spreadAngle = self.angle + i * 0.1;
+ createBullet(self.x, self.y, spreadAngle);
+ }
+ } else if (self.weaponType === "rifle") {
+ // Rifle has higher fire rate and damage
+ self.fireRate = 150;
+ var bullet = createBullet(self.x, self.y, self.angle);
+ bullet.damage = 30;
+ } else {
+ // Standard pistol
+ createBullet(self.x, self.y, self.angle);
+ }
+ };
+ self.reload = function () {
+ if (self.reloading || self.ammo === self.maxAmmo) {
+ return;
+ }
+ self.reloading = true;
+ LK.getSound('reload').play();
+ LK.setTimeout(function () {
+ self.ammo = self.maxAmmo;
+ self.reloading = false;
+ updateAmmoBar();
+ }, self.reloadTime);
+ };
+ self.updateAim = function (targetX, targetY) {
+ // Calculate angle to target
+ var dx = targetX - self.x;
+ var dy = targetY - self.y;
+ self.angle = Math.atan2(dy, dx);
+ // Rotate player to face aim direction
+ self.playerGraphics.rotation = self.angle;
+ // Update aim line rotation and visibility
+ self.aimLine.rotation = self.angle;
+ };
+ return self;
+});
+var Wall = Container.expand(function () {
+ var self = Container.call(this);
+ self.wallGraphics = self.attachAsset('wall', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ return self;
+});
+var WeaponPickup = Container.expand(function () {
+ var self = Container.call(this);
+ self.pickupGraphics = self.attachAsset('weaponPickup', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.active = true;
+ self.type = "standard"; // standard, shotgun, rifle
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ if (self.intersects(player) && player.active) {
+ self.pickup();
+ }
+ // Rotate pickup for visual effect
+ self.pickupGraphics.rotation += 0.02;
+ };
+ self.pickup = function () {
+ if (!self.active) {
+ return;
+ }
+ self.active = false;
+ player.weaponType = self.type;
+ player.ammo = player.maxAmmo;
+ updateAmmoBar();
+ LK.getSound('pickup').play();
+ // Adjust player's weapon properties based on type
+ if (self.type === "shotgun") {
+ player.fireRate = 800;
+ player.maxAmmo = 8;
+ } else if (self.type === "rifle") {
+ player.fireRate = 150;
+ player.maxAmmo = 25;
+ } else {
+ player.fireRate = 300;
+ player.maxAmmo = 15;
+ }
+ // Remove from pickups array
+ var index = weaponPickups.indexOf(self);
+ if (index !== -1) {
+ weaponPickups.splice(index, 1);
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x222222
+});
+
+/****
+* Game Code
+****/
+// Game variables
+var player;
+var bullets = [];
+var enemyBullets = [];
+var enemies = [];
+var walls = [];
+var objectives = [];
+var weaponPickups = [];
+var score = 0;
+var level = storage.level || 1;
+var dragActive = false;
+var dragStartX = 0;
+var dragStartY = 0;
+var moveTargetX = 0;
+var moveTargetY = 0;
+var isMoving = false;
+var lastShootTime = 0;
+// UI elements
+var scoreTxt;
+var healthBar;
+var healthBarBg;
+var ammoBar;
+var ammoBarBg;
+var levelTxt;
+// Initialize game
+function initGame() {
+ // Reset game state
+ bullets = [];
+ enemyBullets = [];
+ enemies = [];
+ walls = [];
+ objectives = [];
+ weaponPickups = [];
+ score = 0;
+ // Create player
+ player = new Player();
+ player.x = 300;
+ player.y = 300;
+ game.addChild(player);
+ // Create UI
+ createUI();
+ // Create level based on current level
+ createLevel(level);
+ // Start background music
+ LK.playMusic('bgMusic');
+}
+function createUI() {
+ // Score text
+ scoreTxt = new Text2('Score: 0', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ scoreTxt.anchor.set(0, 0);
+ LK.gui.top.addChild(scoreTxt);
+ scoreTxt.x = 120;
+ scoreTxt.y = 20;
+ // Level text
+ levelTxt = new Text2('Level: ' + level, {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ levelTxt.anchor.set(1, 0);
+ LK.gui.topRight.addChild(levelTxt);
+ levelTxt.x = -20;
+ levelTxt.y = 20;
+ // Health bar background
+ healthBarBg = LK.getAsset('healthBar', {
+ anchorX: 0,
+ anchorY: 0,
+ tint: 0x333333
+ });
+ LK.gui.bottom.addChild(healthBarBg);
+ healthBarBg.x = -200;
+ healthBarBg.y = -60;
+ // Health bar
+ healthBar = LK.getAsset('healthBar', {
+ anchorX: 0,
+ anchorY: 0,
+ tint: 0x00cc00
+ });
+ LK.gui.bottom.addChild(healthBar);
+ healthBar.x = -200;
+ healthBar.y = -60;
+ // Ammo bar background
+ ammoBarBg = LK.getAsset('healthBar', {
+ anchorX: 0,
+ anchorY: 0,
+ tint: 0x333333
+ });
+ LK.gui.bottom.addChild(ammoBarBg);
+ ammoBarBg.x = -200;
+ ammoBarBg.y = -30;
+ // Ammo bar
+ ammoBar = LK.getAsset('ammoBar', {
+ anchorX: 0,
+ anchorY: 0,
+ tint: 0x3366ff
+ });
+ LK.gui.bottom.addChild(ammoBar);
+ ammoBar.x = -200;
+ ammoBar.y = -30;
+}
+function updateScore() {
+ scoreTxt.setText('Score: ' + score);
+ LK.setScore(score);
+ // Update high score
+ if (score > storage.highScore) {
+ storage.highScore = score;
+ }
+}
+function updateHealthBar() {
+ var healthPercent = player.health / player.maxHealth;
+ healthBar.scale.x = healthPercent;
+ // Change color based on health
+ if (healthPercent < 0.3) {
+ healthBar.tint = 0xff0000; // Red when low health
+ } else if (healthPercent < 0.6) {
+ healthBar.tint = 0xffcc00; // Yellow when medium health
+ } else {
+ healthBar.tint = 0x00cc00; // Green when high health
+ }
+}
+function updateAmmoBar() {
+ var ammoPercent = player.ammo / player.maxAmmo;
+ ammoBar.scale.x = ammoPercent;
+}
+function createLevel(levelNum) {
+ // Clear any existing level elements
+ for (var i = walls.length - 1; i >= 0; i--) {
+ game.removeChild(walls[i]);
+ walls.splice(i, 1);
+ }
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ game.removeChild(enemies[i]);
+ enemies.splice(i, 1);
+ }
+ for (var i = objectives.length - 1; i >= 0; i--) {
+ game.removeChild(objectives[i]);
+ objectives.splice(i, 1);
+ }
+ for (var i = weaponPickups.length - 1; i >= 0; i--) {
+ game.removeChild(weaponPickups[i]);
+ weaponPickups.splice(i, 1);
+ }
+ // Create level based on level number
+ if (levelNum === 1) {
+ createLevel1();
+ } else if (levelNum === 2) {
+ createLevel2();
+ } else if (levelNum === 3) {
+ createLevel3();
+ } else {
+ // If no specific level, create a random one
+ createRandomLevel();
+ }
+}
+function createLevel1() {
+ // Create walls for level 1
+ createWall(400, 400, 300, 50);
+ createWall(800, 400, 300, 50);
+ createWall(600, 600, 50, 400);
+ createWall(600, 1200, 800, 50);
+ createWall(200, 800, 50, 800);
+ createWall(1000, 800, 50, 800);
+ // Create enemies
+ createEnemy(800, 200);
+ createEnemy(1000, 600);
+ createEnemy(400, 1000);
+ // Create objectives
+ createObjective(600, 1000);
+ // Create weapon pickups
+ createWeaponPickup(600, 400, "shotgun");
+}
+function createLevel2() {
+ // Create a more complex level with more enemies and obstacles
+ // Create walls for level 2
+ createWall(600, 400, 1000, 50);
+ createWall(200, 800, 50, 800);
+ createWall(1000, 800, 50, 800);
+ createWall(400, 800, 200, 200);
+ createWall(800, 800, 200, 200);
+ createWall(600, 1200, 800, 50);
+ // Create enemies
+ createEnemy(300, 200);
+ createEnemy(900, 200);
+ createEnemy(300, 600);
+ createEnemy(900, 600);
+ createEnemy(600, 1000);
+ // Create objectives
+ createObjective(400, 600);
+ createObjective(800, 600);
+ // Create weapon pickups
+ createWeaponPickup(600, 200, "rifle");
+ createWeaponPickup(600, 800, "shotgun");
+}
+function createLevel3() {
+ // Create an even more complex level with more enemies and obstacles
+ // Create walls for level 3
+ createWall(600, 400, 1000, 50);
+ createWall(200, 1000, 50, 1200);
+ createWall(1000, 1000, 50, 1200);
+ createWall(400, 800, 100, 100);
+ createWall(800, 800, 100, 100);
+ createWall(400, 1200, 100, 100);
+ createWall(800, 1200, 100, 100);
+ createWall(600, 1500, 800, 50);
+ // Create enemies
+ createEnemy(300, 200);
+ createEnemy(900, 200);
+ createEnemy(300, 600);
+ createEnemy(900, 600);
+ createEnemy(300, 1000);
+ createEnemy(900, 1000);
+ createEnemy(600, 1300);
+ // Create objectives
+ createObjective(400, 600);
+ createObjective(800, 600);
+ createObjective(600, 1000);
+ // Create weapon pickups
+ createWeaponPickup(200, 500, "rifle");
+ createWeaponPickup(1000, 500, "shotgun");
+ createWeaponPickup(600, 1300, "rifle");
+}
+function createRandomLevel() {
+ // Create a random level with walls, enemies, and objectives
+ var numWalls = 10 + level * 2;
+ var numEnemies = 5 + level;
+ var numObjectives = 2 + Math.floor(level / 2);
+ var numPickups = 1 + Math.floor(level / 2);
+ // Create boundary walls
+ createWall(600, 100, 1000, 50);
+ createWall(600, 2000, 1000, 50);
+ createWall(100, 1050, 50, 1900);
+ createWall(1100, 1050, 50, 1900);
+ // Create random walls
+ for (var i = 0; i < numWalls; i++) {
+ var x = 200 + Math.random() * 800;
+ var y = 200 + Math.random() * 1600;
+ var width = 50 + Math.random() * 200;
+ var height = 50 + Math.random() * 200;
+ if (Math.random() < 0.5) {
+ // Horizontal wall
+ createWall(x, y, width, 50);
+ } else {
+ // Vertical wall
+ createWall(x, y, 50, height);
+ }
+ }
+ // Create random enemies
+ for (var i = 0; i < numEnemies; i++) {
+ var x = 200 + Math.random() * 800;
+ var y = 300 + Math.random() * 1400;
+ // Make sure enemy is not too close to player
+ if (Math.sqrt(Math.pow(x - player.x, 2) + Math.pow(y - player.y, 2)) > 400) {
+ createEnemy(x, y);
+ }
+ }
+ // Create random objectives
+ for (var i = 0; i < numObjectives; i++) {
+ var x = 200 + Math.random() * 800;
+ var y = 300 + Math.random() * 1400;
+ createObjective(x, y);
+ }
+ // Create random weapon pickups
+ for (var i = 0; i < numPickups; i++) {
+ var x = 200 + Math.random() * 800;
+ var y = 300 + Math.random() * 1400;
+ var type = Math.random() < 0.5 ? "shotgun" : "rifle";
+ createWeaponPickup(x, y, type);
+ }
+}
+function createWall(x, y, width, height) {
+ var wall = new Wall();
+ wall.x = x;
+ wall.y = y;
+ wall.wallGraphics.width = width;
+ wall.wallGraphics.height = height;
+ walls.push(wall);
+ game.addChild(wall);
+ return wall;
+}
+function createEnemy(x, y) {
+ var enemy = new Enemy();
+ enemy.x = x;
+ enemy.y = y;
+ enemies.push(enemy);
+ game.addChild(enemy);
+ return enemy;
+}
+function createObjective(x, y) {
+ var objective = new Objective();
+ objective.x = x;
+ objective.y = y;
+ objectives.push(objective);
+ game.addChild(objective);
+ return objective;
+}
+function createWeaponPickup(x, y, type) {
+ var pickup = new WeaponPickup();
+ pickup.x = x;
+ pickup.y = y;
+ pickup.type = type;
+ // Change color based on weapon type
+ if (type === "shotgun") {
+ pickup.pickupGraphics.tint = 0xff9900;
+ } else if (type === "rifle") {
+ pickup.pickupGraphics.tint = 0x6699ff;
+ }
+ weaponPickups.push(pickup);
+ game.addChild(pickup);
+ return pickup;
+}
+function createBullet(x, y, angle) {
+ var bullet = new Bullet();
+ bullet.x = x;
+ bullet.y = y;
+ bullet.angle = angle;
+ bullets.push(bullet);
+ game.addChild(bullet);
+ return bullet;
+}
+function handlePlayerMovement() {
+ if (!isMoving || !player.active) {
+ return;
+ }
+ var dx = moveTargetX - player.x;
+ var dy = moveTargetY - player.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < player.speed) {
+ // Arrived at destination
+ isMoving = false;
+ return;
+ }
+ // Normalize direction vector
+ var dirX = dx / distance;
+ var dirY = dy / distance;
+ // Calculate new position
+ var newX = player.x + dirX * player.speed;
+ var newY = player.y + dirY * player.speed;
+ // Check for wall collisions
+ var canMove = true;
+ for (var i = 0; i < walls.length; i++) {
+ var wall = walls[i];
+ var playerRadius = player.playerGraphics.width / 2;
+ // Simple collision check between circle (player) and rectangle (wall)
+ var testX = newX;
+ var testY = newY;
+ if (newX < wall.x - wall.wallGraphics.width / 2) {
+ testX = wall.x - wall.wallGraphics.width / 2;
+ } else if (newX > wall.x + wall.wallGraphics.width / 2) {
+ testX = wall.x + wall.wallGraphics.width / 2;
+ }
+ if (newY < wall.y - wall.wallGraphics.height / 2) {
+ testY = wall.y - wall.wallGraphics.height / 2;
+ } else if (newY > wall.y + wall.wallGraphics.height / 2) {
+ testY = wall.y + wall.wallGraphics.height / 2;
+ }
+ var distX = newX - testX;
+ var distY = newY - testY;
+ var distance = Math.sqrt(distX * distX + distY * distY);
+ if (distance < playerRadius) {
+ canMove = false;
+ break;
+ }
+ }
+ if (canMove) {
+ player.x = newX;
+ player.y = newY;
+ } else {
+ // Try to slide along walls
+ var canMoveX = true;
+ var canMoveY = true;
+ // Check X movement only
+ for (var i = 0; i < walls.length; i++) {
+ var wall = walls[i];
+ var playerRadius = player.playerGraphics.width / 2;
+ var testX = player.x + dirX * player.speed;
+ var testY = player.y;
+ var closestX = testX;
+ var closestY = testY;
+ if (testX < wall.x - wall.wallGraphics.width / 2) {
+ closestX = wall.x - wall.wallGraphics.width / 2;
+ } else if (testX > wall.x + wall.wallGraphics.width / 2) {
+ closestX = wall.x + wall.wallGraphics.width / 2;
+ }
+ if (testY < wall.y - wall.wallGraphics.height / 2) {
+ closestY = wall.y - wall.wallGraphics.height / 2;
+ } else if (testY > wall.y + wall.wallGraphics.height / 2) {
+ closestY = wall.y + wall.wallGraphics.height / 2;
+ }
+ var distX = testX - closestX;
+ var distY = testY - closestY;
+ var distance = Math.sqrt(distX * distX + distY * distY);
+ if (distance < playerRadius) {
+ canMoveX = false;
+ break;
+ }
+ }
+ // Check Y movement only
+ for (var i = 0; i < walls.length; i++) {
+ var wall = walls[i];
+ var playerRadius = player.playerGraphics.width / 2;
+ var testX = player.x;
+ var testY = player.y + dirY * player.speed;
+ var closestX = testX;
+ var closestY = testY;
+ if (testX < wall.x - wall.wallGraphics.width / 2) {
+ closestX = wall.x - wall.wallGraphics.width / 2;
+ } else if (testX > wall.x + wall.wallGraphics.width / 2) {
+ closestX = wall.x + wall.wallGraphics.width / 2;
+ }
+ if (testY < wall.y - wall.wallGraphics.height / 2) {
+ closestY = wall.y - wall.wallGraphics.height / 2;
+ } else if (testY > wall.y + wall.wallGraphics.height / 2) {
+ closestY = wall.y + wall.wallGraphics.height / 2;
+ }
+ var distX = testX - closestX;
+ var distY = testY - closestY;
+ var distance = Math.sqrt(distX * distX + distY * distY);
+ if (distance < playerRadius) {
+ canMoveY = false;
+ break;
+ }
+ }
+ // Apply sliding movement
+ if (canMoveX) {
+ player.x += dirX * player.speed;
+ }
+ if (canMoveY) {
+ player.y += dirY * player.speed;
+ }
+ }
+}
+// Game input handlers
+game.down = function (x, y, obj) {
+ if (!player.active) {
+ return;
+ }
+ dragActive = true;
+ dragStartX = x;
+ dragStartY = y;
+ // Calculate time since last shoot
+ var currentTime = Date.now();
+ if (currentTime - lastShootTime < 300) {
+ // Double tap detected - shoot
+ player.shoot();
+ }
+ lastShootTime = currentTime;
+};
+game.up = function (x, y, obj) {
+ dragActive = false;
+ // Set movement target if drag distance is small
+ var dragDistX = x - dragStartX;
+ var dragDistY = y - dragStartY;
+ var dragDist = Math.sqrt(dragDistX * dragDistX + dragDistY * dragDistY);
+ if (dragDist < 20) {
+ // Tap (not drag) - set movement target
+ moveTargetX = x;
+ moveTargetY = y;
+ isMoving = true;
+ }
+};
+game.move = function (x, y, obj) {
+ if (!dragActive || !player.active) {
+ return;
+ }
+ // Update player aim direction
+ player.updateAim(x, y);
+ // Check if drag distance is large enough to be considered a drag rather than a tap
+ var dragDistX = x - dragStartX;
+ var dragDistY = y - dragStartY;
+ var dragDist = Math.sqrt(dragDistX * dragDistX + dragDistY * dragDistY);
+ if (dragDist > 20) {
+ // Long enough drag - shoot
+ player.shoot();
+ }
+};
+// Game update loop
+game.update = function () {
+ // Handle player movement
+ handlePlayerMovement();
+ // Update all bullets
+ for (var i = bullets.length - 1; i >= 0; i--) {
+ var bullet = bullets[i];
+ if (!bullet.active) {
+ game.removeChild(bullet);
+ bullets.splice(i, 1);
+ continue;
+ }
+ }
+ // Update all enemy bullets
+ for (var i = enemyBullets.length - 1; i >= 0; i--) {
+ var bullet = enemyBullets[i];
+ if (!bullet.active) {
+ game.removeChild(bullet);
+ enemyBullets.splice(i, 1);
+ continue;
+ }
+ }
+ // Update all enemies
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ var enemy = enemies[i];
+ if (!enemy.active) {
+ game.removeChild(enemy);
+ enemies.splice(i, 1);
+ continue;
+ }
+ }
+ // Update all objectives
+ for (var i = objectives.length - 1; i >= 0; i--) {
+ var objective = objectives[i];
+ if (!objective.active) {
+ game.removeChild(objective);
+ objectives.splice(i, 1);
+ continue;
+ }
+ }
+ // Update all weapon pickups
+ for (var i = weaponPickups.length - 1; i >= 0; i--) {
+ var pickup = weaponPickups[i];
+ if (!pickup.active) {
+ game.removeChild(pickup);
+ weaponPickups.splice(i, 1);
+ continue;
+ }
+ }
+ // Check for win condition
+ if (objectives.length === 0 && enemies.length === 0) {
+ // Level completed
+ level++;
+ storage.level = level;
+ // Check if we have more levels
+ if (level <= 3) {
+ // Advance to next level
+ LK.showYouWin();
+ } else {
+ // Game completed
+ LK.showYouWin();
+ level = 1; // Reset level for next game
+ storage.level = level;
+ }
+ }
+};
+// Initialize the game
+initGame();
\ No newline at end of file