/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0 }); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); self.type = 'player'; self.speed = 15; self.damage = 10; self.direction = { x: 0, y: -1 }; // Default upward direction self.graphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.x += self.direction.x * self.speed; self.y += self.direction.y * self.speed; }; self.setType = function (type) { self.type = type; if (type === 'enemy') { self.graphics = self.removeChild(self.graphics); self.graphics = self.attachAsset('enemy_bullet', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 5; self.speed = 8; } return self; }; return self; }); var EnemyMech = Container.expand(function () { var self = Container.call(this); self.health = 30; self.maxHealth = 30; self.speed = 2; self.fireRate = 120; // frames between shots self.fireCounter = 0; self.movementPattern = 'chase'; // Default pattern self.type = 'basic'; self.scoreValue = 100; // Create main body self.body = self.attachAsset('enemy_mech', { anchorX: 0.5, anchorY: 0.5 }); // Create health bar self.healthBarBg = self.attachAsset('health_bar_bg', { anchorX: 0.5, anchorY: 0.5, y: -110, scaleX: 0.8, scaleY: 0.6 }); self.healthBar = self.attachAsset('health_bar', { anchorX: 0, anchorY: 0.5, x: -80, y: -110, scaleX: 0.8, scaleY: 0.6 }); self.takeDamage = function (amount) { self.health -= amount; // Update health bar width var healthPercent = Math.max(0, self.health / self.maxHealth); self.healthBar.scaleX = 0.8 * healthPercent; if (self.health <= 0) { return true; // Signal for destruction } // Flash red when hit LK.effects.flashObject(self.body, 0xff0000, 200); return false; }; self.setType = function (newType) { self.type = newType; if (newType === 'heavy') { self.body.tint = 0x990000; self.health = 60; self.maxHealth = 60; self.speed = 1.2; self.fireRate = 150; self.scoreValue = 200; self.body.scaleX = 1.3; self.body.scaleY = 1.3; } else if (newType === 'speeder') { self.body.tint = 0x0099cc; self.health = 20; self.maxHealth = 20; self.speed = 3.5; self.fireRate = 90; self.scoreValue = 150; self.body.scaleX = 0.8; self.body.scaleY = 0.8; } else { // basic type - default values self.body.tint = 0xcc3300; } // Reset health bar to match new max health self.healthBar.scaleX = 0.8; return self; }; self.setMovementPattern = function (pattern) { self.movementPattern = pattern; return self; }; self.update = function () { // Handle movement based on pattern if (self.movementPattern === 'chase' && playerMech) { // Move toward player var dx = playerMech.x - self.x; var dy = playerMech.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 10) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } } else if (self.movementPattern === 'strafe') { // Move side to side self.x += Math.sin(LK.ticks / 30) * self.speed; // Slowly advance down the screen self.y += self.speed * 0.5; } else if (self.movementPattern === 'circle' && playerMech) { // Circle around player var angle = LK.ticks / 100; var radius = 300; self.x = playerMech.x + Math.cos(angle) * radius; self.y = playerMech.y + Math.sin(angle) * radius; } // Firing logic self.fireCounter++; if (self.fireCounter >= self.fireRate && playerMech) { self.fireCounter = 0; // Calculate direction to player var dx = playerMech.x - self.x; var dy = playerMech.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); // Normalize dx = dx / dist; dy = dy / dist; // Create a new bullet var bullet = new Bullet().setType('enemy'); bullet.x = self.x; bullet.y = self.y; bullet.direction = { x: dx, y: dy }; // Add to game's bullet array enemyBullets.push(bullet); game.addChild(bullet); // Play sound LK.getSound('enemy_shoot').play(); } return false; // No auto-removal }; return self; }); var Explosion = Container.expand(function () { var self = Container.call(this); self.lifespan = 20; // frames self.age = 0; self.graphics = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); self.update = function () { self.age++; self.graphics.alpha = 1 - self.age / self.lifespan; self.graphics.scaleX = 1 + self.age / 10; self.graphics.scaleY = 1 + self.age / 10; if (self.age >= self.lifespan) { return true; // Signal for removal } return false; }; return self; }); var PlayerMech = Container.expand(function () { var self = Container.call(this); self.health = 100; self.maxHealth = 100; self.speed = 6; self.fireRate = 15; // frames between shots self.fireCounter = 0; self.damageMultiplier = 1.0; self.speedMultiplier = 1.0; self.fireRateMultiplier = 1.0; // Create main body self.body = self.attachAsset('player_mech', { anchorX: 0.5, anchorY: 0.5 }); // Health bar self.healthBarBg = self.attachAsset('health_bar_bg', { anchorX: 0.5, anchorY: 0.5, y: -120, scaleX: 1, scaleY: 0.8 }); self.healthBar = self.attachAsset('health_bar', { anchorX: 0, anchorY: 0.5, x: -100, y: -120, scaleX: 1, scaleY: 0.8 }); self.takeDamage = function (amount) { self.health -= amount; // Update health bar width var healthPercent = Math.max(0, self.health / self.maxHealth); self.healthBar.scaleX = healthPercent; // Flash red when hit LK.effects.flashObject(self.body, 0xff0000, 200); if (self.health <= 0) { return true; // Signal for destruction } return false; }; self.heal = function (amount) { self.health = Math.min(self.maxHealth, self.health + amount); // Update health bar width var healthPercent = self.health / self.maxHealth; self.healthBar.scaleX = healthPercent; // Flash green when healed LK.effects.flashObject(self.body, 0x00ff00, 200); }; self.applyPowerUp = function (type, value) { if (type === 'health') { self.heal(value); } else if (type === 'damage') { self.damageMultiplier += value / 100; LK.effects.flashObject(self.body, 0xff0000, 500); } else if (type === 'speed') { self.speedMultiplier += value / 100; LK.effects.flashObject(self.body, 0x00ffff, 500); } else if (type === 'fireRate') { self.fireRateMultiplier += value / 100; LK.effects.flashObject(self.body, 0xffff00, 500); } }; self.shoot = function () { if (self.fireCounter >= Math.max(5, self.fireRate / self.fireRateMultiplier)) { self.fireCounter = 0; // Create a new bullet var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y - self.body.height / 2; bullet.damage = Math.round(bullet.damage * self.damageMultiplier); // Add to game's bullet array playerBullets.push(bullet); game.addChild(bullet); // Play sound LK.getSound('player_shoot').play(); return true; } return false; }; self.update = function () { self.fireCounter++; return false; // No auto-removal }; self.down = function (x, y, obj) { // Handle touch down events if needed }; self.up = function (x, y, obj) { // Handle touch up events if needed }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); self.type = 'health'; // Default type self.value = 25; // Default value self.graphics = self.attachAsset('power_up', { anchorX: 0.5, anchorY: 0.5 }); self.pulse = function () { tween(self.graphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.graphics, { scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.easeInOut, onFinish: self.pulse }); } }); }; self.setType = function (newType) { self.type = newType; if (newType === 'damage') { self.graphics.tint = 0xff0000; self.value = 10; // 10% damage increase } else if (newType === 'speed') { self.graphics.tint = 0x00ffff; self.value = 20; // 20% speed increase } else if (newType === 'fireRate') { self.graphics.tint = 0xffff00; self.value = 15; // 15% fire rate increase } else { // health type self.graphics.tint = 0x00ff00; self.value = 25; // 25 health points } return self; }; self.update = function () { self.graphics.rotation += 0.02; return false; // No auto-removal }; // Start pulsing animation self.pulse(); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000022 // Dark blue space background }); /**** * Game Code ****/ // Create the arena border var arenaBorder = LK.getAsset('arena_border', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3 }); game.addChild(arenaBorder); arenaBorder.x = 2048 / 2; arenaBorder.y = 2732 / 2; // Define game boundaries based on arena size var gameArea = { left: arenaBorder.x - arenaBorder.width / 2, right: arenaBorder.x + arenaBorder.width / 2, top: arenaBorder.y - arenaBorder.height / 2, bottom: arenaBorder.y + arenaBorder.height / 2 }; // Game state variables var playerMech; var playerBullets = []; var enemyMechs = []; var enemyBullets = []; var explosions = []; var powerUps = []; var currentWave = 1; var waveCompleted = false; var waveTimer = 0; var powerUpSpawnTimer = 0; var mechTypes = ['basic', 'heavy', 'speeder']; var movementPatterns = ['chase', 'strafe', 'circle']; var powerUpTypes = ['health', 'damage', 'speed', 'fireRate']; var dragging = false; // Setup score display var scoreText = new Text2('SCORE: 0', { size: 50, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); // Setup wave display var waveText = new Text2('WAVE 1', { size: 60, fill: 0xFFFFFF }); waveText.anchor.set(0.5, 0.5); LK.gui.center.addChild(waveText); waveText.alpha = 0; // Setup high score display var highScoreText = new Text2('HIGH SCORE: ' + storage.highScore, { size: 40, fill: 0xFFCC00 }); highScoreText.anchor.set(1, 0); // Right aligned at the top highScoreText.x = 300; // Position from the right edge LK.gui.topRight.addChild(highScoreText); // Create player mech playerMech = new PlayerMech(); playerMech.x = 2048 / 2; playerMech.y = 2732 - 400; game.addChild(playerMech); // Function to spawn enemies for a wave function spawnWaveEnemies() { // Clear any remaining enemies for (var i = enemyMechs.length - 1; i >= 0; i--) { enemyMechs[i].destroy(); enemyMechs.splice(i, 1); } // Number of enemies based on wave var enemyCount = 3 + currentWave * 2; for (var i = 0; i < enemyCount; i++) { var enemy = new EnemyMech(); // Random type with weighted probability var typeRandom = Math.random(); var type; if (typeRandom < 0.6) { type = 'basic'; } else if (typeRandom < 0.8) { type = 'heavy'; } else { type = 'speeder'; } enemy.setType(type); // Random movement pattern var patternIndex = Math.floor(Math.random() * movementPatterns.length); enemy.setMovementPattern(movementPatterns[patternIndex]); // Position enemies in a grid at the top var cols = Math.min(5, enemyCount); var rows = Math.ceil(enemyCount / cols); var col = i % cols; var row = Math.floor(i / cols); var spacing = 250; var startX = arenaBorder.x - (cols - 1) * spacing / 2; var startY = arenaBorder.y - arenaBorder.height / 2 + 200; enemy.x = startX + col * spacing; enemy.y = startY + row * spacing; // Scale health and speed based on wave enemy.health += (currentWave - 1) * 10; enemy.maxHealth = enemy.health; // Add to game enemyMechs.push(enemy); game.addChild(enemy); } // Show wave notification waveText.setText('WAVE ' + currentWave); waveText.alpha = 1; tween(waveText, { alpha: 0 }, { duration: 2000, easing: tween.easeOut }); // Play wave sound LK.getSound('wave_complete').play(); waveCompleted = false; } // Function to spawn a power-up function spawnPowerUp() { var powerUp = new PowerUp(); // Random position within arena powerUp.x = gameArea.left + Math.random() * (gameArea.right - gameArea.left); powerUp.y = gameArea.top + Math.random() * (gameArea.bottom - gameArea.top); // Random type var typeIndex = Math.floor(Math.random() * powerUpTypes.length); powerUp.setType(powerUpTypes[typeIndex]); // Add to game powerUps.push(powerUp); game.addChild(powerUp); } // Initialize the first wave spawnWaveEnemies(); // Play background music LK.playMusic('battle_music'); // Movement handling function handleMove(x, y, obj) { if (dragging && playerMech) { // Calculate new position but keep within bounds var newX = Math.max(gameArea.left + playerMech.body.width / 2, Math.min(x, gameArea.right - playerMech.body.width / 2)); var newY = Math.max(gameArea.top + playerMech.body.height / 2, Math.min(y, gameArea.bottom - playerMech.body.height / 2)); // Apply speed multiplier to movement var currentX = playerMech.x; var currentY = playerMech.y; var dx = newX - currentX; var dy = newY - currentY; // Calculate distance to move based on speed var distance = Math.sqrt(dx * dx + dy * dy); var maxDistance = playerMech.speed * playerMech.speedMultiplier; if (distance > maxDistance) { var ratio = maxDistance / distance; dx *= ratio; dy *= ratio; playerMech.x += dx; playerMech.y += dy; } else { playerMech.x = newX; playerMech.y = newY; } // Automatically shoot while moving playerMech.shoot(); } } // Touch/mouse events game.down = function (x, y, obj) { dragging = true; handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragging = false; }; game.move = handleMove; // Main game update function game.update = function () { // Check if all enemies are defeated if (enemyMechs.length === 0 && !waveCompleted) { waveCompleted = true; waveTimer = 180; // 3 seconds @ 60fps currentWave++; } // Start next wave after delay if (waveCompleted) { waveTimer--; if (waveTimer <= 0) { spawnWaveEnemies(); } } // Update player mech if (playerMech) { playerMech.update(); } // Update player bullets for (var i = playerBullets.length - 1; i >= 0; i--) { var bullet = playerBullets[i]; bullet.update(); // Check if bullet is out of bounds if (bullet.y < gameArea.top || bullet.y > gameArea.bottom || bullet.x < gameArea.left || bullet.x > gameArea.right) { bullet.destroy(); playerBullets.splice(i, 1); continue; } // Check for collision with enemy mechs var hitEnemy = false; for (var j = enemyMechs.length - 1; j >= 0; j--) { var enemy = enemyMechs[j]; if (bullet.intersects(enemy)) { hitEnemy = true; // Deal damage to enemy var destroyed = enemy.takeDamage(bullet.damage); if (destroyed) { // Create explosion var explosion = new Explosion(); explosion.x = enemy.x; explosion.y = enemy.y; explosions.push(explosion); game.addChild(explosion); // Play explosion sound LK.getSound('explosion').play(); // Add score LK.setScore(LK.getScore() + enemy.scoreValue); scoreText.setText('SCORE: ' + LK.getScore()); // Check if high score was beaten if (LK.getScore() > storage.highScore) { storage.highScore = LK.getScore(); highScoreText.setText('HIGH SCORE: ' + storage.highScore); } // Remove enemy enemy.destroy(); enemyMechs.splice(j, 1); // Random chance to spawn power-up (20%) if (Math.random() < 0.2) { var powerUp = new PowerUp(); powerUp.x = enemy.x; powerUp.y = enemy.y; powerUp.setType(powerUpTypes[Math.floor(Math.random() * powerUpTypes.length)]); powerUps.push(powerUp); game.addChild(powerUp); } } // Remove bullet bullet.destroy(); playerBullets.splice(i, 1); break; } } } // Update enemy mechs for (var i = enemyMechs.length - 1; i >= 0; i--) { var enemy = enemyMechs[i]; enemy.update(); // Keep enemy within bounds enemy.x = Math.max(gameArea.left + enemy.body.width / 2, Math.min(enemy.x, gameArea.right - enemy.body.width / 2)); enemy.y = Math.max(gameArea.top + enemy.body.height / 2, Math.min(enemy.y, gameArea.bottom - enemy.body.height / 2)); } // Update enemy bullets for (var i = enemyBullets.length - 1; i >= 0; i--) { var bullet = enemyBullets[i]; bullet.update(); // Check if bullet is out of bounds if (bullet.y < gameArea.top || bullet.y > gameArea.bottom || bullet.x < gameArea.left || bullet.x > gameArea.right) { bullet.destroy(); enemyBullets.splice(i, 1); continue; } // Check for collision with player if (playerMech && bullet.intersects(playerMech)) { // Deal damage to player var destroyed = playerMech.takeDamage(bullet.damage); if (destroyed) { // Create explosion var explosion = new Explosion(); explosion.x = playerMech.x; explosion.y = playerMech.y; explosion.graphics.scaleX = 2; explosion.graphics.scaleY = 2; explosions.push(explosion); game.addChild(explosion); // Play explosion sound LK.getSound('explosion').play(); // Remove player playerMech.destroy(); playerMech = null; // Game over LK.showGameOver(); } // Remove bullet bullet.destroy(); enemyBullets.splice(i, 1); } } // Update explosions for (var i = explosions.length - 1; i >= 0; i--) { var explosion = explosions[i]; var remove = explosion.update(); if (remove) { explosion.destroy(); explosions.splice(i, 1); } } // Update power-ups for (var i = powerUps.length - 1; i >= 0; i--) { var powerUp = powerUps[i]; powerUp.update(); // Check for collision with player if (playerMech && powerUp.intersects(playerMech)) { // Apply power-up effect playerMech.applyPowerUp(powerUp.type, powerUp.value); // Play power-up sound LK.getSound('power_up_collect').play(); // Remove power-up powerUp.destroy(); powerUps.splice(i, 1); } } // Spawn random power-ups occasionally powerUpSpawnTimer++; if (powerUpSpawnTimer > 600 && powerUps.length < 3) { // Every 10 seconds if less than 3 power-ups powerUpSpawnTimer = 0; if (Math.random() < 0.5) { // 50% chance spawnPowerUp(); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
self.type = 'player';
self.speed = 15;
self.damage = 10;
self.direction = {
x: 0,
y: -1
}; // Default upward direction
self.graphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
};
self.setType = function (type) {
self.type = type;
if (type === 'enemy') {
self.graphics = self.removeChild(self.graphics);
self.graphics = self.attachAsset('enemy_bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.damage = 5;
self.speed = 8;
}
return self;
};
return self;
});
var EnemyMech = Container.expand(function () {
var self = Container.call(this);
self.health = 30;
self.maxHealth = 30;
self.speed = 2;
self.fireRate = 120; // frames between shots
self.fireCounter = 0;
self.movementPattern = 'chase'; // Default pattern
self.type = 'basic';
self.scoreValue = 100;
// Create main body
self.body = self.attachAsset('enemy_mech', {
anchorX: 0.5,
anchorY: 0.5
});
// Create health bar
self.healthBarBg = self.attachAsset('health_bar_bg', {
anchorX: 0.5,
anchorY: 0.5,
y: -110,
scaleX: 0.8,
scaleY: 0.6
});
self.healthBar = self.attachAsset('health_bar', {
anchorX: 0,
anchorY: 0.5,
x: -80,
y: -110,
scaleX: 0.8,
scaleY: 0.6
});
self.takeDamage = function (amount) {
self.health -= amount;
// Update health bar width
var healthPercent = Math.max(0, self.health / self.maxHealth);
self.healthBar.scaleX = 0.8 * healthPercent;
if (self.health <= 0) {
return true; // Signal for destruction
}
// Flash red when hit
LK.effects.flashObject(self.body, 0xff0000, 200);
return false;
};
self.setType = function (newType) {
self.type = newType;
if (newType === 'heavy') {
self.body.tint = 0x990000;
self.health = 60;
self.maxHealth = 60;
self.speed = 1.2;
self.fireRate = 150;
self.scoreValue = 200;
self.body.scaleX = 1.3;
self.body.scaleY = 1.3;
} else if (newType === 'speeder') {
self.body.tint = 0x0099cc;
self.health = 20;
self.maxHealth = 20;
self.speed = 3.5;
self.fireRate = 90;
self.scoreValue = 150;
self.body.scaleX = 0.8;
self.body.scaleY = 0.8;
} else {
// basic type - default values
self.body.tint = 0xcc3300;
}
// Reset health bar to match new max health
self.healthBar.scaleX = 0.8;
return self;
};
self.setMovementPattern = function (pattern) {
self.movementPattern = pattern;
return self;
};
self.update = function () {
// Handle movement based on pattern
if (self.movementPattern === 'chase' && playerMech) {
// Move toward player
var dx = playerMech.x - self.x;
var dy = playerMech.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 10) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
} else if (self.movementPattern === 'strafe') {
// Move side to side
self.x += Math.sin(LK.ticks / 30) * self.speed;
// Slowly advance down the screen
self.y += self.speed * 0.5;
} else if (self.movementPattern === 'circle' && playerMech) {
// Circle around player
var angle = LK.ticks / 100;
var radius = 300;
self.x = playerMech.x + Math.cos(angle) * radius;
self.y = playerMech.y + Math.sin(angle) * radius;
}
// Firing logic
self.fireCounter++;
if (self.fireCounter >= self.fireRate && playerMech) {
self.fireCounter = 0;
// Calculate direction to player
var dx = playerMech.x - self.x;
var dy = playerMech.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// Normalize
dx = dx / dist;
dy = dy / dist;
// Create a new bullet
var bullet = new Bullet().setType('enemy');
bullet.x = self.x;
bullet.y = self.y;
bullet.direction = {
x: dx,
y: dy
};
// Add to game's bullet array
enemyBullets.push(bullet);
game.addChild(bullet);
// Play sound
LK.getSound('enemy_shoot').play();
}
return false; // No auto-removal
};
return self;
});
var Explosion = Container.expand(function () {
var self = Container.call(this);
self.lifespan = 20; // frames
self.age = 0;
self.graphics = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
self.update = function () {
self.age++;
self.graphics.alpha = 1 - self.age / self.lifespan;
self.graphics.scaleX = 1 + self.age / 10;
self.graphics.scaleY = 1 + self.age / 10;
if (self.age >= self.lifespan) {
return true; // Signal for removal
}
return false;
};
return self;
});
var PlayerMech = Container.expand(function () {
var self = Container.call(this);
self.health = 100;
self.maxHealth = 100;
self.speed = 6;
self.fireRate = 15; // frames between shots
self.fireCounter = 0;
self.damageMultiplier = 1.0;
self.speedMultiplier = 1.0;
self.fireRateMultiplier = 1.0;
// Create main body
self.body = self.attachAsset('player_mech', {
anchorX: 0.5,
anchorY: 0.5
});
// Health bar
self.healthBarBg = self.attachAsset('health_bar_bg', {
anchorX: 0.5,
anchorY: 0.5,
y: -120,
scaleX: 1,
scaleY: 0.8
});
self.healthBar = self.attachAsset('health_bar', {
anchorX: 0,
anchorY: 0.5,
x: -100,
y: -120,
scaleX: 1,
scaleY: 0.8
});
self.takeDamage = function (amount) {
self.health -= amount;
// Update health bar width
var healthPercent = Math.max(0, self.health / self.maxHealth);
self.healthBar.scaleX = healthPercent;
// Flash red when hit
LK.effects.flashObject(self.body, 0xff0000, 200);
if (self.health <= 0) {
return true; // Signal for destruction
}
return false;
};
self.heal = function (amount) {
self.health = Math.min(self.maxHealth, self.health + amount);
// Update health bar width
var healthPercent = self.health / self.maxHealth;
self.healthBar.scaleX = healthPercent;
// Flash green when healed
LK.effects.flashObject(self.body, 0x00ff00, 200);
};
self.applyPowerUp = function (type, value) {
if (type === 'health') {
self.heal(value);
} else if (type === 'damage') {
self.damageMultiplier += value / 100;
LK.effects.flashObject(self.body, 0xff0000, 500);
} else if (type === 'speed') {
self.speedMultiplier += value / 100;
LK.effects.flashObject(self.body, 0x00ffff, 500);
} else if (type === 'fireRate') {
self.fireRateMultiplier += value / 100;
LK.effects.flashObject(self.body, 0xffff00, 500);
}
};
self.shoot = function () {
if (self.fireCounter >= Math.max(5, self.fireRate / self.fireRateMultiplier)) {
self.fireCounter = 0;
// Create a new bullet
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y - self.body.height / 2;
bullet.damage = Math.round(bullet.damage * self.damageMultiplier);
// Add to game's bullet array
playerBullets.push(bullet);
game.addChild(bullet);
// Play sound
LK.getSound('player_shoot').play();
return true;
}
return false;
};
self.update = function () {
self.fireCounter++;
return false; // No auto-removal
};
self.down = function (x, y, obj) {
// Handle touch down events if needed
};
self.up = function (x, y, obj) {
// Handle touch up events if needed
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
self.type = 'health'; // Default type
self.value = 25; // Default value
self.graphics = self.attachAsset('power_up', {
anchorX: 0.5,
anchorY: 0.5
});
self.pulse = function () {
tween(self.graphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self.graphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: self.pulse
});
}
});
};
self.setType = function (newType) {
self.type = newType;
if (newType === 'damage') {
self.graphics.tint = 0xff0000;
self.value = 10; // 10% damage increase
} else if (newType === 'speed') {
self.graphics.tint = 0x00ffff;
self.value = 20; // 20% speed increase
} else if (newType === 'fireRate') {
self.graphics.tint = 0xffff00;
self.value = 15; // 15% fire rate increase
} else {
// health type
self.graphics.tint = 0x00ff00;
self.value = 25; // 25 health points
}
return self;
};
self.update = function () {
self.graphics.rotation += 0.02;
return false; // No auto-removal
};
// Start pulsing animation
self.pulse();
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000022 // Dark blue space background
});
/****
* Game Code
****/
// Create the arena border
var arenaBorder = LK.getAsset('arena_border', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
game.addChild(arenaBorder);
arenaBorder.x = 2048 / 2;
arenaBorder.y = 2732 / 2;
// Define game boundaries based on arena size
var gameArea = {
left: arenaBorder.x - arenaBorder.width / 2,
right: arenaBorder.x + arenaBorder.width / 2,
top: arenaBorder.y - arenaBorder.height / 2,
bottom: arenaBorder.y + arenaBorder.height / 2
};
// Game state variables
var playerMech;
var playerBullets = [];
var enemyMechs = [];
var enemyBullets = [];
var explosions = [];
var powerUps = [];
var currentWave = 1;
var waveCompleted = false;
var waveTimer = 0;
var powerUpSpawnTimer = 0;
var mechTypes = ['basic', 'heavy', 'speeder'];
var movementPatterns = ['chase', 'strafe', 'circle'];
var powerUpTypes = ['health', 'damage', 'speed', 'fireRate'];
var dragging = false;
// Setup score display
var scoreText = new Text2('SCORE: 0', {
size: 50,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Setup wave display
var waveText = new Text2('WAVE 1', {
size: 60,
fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(waveText);
waveText.alpha = 0;
// Setup high score display
var highScoreText = new Text2('HIGH SCORE: ' + storage.highScore, {
size: 40,
fill: 0xFFCC00
});
highScoreText.anchor.set(1, 0); // Right aligned at the top
highScoreText.x = 300; // Position from the right edge
LK.gui.topRight.addChild(highScoreText);
// Create player mech
playerMech = new PlayerMech();
playerMech.x = 2048 / 2;
playerMech.y = 2732 - 400;
game.addChild(playerMech);
// Function to spawn enemies for a wave
function spawnWaveEnemies() {
// Clear any remaining enemies
for (var i = enemyMechs.length - 1; i >= 0; i--) {
enemyMechs[i].destroy();
enemyMechs.splice(i, 1);
}
// Number of enemies based on wave
var enemyCount = 3 + currentWave * 2;
for (var i = 0; i < enemyCount; i++) {
var enemy = new EnemyMech();
// Random type with weighted probability
var typeRandom = Math.random();
var type;
if (typeRandom < 0.6) {
type = 'basic';
} else if (typeRandom < 0.8) {
type = 'heavy';
} else {
type = 'speeder';
}
enemy.setType(type);
// Random movement pattern
var patternIndex = Math.floor(Math.random() * movementPatterns.length);
enemy.setMovementPattern(movementPatterns[patternIndex]);
// Position enemies in a grid at the top
var cols = Math.min(5, enemyCount);
var rows = Math.ceil(enemyCount / cols);
var col = i % cols;
var row = Math.floor(i / cols);
var spacing = 250;
var startX = arenaBorder.x - (cols - 1) * spacing / 2;
var startY = arenaBorder.y - arenaBorder.height / 2 + 200;
enemy.x = startX + col * spacing;
enemy.y = startY + row * spacing;
// Scale health and speed based on wave
enemy.health += (currentWave - 1) * 10;
enemy.maxHealth = enemy.health;
// Add to game
enemyMechs.push(enemy);
game.addChild(enemy);
}
// Show wave notification
waveText.setText('WAVE ' + currentWave);
waveText.alpha = 1;
tween(waveText, {
alpha: 0
}, {
duration: 2000,
easing: tween.easeOut
});
// Play wave sound
LK.getSound('wave_complete').play();
waveCompleted = false;
}
// Function to spawn a power-up
function spawnPowerUp() {
var powerUp = new PowerUp();
// Random position within arena
powerUp.x = gameArea.left + Math.random() * (gameArea.right - gameArea.left);
powerUp.y = gameArea.top + Math.random() * (gameArea.bottom - gameArea.top);
// Random type
var typeIndex = Math.floor(Math.random() * powerUpTypes.length);
powerUp.setType(powerUpTypes[typeIndex]);
// Add to game
powerUps.push(powerUp);
game.addChild(powerUp);
}
// Initialize the first wave
spawnWaveEnemies();
// Play background music
LK.playMusic('battle_music');
// Movement handling
function handleMove(x, y, obj) {
if (dragging && playerMech) {
// Calculate new position but keep within bounds
var newX = Math.max(gameArea.left + playerMech.body.width / 2, Math.min(x, gameArea.right - playerMech.body.width / 2));
var newY = Math.max(gameArea.top + playerMech.body.height / 2, Math.min(y, gameArea.bottom - playerMech.body.height / 2));
// Apply speed multiplier to movement
var currentX = playerMech.x;
var currentY = playerMech.y;
var dx = newX - currentX;
var dy = newY - currentY;
// Calculate distance to move based on speed
var distance = Math.sqrt(dx * dx + dy * dy);
var maxDistance = playerMech.speed * playerMech.speedMultiplier;
if (distance > maxDistance) {
var ratio = maxDistance / distance;
dx *= ratio;
dy *= ratio;
playerMech.x += dx;
playerMech.y += dy;
} else {
playerMech.x = newX;
playerMech.y = newY;
}
// Automatically shoot while moving
playerMech.shoot();
}
}
// Touch/mouse events
game.down = function (x, y, obj) {
dragging = true;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragging = false;
};
game.move = handleMove;
// Main game update function
game.update = function () {
// Check if all enemies are defeated
if (enemyMechs.length === 0 && !waveCompleted) {
waveCompleted = true;
waveTimer = 180; // 3 seconds @ 60fps
currentWave++;
}
// Start next wave after delay
if (waveCompleted) {
waveTimer--;
if (waveTimer <= 0) {
spawnWaveEnemies();
}
}
// Update player mech
if (playerMech) {
playerMech.update();
}
// Update player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
bullet.update();
// Check if bullet is out of bounds
if (bullet.y < gameArea.top || bullet.y > gameArea.bottom || bullet.x < gameArea.left || bullet.x > gameArea.right) {
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
// Check for collision with enemy mechs
var hitEnemy = false;
for (var j = enemyMechs.length - 1; j >= 0; j--) {
var enemy = enemyMechs[j];
if (bullet.intersects(enemy)) {
hitEnemy = true;
// Deal damage to enemy
var destroyed = enemy.takeDamage(bullet.damage);
if (destroyed) {
// Create explosion
var explosion = new Explosion();
explosion.x = enemy.x;
explosion.y = enemy.y;
explosions.push(explosion);
game.addChild(explosion);
// Play explosion sound
LK.getSound('explosion').play();
// Add score
LK.setScore(LK.getScore() + enemy.scoreValue);
scoreText.setText('SCORE: ' + LK.getScore());
// Check if high score was beaten
if (LK.getScore() > storage.highScore) {
storage.highScore = LK.getScore();
highScoreText.setText('HIGH SCORE: ' + storage.highScore);
}
// Remove enemy
enemy.destroy();
enemyMechs.splice(j, 1);
// Random chance to spawn power-up (20%)
if (Math.random() < 0.2) {
var powerUp = new PowerUp();
powerUp.x = enemy.x;
powerUp.y = enemy.y;
powerUp.setType(powerUpTypes[Math.floor(Math.random() * powerUpTypes.length)]);
powerUps.push(powerUp);
game.addChild(powerUp);
}
}
// Remove bullet
bullet.destroy();
playerBullets.splice(i, 1);
break;
}
}
}
// Update enemy mechs
for (var i = enemyMechs.length - 1; i >= 0; i--) {
var enemy = enemyMechs[i];
enemy.update();
// Keep enemy within bounds
enemy.x = Math.max(gameArea.left + enemy.body.width / 2, Math.min(enemy.x, gameArea.right - enemy.body.width / 2));
enemy.y = Math.max(gameArea.top + enemy.body.height / 2, Math.min(enemy.y, gameArea.bottom - enemy.body.height / 2));
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
bullet.update();
// Check if bullet is out of bounds
if (bullet.y < gameArea.top || bullet.y > gameArea.bottom || bullet.x < gameArea.left || bullet.x > gameArea.right) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check for collision with player
if (playerMech && bullet.intersects(playerMech)) {
// Deal damage to player
var destroyed = playerMech.takeDamage(bullet.damage);
if (destroyed) {
// Create explosion
var explosion = new Explosion();
explosion.x = playerMech.x;
explosion.y = playerMech.y;
explosion.graphics.scaleX = 2;
explosion.graphics.scaleY = 2;
explosions.push(explosion);
game.addChild(explosion);
// Play explosion sound
LK.getSound('explosion').play();
// Remove player
playerMech.destroy();
playerMech = null;
// Game over
LK.showGameOver();
}
// Remove bullet
bullet.destroy();
enemyBullets.splice(i, 1);
}
}
// Update explosions
for (var i = explosions.length - 1; i >= 0; i--) {
var explosion = explosions[i];
var remove = explosion.update();
if (remove) {
explosion.destroy();
explosions.splice(i, 1);
}
}
// Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
powerUp.update();
// Check for collision with player
if (playerMech && powerUp.intersects(playerMech)) {
// Apply power-up effect
playerMech.applyPowerUp(powerUp.type, powerUp.value);
// Play power-up sound
LK.getSound('power_up_collect').play();
// Remove power-up
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Spawn random power-ups occasionally
powerUpSpawnTimer++;
if (powerUpSpawnTimer > 600 && powerUps.length < 3) {
// Every 10 seconds if less than 3 power-ups
powerUpSpawnTimer = 0;
if (Math.random() < 0.5) {
// 50% chance
spawnPowerUp();
}
}
};