/****
* 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