/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, level: 1 }); var facekit = LK.import("@upit/facekit.v1"); /**** * Classes ****/ var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemyShip', { anchorX: 0.5, anchorY: 0.5 }); self.health = 1; self.score = 10; self.speedX = 0; self.speedY = 3; self.type = 'normal'; self.update = function () { // Basic movement self.x += self.speedX; self.y += self.speedY; // Bounce off walls for some enemy types if (self.type === 'bouncer') { if (self.x < 100 || self.x > 2048 - 100) { self.speedX *= -1; } } // Remove if off screen if (self.y > 2732 + 100) { self.readyToRemove = true; } }; self.damage = function (amount) { self.health -= amount; if (self.health <= 0) { self.explode(); return true; } // Flash red when hit tween(enemyGraphics, { alpha: 0.5 }, { duration: 100, onFinish: function onFinish() { tween(enemyGraphics, { alpha: 1 }, { duration: 100 }); } }); return false; }; self.explode = function () { self.readyToRemove = true; LK.getSound('explosion').play(); // Create explosion effect var explosion = new Explosion(); explosion.x = self.x; explosion.y = self.y; game.addChild(explosion); }; return self; }); var Asteroid = Enemy.expand(function () { var self = Enemy.call(this); // Remove the ship graphic self.removeChildren(); // Add asteroid graphic var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5 }); self.health = 2; self.score = 15; self.type = 'asteroid'; // Random rotation self.rotationSpeed = (Math.random() - 0.5) * 0.1; // Override update to add rotation var parentUpdate = self.update; self.update = function () { parentUpdate.call(self); self.rotation += self.rotationSpeed; }; 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 = 15; // frames self.age = 0; self.update = function () { self.age++; // Grow effect self.scale.x = 1 + self.age / 10; self.scale.y = 1 + self.age / 10; // Fade out over time self.alpha = 1 - self.age / self.lifespan; if (self.age >= self.lifespan) { self.readyToRemove = true; } }; return self; }); var Laser = Container.expand(function () { var self = Container.call(this); var laserGraphics = self.attachAsset('laser', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -15; self.power = 1; self.update = function () { self.y += self.speed; // Remove when off screen if (self.y < -100) { self.readyToRemove = true; } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('playerShip', { anchorX: 0.5, anchorY: 0.5 }); self.health = 5; self.maxHealth = 5; self.fireRate = 20; // frames between shots self.fireTimer = 0; self.specialAttackReady = true; self.specialAttackCooldown = 0; self.invulnerable = false; self.update = function () { // Cooldowns if (self.fireTimer > 0) { self.fireTimer--; } if (self.specialAttackCooldown > 0) { self.specialAttackCooldown--; if (self.specialAttackCooldown <= 0) { self.specialAttackReady = true; } } }; self.fire = function () { if (self.fireTimer <= 0) { var laser = new Laser(); laser.x = self.x; laser.y = self.y - 50; game.addChild(laser); lasers.push(laser); LK.getSound('laserShot').play(); self.fireTimer = self.fireRate; return true; } return false; }; self.specialAttack = function () { if (self.specialAttackReady) { var attack = new SpecialAttack(); attack.x = self.x; attack.y = self.y; game.addChild(attack); specialAttacks.push(attack); LK.getSound('specialAttack').play(); self.specialAttackReady = false; self.specialAttackCooldown = 120; // 2 seconds at 60fps return true; } return false; }; self.damage = function (amount) { if (self.invulnerable) { return false; } self.health -= amount; // Flash player ship when hit self.invulnerable = true; var flashCount = 0; var flashInterval = LK.setInterval(function () { shipGraphics.alpha = shipGraphics.alpha === 1 ? 0.5 : 1; flashCount++; if (flashCount >= 6) { LK.clearInterval(flashInterval); shipGraphics.alpha = 1; self.invulnerable = false; } }, 100); // Update health bar updateHealthBar(); if (self.health <= 0) { return true; // Player is dead } return false; }; self.addHealth = function (amount) { self.health = Math.min(self.health + amount, self.maxHealth); updateHealthBar(); LK.getSound('powerUp').play(); }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerUpGraphics = self.attachAsset('powerUp', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'health'; // default type self.speedY = 2; self.update = function () { self.y += self.speedY; // Bob up and down self.x += Math.sin(LK.ticks / 10) * 1; // Remove if off screen if (self.y > 2732 + 100) { self.readyToRemove = true; } }; return self; }); var SpecialAttack = Container.expand(function () { var self = Container.call(this); var attackGraphics = self.attachAsset('specialAttack', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); self.power = 5; self.lifespan = 30; // frames self.age = 0; self.update = function () { self.age++; // Grow effect self.scale.x = 1 + self.age / 15; self.scale.y = 1 + self.age / 15; // Fade out over time self.alpha = 1 - self.age / self.lifespan; if (self.age >= self.lifespan) { self.readyToRemove = true; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000022 }); /**** * Game Code ****/ // Game variables var player; var lasers = []; var enemies = []; var powerUps = []; var specialAttacks = []; var score = 0; var level = storage.level || 1; var enemySpawnRate = 120 - level * 10; // frames between enemy spawns var enemySpawnTimer = 60; // give player a short break at start var waveSize = 10 + level * 5; var enemiesDefeated = 0; var gameActive = true; var lastMouthOpen = false; var healthBar; var healthBarBg; var scoreText; var levelText; var specialCooldownIndicator; // Initialize game elements function initGame() { // Play background music LK.playMusic('gameBgm'); // Create player player = new Player(); player.x = 2048 / 2; player.y = 2732 - 300; game.addChild(player); // Create health bar background healthBarBg = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0.5, x: 150, y: 100, tint: 0x444444 }); game.addChild(healthBarBg); // Create health bar healthBar = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0.5, x: 150, y: 100 }); game.addChild(healthBar); // Create score text scoreText = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(1, 0); LK.gui.topRight.addChild(scoreText); // Create level text levelText = new Text2('Level: ' + level, { size: 60, fill: 0xFFFFFF }); levelText.anchor.set(0, 0); levelText.x = 150; LK.gui.top.addChild(levelText); // Special attack cooldown indicator specialCooldownIndicator = LK.getAsset('specialAttack', { anchorX: 0.5, anchorY: 0.5, x: 2048 - 100, y: 2732 - 100, scale: 0.3, alpha: 0.6 }); game.addChild(specialCooldownIndicator); } // Update the health bar function updateHealthBar() { // Scale health bar based on current health var healthPercent = player.health / player.maxHealth; healthBar.scale.x = healthPercent; } // Update score display function updateScore(points) { score += points; scoreText.setText('Score: ' + score); // Update high score if needed if (score > storage.highScore) { storage.highScore = score; } } // Spawn a new enemy function spawnEnemy() { var enemy; var enemyType = Math.random(); if (enemyType < 0.7) { // Normal enemy enemy = new Enemy(); enemy.health = 1; } else { // Asteroid enemy = new Asteroid(); enemy.health = 2; } // Set enemy position enemy.x = Math.random() * (2048 - 200) + 100; enemy.y = -100; // For some enemies, set random X movement if (Math.random() < 0.3) { enemy.type = 'bouncer'; enemy.speedX = Math.random() * 4 - 2; } // Add to game game.addChild(enemy); enemies.push(enemy); } // Spawn a power-up function spawnPowerUp() { var powerUp = new PowerUp(); // Position randomly powerUp.x = Math.random() * (2048 - 200) + 100; powerUp.y = -100; // Set type var powerUpType = Math.random(); if (powerUpType < 0.7) { powerUp.type = 'health'; } else { powerUp.type = 'shield'; } // Add to game game.addChild(powerUp); powerUps.push(powerUp); } // Check collisions between game elements function checkCollisions() { // Lasers hitting enemies for (var i = lasers.length - 1; i >= 0; i--) { var laser = lasers[i]; for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (laser.intersects(enemy)) { // Enemy hit var destroyed = enemy.damage(laser.power); if (destroyed) { updateScore(enemy.score); enemy.readyToRemove = true; enemiesDefeated++; // Chance to spawn power-up if (Math.random() < 0.1) { spawnPowerUp(); } // Level up if enough enemies defeated if (enemiesDefeated >= waveSize) { level++; storage.level = level; enemiesDefeated = 0; waveSize = 10 + level * 5; enemySpawnRate = Math.max(20, 120 - level * 10); levelText.setText('Level: ' + level); // Flash level text tween(levelText, { scale: 1.5 }, { duration: 300, onFinish: function onFinish() { tween(levelText, { scale: 1 }, { duration: 300 }); } }); } } // Remove laser laser.readyToRemove = true; lasers.splice(i, 1); break; } } } // Special attacks hitting enemies for (var i = specialAttacks.length - 1; i >= 0; i--) { var attack = specialAttacks[i]; for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (attack.intersects(enemy)) { // Enemy destroyed by special attack updateScore(enemy.score); enemy.explode(); enemies.splice(j, 1); enemiesDefeated++; // Chance to spawn power-up if (Math.random() < 0.2) { spawnPowerUp(); } } } } // Player colliding with enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; if (player.intersects(enemy)) { // Player hit by enemy if (player.damage(1)) { // Player died gameOver(); return; } // Enemy destroyed enemy.explode(); enemies.splice(i, 1); } } // Player collecting power-ups for (var i = powerUps.length - 1; i >= 0; i--) { var powerUp = powerUps[i]; if (player.intersects(powerUp)) { // Apply power-up effect if (powerUp.type === 'health') { player.addHealth(1); } else if (powerUp.type === 'shield') { // Give temporary shield player.invulnerable = true; LK.setTimeout(function () { player.invulnerable = false; }, 5000); } // Remove power-up powerUp.readyToRemove = true; powerUps.splice(i, 1); } } } // Clean up game objects marked for removal function cleanupObjects() { for (var i = lasers.length - 1; i >= 0; i--) { if (lasers[i].readyToRemove) { lasers[i].destroy(); lasers.splice(i, 1); } } for (var i = enemies.length - 1; i >= 0; i--) { if (enemies[i].readyToRemove) { enemies[i].destroy(); enemies.splice(i, 1); } } for (var i = powerUps.length - 1; i >= 0; i--) { if (powerUps[i].readyToRemove) { powerUps[i].destroy(); powerUps.splice(i, 1); } } for (var i = specialAttacks.length - 1; i >= 0; i--) { if (specialAttacks[i].readyToRemove) { specialAttacks[i].destroy(); specialAttacks.splice(i, 1); } } } // Game over function function gameOver() { gameActive = false; LK.showGameOver(); } // Initialize the game initGame(); // Main game update function game.update = function () { if (!gameActive) { return; } // Update player position based on face position if (facekit.noseTip) { // Map face position to game coordinates var targetX = facekit.noseTip.x; var targetY = Math.max(500, Math.min(2732 - 300, facekit.noseTip.y + 500)); // Smooth movement player.x += (targetX - player.x) * 0.1; player.y += (targetY - player.y) * 0.1; } // Fire laser when mouth opens var mouthOpen = facekit.mouthOpen; if (mouthOpen && !lastMouthOpen) { player.fire(); } lastMouthOpen = mouthOpen; // Special attack with loud sound if (facekit.volume > 0.6) { player.specialAttack(); } // Update special attack indicator specialCooldownIndicator.alpha = player.specialAttackReady ? 1 : 0.3; // Spawn enemies enemySpawnTimer--; if (enemySpawnTimer <= 0) { spawnEnemy(); enemySpawnTimer = enemySpawnRate; } // Update game objects player.update(); for (var i = 0; i < lasers.length; i++) { lasers[i].update(); } for (var i = 0; i < enemies.length; i++) { enemies[i].update(); } for (var i = 0; i < powerUps.length; i++) { powerUps[i].update(); } for (var i = 0; i < specialAttacks.length; i++) { specialAttacks[i].update(); } // Check for collisions checkCollisions(); // Clean up objects cleanupObjects(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
level: 1
});
var facekit = LK.import("@upit/facekit.v1");
/****
* Classes
****/
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemyShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 1;
self.score = 10;
self.speedX = 0;
self.speedY = 3;
self.type = 'normal';
self.update = function () {
// Basic movement
self.x += self.speedX;
self.y += self.speedY;
// Bounce off walls for some enemy types
if (self.type === 'bouncer') {
if (self.x < 100 || self.x > 2048 - 100) {
self.speedX *= -1;
}
}
// Remove if off screen
if (self.y > 2732 + 100) {
self.readyToRemove = true;
}
};
self.damage = function (amount) {
self.health -= amount;
if (self.health <= 0) {
self.explode();
return true;
}
// Flash red when hit
tween(enemyGraphics, {
alpha: 0.5
}, {
duration: 100,
onFinish: function onFinish() {
tween(enemyGraphics, {
alpha: 1
}, {
duration: 100
});
}
});
return false;
};
self.explode = function () {
self.readyToRemove = true;
LK.getSound('explosion').play();
// Create explosion effect
var explosion = new Explosion();
explosion.x = self.x;
explosion.y = self.y;
game.addChild(explosion);
};
return self;
});
var Asteroid = Enemy.expand(function () {
var self = Enemy.call(this);
// Remove the ship graphic
self.removeChildren();
// Add asteroid graphic
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 2;
self.score = 15;
self.type = 'asteroid';
// Random rotation
self.rotationSpeed = (Math.random() - 0.5) * 0.1;
// Override update to add rotation
var parentUpdate = self.update;
self.update = function () {
parentUpdate.call(self);
self.rotation += self.rotationSpeed;
};
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 = 15; // frames
self.age = 0;
self.update = function () {
self.age++;
// Grow effect
self.scale.x = 1 + self.age / 10;
self.scale.y = 1 + self.age / 10;
// Fade out over time
self.alpha = 1 - self.age / self.lifespan;
if (self.age >= self.lifespan) {
self.readyToRemove = true;
}
};
return self;
});
var Laser = Container.expand(function () {
var self = Container.call(this);
var laserGraphics = self.attachAsset('laser', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -15;
self.power = 1;
self.update = function () {
self.y += self.speed;
// Remove when off screen
if (self.y < -100) {
self.readyToRemove = true;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 5;
self.maxHealth = 5;
self.fireRate = 20; // frames between shots
self.fireTimer = 0;
self.specialAttackReady = true;
self.specialAttackCooldown = 0;
self.invulnerable = false;
self.update = function () {
// Cooldowns
if (self.fireTimer > 0) {
self.fireTimer--;
}
if (self.specialAttackCooldown > 0) {
self.specialAttackCooldown--;
if (self.specialAttackCooldown <= 0) {
self.specialAttackReady = true;
}
}
};
self.fire = function () {
if (self.fireTimer <= 0) {
var laser = new Laser();
laser.x = self.x;
laser.y = self.y - 50;
game.addChild(laser);
lasers.push(laser);
LK.getSound('laserShot').play();
self.fireTimer = self.fireRate;
return true;
}
return false;
};
self.specialAttack = function () {
if (self.specialAttackReady) {
var attack = new SpecialAttack();
attack.x = self.x;
attack.y = self.y;
game.addChild(attack);
specialAttacks.push(attack);
LK.getSound('specialAttack').play();
self.specialAttackReady = false;
self.specialAttackCooldown = 120; // 2 seconds at 60fps
return true;
}
return false;
};
self.damage = function (amount) {
if (self.invulnerable) {
return false;
}
self.health -= amount;
// Flash player ship when hit
self.invulnerable = true;
var flashCount = 0;
var flashInterval = LK.setInterval(function () {
shipGraphics.alpha = shipGraphics.alpha === 1 ? 0.5 : 1;
flashCount++;
if (flashCount >= 6) {
LK.clearInterval(flashInterval);
shipGraphics.alpha = 1;
self.invulnerable = false;
}
}, 100);
// Update health bar
updateHealthBar();
if (self.health <= 0) {
return true; // Player is dead
}
return false;
};
self.addHealth = function (amount) {
self.health = Math.min(self.health + amount, self.maxHealth);
updateHealthBar();
LK.getSound('powerUp').play();
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'health'; // default type
self.speedY = 2;
self.update = function () {
self.y += self.speedY;
// Bob up and down
self.x += Math.sin(LK.ticks / 10) * 1;
// Remove if off screen
if (self.y > 2732 + 100) {
self.readyToRemove = true;
}
};
return self;
});
var SpecialAttack = Container.expand(function () {
var self = Container.call(this);
var attackGraphics = self.attachAsset('specialAttack', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7
});
self.power = 5;
self.lifespan = 30; // frames
self.age = 0;
self.update = function () {
self.age++;
// Grow effect
self.scale.x = 1 + self.age / 15;
self.scale.y = 1 + self.age / 15;
// Fade out over time
self.alpha = 1 - self.age / self.lifespan;
if (self.age >= self.lifespan) {
self.readyToRemove = true;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000022
});
/****
* Game Code
****/
// Game variables
var player;
var lasers = [];
var enemies = [];
var powerUps = [];
var specialAttacks = [];
var score = 0;
var level = storage.level || 1;
var enemySpawnRate = 120 - level * 10; // frames between enemy spawns
var enemySpawnTimer = 60; // give player a short break at start
var waveSize = 10 + level * 5;
var enemiesDefeated = 0;
var gameActive = true;
var lastMouthOpen = false;
var healthBar;
var healthBarBg;
var scoreText;
var levelText;
var specialCooldownIndicator;
// Initialize game elements
function initGame() {
// Play background music
LK.playMusic('gameBgm');
// Create player
player = new Player();
player.x = 2048 / 2;
player.y = 2732 - 300;
game.addChild(player);
// Create health bar background
healthBarBg = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0.5,
x: 150,
y: 100,
tint: 0x444444
});
game.addChild(healthBarBg);
// Create health bar
healthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0.5,
x: 150,
y: 100
});
game.addChild(healthBar);
// Create score text
scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
// Create level text
levelText = new Text2('Level: ' + level, {
size: 60,
fill: 0xFFFFFF
});
levelText.anchor.set(0, 0);
levelText.x = 150;
LK.gui.top.addChild(levelText);
// Special attack cooldown indicator
specialCooldownIndicator = LK.getAsset('specialAttack', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 - 100,
y: 2732 - 100,
scale: 0.3,
alpha: 0.6
});
game.addChild(specialCooldownIndicator);
}
// Update the health bar
function updateHealthBar() {
// Scale health bar based on current health
var healthPercent = player.health / player.maxHealth;
healthBar.scale.x = healthPercent;
}
// Update score display
function updateScore(points) {
score += points;
scoreText.setText('Score: ' + score);
// Update high score if needed
if (score > storage.highScore) {
storage.highScore = score;
}
}
// Spawn a new enemy
function spawnEnemy() {
var enemy;
var enemyType = Math.random();
if (enemyType < 0.7) {
// Normal enemy
enemy = new Enemy();
enemy.health = 1;
} else {
// Asteroid
enemy = new Asteroid();
enemy.health = 2;
}
// Set enemy position
enemy.x = Math.random() * (2048 - 200) + 100;
enemy.y = -100;
// For some enemies, set random X movement
if (Math.random() < 0.3) {
enemy.type = 'bouncer';
enemy.speedX = Math.random() * 4 - 2;
}
// Add to game
game.addChild(enemy);
enemies.push(enemy);
}
// Spawn a power-up
function spawnPowerUp() {
var powerUp = new PowerUp();
// Position randomly
powerUp.x = Math.random() * (2048 - 200) + 100;
powerUp.y = -100;
// Set type
var powerUpType = Math.random();
if (powerUpType < 0.7) {
powerUp.type = 'health';
} else {
powerUp.type = 'shield';
}
// Add to game
game.addChild(powerUp);
powerUps.push(powerUp);
}
// Check collisions between game elements
function checkCollisions() {
// Lasers hitting enemies
for (var i = lasers.length - 1; i >= 0; i--) {
var laser = lasers[i];
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (laser.intersects(enemy)) {
// Enemy hit
var destroyed = enemy.damage(laser.power);
if (destroyed) {
updateScore(enemy.score);
enemy.readyToRemove = true;
enemiesDefeated++;
// Chance to spawn power-up
if (Math.random() < 0.1) {
spawnPowerUp();
}
// Level up if enough enemies defeated
if (enemiesDefeated >= waveSize) {
level++;
storage.level = level;
enemiesDefeated = 0;
waveSize = 10 + level * 5;
enemySpawnRate = Math.max(20, 120 - level * 10);
levelText.setText('Level: ' + level);
// Flash level text
tween(levelText, {
scale: 1.5
}, {
duration: 300,
onFinish: function onFinish() {
tween(levelText, {
scale: 1
}, {
duration: 300
});
}
});
}
}
// Remove laser
laser.readyToRemove = true;
lasers.splice(i, 1);
break;
}
}
}
// Special attacks hitting enemies
for (var i = specialAttacks.length - 1; i >= 0; i--) {
var attack = specialAttacks[i];
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (attack.intersects(enemy)) {
// Enemy destroyed by special attack
updateScore(enemy.score);
enemy.explode();
enemies.splice(j, 1);
enemiesDefeated++;
// Chance to spawn power-up
if (Math.random() < 0.2) {
spawnPowerUp();
}
}
}
}
// Player colliding with enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (player.intersects(enemy)) {
// Player hit by enemy
if (player.damage(1)) {
// Player died
gameOver();
return;
}
// Enemy destroyed
enemy.explode();
enemies.splice(i, 1);
}
}
// Player collecting power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (player.intersects(powerUp)) {
// Apply power-up effect
if (powerUp.type === 'health') {
player.addHealth(1);
} else if (powerUp.type === 'shield') {
// Give temporary shield
player.invulnerable = true;
LK.setTimeout(function () {
player.invulnerable = false;
}, 5000);
}
// Remove power-up
powerUp.readyToRemove = true;
powerUps.splice(i, 1);
}
}
}
// Clean up game objects marked for removal
function cleanupObjects() {
for (var i = lasers.length - 1; i >= 0; i--) {
if (lasers[i].readyToRemove) {
lasers[i].destroy();
lasers.splice(i, 1);
}
}
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i].readyToRemove) {
enemies[i].destroy();
enemies.splice(i, 1);
}
}
for (var i = powerUps.length - 1; i >= 0; i--) {
if (powerUps[i].readyToRemove) {
powerUps[i].destroy();
powerUps.splice(i, 1);
}
}
for (var i = specialAttacks.length - 1; i >= 0; i--) {
if (specialAttacks[i].readyToRemove) {
specialAttacks[i].destroy();
specialAttacks.splice(i, 1);
}
}
}
// Game over function
function gameOver() {
gameActive = false;
LK.showGameOver();
}
// Initialize the game
initGame();
// Main game update function
game.update = function () {
if (!gameActive) {
return;
}
// Update player position based on face position
if (facekit.noseTip) {
// Map face position to game coordinates
var targetX = facekit.noseTip.x;
var targetY = Math.max(500, Math.min(2732 - 300, facekit.noseTip.y + 500));
// Smooth movement
player.x += (targetX - player.x) * 0.1;
player.y += (targetY - player.y) * 0.1;
}
// Fire laser when mouth opens
var mouthOpen = facekit.mouthOpen;
if (mouthOpen && !lastMouthOpen) {
player.fire();
}
lastMouthOpen = mouthOpen;
// Special attack with loud sound
if (facekit.volume > 0.6) {
player.specialAttack();
}
// Update special attack indicator
specialCooldownIndicator.alpha = player.specialAttackReady ? 1 : 0.3;
// Spawn enemies
enemySpawnTimer--;
if (enemySpawnTimer <= 0) {
spawnEnemy();
enemySpawnTimer = enemySpawnRate;
}
// Update game objects
player.update();
for (var i = 0; i < lasers.length; i++) {
lasers[i].update();
}
for (var i = 0; i < enemies.length; i++) {
enemies[i].update();
}
for (var i = 0; i < powerUps.length; i++) {
powerUps[i].update();
}
for (var i = 0; i < specialAttacks.length; i++) {
specialAttacks[i].update();
}
// Check for collisions
checkCollisions();
// Clean up objects
cleanupObjects();
};