/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
shipColor: 3447003
});
/****
* Classes
****/
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemyShip', {
anchorX: 0.5,
anchorY: 0.5
});
// Type: 0 = basic, 1 = shooter, 2 = fast
self.type = 0;
self.health = 1;
self.points = 100;
self.moveSpeed = 2;
self.shotFrequency = 120; // frames between shots
self.shotCounter = Math.floor(Math.random() * 60); // Random initial delay
self.init = function (type) {
self.type = type || 0;
if (self.type === 0) {
// Basic enemy
enemyGraphics.tint = 0xe74c3c;
self.health = 1;
self.points = 100;
self.moveSpeed = 2;
self.shotFrequency = 0; // Doesn't shoot
} else if (self.type === 1) {
// Shooter enemy
enemyGraphics.tint = 0xf39c12;
self.health = 2;
self.points = 200;
self.moveSpeed = 1;
self.shotFrequency = 120;
} else if (self.type === 2) {
// Fast enemy
enemyGraphics.tint = 0x9b59b6;
self.health = 1;
self.points = 150;
self.moveSpeed = 4;
self.shotFrequency = 0;
}
return self;
};
self.movePattern = function () {
// Default movement pattern
self.y += self.moveSpeed;
if (self.type === 2) {
// Fast enemy zigzags
self.x += Math.sin(LK.ticks / 10) * 5;
}
};
self.tryShoot = function () {
if (self.shotFrequency === 0) {
return null;
}
self.shotCounter++;
if (self.shotCounter >= self.shotFrequency) {
self.shotCounter = 0;
return true;
}
return false;
};
self.takeDamage = function (amount) {
self.health -= amount;
// Flash red when hit
tween(enemyGraphics, {
tint: 0xff0000
}, {
duration: 100,
onFinish: function onFinish() {
if (self.type === 0) {
tween(enemyGraphics, {
tint: 0xe74c3c
}, {
duration: 100
});
} else if (self.type === 1) {
tween(enemyGraphics, {
tint: 0xf39c12
}, {
duration: 100
});
} else if (self.type === 2) {
tween(enemyGraphics, {
tint: 0x9b59b6
}, {
duration: 100
});
}
}
});
return self.health <= 0;
};
self.update = function () {
self.movePattern();
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.power = 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Explosion = Container.expand(function () {
var self = Container.call(this);
var explosionGraphics = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.9
});
self.lifespan = 30; // frames
self.update = function () {
self.lifespan--;
if (self.lifespan <= 0) {
self.destroy();
return;
}
// Gradually fade out and expand
explosionGraphics.alpha = self.lifespan / 30;
explosionGraphics.scale.x = 1 + (1 - self.lifespan / 30) * 2;
explosionGraphics.scale.y = 1 + (1 - self.lifespan / 30) * 2;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5
});
// Set the ship color from storage if available
playerGraphics.tint = storage.shipColor || 0x3498db;
self.lives = 3;
self.score = 0;
self.fireRate = 15; // frames between shots
self.fireCounter = 0;
self.doubleFire = false;
self.doubleFireduration = 0;
self.shield = false;
self.shieldDuration = 0;
self.invulnerable = false;
self.invulnerableDuration = 0;
// Shield visual
var shieldGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0,
tint: 0x3498db,
scaleX: 1.5,
scaleY: 1.5
});
self.canFire = function () {
self.fireCounter++;
if (self.fireCounter >= self.fireRate) {
self.fireCounter = 0;
return true;
}
return false;
};
self.takeDamage = function () {
if (self.invulnerable || self.shield) {
if (self.shield) {
// Remove shield instead of taking damage
self.shield = false;
shieldGraphics.alpha = 0;
// Flash effect
LK.effects.flashObject(self, 0x3498db, 500);
}
return false;
}
self.lives--;
// Become temporarily invulnerable
self.invulnerable = true;
self.invulnerableDuration = 90; // 1.5 seconds
// Flash effect
LK.effects.flashObject(self, 0xff0000, 500);
return self.lives <= 0;
};
self.applyPowerUp = function (type) {
if (type === 0) {
// Double fire
self.doubleFire = true;
self.doubleFireduration = 300; // 5 seconds
} else if (type === 1) {
// Shield
self.shield = true;
shieldGraphics.alpha = 0.7;
self.shieldDuration = 300; // 5 seconds
} else if (type === 2) {
// Extra life
self.lives++;
}
};
self.update = function () {
// Update power-ups durations
if (self.doubleFire) {
self.doubleFireduration--;
if (self.doubleFireduration <= 0) {
self.doubleFire = false;
}
}
if (self.shield) {
self.shieldDuration--;
if (self.shieldDuration <= 0) {
self.shield = false;
shieldGraphics.alpha = 0;
} else {
// Pulsate shield
shieldGraphics.alpha = 0.5 + Math.sin(LK.ticks / 10) * 0.2;
}
}
if (self.invulnerable) {
self.invulnerableDuration--;
if (self.invulnerableDuration <= 0) {
self.invulnerable = false;
}
// Blink when invulnerable
self.alpha = Math.floor(LK.ticks / 5) % 2 ? 0.5 : 1;
} else {
self.alpha = 1;
}
};
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -15;
self.power = 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
// PowerUp types: 0 = double fire, 1 = shield, 2 = extra life
self.type = Math.floor(Math.random() * 3);
// Set color based on type
if (self.type === 0) {
powerUpGraphics.tint = 0xff5500; // orange for double fire
} else if (self.type === 1) {
powerUpGraphics.tint = 0x3498db; // blue for shield
} else {
powerUpGraphics.tint = 0x2ecc71; // green for extra life
}
self.speed = 3;
self.update = function () {
self.y += self.speed;
// Pulsate effect
if (LK.ticks % 10 === 0) {
tween(powerUpGraphics.scale, {
x: 1.1,
y: 1.1
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(powerUpGraphics.scale, {
x: 1,
y: 1
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Set the game's background
game.setBackgroundColor(0x0a0a2a); // Deep space blue
// Game state variables
var player;
var enemies = [];
var playerBullets = [];
var enemyBullets = [];
var powerUps = [];
var explosions = [];
var score = 0;
var level = 1;
var enemySpawnRate = 60; // frames between enemy spawns
var enemySpawnCounter = 0;
var powerUpChance = 0.1; // 10% chance on enemy death
var gameActive = true;
var dragNode = null;
var isPaused = false;
// UI elements
var scoreText = new Text2('SCORE: 0', {
size: 70,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.y = 20;
scoreText.x = -scoreText.width - 20;
var livesText = new Text2('LIVES: 3', {
size: 70,
fill: 0xFFFFFF
});
livesText.anchor.set(1, 0);
LK.gui.topLeft.addChild(livesText);
livesText.y = 20;
livesText.x = 120; // Keep away from top-left corner menu icon
var levelText = new Text2('LEVEL: 1', {
size: 70,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
levelText.y = 20;
// Initialize the player
player = new Player();
player.x = 2048 / 2;
player.y = 2732 - 300;
game.addChild(player);
// Create stars for background
var stars = [];
function createStars() {
for (var i = 0; i < 100; i++) {
var star = LK.getAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3 + Math.random() * 0.7,
scaleY: 0.3 + Math.random() * 0.7,
alpha: 0.3 + Math.random() * 0.7,
tint: 0xffffff
});
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
star.speed = 0.5 + Math.random() * 2;
stars.push(star);
game.addChild(star);
}
}
createStars();
// Start background music
LK.playMusic('gameMusic', {
fade: {
start: 0,
end: 0.7,
duration: 1000
}
});
// Spawn a new enemy
function spawnEnemy() {
// Choose enemy type based on level
var typeChances = [0.7, 0.2, 0.1]; // Default chances
// Adjust chances based on level
if (level >= 3) {
typeChances = [0.5, 0.3, 0.2];
}
if (level >= 5) {
typeChances = [0.4, 0.3, 0.3];
}
if (level >= 8) {
typeChances = [0.3, 0.4, 0.3];
}
// Determine enemy type
var rand = Math.random();
var enemyType = 0;
if (rand > typeChances[0]) {
enemyType = rand > typeChances[0] + typeChances[1] ? 2 : 1;
}
var enemy = new Enemy().init(enemyType);
enemy.x = 200 + Math.random() * (2048 - 400);
enemy.y = -100;
enemies.push(enemy);
game.addChild(enemy);
}
// Fire a bullet from the player
function firePlayerBullet(offsetX) {
offsetX = offsetX || 0;
var bullet = new PlayerBullet();
bullet.x = player.x + offsetX;
bullet.y = player.y - 50;
playerBullets.push(bullet);
game.addChild(bullet);
LK.getSound('playerShoot').play();
}
// Fire a bullet from an enemy
function fireEnemyBullet(enemy) {
var bullet = new EnemyBullet();
bullet.x = enemy.x;
bullet.y = enemy.y + 50;
enemyBullets.push(bullet);
game.addChild(bullet);
LK.getSound('enemyShoot').play();
}
// Create an explosion
function createExplosion(x, y, size) {
var explosion = new Explosion();
explosion.x = x;
explosion.y = y;
explosion.scale.set(size || 1);
explosions.push(explosion);
game.addChild(explosion);
LK.getSound('explosion').play();
}
// Spawn a power-up
function spawnPowerUp(x, y) {
var powerUp = new PowerUp();
powerUp.x = x;
powerUp.y = y;
powerUps.push(powerUp);
game.addChild(powerUp);
}
// Update score display
function updateScore(newScore) {
score = newScore;
scoreText.setText("SCORE: " + score);
// Check for level up (every 1000 points)
var newLevel = Math.floor(score / 1000) + 1;
if (newLevel > level) {
level = newLevel;
levelText.setText("LEVEL: " + level);
// Increase difficulty with level
enemySpawnRate = Math.max(20, 60 - (level - 1) * 5);
}
// Set score in LK system
LK.setScore(score);
// Update high score if needed
if (score > storage.highScore) {
storage.highScore = score;
}
}
// Update lives display
function updateLives() {
livesText.setText("LIVES: " + player.lives);
}
// Handle player and enemy movement
function handleGameInput(x, y) {
if (dragNode && gameActive && !isPaused) {
dragNode.x = Math.max(dragNode.width / 2, Math.min(2048 - dragNode.width / 2, x));
// Restrict vertical movement to bottom third of screen
dragNode.y = Math.max(2732 / 3 * 2, Math.min(2732 - dragNode.height / 2, y));
}
}
// Mouse or touch down on the game
game.down = function (x, y, obj) {
if (!gameActive || isPaused) {
return;
}
// Set drag node to player if within bounds
if (Math.abs(x - player.x) < 100 && Math.abs(y - player.y) < 100) {
dragNode = player;
} else {
// Fire when tapping elsewhere
if (player.canFire()) {
if (player.doubleFire) {
firePlayerBullet(-30);
firePlayerBullet(30);
} else {
firePlayerBullet(0);
}
}
}
// Call move handler for immediate response
handleGameInput(x, y);
};
// Mouse or touch move on the game
game.move = function (x, y, obj) {
handleGameInput(x, y);
};
// Mouse or touch up on the game
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game update loop
game.update = function () {
if (!gameActive || isPaused) {
return;
}
// Update stars (background)
for (var i = 0; i < stars.length; i++) {
stars[i].y += stars[i].speed;
if (stars[i].y > 2732) {
stars[i].y = 0;
stars[i].x = Math.random() * 2048;
}
}
// Spawn enemies
enemySpawnCounter++;
if (enemySpawnCounter >= enemySpawnRate) {
enemySpawnCounter = 0;
spawnEnemy();
}
// Auto-fire for player (if holding down)
if (dragNode === player && player.canFire()) {
if (player.doubleFire) {
firePlayerBullet(-30);
firePlayerBullet(30);
} else {
firePlayerBullet(0);
}
}
// Update player
player.update();
// Update bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
// Check if bullet is off screen
if (bullet.y < -50) {
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
// Check for collision with enemies
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
// Handle enemy hit
if (enemy.takeDamage(bullet.power)) {
// Enemy destroyed
createExplosion(enemy.x, enemy.y, 1);
updateScore(score + enemy.points);
// Chance to spawn power-up
if (Math.random() < powerUpChance) {
spawnPowerUp(enemy.x, enemy.y);
}
enemy.destroy();
enemies.splice(j, 1);
}
// Remove bullet
bullet.destroy();
playerBullets.splice(i, 1);
break;
}
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
// Check if bullet is off screen
if (bullet.y > 2732 + 50) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check for collision with player
if (bullet.intersects(player)) {
// Handle player hit
if (player.takeDamage()) {
// Game over
gameActive = false;
createExplosion(player.x, player.y, 2);
LK.setTimeout(function () {
LK.showGameOver();
}, 1500);
}
updateLives();
// Remove bullet
bullet.destroy();
enemyBullets.splice(i, 1);
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
// Check if enemy is off screen
if (enemy.y > 2732 + 100) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Check for collision with player
if (enemy.intersects(player)) {
// Handle player collision with enemy
if (player.takeDamage()) {
// Game over
gameActive = false;
createExplosion(player.x, player.y, 2);
LK.setTimeout(function () {
LK.showGameOver();
}, 1500);
}
updateLives();
// Destroy enemy
createExplosion(enemy.x, enemy.y, 1);
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Enemy shooting
if (enemy.tryShoot()) {
fireEnemyBullet(enemy);
}
// Update enemy
enemy.update();
}
// Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
// Check if power-up is off screen
if (powerUp.y > 2732 + 50) {
powerUp.destroy();
powerUps.splice(i, 1);
continue;
}
// Check for collision with player
if (powerUp.intersects(player)) {
// Apply power-up effect
player.applyPowerUp(powerUp.type);
// Play sound and add points
LK.getSound('powerUp').play();
updateScore(score + 50);
// Remove power-up
powerUp.destroy();
powerUps.splice(i, 1);
continue;
}
// Update power-up
powerUp.update();
}
// Update explosions
for (var i = explosions.length - 1; i >= 0; i--) {
explosions[i].update();
if (explosions[i].lifespan <= 0) {
explosions.splice(i, 1);
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,657 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ highScore: 0,
+ shipColor: 3447003
+});
+
+/****
+* Classes
+****/
+var Enemy = Container.expand(function () {
+ var self = Container.call(this);
+ var enemyGraphics = self.attachAsset('enemyShip', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Type: 0 = basic, 1 = shooter, 2 = fast
+ self.type = 0;
+ self.health = 1;
+ self.points = 100;
+ self.moveSpeed = 2;
+ self.shotFrequency = 120; // frames between shots
+ self.shotCounter = Math.floor(Math.random() * 60); // Random initial delay
+ self.init = function (type) {
+ self.type = type || 0;
+ if (self.type === 0) {
+ // Basic enemy
+ enemyGraphics.tint = 0xe74c3c;
+ self.health = 1;
+ self.points = 100;
+ self.moveSpeed = 2;
+ self.shotFrequency = 0; // Doesn't shoot
+ } else if (self.type === 1) {
+ // Shooter enemy
+ enemyGraphics.tint = 0xf39c12;
+ self.health = 2;
+ self.points = 200;
+ self.moveSpeed = 1;
+ self.shotFrequency = 120;
+ } else if (self.type === 2) {
+ // Fast enemy
+ enemyGraphics.tint = 0x9b59b6;
+ self.health = 1;
+ self.points = 150;
+ self.moveSpeed = 4;
+ self.shotFrequency = 0;
+ }
+ return self;
+ };
+ self.movePattern = function () {
+ // Default movement pattern
+ self.y += self.moveSpeed;
+ if (self.type === 2) {
+ // Fast enemy zigzags
+ self.x += Math.sin(LK.ticks / 10) * 5;
+ }
+ };
+ self.tryShoot = function () {
+ if (self.shotFrequency === 0) {
+ return null;
+ }
+ self.shotCounter++;
+ if (self.shotCounter >= self.shotFrequency) {
+ self.shotCounter = 0;
+ return true;
+ }
+ return false;
+ };
+ self.takeDamage = function (amount) {
+ self.health -= amount;
+ // Flash red when hit
+ tween(enemyGraphics, {
+ tint: 0xff0000
+ }, {
+ duration: 100,
+ onFinish: function onFinish() {
+ if (self.type === 0) {
+ tween(enemyGraphics, {
+ tint: 0xe74c3c
+ }, {
+ duration: 100
+ });
+ } else if (self.type === 1) {
+ tween(enemyGraphics, {
+ tint: 0xf39c12
+ }, {
+ duration: 100
+ });
+ } else if (self.type === 2) {
+ tween(enemyGraphics, {
+ tint: 0x9b59b6
+ }, {
+ duration: 100
+ });
+ }
+ }
+ });
+ return self.health <= 0;
+ };
+ self.update = function () {
+ self.movePattern();
+ };
+ return self;
+});
+var EnemyBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bulletGraphics = self.attachAsset('enemyBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 10;
+ self.power = 1;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+var Explosion = Container.expand(function () {
+ var self = Container.call(this);
+ var explosionGraphics = self.attachAsset('explosion', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.9
+ });
+ self.lifespan = 30; // frames
+ self.update = function () {
+ self.lifespan--;
+ if (self.lifespan <= 0) {
+ self.destroy();
+ return;
+ }
+ // Gradually fade out and expand
+ explosionGraphics.alpha = self.lifespan / 30;
+ explosionGraphics.scale.x = 1 + (1 - self.lifespan / 30) * 2;
+ explosionGraphics.scale.y = 1 + (1 - self.lifespan / 30) * 2;
+ };
+ return self;
+});
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ var playerGraphics = self.attachAsset('playerShip', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Set the ship color from storage if available
+ playerGraphics.tint = storage.shipColor || 0x3498db;
+ self.lives = 3;
+ self.score = 0;
+ self.fireRate = 15; // frames between shots
+ self.fireCounter = 0;
+ self.doubleFire = false;
+ self.doubleFireduration = 0;
+ self.shield = false;
+ self.shieldDuration = 0;
+ self.invulnerable = false;
+ self.invulnerableDuration = 0;
+ // Shield visual
+ var shieldGraphics = self.attachAsset('powerUp', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0,
+ tint: 0x3498db,
+ scaleX: 1.5,
+ scaleY: 1.5
+ });
+ self.canFire = function () {
+ self.fireCounter++;
+ if (self.fireCounter >= self.fireRate) {
+ self.fireCounter = 0;
+ return true;
+ }
+ return false;
+ };
+ self.takeDamage = function () {
+ if (self.invulnerable || self.shield) {
+ if (self.shield) {
+ // Remove shield instead of taking damage
+ self.shield = false;
+ shieldGraphics.alpha = 0;
+ // Flash effect
+ LK.effects.flashObject(self, 0x3498db, 500);
+ }
+ return false;
+ }
+ self.lives--;
+ // Become temporarily invulnerable
+ self.invulnerable = true;
+ self.invulnerableDuration = 90; // 1.5 seconds
+ // Flash effect
+ LK.effects.flashObject(self, 0xff0000, 500);
+ return self.lives <= 0;
+ };
+ self.applyPowerUp = function (type) {
+ if (type === 0) {
+ // Double fire
+ self.doubleFire = true;
+ self.doubleFireduration = 300; // 5 seconds
+ } else if (type === 1) {
+ // Shield
+ self.shield = true;
+ shieldGraphics.alpha = 0.7;
+ self.shieldDuration = 300; // 5 seconds
+ } else if (type === 2) {
+ // Extra life
+ self.lives++;
+ }
+ };
+ self.update = function () {
+ // Update power-ups durations
+ if (self.doubleFire) {
+ self.doubleFireduration--;
+ if (self.doubleFireduration <= 0) {
+ self.doubleFire = false;
+ }
+ }
+ if (self.shield) {
+ self.shieldDuration--;
+ if (self.shieldDuration <= 0) {
+ self.shield = false;
+ shieldGraphics.alpha = 0;
+ } else {
+ // Pulsate shield
+ shieldGraphics.alpha = 0.5 + Math.sin(LK.ticks / 10) * 0.2;
+ }
+ }
+ if (self.invulnerable) {
+ self.invulnerableDuration--;
+ if (self.invulnerableDuration <= 0) {
+ self.invulnerable = false;
+ }
+ // Blink when invulnerable
+ self.alpha = Math.floor(LK.ticks / 5) % 2 ? 0.5 : 1;
+ } else {
+ self.alpha = 1;
+ }
+ };
+ return self;
+});
+var PlayerBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bulletGraphics = self.attachAsset('playerBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -15;
+ self.power = 1;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+var PowerUp = Container.expand(function () {
+ var self = Container.call(this);
+ var powerUpGraphics = self.attachAsset('powerUp', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // PowerUp types: 0 = double fire, 1 = shield, 2 = extra life
+ self.type = Math.floor(Math.random() * 3);
+ // Set color based on type
+ if (self.type === 0) {
+ powerUpGraphics.tint = 0xff5500; // orange for double fire
+ } else if (self.type === 1) {
+ powerUpGraphics.tint = 0x3498db; // blue for shield
+ } else {
+ powerUpGraphics.tint = 0x2ecc71; // green for extra life
+ }
+ self.speed = 3;
+ self.update = function () {
+ self.y += self.speed;
+ // Pulsate effect
+ if (LK.ticks % 10 === 0) {
+ tween(powerUpGraphics.scale, {
+ x: 1.1,
+ y: 1.1
+ }, {
+ duration: 500,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ tween(powerUpGraphics.scale, {
+ x: 1,
+ y: 1
+ }, {
+ duration: 500,
+ easing: tween.easeInOut
+ });
+ }
+ });
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
backgroundColor: 0x000000
-});
\ No newline at end of file
+});
+
+/****
+* Game Code
+****/
+// Set the game's background
+game.setBackgroundColor(0x0a0a2a); // Deep space blue
+// Game state variables
+var player;
+var enemies = [];
+var playerBullets = [];
+var enemyBullets = [];
+var powerUps = [];
+var explosions = [];
+var score = 0;
+var level = 1;
+var enemySpawnRate = 60; // frames between enemy spawns
+var enemySpawnCounter = 0;
+var powerUpChance = 0.1; // 10% chance on enemy death
+var gameActive = true;
+var dragNode = null;
+var isPaused = false;
+// UI elements
+var scoreText = new Text2('SCORE: 0', {
+ size: 70,
+ fill: 0xFFFFFF
+});
+scoreText.anchor.set(0, 0);
+LK.gui.topRight.addChild(scoreText);
+scoreText.y = 20;
+scoreText.x = -scoreText.width - 20;
+var livesText = new Text2('LIVES: 3', {
+ size: 70,
+ fill: 0xFFFFFF
+});
+livesText.anchor.set(1, 0);
+LK.gui.topLeft.addChild(livesText);
+livesText.y = 20;
+livesText.x = 120; // Keep away from top-left corner menu icon
+var levelText = new Text2('LEVEL: 1', {
+ size: 70,
+ fill: 0xFFFFFF
+});
+levelText.anchor.set(0.5, 0);
+LK.gui.top.addChild(levelText);
+levelText.y = 20;
+// Initialize the player
+player = new Player();
+player.x = 2048 / 2;
+player.y = 2732 - 300;
+game.addChild(player);
+// Create stars for background
+var stars = [];
+function createStars() {
+ for (var i = 0; i < 100; i++) {
+ var star = LK.getAsset('playerBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.3 + Math.random() * 0.7,
+ scaleY: 0.3 + Math.random() * 0.7,
+ alpha: 0.3 + Math.random() * 0.7,
+ tint: 0xffffff
+ });
+ star.x = Math.random() * 2048;
+ star.y = Math.random() * 2732;
+ star.speed = 0.5 + Math.random() * 2;
+ stars.push(star);
+ game.addChild(star);
+ }
+}
+createStars();
+// Start background music
+LK.playMusic('gameMusic', {
+ fade: {
+ start: 0,
+ end: 0.7,
+ duration: 1000
+ }
+});
+// Spawn a new enemy
+function spawnEnemy() {
+ // Choose enemy type based on level
+ var typeChances = [0.7, 0.2, 0.1]; // Default chances
+ // Adjust chances based on level
+ if (level >= 3) {
+ typeChances = [0.5, 0.3, 0.2];
+ }
+ if (level >= 5) {
+ typeChances = [0.4, 0.3, 0.3];
+ }
+ if (level >= 8) {
+ typeChances = [0.3, 0.4, 0.3];
+ }
+ // Determine enemy type
+ var rand = Math.random();
+ var enemyType = 0;
+ if (rand > typeChances[0]) {
+ enemyType = rand > typeChances[0] + typeChances[1] ? 2 : 1;
+ }
+ var enemy = new Enemy().init(enemyType);
+ enemy.x = 200 + Math.random() * (2048 - 400);
+ enemy.y = -100;
+ enemies.push(enemy);
+ game.addChild(enemy);
+}
+// Fire a bullet from the player
+function firePlayerBullet(offsetX) {
+ offsetX = offsetX || 0;
+ var bullet = new PlayerBullet();
+ bullet.x = player.x + offsetX;
+ bullet.y = player.y - 50;
+ playerBullets.push(bullet);
+ game.addChild(bullet);
+ LK.getSound('playerShoot').play();
+}
+// Fire a bullet from an enemy
+function fireEnemyBullet(enemy) {
+ var bullet = new EnemyBullet();
+ bullet.x = enemy.x;
+ bullet.y = enemy.y + 50;
+ enemyBullets.push(bullet);
+ game.addChild(bullet);
+ LK.getSound('enemyShoot').play();
+}
+// Create an explosion
+function createExplosion(x, y, size) {
+ var explosion = new Explosion();
+ explosion.x = x;
+ explosion.y = y;
+ explosion.scale.set(size || 1);
+ explosions.push(explosion);
+ game.addChild(explosion);
+ LK.getSound('explosion').play();
+}
+// Spawn a power-up
+function spawnPowerUp(x, y) {
+ var powerUp = new PowerUp();
+ powerUp.x = x;
+ powerUp.y = y;
+ powerUps.push(powerUp);
+ game.addChild(powerUp);
+}
+// Update score display
+function updateScore(newScore) {
+ score = newScore;
+ scoreText.setText("SCORE: " + score);
+ // Check for level up (every 1000 points)
+ var newLevel = Math.floor(score / 1000) + 1;
+ if (newLevel > level) {
+ level = newLevel;
+ levelText.setText("LEVEL: " + level);
+ // Increase difficulty with level
+ enemySpawnRate = Math.max(20, 60 - (level - 1) * 5);
+ }
+ // Set score in LK system
+ LK.setScore(score);
+ // Update high score if needed
+ if (score > storage.highScore) {
+ storage.highScore = score;
+ }
+}
+// Update lives display
+function updateLives() {
+ livesText.setText("LIVES: " + player.lives);
+}
+// Handle player and enemy movement
+function handleGameInput(x, y) {
+ if (dragNode && gameActive && !isPaused) {
+ dragNode.x = Math.max(dragNode.width / 2, Math.min(2048 - dragNode.width / 2, x));
+ // Restrict vertical movement to bottom third of screen
+ dragNode.y = Math.max(2732 / 3 * 2, Math.min(2732 - dragNode.height / 2, y));
+ }
+}
+// Mouse or touch down on the game
+game.down = function (x, y, obj) {
+ if (!gameActive || isPaused) {
+ return;
+ }
+ // Set drag node to player if within bounds
+ if (Math.abs(x - player.x) < 100 && Math.abs(y - player.y) < 100) {
+ dragNode = player;
+ } else {
+ // Fire when tapping elsewhere
+ if (player.canFire()) {
+ if (player.doubleFire) {
+ firePlayerBullet(-30);
+ firePlayerBullet(30);
+ } else {
+ firePlayerBullet(0);
+ }
+ }
+ }
+ // Call move handler for immediate response
+ handleGameInput(x, y);
+};
+// Mouse or touch move on the game
+game.move = function (x, y, obj) {
+ handleGameInput(x, y);
+};
+// Mouse or touch up on the game
+game.up = function (x, y, obj) {
+ dragNode = null;
+};
+// Main game update loop
+game.update = function () {
+ if (!gameActive || isPaused) {
+ return;
+ }
+ // Update stars (background)
+ for (var i = 0; i < stars.length; i++) {
+ stars[i].y += stars[i].speed;
+ if (stars[i].y > 2732) {
+ stars[i].y = 0;
+ stars[i].x = Math.random() * 2048;
+ }
+ }
+ // Spawn enemies
+ enemySpawnCounter++;
+ if (enemySpawnCounter >= enemySpawnRate) {
+ enemySpawnCounter = 0;
+ spawnEnemy();
+ }
+ // Auto-fire for player (if holding down)
+ if (dragNode === player && player.canFire()) {
+ if (player.doubleFire) {
+ firePlayerBullet(-30);
+ firePlayerBullet(30);
+ } else {
+ firePlayerBullet(0);
+ }
+ }
+ // Update player
+ player.update();
+ // Update bullets
+ for (var i = playerBullets.length - 1; i >= 0; i--) {
+ var bullet = playerBullets[i];
+ // Check if bullet is off screen
+ if (bullet.y < -50) {
+ bullet.destroy();
+ playerBullets.splice(i, 1);
+ continue;
+ }
+ // Check for collision with enemies
+ for (var j = enemies.length - 1; j >= 0; j--) {
+ var enemy = enemies[j];
+ if (bullet.intersects(enemy)) {
+ // Handle enemy hit
+ if (enemy.takeDamage(bullet.power)) {
+ // Enemy destroyed
+ createExplosion(enemy.x, enemy.y, 1);
+ updateScore(score + enemy.points);
+ // Chance to spawn power-up
+ if (Math.random() < powerUpChance) {
+ spawnPowerUp(enemy.x, enemy.y);
+ }
+ enemy.destroy();
+ enemies.splice(j, 1);
+ }
+ // Remove bullet
+ bullet.destroy();
+ playerBullets.splice(i, 1);
+ break;
+ }
+ }
+ }
+ // Update enemy bullets
+ for (var i = enemyBullets.length - 1; i >= 0; i--) {
+ var bullet = enemyBullets[i];
+ // Check if bullet is off screen
+ if (bullet.y > 2732 + 50) {
+ bullet.destroy();
+ enemyBullets.splice(i, 1);
+ continue;
+ }
+ // Check for collision with player
+ if (bullet.intersects(player)) {
+ // Handle player hit
+ if (player.takeDamage()) {
+ // Game over
+ gameActive = false;
+ createExplosion(player.x, player.y, 2);
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 1500);
+ }
+ updateLives();
+ // Remove bullet
+ bullet.destroy();
+ enemyBullets.splice(i, 1);
+ }
+ }
+ // Update enemies
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ var enemy = enemies[i];
+ // Check if enemy is off screen
+ if (enemy.y > 2732 + 100) {
+ enemy.destroy();
+ enemies.splice(i, 1);
+ continue;
+ }
+ // Check for collision with player
+ if (enemy.intersects(player)) {
+ // Handle player collision with enemy
+ if (player.takeDamage()) {
+ // Game over
+ gameActive = false;
+ createExplosion(player.x, player.y, 2);
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 1500);
+ }
+ updateLives();
+ // Destroy enemy
+ createExplosion(enemy.x, enemy.y, 1);
+ enemy.destroy();
+ enemies.splice(i, 1);
+ continue;
+ }
+ // Enemy shooting
+ if (enemy.tryShoot()) {
+ fireEnemyBullet(enemy);
+ }
+ // Update enemy
+ enemy.update();
+ }
+ // Update power-ups
+ for (var i = powerUps.length - 1; i >= 0; i--) {
+ var powerUp = powerUps[i];
+ // Check if power-up is off screen
+ if (powerUp.y > 2732 + 50) {
+ powerUp.destroy();
+ powerUps.splice(i, 1);
+ continue;
+ }
+ // Check for collision with player
+ if (powerUp.intersects(player)) {
+ // Apply power-up effect
+ player.applyPowerUp(powerUp.type);
+ // Play sound and add points
+ LK.getSound('powerUp').play();
+ updateScore(score + 50);
+ // Remove power-up
+ powerUp.destroy();
+ powerUps.splice(i, 1);
+ continue;
+ }
+ // Update power-up
+ powerUp.update();
+ }
+ // Update explosions
+ for (var i = explosions.length - 1; i >= 0; i--) {
+ explosions[i].update();
+ if (explosions[i].lifespan <= 0) {
+ explosions.splice(i, 1);
+ }
+ }
+};
\ No newline at end of file