/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); var facekit = LK.import("@upit/facekit.v1"); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -15; self.power = 1; self.update = function () { self.y += self.speed; }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemyShip', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.health = 1; self.moveDirection = 1; // 1 for right, -1 for left self.moveDistance = 0; self.maxDistance = 200; // Maximum horizontal movement self.descendAmount = 50; // Amount to descend after changing direction self.hit = function (damage) { self.health -= damage; if (self.health <= 0) { return true; // Enemy is destroyed } // Visual feedback for hit tween(enemyGraphics, { tint: 0xff0000 }, { duration: 100, easing: tween.linear, onFinish: function onFinish() { tween(enemyGraphics, { tint: 0xffffff }, { duration: 100, easing: tween.linear }); } }); return false; // Enemy still alive }; self.update = function () { // Move horizontally self.x += self.speed * self.moveDirection; self.moveDistance += Math.abs(self.speed); // Change direction and descend when reached max distance if (self.moveDistance >= self.maxDistance) { self.moveDirection *= -1; // Reverse direction self.y += self.descendAmount; // Move down self.moveDistance = 0; // Reset distance counter } // Simple rotation animation self.rotation = Math.sin(LK.ticks / 30) * 0.1; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('playerShip', { anchorX: 0.5, anchorY: 0.5 }); self.canFire = true; self.fireDelay = 300; self.lastFired = 0; self.specialWeapon = false; self.specialTimer = 0; self.lives = 3; self.fire = function () { var currentTime = Date.now(); if (self.canFire && currentTime - self.lastFired > self.fireDelay) { var bullet; if (self.specialWeapon) { bullet = new SpecialBullet(); } else { bullet = new Bullet(); } bullet.x = self.x; bullet.y = self.y - 60; game.addChild(bullet); bullets.push(bullet); LK.getSound('laser').play(); self.lastFired = currentTime; } }; self.activateSpecialWeapon = function () { self.specialWeapon = true; self.specialTimer = 5000; // Special weapon lasts for 5 seconds // Visual feedback for special weapon tween(shipGraphics, { tint: 0xffff00 }, { duration: 300, easing: tween.easeOut }); }; self.update = function () { // Update special weapon timer if (self.specialWeapon && self.specialTimer > 0) { self.specialTimer -= 16.67; // Approximate for 60fps if (self.specialTimer <= 0) { self.specialWeapon = false; tween(shipGraphics, { tint: 0xffffff }, { duration: 300, easing: tween.easeOut }); } } }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerUpGraphics = self.attachAsset('powerUp', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3; self.type = "special"; // Default type self.update = function () { self.y += self.speed; self.rotation += 0.03; }; return self; }); var SpecialBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('specialBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -18; self.power = 3; self.radius = 25; self.update = function () { self.y += self.speed; self.rotation += 0.1; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000022 }); /**** * Game Code ****/ // Game variables var player; var bullets = []; var enemies = []; var powerUps = []; var gameStarted = false; var gameOver = false; var score = 0; var level = 1; var enemiesPerRow = 5; var enemyRows = 3; var enemySpawnDelay = 800; var lastEnemySpawn = 0; var powerUpChance = 0.2; var highScore = storage.highScore || 0; // UI Elements var scoreTxt = new Text2('SCORE: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); scoreTxt.x = -scoreTxt.width - 20; scoreTxt.y = 20; var levelTxt = new Text2('LEVEL: 1', { size: 60, fill: 0xFFFFFF }); levelTxt.anchor.set(1, 0); LK.gui.top.addChild(levelTxt); levelTxt.y = 20; var instructionsTxt = new Text2('Open mouth to FIRE\nMake noise for SPECIAL ATTACK', { size: 40, fill: 0xFFFFFF }); instructionsTxt.anchor.set(0.5, 0); LK.gui.bottom.addChild(instructionsTxt); instructionsTxt.y = -100; var livesTxt = new Text2('LIVES: 3', { size: 60, fill: 0xFFFFFF }); livesTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(livesTxt); livesTxt.x = 120; // Keep away from top-left corner (menu icon) livesTxt.y = 20; // Start the game function startGame() { if (!gameStarted) { gameStarted = true; // Initialize player player = new Player(); player.x = 2048 / 2; player.y = 2732 - 200; game.addChild(player); // Reset game state score = 0; level = 1; bullets = []; enemies = []; powerUps = []; // Start background music LK.playMusic('gameMusic', { fade: { start: 0, end: 0.4, duration: 1000 } }); // Start spawning enemies spawnEnemyWave(); } } // Spawn wave of enemies function spawnEnemyWave() { var startX = (2048 - enemiesPerRow * 150) / 2 + 75; var startY = 200; for (var row = 0; row < enemyRows; row++) { for (var col = 0; col < enemiesPerRow; col++) { var enemy = new Enemy(); enemy.x = startX + col * 150; enemy.y = startY + row * 120; enemy.health = Math.ceil(level / 3); // Increase health every 3 levels enemy.speed = 1 + level * 0.5; // Increase speed with level // Alternate movement direction by row if (row % 2 === 1) { enemy.moveDirection = -1; } game.addChild(enemy); enemies.push(enemy); } } } // Spawn a power-up function spawnPowerUp(x, y) { if (Math.random() < powerUpChance) { var powerUp = new PowerUp(); powerUp.x = x; powerUp.y = y; game.addChild(powerUp); powerUps.push(powerUp); } } // Update score display function updateScoreDisplay() { scoreTxt.setText("SCORE: " + score); levelTxt.setText("LEVEL: " + level); livesTxt.setText("LIVES: " + player.lives); } // Check for level completion function checkLevelComplete() { if (enemies.length === 0) { level++; enemiesPerRow = Math.min(enemiesPerRow + 1, 8); enemyRows = Math.min(enemyRows + 1, 5); powerUpChance = Math.min(powerUpChance + 0.05, 0.5); // Clear all bullets for (var i = bullets.length - 1; i >= 0; i--) { bullets[i].destroy(); } bullets = []; // Spawn new enemy wave spawnEnemyWave(); // Update level display updateScoreDisplay(); } } // Check for game over conditions function checkGameOver() { // Check if player has no lives left if (player.lives <= 0) { endGame(); return; } // Check if any enemies have reached the bottom for (var i = 0; i < enemies.length; i++) { if (enemies[i].y > 2732 - 150) { endGame(); return; } } } // End game function function endGame() { gameOver = true; gameStarted = false; // Check for high score if (score > highScore) { highScore = score; storage.highScore = highScore; } // Show game over screen LK.showGameOver(); // Stop music LK.stopMusic(); } // Main update function game.update = function () { // Start game if face is detected and game not started if (facekit.mouthCenter && !gameStarted && !gameOver) { startGame(); } if (gameStarted && !gameOver) { // Update player position based on face position if (facekit.mouthCenter) { var targetX = facekit.mouthCenter.x; player.x += (targetX - player.x) * 0.2; // Smooth movement // Fire weapon if mouth is open if (facekit.mouthOpen) { player.fire(); } // Activate special weapon if making noise if (facekit.volume > 0.3 && !player.specialWeapon) { player.activateSpecialWeapon(); } } // Update player player.update(); // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; // Update bullet position bullet.update(); // Remove bullets that go off screen if (bullet.y < -100) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check for collisions with enemies for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (bullet.intersects(enemy)) { var destroyed = enemy.hit(bullet.power); if (destroyed) { // Add score score += 10 * level; // Play explosion sound LK.getSound('explosion').play(); // Flash effect for destroyed enemy LK.effects.flashObject(enemy, 0xff0000, 200); // Possibly spawn power-up spawnPowerUp(enemy.x, enemy.y); // Remove enemy enemy.destroy(); enemies.splice(j, 1); } // Remove bullet bullet.destroy(); bullets.splice(i, 1); break; } } } // Update enemies for (var i = 0; i < enemies.length; i++) { enemies[i].update(); // Check for collision with player if (enemies[i].intersects(player)) { player.lives--; // Flash screen red LK.effects.flashScreen(0xff0000, 300); // Remove enemy enemies[i].destroy(); enemies.splice(i, 1); i--; // Check if game over if (player.lives <= 0) { checkGameOver(); } else { updateScoreDisplay(); } continue; } } // Update power-ups for (var i = powerUps.length - 1; i >= 0; i--) { var powerUp = powerUps[i]; // Update power-up position powerUp.update(); // Remove power-ups that go off screen if (powerUp.y > 2732 + 100) { powerUp.destroy(); powerUps.splice(i, 1); continue; } // Check for collision with player if (powerUp.intersects(player)) { // Apply power-up effect player.activateSpecialWeapon(); // Play power-up sound LK.getSound('powerup').play(); // Remove power-up powerUp.destroy(); powerUps.splice(i, 1); } } // Check if level is complete checkLevelComplete(); // Check for game over conditions checkGameOver(); // Update UI updateScoreDisplay(); } }; // Event handlers game.down = function (x, y, obj) { // Touch to start game if (!gameStarted && !gameOver) { startGame(); } }; // Start with an instructional message var startText = new Text2('Face the camera and\nopen your mouth to start!', { size: 80, fill: 0xFFFFFF }); startText.anchor.set(0.5, 0.5); startText.x = 2048 / 2; startText.y = 2732 / 2; game.addChild(startText); // Remove start text when game starts var checkStarted = LK.setInterval(function () { if (gameStarted) { startText.destroy(); LK.clearInterval(checkStarted); } }, 100);
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,457 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1");
+var facekit = LK.import("@upit/facekit.v1");
+
+/****
+* Classes
+****/
+var Bullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bulletGraphics = self.attachAsset('bullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -15;
+ self.power = 1;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+var Enemy = Container.expand(function () {
+ var self = Container.call(this);
+ var enemyGraphics = self.attachAsset('enemyShip', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 2;
+ self.health = 1;
+ self.moveDirection = 1; // 1 for right, -1 for left
+ self.moveDistance = 0;
+ self.maxDistance = 200; // Maximum horizontal movement
+ self.descendAmount = 50; // Amount to descend after changing direction
+ self.hit = function (damage) {
+ self.health -= damage;
+ if (self.health <= 0) {
+ return true; // Enemy is destroyed
+ }
+ // Visual feedback for hit
+ tween(enemyGraphics, {
+ tint: 0xff0000
+ }, {
+ duration: 100,
+ easing: tween.linear,
+ onFinish: function onFinish() {
+ tween(enemyGraphics, {
+ tint: 0xffffff
+ }, {
+ duration: 100,
+ easing: tween.linear
+ });
+ }
+ });
+ return false; // Enemy still alive
+ };
+ self.update = function () {
+ // Move horizontally
+ self.x += self.speed * self.moveDirection;
+ self.moveDistance += Math.abs(self.speed);
+ // Change direction and descend when reached max distance
+ if (self.moveDistance >= self.maxDistance) {
+ self.moveDirection *= -1; // Reverse direction
+ self.y += self.descendAmount; // Move down
+ self.moveDistance = 0; // Reset distance counter
+ }
+ // Simple rotation animation
+ self.rotation = Math.sin(LK.ticks / 30) * 0.1;
+ };
+ return self;
+});
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ var shipGraphics = self.attachAsset('playerShip', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.canFire = true;
+ self.fireDelay = 300;
+ self.lastFired = 0;
+ self.specialWeapon = false;
+ self.specialTimer = 0;
+ self.lives = 3;
+ self.fire = function () {
+ var currentTime = Date.now();
+ if (self.canFire && currentTime - self.lastFired > self.fireDelay) {
+ var bullet;
+ if (self.specialWeapon) {
+ bullet = new SpecialBullet();
+ } else {
+ bullet = new Bullet();
+ }
+ bullet.x = self.x;
+ bullet.y = self.y - 60;
+ game.addChild(bullet);
+ bullets.push(bullet);
+ LK.getSound('laser').play();
+ self.lastFired = currentTime;
+ }
+ };
+ self.activateSpecialWeapon = function () {
+ self.specialWeapon = true;
+ self.specialTimer = 5000; // Special weapon lasts for 5 seconds
+ // Visual feedback for special weapon
+ tween(shipGraphics, {
+ tint: 0xffff00
+ }, {
+ duration: 300,
+ easing: tween.easeOut
+ });
+ };
+ self.update = function () {
+ // Update special weapon timer
+ if (self.specialWeapon && self.specialTimer > 0) {
+ self.specialTimer -= 16.67; // Approximate for 60fps
+ if (self.specialTimer <= 0) {
+ self.specialWeapon = false;
+ tween(shipGraphics, {
+ tint: 0xffffff
+ }, {
+ duration: 300,
+ easing: tween.easeOut
+ });
+ }
+ }
+ };
+ return self;
+});
+var PowerUp = Container.expand(function () {
+ var self = Container.call(this);
+ var powerUpGraphics = self.attachAsset('powerUp', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 3;
+ self.type = "special"; // Default type
+ self.update = function () {
+ self.y += self.speed;
+ self.rotation += 0.03;
+ };
+ return self;
+});
+var SpecialBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bulletGraphics = self.attachAsset('specialBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -18;
+ self.power = 3;
+ self.radius = 25;
+ self.update = function () {
+ self.y += self.speed;
+ self.rotation += 0.1;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x000022
+});
+
+/****
+* Game Code
+****/
+// Game variables
+var player;
+var bullets = [];
+var enemies = [];
+var powerUps = [];
+var gameStarted = false;
+var gameOver = false;
+var score = 0;
+var level = 1;
+var enemiesPerRow = 5;
+var enemyRows = 3;
+var enemySpawnDelay = 800;
+var lastEnemySpawn = 0;
+var powerUpChance = 0.2;
+var highScore = storage.highScore || 0;
+// UI Elements
+var scoreTxt = new Text2('SCORE: 0', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0, 0);
+LK.gui.topRight.addChild(scoreTxt);
+scoreTxt.x = -scoreTxt.width - 20;
+scoreTxt.y = 20;
+var levelTxt = new Text2('LEVEL: 1', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+levelTxt.anchor.set(1, 0);
+LK.gui.top.addChild(levelTxt);
+levelTxt.y = 20;
+var instructionsTxt = new Text2('Open mouth to FIRE\nMake noise for SPECIAL ATTACK', {
+ size: 40,
+ fill: 0xFFFFFF
+});
+instructionsTxt.anchor.set(0.5, 0);
+LK.gui.bottom.addChild(instructionsTxt);
+instructionsTxt.y = -100;
+var livesTxt = new Text2('LIVES: 3', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+livesTxt.anchor.set(0, 0);
+LK.gui.topLeft.addChild(livesTxt);
+livesTxt.x = 120; // Keep away from top-left corner (menu icon)
+livesTxt.y = 20;
+// Start the game
+function startGame() {
+ if (!gameStarted) {
+ gameStarted = true;
+ // Initialize player
+ player = new Player();
+ player.x = 2048 / 2;
+ player.y = 2732 - 200;
+ game.addChild(player);
+ // Reset game state
+ score = 0;
+ level = 1;
+ bullets = [];
+ enemies = [];
+ powerUps = [];
+ // Start background music
+ LK.playMusic('gameMusic', {
+ fade: {
+ start: 0,
+ end: 0.4,
+ duration: 1000
+ }
+ });
+ // Start spawning enemies
+ spawnEnemyWave();
+ }
+}
+// Spawn wave of enemies
+function spawnEnemyWave() {
+ var startX = (2048 - enemiesPerRow * 150) / 2 + 75;
+ var startY = 200;
+ for (var row = 0; row < enemyRows; row++) {
+ for (var col = 0; col < enemiesPerRow; col++) {
+ var enemy = new Enemy();
+ enemy.x = startX + col * 150;
+ enemy.y = startY + row * 120;
+ enemy.health = Math.ceil(level / 3); // Increase health every 3 levels
+ enemy.speed = 1 + level * 0.5; // Increase speed with level
+ // Alternate movement direction by row
+ if (row % 2 === 1) {
+ enemy.moveDirection = -1;
+ }
+ game.addChild(enemy);
+ enemies.push(enemy);
+ }
+ }
+}
+// Spawn a power-up
+function spawnPowerUp(x, y) {
+ if (Math.random() < powerUpChance) {
+ var powerUp = new PowerUp();
+ powerUp.x = x;
+ powerUp.y = y;
+ game.addChild(powerUp);
+ powerUps.push(powerUp);
+ }
+}
+// Update score display
+function updateScoreDisplay() {
+ scoreTxt.setText("SCORE: " + score);
+ levelTxt.setText("LEVEL: " + level);
+ livesTxt.setText("LIVES: " + player.lives);
+}
+// Check for level completion
+function checkLevelComplete() {
+ if (enemies.length === 0) {
+ level++;
+ enemiesPerRow = Math.min(enemiesPerRow + 1, 8);
+ enemyRows = Math.min(enemyRows + 1, 5);
+ powerUpChance = Math.min(powerUpChance + 0.05, 0.5);
+ // Clear all bullets
+ for (var i = bullets.length - 1; i >= 0; i--) {
+ bullets[i].destroy();
+ }
+ bullets = [];
+ // Spawn new enemy wave
+ spawnEnemyWave();
+ // Update level display
+ updateScoreDisplay();
+ }
+}
+// Check for game over conditions
+function checkGameOver() {
+ // Check if player has no lives left
+ if (player.lives <= 0) {
+ endGame();
+ return;
+ }
+ // Check if any enemies have reached the bottom
+ for (var i = 0; i < enemies.length; i++) {
+ if (enemies[i].y > 2732 - 150) {
+ endGame();
+ return;
+ }
+ }
+}
+// End game function
+function endGame() {
+ gameOver = true;
+ gameStarted = false;
+ // Check for high score
+ if (score > highScore) {
+ highScore = score;
+ storage.highScore = highScore;
+ }
+ // Show game over screen
+ LK.showGameOver();
+ // Stop music
+ LK.stopMusic();
+}
+// Main update function
+game.update = function () {
+ // Start game if face is detected and game not started
+ if (facekit.mouthCenter && !gameStarted && !gameOver) {
+ startGame();
+ }
+ if (gameStarted && !gameOver) {
+ // Update player position based on face position
+ if (facekit.mouthCenter) {
+ var targetX = facekit.mouthCenter.x;
+ player.x += (targetX - player.x) * 0.2; // Smooth movement
+ // Fire weapon if mouth is open
+ if (facekit.mouthOpen) {
+ player.fire();
+ }
+ // Activate special weapon if making noise
+ if (facekit.volume > 0.3 && !player.specialWeapon) {
+ player.activateSpecialWeapon();
+ }
+ }
+ // Update player
+ player.update();
+ // Update bullets
+ for (var i = bullets.length - 1; i >= 0; i--) {
+ var bullet = bullets[i];
+ // Update bullet position
+ bullet.update();
+ // Remove bullets that go off screen
+ if (bullet.y < -100) {
+ bullet.destroy();
+ bullets.splice(i, 1);
+ continue;
+ }
+ // Check for collisions with enemies
+ for (var j = enemies.length - 1; j >= 0; j--) {
+ var enemy = enemies[j];
+ if (bullet.intersects(enemy)) {
+ var destroyed = enemy.hit(bullet.power);
+ if (destroyed) {
+ // Add score
+ score += 10 * level;
+ // Play explosion sound
+ LK.getSound('explosion').play();
+ // Flash effect for destroyed enemy
+ LK.effects.flashObject(enemy, 0xff0000, 200);
+ // Possibly spawn power-up
+ spawnPowerUp(enemy.x, enemy.y);
+ // Remove enemy
+ enemy.destroy();
+ enemies.splice(j, 1);
+ }
+ // Remove bullet
+ bullet.destroy();
+ bullets.splice(i, 1);
+ break;
+ }
+ }
+ }
+ // Update enemies
+ for (var i = 0; i < enemies.length; i++) {
+ enemies[i].update();
+ // Check for collision with player
+ if (enemies[i].intersects(player)) {
+ player.lives--;
+ // Flash screen red
+ LK.effects.flashScreen(0xff0000, 300);
+ // Remove enemy
+ enemies[i].destroy();
+ enemies.splice(i, 1);
+ i--;
+ // Check if game over
+ if (player.lives <= 0) {
+ checkGameOver();
+ } else {
+ updateScoreDisplay();
+ }
+ continue;
+ }
+ }
+ // Update power-ups
+ for (var i = powerUps.length - 1; i >= 0; i--) {
+ var powerUp = powerUps[i];
+ // Update power-up position
+ powerUp.update();
+ // Remove power-ups that go off screen
+ if (powerUp.y > 2732 + 100) {
+ powerUp.destroy();
+ powerUps.splice(i, 1);
+ continue;
+ }
+ // Check for collision with player
+ if (powerUp.intersects(player)) {
+ // Apply power-up effect
+ player.activateSpecialWeapon();
+ // Play power-up sound
+ LK.getSound('powerup').play();
+ // Remove power-up
+ powerUp.destroy();
+ powerUps.splice(i, 1);
+ }
+ }
+ // Check if level is complete
+ checkLevelComplete();
+ // Check for game over conditions
+ checkGameOver();
+ // Update UI
+ updateScoreDisplay();
+ }
+};
+// Event handlers
+game.down = function (x, y, obj) {
+ // Touch to start game
+ if (!gameStarted && !gameOver) {
+ startGame();
+ }
+};
+// Start with an instructional message
+var startText = new Text2('Face the camera and\nopen your mouth to start!', {
+ size: 80,
+ fill: 0xFFFFFF
+});
+startText.anchor.set(0.5, 0.5);
+startText.x = 2048 / 2;
+startText.y = 2732 / 2;
+game.addChild(startText);
+// Remove start text when game starts
+var checkStarted = LK.setInterval(function () {
+ if (gameStarted) {
+ startText.destroy();
+ LK.clearInterval(checkStarted);
+ }
+}, 100);
\ No newline at end of file