/**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 20; self.velocityX = 0; self.velocityY = 0; self.damage = 25; self.isPlayerBullet = true; self.update = function () { self.x += self.velocityX; self.y += self.velocityY; }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100; self.maxHealth = 100; self.speed = 6; self.lastShot = 0; self.shootCooldown = 300; self.lastMove = 0; self.moveTimer = 0; self.targetX = 0; self.targetY = 0; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.health = 0; return true; // Enemy died } // Flash red when taking damage tween(enemyGraphics, { tint: 0xFF0000 }, { duration: 100, onFinish: function onFinish() { tween(enemyGraphics, { tint: 0xFFFFFF }, { duration: 100 }); } }); return false; }; self.canShoot = function () { return LK.ticks - self.lastShot > self.shootCooldown; }; self.shoot = function (targetX, targetY) { if (!self.canShoot()) { return null; } self.lastShot = LK.ticks; var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; var dx = targetX - self.x; var dy = targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); bullet.velocityX = dx / distance * bullet.speed; bullet.velocityY = dy / distance * bullet.speed; bullet.isPlayerBullet = false; return bullet; }; self.update = function () { // Simple AI movement if (LK.ticks - self.lastMove > self.moveTimer) { self.targetX = player.x + (Math.random() - 0.5) * 400; self.targetY = player.y + (Math.random() - 0.5) * 400; self.targetX = Math.max(200, Math.min(1848, self.targetX)); self.targetY = Math.max(200, Math.min(2532, self.targetY)); self.lastMove = LK.ticks; self.moveTimer = 60 + Math.random() * 120; } // Move towards target var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 10) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } // Shoot at player occasionally if (self.canShoot() && Math.random() < 0.02) { var bullet = self.shoot(player.x, player.y); if (bullet) { bullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); } } }; return self; }); var HealthPack = Container.expand(function () { var self = Container.call(this); var healthGraphics = self.attachAsset('healthPack', { anchorX: 0.5, anchorY: 0.5 }); self.healAmount = 50; self.collected = false; self.update = function () { // Rotate for visual effect healthGraphics.rotation += 0.1; // Check if player collects it if (!self.collected && self.intersects(player)) { player.heal(self.healAmount); self.collected = true; } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100; self.maxHealth = 100; self.speed = 8; self.materials = 100; self.lastShot = 0; self.shootCooldown = 200; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.health = 0; return true; // Player died } // Flash red when taking damage tween(playerGraphics, { tint: 0xFF0000 }, { duration: 100, onFinish: function onFinish() { tween(playerGraphics, { tint: 0xFFFFFF }, { duration: 100 }); } }); return false; }; self.heal = function (amount) { self.health = Math.min(self.maxHealth, self.health + amount); }; self.canShoot = function () { return LK.ticks - self.lastShot > self.shootCooldown; }; self.shoot = function (targetX, targetY) { if (!self.canShoot()) { return null; } self.lastShot = LK.ticks; var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; var dx = targetX - self.x; var dy = targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); bullet.velocityX = dx / distance * bullet.speed; bullet.velocityY = dy / distance * bullet.speed; bullet.isPlayerBullet = true; return bullet; }; return self; }); var Structure = Container.expand(function (type) { var self = Container.call(this); self.structureType = type || 'wall'; self.health = 200; self.maxHealth = 200; var structureGraphics = self.attachAsset(self.structureType, { anchorX: 0.5, anchorY: 0.5 }); self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { return true; // Structure destroyed } // Visual feedback for damage var healthPercent = self.health / self.maxHealth; structureGraphics.alpha = 0.5 + healthPercent * 0.5; return false; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2E7D32 }); /**** * Game Code ****/ // Game state variables var gameMode = 'combat'; // 'combat' or 'build' var selectedStructure = 'wall'; var gridSize = 120; var buildPreview = null; var showBuildGrid = false; // Game objects var player = null; var enemy = null; var bullets = []; var structures = []; var healthPacks = []; var buildGrids = []; // UI elements var healthBar = null; var enemyHealthBar = null; var materialsText = null; var modeText = null; var buildButtons = []; // Initialize UI function initializeUI() { // Player health bar healthBar = new Text2('Health: 100', { size: 40, fill: 0x4CAF50 }); healthBar.anchor.set(0, 0); healthBar.x = 150; healthBar.y = 50; LK.gui.topLeft.addChild(healthBar); // Enemy health bar enemyHealthBar = new Text2('Enemy: 100', { size: 40, fill: 0xF44336 }); enemyHealthBar.anchor.set(1, 0); enemyHealthBar.x = -50; enemyHealthBar.y = 50; LK.gui.topRight.addChild(enemyHealthBar); // Materials counter materialsText = new Text2('Materials: 100', { size: 40, fill: 0x795548 }); materialsText.anchor.set(0, 0); materialsText.x = 150; materialsText.y = 100; LK.gui.topLeft.addChild(materialsText); // Mode indicator modeText = new Text2('Combat Mode', { size: 60, fill: 0xFFFFFF }); modeText.anchor.set(0.5, 0); modeText.x = 0; modeText.y = 50; LK.gui.top.addChild(modeText); // Build mode button var buildModeBtn = new Text2('BUILD', { size: 50, fill: 0xFFC107 }); buildModeBtn.anchor.set(0.5, 1); buildModeBtn.x = -100; buildModeBtn.y = -50; LK.gui.bottom.addChild(buildModeBtn); // Combat mode button var combatModeBtn = new Text2('COMBAT', { size: 50, fill: 0xFF5722 }); combatModeBtn.anchor.set(0.5, 1); combatModeBtn.x = 100; combatModeBtn.y = -50; LK.gui.bottom.addChild(combatModeBtn); // Structure selection buttons (visible in build mode) var wallBtn = new Text2('WALL', { size: 40, fill: 0x8D6E63 }); wallBtn.anchor.set(0, 1); wallBtn.x = 50; wallBtn.y = -120; LK.gui.bottomLeft.addChild(wallBtn); buildButtons.push(wallBtn); var rampBtn = new Text2('RAMP', { size: 40, fill: 0x795548 }); rampBtn.anchor.set(0, 1); rampBtn.x = 50; rampBtn.y = -170; LK.gui.bottomLeft.addChild(rampBtn); buildButtons.push(rampBtn); var floorBtn = new Text2('FLOOR', { size: 40, fill: 0x6D4C41 }); floorBtn.anchor.set(0, 1); floorBtn.x = 50; floorBtn.y = -220; LK.gui.bottomLeft.addChild(floorBtn); buildButtons.push(floorBtn); updateBuildButtonsVisibility(); } function updateBuildButtonsVisibility() { for (var i = 0; i < buildButtons.length; i++) { buildButtons[i].visible = gameMode === 'build'; } } function updateUI() { if (player) { healthBar.setText('Health: ' + player.health); materialsText.setText('Materials: ' + player.materials); } if (enemy) { enemyHealthBar.setText('Enemy: ' + enemy.health); } modeText.setText(gameMode === 'build' ? 'Build Mode' : 'Combat Mode'); } function switchMode(newMode) { gameMode = newMode; updateBuildButtonsVisibility(); if (gameMode === 'build') { showBuildGrid = true; createBuildGrid(); } else { showBuildGrid = false; clearBuildGrid(); if (buildPreview) { buildPreview.destroy(); buildPreview = null; } } } function createBuildGrid() { clearBuildGrid(); for (var x = gridSize; x < 2048; x += gridSize) { for (var y = gridSize; y < 2732; y += gridSize) { var grid = LK.getAsset('buildGrid', { anchorX: 0.5, anchorY: 0.5 }); grid.x = x; grid.y = y; grid.alpha = 0.2; buildGrids.push(grid); game.addChild(grid); } } } function clearBuildGrid() { for (var i = 0; i < buildGrids.length; i++) { buildGrids[i].destroy(); } buildGrids = []; } function snapToGrid(x, y) { var snappedX = Math.round(x / gridSize) * gridSize; var snappedY = Math.round(y / gridSize) * gridSize; return { x: snappedX, y: snappedY }; } function canBuildAt(x, y) { // Check if position is within bounds if (x < gridSize || x >= 2048 - gridSize || y < gridSize || y >= 2732 - gridSize) { return false; } // Check if there's already a structure here for (var i = 0; i < structures.length; i++) { var structure = structures[i]; var dx = Math.abs(structure.x - x); var dy = Math.abs(structure.y - y); if (dx < gridSize && dy < gridSize) { return false; } } return true; } function buildStructure(x, y, type) { var snapped = snapToGrid(x, y); if (!canBuildAt(snapped.x, snapped.y)) { return false; } var cost = 10; if (player.materials < cost) { return false; } player.materials -= cost; var structure = new Structure(type); structure.x = snapped.x; structure.y = snapped.y; structures.push(structure); game.addChild(structure); LK.getSound('build').play(); return true; } function spawnHealthPack() { if (healthPacks.length >= 3) { return; } // Max 3 health packs var healthPack = new HealthPack(); healthPack.x = 200 + Math.random() * 1648; healthPack.y = 200 + Math.random() * 2332; healthPacks.push(healthPack); game.addChild(healthPack); } // Initialize game objects function initializeGame() { // Create player player = new Player(); player.x = 1024; player.y = 2200; game.addChild(player); // Create enemy enemy = new Enemy(); enemy.x = 1024; enemy.y = 500; game.addChild(enemy); // Initialize UI initializeUI(); // Spawn initial health pack spawnHealthPack(); } // Event handlers function handleMove(x, y, obj) { if (gameMode === 'build' && buildPreview) { var snapped = snapToGrid(x, y); buildPreview.x = snapped.x; buildPreview.y = snapped.y; buildPreview.alpha = canBuildAt(snapped.x, snapped.y) ? 0.7 : 0.3; } } function handleDown(x, y, obj) { if (gameMode === 'combat') { // Shoot at target location if (player.canShoot()) { var bullet = player.shoot(x, y); if (bullet) { bullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); } } } else if (gameMode === 'build') { // Build structure buildStructure(x, y, selectedStructure); } } function handleUp(x, y, obj) { // Check UI button clicks using game coordinates var gamePos = game.toLocal({ x: x, y: y }); // Convert to GUI coordinates for button detection var guiBottomX = gamePos.x - 1024; // Relative to center var guiBottomY = gamePos.y - 2732; // Relative to bottom // Build mode button if (guiBottomX >= -150 && guiBottomX <= -50 && guiBottomY >= -100 && guiBottomY <= 0) { switchMode('build'); } // Combat mode button if (guiBottomX >= 50 && guiBottomX <= 150 && guiBottomY >= -100 && guiBottomY <= 0) { switchMode('combat'); } // Structure selection buttons if (gameMode === 'build') { var guiLeftX = gamePos.x; // Relative to left var guiLeftY = gamePos.y - 2732; // Relative to bottom if (guiLeftX >= 50 && guiLeftX <= 150) { if (guiLeftY >= -150 && guiLeftY <= -100) { selectedStructure = 'wall'; } else if (guiLeftY >= -200 && guiLeftY <= -150) { selectedStructure = 'ramp'; } else if (guiLeftY >= -250 && guiLeftY <= -200) { selectedStructure = 'floor'; } } } } // Assign event handlers game.move = handleMove; game.down = handleDown; game.up = handleUp; // Main game loop game.update = function () { // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; // Track last position for boundary checking if (bullet.lastX === undefined) { bullet.lastX = bullet.x; } if (bullet.lastY === undefined) { bullet.lastY = bullet.y; } // Check if bullet went off screen if (bullet.lastX >= 0 && bullet.x < 0 || bullet.lastX <= 2048 && bullet.x > 2048 || bullet.lastY >= 0 && bullet.y < 0 || bullet.lastY <= 2732 && bullet.y > 2732) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check collisions with structures var hitStructure = false; for (var j = structures.length - 1; j >= 0; j--) { var structure = structures[j]; if (bullet.intersects(structure)) { if (structure.takeDamage(bullet.damage)) { structure.destroy(); structures.splice(j, 1); } hitStructure = true; break; } } if (hitStructure) { bullet.destroy(); bullets.splice(i, 1); LK.getSound('hit').play(); continue; } // Check collisions with players if (bullet.isPlayerBullet && bullet.intersects(enemy)) { if (enemy.takeDamage(bullet.damage)) { LK.showYouWin(); return; } bullet.destroy(); bullets.splice(i, 1); LK.getSound('hit').play(); continue; } else if (!bullet.isPlayerBullet && bullet.intersects(player)) { if (player.takeDamage(bullet.damage)) { LK.showGameOver(); return; } bullet.destroy(); bullets.splice(i, 1); LK.getSound('hit').play(); continue; } // Update last position bullet.lastX = bullet.x; bullet.lastY = bullet.y; } // Update health packs for (var i = healthPacks.length - 1; i >= 0; i--) { var healthPack = healthPacks[i]; if (healthPack.collected) { healthPack.destroy(); healthPacks.splice(i, 1); } } // Spawn health packs periodically if (LK.ticks % 600 === 0) { // Every 10 seconds spawnHealthPack(); } // Give player materials over time if (LK.ticks % 180 === 0) { // Every 3 seconds player.materials = Math.min(200, player.materials + 5); } // Update UI updateUI(); // Handle build mode preview if (gameMode === 'build' && !buildPreview) { buildPreview = LK.getAsset(selectedStructure, { anchorX: 0.5, anchorY: 0.5 }); buildPreview.alpha = 0.5; game.addChild(buildPreview); } else if (gameMode !== 'build' && buildPreview) { buildPreview.destroy(); buildPreview = null; } // Update build preview structure type if (buildPreview && buildPreview.structureType !== selectedStructure) { buildPreview.destroy(); buildPreview = LK.getAsset(selectedStructure, { anchorX: 0.5, anchorY: 0.5 }); buildPreview.alpha = 0.5; game.addChild(buildPreview); } }; // Start the game initializeGame();
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 20;
self.velocityX = 0;
self.velocityY = 0;
self.damage = 25;
self.isPlayerBullet = true;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.speed = 6;
self.lastShot = 0;
self.shootCooldown = 300;
self.lastMove = 0;
self.moveTimer = 0;
self.targetX = 0;
self.targetY = 0;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
return true; // Enemy died
}
// Flash red when taking damage
tween(enemyGraphics, {
tint: 0xFF0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(enemyGraphics, {
tint: 0xFFFFFF
}, {
duration: 100
});
}
});
return false;
};
self.canShoot = function () {
return LK.ticks - self.lastShot > self.shootCooldown;
};
self.shoot = function (targetX, targetY) {
if (!self.canShoot()) {
return null;
}
self.lastShot = LK.ticks;
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
bullet.velocityX = dx / distance * bullet.speed;
bullet.velocityY = dy / distance * bullet.speed;
bullet.isPlayerBullet = false;
return bullet;
};
self.update = function () {
// Simple AI movement
if (LK.ticks - self.lastMove > self.moveTimer) {
self.targetX = player.x + (Math.random() - 0.5) * 400;
self.targetY = player.y + (Math.random() - 0.5) * 400;
self.targetX = Math.max(200, Math.min(1848, self.targetX));
self.targetY = Math.max(200, Math.min(2532, self.targetY));
self.lastMove = LK.ticks;
self.moveTimer = 60 + Math.random() * 120;
}
// Move towards target
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 10) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Shoot at player occasionally
if (self.canShoot() && Math.random() < 0.02) {
var bullet = self.shoot(player.x, player.y);
if (bullet) {
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
}
}
};
return self;
});
var HealthPack = Container.expand(function () {
var self = Container.call(this);
var healthGraphics = self.attachAsset('healthPack', {
anchorX: 0.5,
anchorY: 0.5
});
self.healAmount = 50;
self.collected = false;
self.update = function () {
// Rotate for visual effect
healthGraphics.rotation += 0.1;
// Check if player collects it
if (!self.collected && self.intersects(player)) {
player.heal(self.healAmount);
self.collected = true;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.speed = 8;
self.materials = 100;
self.lastShot = 0;
self.shootCooldown = 200;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
return true; // Player died
}
// Flash red when taking damage
tween(playerGraphics, {
tint: 0xFF0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(playerGraphics, {
tint: 0xFFFFFF
}, {
duration: 100
});
}
});
return false;
};
self.heal = function (amount) {
self.health = Math.min(self.maxHealth, self.health + amount);
};
self.canShoot = function () {
return LK.ticks - self.lastShot > self.shootCooldown;
};
self.shoot = function (targetX, targetY) {
if (!self.canShoot()) {
return null;
}
self.lastShot = LK.ticks;
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
bullet.velocityX = dx / distance * bullet.speed;
bullet.velocityY = dy / distance * bullet.speed;
bullet.isPlayerBullet = true;
return bullet;
};
return self;
});
var Structure = Container.expand(function (type) {
var self = Container.call(this);
self.structureType = type || 'wall';
self.health = 200;
self.maxHealth = 200;
var structureGraphics = self.attachAsset(self.structureType, {
anchorX: 0.5,
anchorY: 0.5
});
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
return true; // Structure destroyed
}
// Visual feedback for damage
var healthPercent = self.health / self.maxHealth;
structureGraphics.alpha = 0.5 + healthPercent * 0.5;
return false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2E7D32
});
/****
* Game Code
****/
// Game state variables
var gameMode = 'combat'; // 'combat' or 'build'
var selectedStructure = 'wall';
var gridSize = 120;
var buildPreview = null;
var showBuildGrid = false;
// Game objects
var player = null;
var enemy = null;
var bullets = [];
var structures = [];
var healthPacks = [];
var buildGrids = [];
// UI elements
var healthBar = null;
var enemyHealthBar = null;
var materialsText = null;
var modeText = null;
var buildButtons = [];
// Initialize UI
function initializeUI() {
// Player health bar
healthBar = new Text2('Health: 100', {
size: 40,
fill: 0x4CAF50
});
healthBar.anchor.set(0, 0);
healthBar.x = 150;
healthBar.y = 50;
LK.gui.topLeft.addChild(healthBar);
// Enemy health bar
enemyHealthBar = new Text2('Enemy: 100', {
size: 40,
fill: 0xF44336
});
enemyHealthBar.anchor.set(1, 0);
enemyHealthBar.x = -50;
enemyHealthBar.y = 50;
LK.gui.topRight.addChild(enemyHealthBar);
// Materials counter
materialsText = new Text2('Materials: 100', {
size: 40,
fill: 0x795548
});
materialsText.anchor.set(0, 0);
materialsText.x = 150;
materialsText.y = 100;
LK.gui.topLeft.addChild(materialsText);
// Mode indicator
modeText = new Text2('Combat Mode', {
size: 60,
fill: 0xFFFFFF
});
modeText.anchor.set(0.5, 0);
modeText.x = 0;
modeText.y = 50;
LK.gui.top.addChild(modeText);
// Build mode button
var buildModeBtn = new Text2('BUILD', {
size: 50,
fill: 0xFFC107
});
buildModeBtn.anchor.set(0.5, 1);
buildModeBtn.x = -100;
buildModeBtn.y = -50;
LK.gui.bottom.addChild(buildModeBtn);
// Combat mode button
var combatModeBtn = new Text2('COMBAT', {
size: 50,
fill: 0xFF5722
});
combatModeBtn.anchor.set(0.5, 1);
combatModeBtn.x = 100;
combatModeBtn.y = -50;
LK.gui.bottom.addChild(combatModeBtn);
// Structure selection buttons (visible in build mode)
var wallBtn = new Text2('WALL', {
size: 40,
fill: 0x8D6E63
});
wallBtn.anchor.set(0, 1);
wallBtn.x = 50;
wallBtn.y = -120;
LK.gui.bottomLeft.addChild(wallBtn);
buildButtons.push(wallBtn);
var rampBtn = new Text2('RAMP', {
size: 40,
fill: 0x795548
});
rampBtn.anchor.set(0, 1);
rampBtn.x = 50;
rampBtn.y = -170;
LK.gui.bottomLeft.addChild(rampBtn);
buildButtons.push(rampBtn);
var floorBtn = new Text2('FLOOR', {
size: 40,
fill: 0x6D4C41
});
floorBtn.anchor.set(0, 1);
floorBtn.x = 50;
floorBtn.y = -220;
LK.gui.bottomLeft.addChild(floorBtn);
buildButtons.push(floorBtn);
updateBuildButtonsVisibility();
}
function updateBuildButtonsVisibility() {
for (var i = 0; i < buildButtons.length; i++) {
buildButtons[i].visible = gameMode === 'build';
}
}
function updateUI() {
if (player) {
healthBar.setText('Health: ' + player.health);
materialsText.setText('Materials: ' + player.materials);
}
if (enemy) {
enemyHealthBar.setText('Enemy: ' + enemy.health);
}
modeText.setText(gameMode === 'build' ? 'Build Mode' : 'Combat Mode');
}
function switchMode(newMode) {
gameMode = newMode;
updateBuildButtonsVisibility();
if (gameMode === 'build') {
showBuildGrid = true;
createBuildGrid();
} else {
showBuildGrid = false;
clearBuildGrid();
if (buildPreview) {
buildPreview.destroy();
buildPreview = null;
}
}
}
function createBuildGrid() {
clearBuildGrid();
for (var x = gridSize; x < 2048; x += gridSize) {
for (var y = gridSize; y < 2732; y += gridSize) {
var grid = LK.getAsset('buildGrid', {
anchorX: 0.5,
anchorY: 0.5
});
grid.x = x;
grid.y = y;
grid.alpha = 0.2;
buildGrids.push(grid);
game.addChild(grid);
}
}
}
function clearBuildGrid() {
for (var i = 0; i < buildGrids.length; i++) {
buildGrids[i].destroy();
}
buildGrids = [];
}
function snapToGrid(x, y) {
var snappedX = Math.round(x / gridSize) * gridSize;
var snappedY = Math.round(y / gridSize) * gridSize;
return {
x: snappedX,
y: snappedY
};
}
function canBuildAt(x, y) {
// Check if position is within bounds
if (x < gridSize || x >= 2048 - gridSize || y < gridSize || y >= 2732 - gridSize) {
return false;
}
// Check if there's already a structure here
for (var i = 0; i < structures.length; i++) {
var structure = structures[i];
var dx = Math.abs(structure.x - x);
var dy = Math.abs(structure.y - y);
if (dx < gridSize && dy < gridSize) {
return false;
}
}
return true;
}
function buildStructure(x, y, type) {
var snapped = snapToGrid(x, y);
if (!canBuildAt(snapped.x, snapped.y)) {
return false;
}
var cost = 10;
if (player.materials < cost) {
return false;
}
player.materials -= cost;
var structure = new Structure(type);
structure.x = snapped.x;
structure.y = snapped.y;
structures.push(structure);
game.addChild(structure);
LK.getSound('build').play();
return true;
}
function spawnHealthPack() {
if (healthPacks.length >= 3) {
return;
} // Max 3 health packs
var healthPack = new HealthPack();
healthPack.x = 200 + Math.random() * 1648;
healthPack.y = 200 + Math.random() * 2332;
healthPacks.push(healthPack);
game.addChild(healthPack);
}
// Initialize game objects
function initializeGame() {
// Create player
player = new Player();
player.x = 1024;
player.y = 2200;
game.addChild(player);
// Create enemy
enemy = new Enemy();
enemy.x = 1024;
enemy.y = 500;
game.addChild(enemy);
// Initialize UI
initializeUI();
// Spawn initial health pack
spawnHealthPack();
}
// Event handlers
function handleMove(x, y, obj) {
if (gameMode === 'build' && buildPreview) {
var snapped = snapToGrid(x, y);
buildPreview.x = snapped.x;
buildPreview.y = snapped.y;
buildPreview.alpha = canBuildAt(snapped.x, snapped.y) ? 0.7 : 0.3;
}
}
function handleDown(x, y, obj) {
if (gameMode === 'combat') {
// Shoot at target location
if (player.canShoot()) {
var bullet = player.shoot(x, y);
if (bullet) {
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
}
}
} else if (gameMode === 'build') {
// Build structure
buildStructure(x, y, selectedStructure);
}
}
function handleUp(x, y, obj) {
// Check UI button clicks using game coordinates
var gamePos = game.toLocal({
x: x,
y: y
});
// Convert to GUI coordinates for button detection
var guiBottomX = gamePos.x - 1024; // Relative to center
var guiBottomY = gamePos.y - 2732; // Relative to bottom
// Build mode button
if (guiBottomX >= -150 && guiBottomX <= -50 && guiBottomY >= -100 && guiBottomY <= 0) {
switchMode('build');
}
// Combat mode button
if (guiBottomX >= 50 && guiBottomX <= 150 && guiBottomY >= -100 && guiBottomY <= 0) {
switchMode('combat');
}
// Structure selection buttons
if (gameMode === 'build') {
var guiLeftX = gamePos.x; // Relative to left
var guiLeftY = gamePos.y - 2732; // Relative to bottom
if (guiLeftX >= 50 && guiLeftX <= 150) {
if (guiLeftY >= -150 && guiLeftY <= -100) {
selectedStructure = 'wall';
} else if (guiLeftY >= -200 && guiLeftY <= -150) {
selectedStructure = 'ramp';
} else if (guiLeftY >= -250 && guiLeftY <= -200) {
selectedStructure = 'floor';
}
}
}
}
// Assign event handlers
game.move = handleMove;
game.down = handleDown;
game.up = handleUp;
// Main game loop
game.update = function () {
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Track last position for boundary checking
if (bullet.lastX === undefined) {
bullet.lastX = bullet.x;
}
if (bullet.lastY === undefined) {
bullet.lastY = bullet.y;
}
// Check if bullet went off screen
if (bullet.lastX >= 0 && bullet.x < 0 || bullet.lastX <= 2048 && bullet.x > 2048 || bullet.lastY >= 0 && bullet.y < 0 || bullet.lastY <= 2732 && bullet.y > 2732) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check collisions with structures
var hitStructure = false;
for (var j = structures.length - 1; j >= 0; j--) {
var structure = structures[j];
if (bullet.intersects(structure)) {
if (structure.takeDamage(bullet.damage)) {
structure.destroy();
structures.splice(j, 1);
}
hitStructure = true;
break;
}
}
if (hitStructure) {
bullet.destroy();
bullets.splice(i, 1);
LK.getSound('hit').play();
continue;
}
// Check collisions with players
if (bullet.isPlayerBullet && bullet.intersects(enemy)) {
if (enemy.takeDamage(bullet.damage)) {
LK.showYouWin();
return;
}
bullet.destroy();
bullets.splice(i, 1);
LK.getSound('hit').play();
continue;
} else if (!bullet.isPlayerBullet && bullet.intersects(player)) {
if (player.takeDamage(bullet.damage)) {
LK.showGameOver();
return;
}
bullet.destroy();
bullets.splice(i, 1);
LK.getSound('hit').play();
continue;
}
// Update last position
bullet.lastX = bullet.x;
bullet.lastY = bullet.y;
}
// Update health packs
for (var i = healthPacks.length - 1; i >= 0; i--) {
var healthPack = healthPacks[i];
if (healthPack.collected) {
healthPack.destroy();
healthPacks.splice(i, 1);
}
}
// Spawn health packs periodically
if (LK.ticks % 600 === 0) {
// Every 10 seconds
spawnHealthPack();
}
// Give player materials over time
if (LK.ticks % 180 === 0) {
// Every 3 seconds
player.materials = Math.min(200, player.materials + 5);
}
// Update UI
updateUI();
// Handle build mode preview
if (gameMode === 'build' && !buildPreview) {
buildPreview = LK.getAsset(selectedStructure, {
anchorX: 0.5,
anchorY: 0.5
});
buildPreview.alpha = 0.5;
game.addChild(buildPreview);
} else if (gameMode !== 'build' && buildPreview) {
buildPreview.destroy();
buildPreview = null;
}
// Update build preview structure type
if (buildPreview && buildPreview.structureType !== selectedStructure) {
buildPreview.destroy();
buildPreview = LK.getAsset(selectedStructure, {
anchorX: 0.5,
anchorY: 0.5
});
buildPreview.alpha = 0.5;
game.addChild(buildPreview);
}
};
// Start the game
initializeGame();