/**** * 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 asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5 }); var size = 0.5 + Math.random() * 1.5; // Random size between 0.5 and 2.0 asteroidGraphics.scale.set(size, size); self.speed = 2 + Math.random() * 4; // Speed between 2 and 6 self.rotationSpeed = (Math.random() - 0.5) * 0.1; // Random rotation self.update = function () { self.y += self.speed; self.rotation += self.rotationSpeed; }; return self; }); var Bullet = Container.expand(function (isEnemy) { var self = Container.call(this); self.isEnemy = isEnemy || false; var assetId = self.isEnemy ? 'enemyBullet' : 'bullet'; var bulletGraphics = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5, scaleX: self.isEnemy ? 1 : 3, scaleY: self.isEnemy ? 1 : 3 }); self.speed = self.isEnemy ? 8 : -15; self.update = function () { self.y += self.speed; }; return self; }); var EnemyShip = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'basic'; var shipGraphics = self.attachAsset('enemyShip', { anchorX: 0.5, anchorY: 0.5 }); // Configure enemy based on type switch (self.type) { case 'basic': self.health = 1; self.speed = 3; self.points = 10; self.fireRate = 0; // Doesn't shoot break; case 'shooter': self.health = 2; self.speed = 2; self.points = 20; self.fireRate = 120; // Frames between shots shipGraphics.tint = 0x9b59b6; // Purple break; case 'elite': self.health = 3; self.speed = 4; self.points = 30; self.fireRate = 90; // Frames between shots shipGraphics.tint = 0xf39c12; // Orange break; } self.fireCounter = Math.floor(Math.random() * self.fireRate); self.movePattern = Math.floor(Math.random() * 3); // 0: straight, 1: zigzag, 2: sine self.patternStep = 0; self.initialX = 0; self.canFire = function () { if (self.fireRate === 0) { return false; } if (self.fireCounter <= 0) { self.fireCounter = self.fireRate; return true; } return false; }; self.hit = function () { self.health--; if (self.health <= 0) { return true; // Enemy destroyed } LK.effects.flashObject(self, 0xffffff, 200); return false; // Enemy still alive }; self.update = function () { // Move downward self.y += self.speed; // Apply movement pattern if (self.movePattern === 1) { // Zigzag if (self.patternStep < 60) { self.x += 1; } else if (self.patternStep < 120) { self.x -= 1; } else { self.patternStep = 0; } self.patternStep++; } else if (self.movePattern === 2) { // Sine wave if (self.initialX === 0) { self.initialX = self.x; } self.x = self.initialX + Math.sin(self.patternStep * 0.05) * 100; self.patternStep++; } // Update fire counter if (self.fireCounter > 0) { self.fireCounter--; } }; return self; }); var PlayerShip = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('playerShip', { anchorX: 0.5, anchorY: 0.5 }); self.shield = self.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.speed = 12; self.fireRate = 20; // Frames between shots self.fireCounter = 0; self.hasShield = false; self.hasDoubleFire = false; self.health = 3; self.activateShield = function () { self.hasShield = true; self.shield.alpha = 0.4; // Shield expires after 10 seconds LK.setTimeout(function () { self.hasShield = false; tween(self.shield, { alpha: 0 }, { duration: 500 }); }, 10000); }; self.hit = function () { if (self.hasShield) { self.hasShield = false; tween(self.shield, { alpha: 0 }, { duration: 500 }); return false; // No damage taken } else { self.health--; LK.getSound('playerHit').play(); LK.effects.flashObject(self, 0xff0000, 500); return true; // Damage taken } }; self.activateDoubleFire = function () { self.hasDoubleFire = true; // Double fire expires after 8 seconds LK.setTimeout(function () { self.hasDoubleFire = false; }, 8000); }; self.canFire = function () { if (self.fireCounter <= 0) { self.fireCounter = self.fireRate; return true; } return false; }; self.update = function () { if (self.fireCounter > 0) { self.fireCounter--; } }; return self; }); var PowerUp = Container.expand(function (type) { var self = Container.call(this); self.type = type || Math.random() < 0.5 ? 'shield' : 'doubleFire'; var powerUpGraphics = self.attachAsset('powerUp', { anchorX: 0.5, anchorY: 0.5 }); // Set color based on type if (self.type === 'shield') { powerUpGraphics.tint = 0x3498db; // Blue } else if (self.type === 'doubleFire') { powerUpGraphics.tint = 0xf1c40f; // Yellow } self.speed = 3; self.pulseDirection = 1; self.pulseStep = 0; self.update = function () { self.y += self.speed; // Pulse animation self.pulseStep += 0.05 * self.pulseDirection; if (self.pulseStep >= 1) { self.pulseDirection = -1; } else if (self.pulseStep <= 0) { self.pulseDirection = 1; } powerUpGraphics.alpha = 0.7 + self.pulseStep * 0.3; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game state var gameActive = true; var score = 0; var wave = 1; var enemiesDefeated = 0; var enemiesRequired = 10; // Enemies to defeat to advance to next wave // Game elements var player; var bullets = []; var enemyBullets = []; var enemies = []; var asteroids = []; var powerUps = []; // Background stars var stars = []; var starCount = 50; // Game dimensions var gameWidth = 2048; var gameHeight = 2732; var playerBoundaryLeft = 50; var playerBoundaryRight = gameWidth - 50; var playerBoundaryTop = 100; var playerBoundaryBottom = gameHeight - 200; // UI elements var scoreTxt; var waveTxt; var healthTxt; // Spawn timers var enemySpawnTimer; var asteroidSpawnTimer; var powerUpSpawnTimer; // Initialize player function initPlayer() { player = new PlayerShip(); player.x = gameWidth / 2; player.y = gameHeight - 300; game.addChild(player); } // Initialize UI function initUI() { // Add "Glaud" text in small orange letters at the top right var glaudTxt = new Text2('Glaud', { size: 30, fill: 0xFF8800 // Orange color }); glaudTxt.anchor.set(1, 0); // Anchor to top right LK.gui.topRight.addChild(glaudTxt); // Wave text waveTxt = new Text2('Wave: 1', { size: 60, fill: 0xFFFFFF }); waveTxt.anchor.set(0.5, 0); LK.gui.top.addChild(waveTxt); // Score text scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); scoreTxt.y = 70; // Position below the wave text LK.gui.top.addChild(scoreTxt); // Health text healthTxt = new Text2('❤️❤️❤️', { size: 60, fill: 0xFFFFFF }); healthTxt.anchor.set(0.5, 0); healthTxt.y = 140; // Position below the score text LK.gui.top.addChild(healthTxt); } // Initialize stars background function initStars() { for (var i = 0; i < starCount; i++) { var star = LK.getAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.1 + Math.random() * 0.1, scaleY: 0.1 + Math.random() * 0.1, alpha: 0.3 + Math.random() * 0.5 }); star.x = Math.random() * gameWidth; star.y = Math.random() * gameHeight; star.speed = 0.5 + Math.random() * 1.5; game.addChild(star); stars.push(star); } } // Spawn timers function initSpawnTimers() { // Enemy spawn timer (adjusted by wave) enemySpawnTimer = LK.setInterval(function () { spawnEnemy(); }, 2000 - (wave * 100 > 1500 ? 1500 : wave * 100)); // Asteroid spawn timer asteroidSpawnTimer = LK.setInterval(function () { spawnAsteroid(); }, 3000); // Power-up spawn timer powerUpSpawnTimer = LK.setInterval(function () { if (Math.random() < 0.3) { // 30% chance to spawn power-up spawnPowerUp(); } }, 10000); } // Spawn an enemy function spawnEnemy() { if (!gameActive) { return; } var enemyType = 'basic'; var rand = Math.random(); // Adjust enemy type probability based on wave if (wave >= 3) { if (rand < 0.3) { enemyType = 'shooter'; } else if (wave >= 5 && rand < 0.5) { enemyType = 'elite'; } } var enemy = new EnemyShip(enemyType); enemy.x = 100 + Math.random() * (gameWidth - 200); enemy.y = -100; game.addChild(enemy); enemies.push(enemy); } // Spawn an asteroid function spawnAsteroid() { if (!gameActive) { return; } var asteroid = new Asteroid(); asteroid.x = Math.random() * gameWidth; asteroid.y = -100; game.addChild(asteroid); asteroids.push(asteroid); } // Spawn a power-up function spawnPowerUp() { if (!gameActive) { return; } var powerUp = new PowerUp(); powerUp.x = 100 + Math.random() * (gameWidth - 200); powerUp.y = -100; game.addChild(powerUp); powerUps.push(powerUp); } // Fire player bullets function firePlayerBullet() { if (!player.canFire() || !gameActive) { return; } LK.getSound('playerShoot').play(); if (player.hasDoubleFire) { // Double fire - two bullets side by side var bullet1 = new Bullet(); bullet1.x = player.x - 20; bullet1.y = player.y - 30; game.addChild(bullet1); bullets.push(bullet1); var bullet2 = new Bullet(); bullet2.x = player.x + 20; bullet2.y = player.y - 30; game.addChild(bullet2); bullets.push(bullet2); } else { // Normal fire - single bullet var bullet = new Bullet(); bullet.x = player.x; bullet.y = player.y - 30; game.addChild(bullet); bullets.push(bullet); } } // Fire enemy bullet function fireEnemyBullet(enemy) { if (!gameActive) { return; } var bullet = new Bullet(true); bullet.x = enemy.x; bullet.y = enemy.y + 40; game.addChild(bullet); enemyBullets.push(bullet); LK.getSound('enemyShoot').play(); } // Handle collision between two game objects function checkCollision(obj1, obj2) { return obj1.intersects(obj2); } // Handle player movement function movePlayer(x, y) { if (!gameActive || !player) { return; } // Keep player within boundaries if (x < playerBoundaryLeft) { x = playerBoundaryLeft; } if (x > playerBoundaryRight) { x = playerBoundaryRight; } // Only change x position, keep y position fixed player.x = x; // Do not change y position anymore } // Update UI function updateUI() { scoreTxt.setText('Score: ' + score); waveTxt.setText('Wave: ' + wave); // Display health as heart emojis var hearts = ''; for (var i = 0; i < player.health; i++) { hearts += '❤️'; } healthTxt.setText(hearts); } // Check if wave is complete function checkWaveProgress() { if (enemiesDefeated >= enemiesRequired) { wave++; enemiesDefeated = 0; enemiesRequired = Math.min(10 + wave * 5, 50); // Increase required enemies, max 50 waveTxt.setText('Wave: ' + wave); // Reset spawn timers with new rates LK.clearInterval(enemySpawnTimer); enemySpawnTimer = LK.setInterval(function () { spawnEnemy(); }, Math.max(2000 - wave * 100, 500)); // Minimum 500ms } } // Game over check function checkGameOver() { if (player.health <= 0) { gameActive = false; // Check for high score if (score > storage.highScore) { storage.highScore = score; } // Show game over screen LK.setScore(score); LK.showGameOver(); } } // Initialize game function initGame() { // Set background color game.setBackgroundColor(0x0a0a2a); // Dark blue space color // Reset game state gameActive = true; score = 0; wave = 1; enemiesDefeated = 0; enemiesRequired = 10; LK.setScore(0); // Initialize game elements initPlayer(); initUI(); initStars(); initSpawnTimers(); // Play background music LK.playMusic('gameMusic', { fade: { start: 0, end: 0.7, duration: 1000 } }); } // Start the game initGame(); // Game touch controls var isDragging = false; game.down = function (x, y) { isDragging = true; movePlayer(x, y); // Fire a bullet when player touches the screen firePlayerBullet(); }; game.up = function () { isDragging = false; }; game.move = function (x, y) { if (isDragging) { movePlayer(x, y); } }; // Game update loop game.update = function () { if (!gameActive) { return; } // Update player if (player) { player.update(); } // Update stars for (var i = 0; i < stars.length; i++) { stars[i].y += stars[i].speed; // Reset star when it goes off-screen if (stars[i].y > gameHeight) { stars[i].y = -10; stars[i].x = Math.random() * gameWidth; } } // Update player bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; bullet.update(); // Remove bullets that go off-screen if (bullet.y < -50) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check bullet collisions with enemies for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (checkCollision(bullet, enemy)) { // Enemy hit if (enemy.hit()) { // Enemy destroyed score += enemy.points; LK.setScore(score); enemiesDefeated++; LK.getSound('explosion').play(); LK.effects.flashObject(enemy, 0xffffff, 100); enemy.destroy(); enemies.splice(j, 1); } // Remove bullet bullet.destroy(); bullets.splice(i, 1); break; } } // Check bullet collisions with asteroids if (bullets[i]) { // Make sure bullet wasn't removed in enemy collision check for (var j = asteroids.length - 1; j >= 0; j--) { var asteroid = asteroids[j]; if (checkCollision(bullet, asteroid)) { // Asteroid destroyed score += 5; LK.setScore(score); LK.getSound('explosion').play(); LK.effects.flashObject(asteroid, 0xffffff, 100); asteroid.destroy(); asteroids.splice(j, 1); // Remove bullet bullet.destroy(); bullets.splice(i, 1); break; } } } } // Update enemy bullets for (var i = enemyBullets.length - 1; i >= 0; i--) { var bullet = enemyBullets[i]; bullet.update(); // Remove bullets that go off-screen if (bullet.y > gameHeight + 50) { bullet.destroy(); enemyBullets.splice(i, 1); continue; } // Check bullet collisions with player if (player && checkCollision(bullet, player)) { if (player.hit()) { // Player damaged, check game over checkGameOver(); } // 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(); // Reduce health if enemies reach the bottom if (enemy.y > gameHeight - 50) { player.health--; updateUI(); checkGameOver(); LK.getSound('playerHit').play(); LK.effects.flashObject(player, 0xff0000, 500); enemy.destroy(); enemies.splice(i, 1); continue; } // Remove enemies that go off-screen if (enemy.y > gameHeight + 100) { enemy.destroy(); enemies.splice(i, 1); continue; } // Fire enemy bullets if (enemy.canFire()) { fireEnemyBullet(enemy); } // Check collisions with player if (player && checkCollision(enemy, player)) { if (player.hit()) { // Player damaged, check game over checkGameOver(); } // Remove enemy enemy.destroy(); enemies.splice(i, 1); // Add to score and enemy count score += enemy.points; LK.setScore(score); enemiesDefeated++; LK.getSound('explosion').play(); continue; } } // Update asteroids for (var i = asteroids.length - 1; i >= 0; i--) { var asteroid = asteroids[i]; asteroid.update(); // Reduce health if asteroids reach the bottom if (asteroid.y > gameHeight - 50) { player.health--; updateUI(); checkGameOver(); LK.getSound('playerHit').play(); LK.effects.flashObject(player, 0xff0000, 500); asteroid.destroy(); asteroids.splice(i, 1); continue; } // Remove asteroids that go off-screen if (asteroid.y > gameHeight + 100) { asteroid.destroy(); asteroids.splice(i, 1); continue; } // Check collisions with player if (player && checkCollision(asteroid, player)) { if (player.hit()) { // Player damaged, check game over checkGameOver(); } // Remove asteroid asteroid.destroy(); asteroids.splice(i, 1); continue; } } // Update power-ups for (var i = powerUps.length - 1; i >= 0; i--) { var powerUp = powerUps[i]; powerUp.update(); // Remove power-ups that go off-screen if (powerUp.y > gameHeight + 100) { powerUp.destroy(); powerUps.splice(i, 1); continue; } // Check collisions with player if (player && checkCollision(powerUp, player)) { // Apply power-up effect if (powerUp.type === 'shield') { player.activateShield(); } else if (powerUp.type === 'doubleFire') { player.activateDoubleFire(); } LK.getSound('powerUpCollect').play(); // Remove power-up powerUp.destroy(); powerUps.splice(i, 1); } } // Auto-fire if player is dragging (every 0.3 seconds) if (isDragging && LK.ticks % 18 === 0) { firePlayerBullet(); } // Update UI updateUI(); // Check wave progress checkWaveProgress(); };
===================================================================
--- original.js
+++ change.js
@@ -268,8 +268,15 @@
game.addChild(player);
}
// Initialize UI
function initUI() {
+ // Add "Glaud" text in small orange letters at the top right
+ var glaudTxt = new Text2('Glaud', {
+ size: 30,
+ fill: 0xFF8800 // Orange color
+ });
+ glaudTxt.anchor.set(1, 0); // Anchor to top right
+ LK.gui.topRight.addChild(glaudTxt);
// Wave text
waveTxt = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFFFF