/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0 }); /**** * Classes ****/ var Asteroid = Container.expand(function () { var self = Container.call(this); var size = 40 + Math.random() * 60; var asteroidGraphic = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: size / 80, scaleY: size / 80 }); // Randomly tint the asteroid to give variety var grayTint = 0x777777 + Math.floor(Math.random() * 0x444444); asteroidGraphic.tint = grayTint; self.health = Math.ceil(size / 30); self.speed = 2 + Math.random() * 3; self.rotationSpeed = (Math.random() - 0.5) * 0.05; self.hitSize = size; // Store the hit size for collision detection self.update = function () { self.y += self.speed; asteroidGraphic.rotation += self.rotationSpeed; // Check if asteroid is out of screen if (self.y > 2732 + 100) { self.destroy(); } }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphic = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.health = 2; self.speed = 2; self.shootTimer = 0; self.shootInterval = 120 + Math.floor(Math.random() * 60); self.moveType = Math.floor(Math.random() * 3); // 0: straight, 1: sine, 2: zigzag self.initialX = 0; self.moveCounter = 0; self.update = function () { // Movement patterns if (self.moveType === 0) { // Straight down self.y += self.speed; } else if (self.moveType === 1) { // Sine wave self.y += self.speed; self.x = self.initialX + Math.sin(self.moveCounter * 0.05) * 150; self.moveCounter++; } else if (self.moveType === 2) { // Zigzag self.y += self.speed; if (self.moveCounter % 60 < 30) { self.x += 2; } else { self.x -= 2; } self.moveCounter++; } // Shooting logic self.shootTimer++; if (self.shootTimer >= self.shootInterval) { self.shootTimer = 0; if (gameActive) { var bullet = new EnemyBullet(); bullet.x = self.x; bullet.y = self.y + 40; game.addChild(bullet); enemyBullets.push(bullet); LK.getSound('enemyShoot').play(); } } // Check if enemy is out of screen if (self.y > 2732 + 50) { self.destroy(); } }; return self; }); var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphic = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.update = function () { self.y += self.speed; // Check if bullet is out of screen if (self.y > 2732 + 50) { self.destroy(); } }; return self; }); var Explosion = Container.expand(function () { var self = Container.call(this); var explosionGraphic = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); self.lifetime = 0; self.maxLifetime = 30; self.update = function () { self.lifetime++; var progress = self.lifetime / self.maxLifetime; explosionGraphic.scaleX = 1 + progress; explosionGraphic.scaleY = 1 + progress; explosionGraphic.alpha = 0.8 * (1 - progress); if (self.lifetime >= self.maxLifetime) { self.destroy(); } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var shipGraphic = self.attachAsset('playerShip', { anchorX: 0.5, anchorY: 0.5 }); var thruster = self.attachAsset('playerThruster', { anchorX: 0.5, anchorY: 0, y: 50, alpha: 0.7 }); self.shootTimer = 0; self.shootInterval = 15; // 4 shots per second at 60fps self.shootType = 0; // 0: single, 1: triple self.speedMultiplier = 1; self.tripleTimer = 0; self.speedTimer = 0; // Thruster animation LK.setInterval(function () { var scale = 0.8 + Math.random() * 0.4; tween(thruster, { scaleX: scale, scaleY: scale }, { duration: 100 }); }, 150); self.update = function () { // Countdown powerup timers if (self.tripleTimer > 0) { self.tripleTimer--; if (self.tripleTimer === 0) { self.shootType = 0; } } if (self.speedTimer > 0) { self.speedTimer--; if (self.speedTimer === 0) { self.speedMultiplier = 1; } } // Auto-shooting if (gameActive) { self.shootTimer++; if (self.shootTimer >= self.shootInterval) { self.shootTimer = 0; if (self.shootType === 0) { // Single shot var bullet = new PlayerBullet(); bullet.x = self.x; bullet.y = self.y - 40; game.addChild(bullet); playerBullets.push(bullet); LK.getSound('playerShoot').play(); } else { // Triple shot for (var i = -1; i <= 1; i++) { var bullet = new PlayerBullet(); bullet.x = self.x + i * 20; bullet.y = self.y - 40; game.addChild(bullet); playerBullets.push(bullet); } LK.getSound('playerShoot').play(); } } } }; self.activateTripleShot = function () { self.shootType = 1; self.tripleTimer = 300; // 5 seconds at 60fps }; self.activateSpeedBoost = function () { self.speedMultiplier = 1.5; self.speedTimer = 300; // 5 seconds at 60fps }; return self; }); var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphic = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -15; self.damage = 1; self.update = function () { self.y += self.speed; // Check if bullet is out of screen if (self.y < -50) { self.destroy(); } }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphic = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.type = Math.floor(Math.random() * 3); // 0: triple shot, 1: shield, 2: speed if (self.type === 0) { powerupGraphic.tint = 0xff00ff; // Purple for triple shot } else if (self.type === 1) { powerupGraphic.tint = 0x00ffff; // Cyan for shield } else { powerupGraphic.tint = 0xffff00; // Yellow for speed } self.speed = 3; self.rotationSpeed = (Math.random() - 0.5) * 0.1; self.update = function () { self.y += self.speed; powerupGraphic.rotation += self.rotationSpeed; // Check if power-up is out of screen if (self.y > 2732 + 50) { self.destroy(); } }; return self; }); var Shield = Container.expand(function () { var self = Container.call(this); var shieldGraphic = self.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); self.duration = 300; // 5 seconds at 60fps self.timer = 0; self.update = function () { self.timer++; // Flash when about to end if (self.timer > self.duration - 60) { shieldGraphic.alpha = 0.5 * (1 + Math.sin(self.timer * 0.2)); } if (self.timer >= self.duration) { self.destroy(); playerHasShield = false; } }; return self; }); var Star = Container.expand(function () { var self = Container.call(this); var starGraphic = self.attachAsset('starParticle', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 1 + Math.random() * 5; self.alpha = 0.3 + Math.random() * 0.7; starGraphic.alpha = self.alpha; self.update = function () { self.y += self.speed; if (self.y > 2732) { self.y = -10; self.x = Math.random() * 2048; self.speed = 1 + Math.random() * 5; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000022 }); /**** * Game Code ****/ /* Supported Types: 1. Shape: - Simple geometric figures with these properties: * width: (required) pixel width of the shape. * height: (required) pixel height of the shape. * color: (required) color of the shape. * shape: (required) type of shape. Valid options: 'box', 'ellipse'. 2. Image: - Imported images with these properties: * width: (required) pixel resolution width. * height: (required) pixel resolution height. * id: (required) identifier for the image. * flipX: (optional) horizontal flip. Valid values: 0 (no flip), 1 (flip). * flipY: (optional) vertical flip. Valid values: 0 (no flip), 1 (flip). * orientation: (optional) rotation in multiples of 90 degrees, clockwise. Valid values: - 0: No rotation. - 1: Rotate 90 degrees. - 2: Rotate 180 degrees. - 3: Rotate 270 degrees. Note: Width and height remain unchanged upon flipping. 3. Sound: - Sound effects with these properties: * id: (required) identifier for the sound. * volume: (optional) custom volume. Valid values are a float from 0 to 1. 4. Music: - In contract to sound effects, only one music can be played at a time - Music is using the same API to initilize just like sound. - Music loops by default - Music with these config options: * id: (required) identifier for the sound. * volume: (optional) custom volume. Valid values are a float from 0 to 1. * start: (optional) a float from 0 to 1 used for cropping and indicates the start of the cropping * end: (optional) a float from 0 to 1 used for cropping and indicates the end of the cropping */ // Game state variables var gameActive = true; var score = 0; var lives = 3; var level = 1; var spawnCounter = 0; var playerBullets = []; var enemyBullets = []; var enemies = []; var asteroids = []; var powerups = []; var stars = []; var explosions = []; var playerHasShield = false; var shield = null; var lastTouch = { x: 0, y: 0 }; var touchActive = false; // Create UI var scoreTxt = new Text2('SCORE: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); scoreTxt.x = -300; scoreTxt.y = 30; var livesTxt = new Text2('LIVES: 3', { size: 60, fill: 0xFFFFFF }); livesTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(livesTxt); livesTxt.x = 120; // Avoiding top-left 100x100px livesTxt.y = 30; var levelTxt = new Text2('LEVEL: 1', { size: 60, fill: 0xFFFFFF }); levelTxt.anchor.set(0.5, 0); LK.gui.top.addChild(levelTxt); levelTxt.y = 30; // Create player var player = new Player(); player.x = 2048 / 2; player.y = 2732 - 200; game.addChild(player); // Create star background for (var i = 0; i < 100; i++) { var star = new Star(); star.x = Math.random() * 2048; star.y = Math.random() * 2732; game.addChild(star); stars.push(star); } // Start game music LK.playMusic('gameMusic', { fade: { start: 0, end: 0.4, duration: 1000 } }); // Increase score and update display function addScore(points) { score += points; scoreTxt.setText('SCORE: ' + score); // Update high score if needed if (score > storage.highScore) { storage.highScore = score; } } // Spawn enemy function spawnEnemy() { var enemy = new Enemy(); enemy.x = 200 + Math.random() * (2048 - 400); enemy.y = -100; enemy.initialX = enemy.x; game.addChild(enemy); enemies.push(enemy); } // Spawn asteroid function spawnAsteroid() { var asteroid = new Asteroid(); asteroid.x = Math.random() * 2048; asteroid.y = -100; game.addChild(asteroid); asteroids.push(asteroid); } // Spawn power-up function spawnPowerUp() { var powerup = new PowerUp(); powerup.x = 200 + Math.random() * (2048 - 400); powerup.y = -100; game.addChild(powerup); powerups.push(powerup); } // Create explosion function createExplosion(x, y) { var explosion = new Explosion(); explosion.x = x; explosion.y = y; game.addChild(explosion); explosions.push(explosion); LK.getSound('explosion').play(); } // Handle player hits function hitPlayer() { if (playerHasShield) { playerHasShield = false; if (shield) { shield.destroy(); shield = null; } return; } lives--; livesTxt.setText('LIVES: ' + lives); LK.getSound('playerHit').play(); LK.effects.flashScreen(0xff0000, 500); if (lives <= 0) { gameActive = false; LK.setTimeout(function () { LK.showGameOver(); }, 1000); } } // Touch handlers game.down = function (x, y, obj) { touchActive = true; lastTouch.x = x; lastTouch.y = y; }; game.move = function (x, y, obj) { if (touchActive && gameActive) { // Calculate delta movement var dx = x - lastTouch.x; // Apply movement with speed multiplier player.x += dx * player.speedMultiplier; // Keep player within bounds if (player.x < 50) { player.x = 50; } if (player.x > 2048 - 50) { player.x = 2048 - 50; } // Update last touch position lastTouch.x = x; lastTouch.y = y; } }; game.up = function (x, y, obj) { touchActive = false; }; // Game update loop game.update = function () { // Process spawning logic if (gameActive) { spawnCounter++; // Enemy spawning - frequency based on level if (spawnCounter % Math.max(180 - level * 10, 60) === 0) { spawnEnemy(); } // Asteroid spawning - frequency based on level if (spawnCounter % Math.max(240 - level * 15, 90) === 0) { spawnAsteroid(); } // Power-up spawning - rare if (spawnCounter % 600 === 0) { spawnPowerUp(); } // Level up every 1000 points if (score >= level * 1000) { level++; levelTxt.setText('LEVEL: ' + level); } } // Update all stars for (var i = 0; i < stars.length; i++) { stars[i].update(); } // Update player player.update(); // Update shield if active if (shield) { shield.update(); shield.x = player.x; shield.y = player.y; } // Update player bullets for (var i = playerBullets.length - 1; i >= 0; i--) { var bullet = playerBullets[i]; bullet.update(); // Check if bullet is destroyed if (!bullet.parent) { playerBullets.splice(i, 1); continue; } // Check collisions with enemies for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (bullet.intersects(enemy)) { enemy.health--; if (enemy.health <= 0) { createExplosion(enemy.x, enemy.y); enemy.destroy(); enemies.splice(j, 1); addScore(100); } else { // Flash enemy when hit LK.effects.flashObject(enemy, 0xffffff, 200); } // Remove bullet bullet.destroy(); playerBullets.splice(i, 1); break; } } // Check collisions with asteroids (if bullet still exists) if (bullet.parent) { for (var j = asteroids.length - 1; j >= 0; j--) { var asteroid = asteroids[j]; if (bullet.intersects(asteroid)) { asteroid.health--; if (asteroid.health <= 0) { createExplosion(asteroid.x, asteroid.y); asteroid.destroy(); asteroids.splice(j, 1); addScore(50); } else { // Flash asteroid when hit LK.effects.flashObject(asteroid, 0xffffff, 200); } // 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]; bullet.update(); // Check if bullet is destroyed if (!bullet.parent) { enemyBullets.splice(i, 1); continue; } // Check collision with player if (gameActive && bullet.intersects(player)) { hitPlayer(); // Remove bullet bullet.destroy(); enemyBullets.splice(i, 1); } } // Update enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; enemy.update(); // Check if enemy is destroyed if (!enemy.parent) { enemies.splice(i, 1); continue; } // Check collision with player if (gameActive && enemy.intersects(player)) { hitPlayer(); createExplosion(enemy.x, enemy.y); enemy.destroy(); enemies.splice(i, 1); } } // Update asteroids for (var i = asteroids.length - 1; i >= 0; i--) { var asteroid = asteroids[i]; asteroid.update(); // Check if asteroid is destroyed if (!asteroid.parent) { asteroids.splice(i, 1); continue; } // Check collision with player if (gameActive && asteroid.intersects(player)) { hitPlayer(); createExplosion(asteroid.x, asteroid.y); asteroid.destroy(); asteroids.splice(i, 1); } } // Update power-ups for (var i = powerups.length - 1; i >= 0; i--) { var powerup = powerups[i]; powerup.update(); // Check if power-up is destroyed if (!powerup.parent) { powerups.splice(i, 1); continue; } // Check collision with player if (gameActive && powerup.intersects(player)) { LK.getSound('powerupCollect').play(); // Apply power-up effect if (powerup.type === 0) { player.activateTripleShot(); } else if (powerup.type === 1) { playerHasShield = true; if (shield) { shield.destroy(); } shield = new Shield(); shield.x = player.x; shield.y = player.y; game.addChild(shield); } else { player.activateSpeedBoost(); } addScore(25); powerup.destroy(); powerups.splice(i, 1); } } // Update explosions for (var i = explosions.length - 1; i >= 0; i--) { var explosion = explosions[i]; explosion.update(); // Check if explosion is destroyed if (!explosion.parent) { explosions.splice(i, 1); } } };
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,672 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ highScore: 0
+});
+
+/****
+* Classes
+****/
+var Asteroid = Container.expand(function () {
+ var self = Container.call(this);
+ var size = 40 + Math.random() * 60;
+ var asteroidGraphic = self.attachAsset('asteroid', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: size / 80,
+ scaleY: size / 80
+ });
+ // Randomly tint the asteroid to give variety
+ var grayTint = 0x777777 + Math.floor(Math.random() * 0x444444);
+ asteroidGraphic.tint = grayTint;
+ self.health = Math.ceil(size / 30);
+ self.speed = 2 + Math.random() * 3;
+ self.rotationSpeed = (Math.random() - 0.5) * 0.05;
+ self.hitSize = size; // Store the hit size for collision detection
+ self.update = function () {
+ self.y += self.speed;
+ asteroidGraphic.rotation += self.rotationSpeed;
+ // Check if asteroid is out of screen
+ if (self.y > 2732 + 100) {
+ self.destroy();
+ }
+ };
+ return self;
+});
+var Enemy = Container.expand(function () {
+ var self = Container.call(this);
+ var enemyGraphic = self.attachAsset('enemy', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.health = 2;
+ self.speed = 2;
+ self.shootTimer = 0;
+ self.shootInterval = 120 + Math.floor(Math.random() * 60);
+ self.moveType = Math.floor(Math.random() * 3); // 0: straight, 1: sine, 2: zigzag
+ self.initialX = 0;
+ self.moveCounter = 0;
+ self.update = function () {
+ // Movement patterns
+ if (self.moveType === 0) {
+ // Straight down
+ self.y += self.speed;
+ } else if (self.moveType === 1) {
+ // Sine wave
+ self.y += self.speed;
+ self.x = self.initialX + Math.sin(self.moveCounter * 0.05) * 150;
+ self.moveCounter++;
+ } else if (self.moveType === 2) {
+ // Zigzag
+ self.y += self.speed;
+ if (self.moveCounter % 60 < 30) {
+ self.x += 2;
+ } else {
+ self.x -= 2;
+ }
+ self.moveCounter++;
+ }
+ // Shooting logic
+ self.shootTimer++;
+ if (self.shootTimer >= self.shootInterval) {
+ self.shootTimer = 0;
+ if (gameActive) {
+ var bullet = new EnemyBullet();
+ bullet.x = self.x;
+ bullet.y = self.y + 40;
+ game.addChild(bullet);
+ enemyBullets.push(bullet);
+ LK.getSound('enemyShoot').play();
+ }
+ }
+ // Check if enemy is out of screen
+ if (self.y > 2732 + 50) {
+ self.destroy();
+ }
+ };
+ return self;
+});
+var EnemyBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bulletGraphic = self.attachAsset('enemyBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 8;
+ self.update = function () {
+ self.y += self.speed;
+ // Check if bullet is out of screen
+ if (self.y > 2732 + 50) {
+ self.destroy();
+ }
+ };
+ return self;
+});
+var Explosion = Container.expand(function () {
+ var self = Container.call(this);
+ var explosionGraphic = self.attachAsset('explosion', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.8
+ });
+ self.lifetime = 0;
+ self.maxLifetime = 30;
+ self.update = function () {
+ self.lifetime++;
+ var progress = self.lifetime / self.maxLifetime;
+ explosionGraphic.scaleX = 1 + progress;
+ explosionGraphic.scaleY = 1 + progress;
+ explosionGraphic.alpha = 0.8 * (1 - progress);
+ if (self.lifetime >= self.maxLifetime) {
+ self.destroy();
+ }
+ };
+ return self;
+});
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ var shipGraphic = self.attachAsset('playerShip', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var thruster = self.attachAsset('playerThruster', {
+ anchorX: 0.5,
+ anchorY: 0,
+ y: 50,
+ alpha: 0.7
+ });
+ self.shootTimer = 0;
+ self.shootInterval = 15; // 4 shots per second at 60fps
+ self.shootType = 0; // 0: single, 1: triple
+ self.speedMultiplier = 1;
+ self.tripleTimer = 0;
+ self.speedTimer = 0;
+ // Thruster animation
+ LK.setInterval(function () {
+ var scale = 0.8 + Math.random() * 0.4;
+ tween(thruster, {
+ scaleX: scale,
+ scaleY: scale
+ }, {
+ duration: 100
+ });
+ }, 150);
+ self.update = function () {
+ // Countdown powerup timers
+ if (self.tripleTimer > 0) {
+ self.tripleTimer--;
+ if (self.tripleTimer === 0) {
+ self.shootType = 0;
+ }
+ }
+ if (self.speedTimer > 0) {
+ self.speedTimer--;
+ if (self.speedTimer === 0) {
+ self.speedMultiplier = 1;
+ }
+ }
+ // Auto-shooting
+ if (gameActive) {
+ self.shootTimer++;
+ if (self.shootTimer >= self.shootInterval) {
+ self.shootTimer = 0;
+ if (self.shootType === 0) {
+ // Single shot
+ var bullet = new PlayerBullet();
+ bullet.x = self.x;
+ bullet.y = self.y - 40;
+ game.addChild(bullet);
+ playerBullets.push(bullet);
+ LK.getSound('playerShoot').play();
+ } else {
+ // Triple shot
+ for (var i = -1; i <= 1; i++) {
+ var bullet = new PlayerBullet();
+ bullet.x = self.x + i * 20;
+ bullet.y = self.y - 40;
+ game.addChild(bullet);
+ playerBullets.push(bullet);
+ }
+ LK.getSound('playerShoot').play();
+ }
+ }
+ }
+ };
+ self.activateTripleShot = function () {
+ self.shootType = 1;
+ self.tripleTimer = 300; // 5 seconds at 60fps
+ };
+ self.activateSpeedBoost = function () {
+ self.speedMultiplier = 1.5;
+ self.speedTimer = 300; // 5 seconds at 60fps
+ };
+ return self;
+});
+var PlayerBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bulletGraphic = self.attachAsset('playerBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -15;
+ self.damage = 1;
+ self.update = function () {
+ self.y += self.speed;
+ // Check if bullet is out of screen
+ if (self.y < -50) {
+ self.destroy();
+ }
+ };
+ return self;
+});
+var PowerUp = Container.expand(function () {
+ var self = Container.call(this);
+ var powerupGraphic = self.attachAsset('powerup', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.type = Math.floor(Math.random() * 3); // 0: triple shot, 1: shield, 2: speed
+ if (self.type === 0) {
+ powerupGraphic.tint = 0xff00ff; // Purple for triple shot
+ } else if (self.type === 1) {
+ powerupGraphic.tint = 0x00ffff; // Cyan for shield
+ } else {
+ powerupGraphic.tint = 0xffff00; // Yellow for speed
+ }
+ self.speed = 3;
+ self.rotationSpeed = (Math.random() - 0.5) * 0.1;
+ self.update = function () {
+ self.y += self.speed;
+ powerupGraphic.rotation += self.rotationSpeed;
+ // Check if power-up is out of screen
+ if (self.y > 2732 + 50) {
+ self.destroy();
+ }
+ };
+ return self;
+});
+var Shield = Container.expand(function () {
+ var self = Container.call(this);
+ var shieldGraphic = self.attachAsset('shield', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.5
+ });
+ self.duration = 300; // 5 seconds at 60fps
+ self.timer = 0;
+ self.update = function () {
+ self.timer++;
+ // Flash when about to end
+ if (self.timer > self.duration - 60) {
+ shieldGraphic.alpha = 0.5 * (1 + Math.sin(self.timer * 0.2));
+ }
+ if (self.timer >= self.duration) {
+ self.destroy();
+ playerHasShield = false;
+ }
+ };
+ return self;
+});
+var Star = Container.expand(function () {
+ var self = Container.call(this);
+ var starGraphic = self.attachAsset('starParticle', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 1 + Math.random() * 5;
+ self.alpha = 0.3 + Math.random() * 0.7;
+ starGraphic.alpha = self.alpha;
+ self.update = function () {
+ self.y += self.speed;
+ if (self.y > 2732) {
+ self.y = -10;
+ self.x = Math.random() * 2048;
+ self.speed = 1 + Math.random() * 5;
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x000022
+});
+
+/****
+* Game Code
+****/
+/*
+Supported Types:
+1. Shape:
+ - Simple geometric figures with these properties:
+ * width: (required) pixel width of the shape.
+ * height: (required) pixel height of the shape.
+ * color: (required) color of the shape.
+ * shape: (required) type of shape. Valid options: 'box', 'ellipse'.
+2. Image:
+ - Imported images with these properties:
+ * width: (required) pixel resolution width.
+ * height: (required) pixel resolution height.
+ * id: (required) identifier for the image.
+ * flipX: (optional) horizontal flip. Valid values: 0 (no flip), 1 (flip).
+ * flipY: (optional) vertical flip. Valid values: 0 (no flip), 1 (flip).
+ * orientation: (optional) rotation in multiples of 90 degrees, clockwise. Valid values:
+ - 0: No rotation.
+ - 1: Rotate 90 degrees.
+ - 2: Rotate 180 degrees.
+ - 3: Rotate 270 degrees.
+ Note: Width and height remain unchanged upon flipping.
+3. Sound:
+ - Sound effects with these properties:
+ * id: (required) identifier for the sound.
+ * volume: (optional) custom volume. Valid values are a float from 0 to 1.
+4. Music:
+- In contract to sound effects, only one music can be played at a time
+- Music is using the same API to initilize just like sound.
+- Music loops by default
+- Music with these config options:
+ * id: (required) identifier for the sound.
+ * volume: (optional) custom volume. Valid values are a float from 0 to 1.
+ * start: (optional) a float from 0 to 1 used for cropping and indicates the start of the cropping
+ * end: (optional) a float from 0 to 1 used for cropping and indicates the end of the cropping
+*/
+// Game state variables
+var gameActive = true;
+var score = 0;
+var lives = 3;
+var level = 1;
+var spawnCounter = 0;
+var playerBullets = [];
+var enemyBullets = [];
+var enemies = [];
+var asteroids = [];
+var powerups = [];
+var stars = [];
+var explosions = [];
+var playerHasShield = false;
+var shield = null;
+var lastTouch = {
+ x: 0,
+ y: 0
+};
+var touchActive = false;
+// Create UI
+var scoreTxt = new Text2('SCORE: 0', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0, 0);
+LK.gui.topRight.addChild(scoreTxt);
+scoreTxt.x = -300;
+scoreTxt.y = 30;
+var livesTxt = new Text2('LIVES: 3', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+livesTxt.anchor.set(0, 0);
+LK.gui.topLeft.addChild(livesTxt);
+livesTxt.x = 120; // Avoiding top-left 100x100px
+livesTxt.y = 30;
+var levelTxt = new Text2('LEVEL: 1', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+levelTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(levelTxt);
+levelTxt.y = 30;
+// Create player
+var player = new Player();
+player.x = 2048 / 2;
+player.y = 2732 - 200;
+game.addChild(player);
+// Create star background
+for (var i = 0; i < 100; i++) {
+ var star = new Star();
+ star.x = Math.random() * 2048;
+ star.y = Math.random() * 2732;
+ game.addChild(star);
+ stars.push(star);
+}
+// Start game music
+LK.playMusic('gameMusic', {
+ fade: {
+ start: 0,
+ end: 0.4,
+ duration: 1000
+ }
+});
+// Increase score and update display
+function addScore(points) {
+ score += points;
+ scoreTxt.setText('SCORE: ' + score);
+ // Update high score if needed
+ if (score > storage.highScore) {
+ storage.highScore = score;
+ }
+}
+// Spawn enemy
+function spawnEnemy() {
+ var enemy = new Enemy();
+ enemy.x = 200 + Math.random() * (2048 - 400);
+ enemy.y = -100;
+ enemy.initialX = enemy.x;
+ game.addChild(enemy);
+ enemies.push(enemy);
+}
+// Spawn asteroid
+function spawnAsteroid() {
+ var asteroid = new Asteroid();
+ asteroid.x = Math.random() * 2048;
+ asteroid.y = -100;
+ game.addChild(asteroid);
+ asteroids.push(asteroid);
+}
+// Spawn power-up
+function spawnPowerUp() {
+ var powerup = new PowerUp();
+ powerup.x = 200 + Math.random() * (2048 - 400);
+ powerup.y = -100;
+ game.addChild(powerup);
+ powerups.push(powerup);
+}
+// Create explosion
+function createExplosion(x, y) {
+ var explosion = new Explosion();
+ explosion.x = x;
+ explosion.y = y;
+ game.addChild(explosion);
+ explosions.push(explosion);
+ LK.getSound('explosion').play();
+}
+// Handle player hits
+function hitPlayer() {
+ if (playerHasShield) {
+ playerHasShield = false;
+ if (shield) {
+ shield.destroy();
+ shield = null;
+ }
+ return;
+ }
+ lives--;
+ livesTxt.setText('LIVES: ' + lives);
+ LK.getSound('playerHit').play();
+ LK.effects.flashScreen(0xff0000, 500);
+ if (lives <= 0) {
+ gameActive = false;
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 1000);
+ }
+}
+// Touch handlers
+game.down = function (x, y, obj) {
+ touchActive = true;
+ lastTouch.x = x;
+ lastTouch.y = y;
+};
+game.move = function (x, y, obj) {
+ if (touchActive && gameActive) {
+ // Calculate delta movement
+ var dx = x - lastTouch.x;
+ // Apply movement with speed multiplier
+ player.x += dx * player.speedMultiplier;
+ // Keep player within bounds
+ if (player.x < 50) {
+ player.x = 50;
+ }
+ if (player.x > 2048 - 50) {
+ player.x = 2048 - 50;
+ }
+ // Update last touch position
+ lastTouch.x = x;
+ lastTouch.y = y;
+ }
+};
+game.up = function (x, y, obj) {
+ touchActive = false;
+};
+// Game update loop
+game.update = function () {
+ // Process spawning logic
+ if (gameActive) {
+ spawnCounter++;
+ // Enemy spawning - frequency based on level
+ if (spawnCounter % Math.max(180 - level * 10, 60) === 0) {
+ spawnEnemy();
+ }
+ // Asteroid spawning - frequency based on level
+ if (spawnCounter % Math.max(240 - level * 15, 90) === 0) {
+ spawnAsteroid();
+ }
+ // Power-up spawning - rare
+ if (spawnCounter % 600 === 0) {
+ spawnPowerUp();
+ }
+ // Level up every 1000 points
+ if (score >= level * 1000) {
+ level++;
+ levelTxt.setText('LEVEL: ' + level);
+ }
+ }
+ // Update all stars
+ for (var i = 0; i < stars.length; i++) {
+ stars[i].update();
+ }
+ // Update player
+ player.update();
+ // Update shield if active
+ if (shield) {
+ shield.update();
+ shield.x = player.x;
+ shield.y = player.y;
+ }
+ // Update player bullets
+ for (var i = playerBullets.length - 1; i >= 0; i--) {
+ var bullet = playerBullets[i];
+ bullet.update();
+ // Check if bullet is destroyed
+ if (!bullet.parent) {
+ playerBullets.splice(i, 1);
+ continue;
+ }
+ // Check collisions with enemies
+ for (var j = enemies.length - 1; j >= 0; j--) {
+ var enemy = enemies[j];
+ if (bullet.intersects(enemy)) {
+ enemy.health--;
+ if (enemy.health <= 0) {
+ createExplosion(enemy.x, enemy.y);
+ enemy.destroy();
+ enemies.splice(j, 1);
+ addScore(100);
+ } else {
+ // Flash enemy when hit
+ LK.effects.flashObject(enemy, 0xffffff, 200);
+ }
+ // Remove bullet
+ bullet.destroy();
+ playerBullets.splice(i, 1);
+ break;
+ }
+ }
+ // Check collisions with asteroids (if bullet still exists)
+ if (bullet.parent) {
+ for (var j = asteroids.length - 1; j >= 0; j--) {
+ var asteroid = asteroids[j];
+ if (bullet.intersects(asteroid)) {
+ asteroid.health--;
+ if (asteroid.health <= 0) {
+ createExplosion(asteroid.x, asteroid.y);
+ asteroid.destroy();
+ asteroids.splice(j, 1);
+ addScore(50);
+ } else {
+ // Flash asteroid when hit
+ LK.effects.flashObject(asteroid, 0xffffff, 200);
+ }
+ // 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];
+ bullet.update();
+ // Check if bullet is destroyed
+ if (!bullet.parent) {
+ enemyBullets.splice(i, 1);
+ continue;
+ }
+ // Check collision with player
+ if (gameActive && bullet.intersects(player)) {
+ hitPlayer();
+ // Remove bullet
+ bullet.destroy();
+ enemyBullets.splice(i, 1);
+ }
+ }
+ // Update enemies
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ var enemy = enemies[i];
+ enemy.update();
+ // Check if enemy is destroyed
+ if (!enemy.parent) {
+ enemies.splice(i, 1);
+ continue;
+ }
+ // Check collision with player
+ if (gameActive && enemy.intersects(player)) {
+ hitPlayer();
+ createExplosion(enemy.x, enemy.y);
+ enemy.destroy();
+ enemies.splice(i, 1);
+ }
+ }
+ // Update asteroids
+ for (var i = asteroids.length - 1; i >= 0; i--) {
+ var asteroid = asteroids[i];
+ asteroid.update();
+ // Check if asteroid is destroyed
+ if (!asteroid.parent) {
+ asteroids.splice(i, 1);
+ continue;
+ }
+ // Check collision with player
+ if (gameActive && asteroid.intersects(player)) {
+ hitPlayer();
+ createExplosion(asteroid.x, asteroid.y);
+ asteroid.destroy();
+ asteroids.splice(i, 1);
+ }
+ }
+ // Update power-ups
+ for (var i = powerups.length - 1; i >= 0; i--) {
+ var powerup = powerups[i];
+ powerup.update();
+ // Check if power-up is destroyed
+ if (!powerup.parent) {
+ powerups.splice(i, 1);
+ continue;
+ }
+ // Check collision with player
+ if (gameActive && powerup.intersects(player)) {
+ LK.getSound('powerupCollect').play();
+ // Apply power-up effect
+ if (powerup.type === 0) {
+ player.activateTripleShot();
+ } else if (powerup.type === 1) {
+ playerHasShield = true;
+ if (shield) {
+ shield.destroy();
+ }
+ shield = new Shield();
+ shield.x = player.x;
+ shield.y = player.y;
+ game.addChild(shield);
+ } else {
+ player.activateSpeedBoost();
+ }
+ addScore(25);
+ powerup.destroy();
+ powerups.splice(i, 1);
+ }
+ }
+ // Update explosions
+ for (var i = explosions.length - 1; i >= 0; i--) {
+ var explosion = explosions[i];
+ explosion.update();
+ // Check if explosion is destroyed
+ if (!explosion.parent) {
+ explosions.splice(i, 1);
+ }
+ }
+};
\ No newline at end of file