/****
* 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();
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,670 @@
-/****
+/****
+* 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: 0x000000
-});
\ No newline at end of file
+ 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();
+ }
+ }
+};
\ No newline at end of file