/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, lastScore: 0 }); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); self.bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 20; self.damage = 1; self.isPlayerBullet = true; self.update = function () { self.x += self.speed; // Auto destroy when off screen if (self.x > 2148) { self.destroy(); } }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); self.enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.speedX = -5; self.speedY = 0; self.health = 5; self.score = 100; self.canShoot = false; self.shootTimer = 0; self.shootInterval = 120; // 2 seconds at 60fps self.update = function () { self.x += self.speedX; self.y += self.speedY; // Simple movement pattern if (self.movePattern === 'sine') { self.y += Math.sin(LK.ticks * 0.05) * 2; } else if (self.movePattern === 'zigzag') { if (LK.ticks % 60 === 0) { self.speedY = -self.speedY || (Math.random() > 0.5 ? 3 : -3); } } // Shooting logic if (self.canShoot) { self.shootTimer++; if (self.shootTimer >= self.shootInterval) { self.shootTimer = 0; self.shoot(); } } // Auto destroy when off screen if (self.x < -100) { self.destroy(); } }; self.shoot = function () { if (!game) { return; } var bullet = new Bullet(); bullet.x = self.x - 20; bullet.y = self.y; bullet.speed = -15; bullet.isPlayerBullet = false; bullet.bulletGraphics.tint = 0xff0000; // Red enemy bullets game.addChild(bullet); game.enemyBullets.push(bullet); }; self.takeDamage = function (damage) { self.health -= damage; // Flash red when taking damage LK.effects.flashObject(self, 0xff0000, 200); if (self.health <= 0) { // Explosion effect LK.getSound('explosion').play(); LK.effects.flashObject(self, 0xffffff, 300); // Add score game.increaseScore(self.score); // Potentially drop powerup (20% chance) if (Math.random() < 0.2) { game.spawnPowerup(self.x, self.y); } self.destroy(); } }; return self; }); var Boss = Enemy.expand(function () { var self = Enemy.call(this); // Replace graphics with boss graphic self.enemyGraphics.destroy(); self.enemyGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5 }); self.health = 75; self.score = 2000; self.speedX = -2; self.canShoot = true; self.shootInterval = 60; // 1 second at 60fps self.phase = 1; self.phaseTimer = 0; self.isBoss = true; // Override update function self.update = function () { self.phaseTimer++; // Boss movement based on phases if (self.phase === 1) { // Enter the screen if (self.x > 1600) { self.x += self.speedX; } else { self.phase = 2; self.phaseTimer = 0; } } else if (self.phase === 2) { // Move up and down self.y += Math.sin(self.phaseTimer * 0.03) * 4; // Shooting pattern if (self.phaseTimer % 20 === 0) { self.shoot(); } // Phase transition if (self.phaseTimer > 300) { self.phase = 3; self.phaseTimer = 0; } } else if (self.phase === 3) { // Charge at player if (self.phaseTimer < 60) { // Prepare self.speedX = 0; } else if (self.phaseTimer < 120) { // Charge self.x -= 15; } else { // Return to position if (self.x < 1600) { self.x += 5; } else { self.phase = 2; self.phaseTimer = 0; } } } // Health-based phase changes if (self.health < 25 && self.shootInterval > 40) { self.shootInterval = 40; // Shoot faster when at low health } }; // Override shoot function for more complex patterns self.shoot = function () { if (!game) { return; } // Different shooting patterns based on phase if (self.phase === 2) { // Spread shot for (var i = -2; i <= 2; i++) { var bullet = new Bullet(); bullet.x = self.x - 50; bullet.y = self.y; bullet.speed = -15; bullet.speedY = i * 2; bullet.isPlayerBullet = false; bullet.bulletGraphics.tint = 0xff0000; // Custom update for diagonal movement var originalUpdate = bullet.update; bullet.update = function () { this.x += this.speed; this.y += this.speedY; // Off screen check if (this.x < -100 || this.y < -100 || this.y > 2832) { this.destroy(); } }; game.addChild(bullet); game.enemyBullets.push(bullet); } } else if (self.phase === 3) { // Aimed shot at player var bullet = new Bullet(); bullet.x = self.x - 50; bullet.y = self.y; // Calculate angle to player var dx = game.player.x - bullet.x; var dy = game.player.y - bullet.y; var angle = Math.atan2(dy, dx); bullet.speed = -15 * Math.cos(angle); bullet.speedY = 15 * Math.sin(angle); bullet.isPlayerBullet = false; bullet.bulletGraphics.tint = 0xff5500; // Orange for aimed shots // Custom update for angle-based movement bullet.update = function () { this.x += this.speed; this.y += this.speedY; // Off screen check if (this.x < -100 || this.y < -100 || this.y > 2832) { this.destroy(); } }; game.addChild(bullet); game.enemyBullets.push(bullet); } LK.getSound('shoot').play(); }; return self; }); var Obstacle = Container.expand(function () { var self = Container.call(this); self.obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -8; self.update = function () { self.x += self.speed; // Auto destroy when off screen if (self.x < -100) { self.destroy(); } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); self.playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.health = 5; self.maxHealth = 5; self.shield = 0; self.weaponLevel = 1; self.specialMeter = 0; self.specialMax = 100; self.shootCooldown = 0; self.invulnerable = 0; self.update = function () { // Shooting cooldown if (self.shootCooldown > 0) { self.shootCooldown--; } // Invulnerability frames if (self.invulnerable > 0) { self.invulnerable--; // Flash effect during invulnerability if (LK.ticks % 5 === 0) { self.playerGraphics.alpha = self.playerGraphics.alpha === 1 ? 0.5 : 1; } } else { self.playerGraphics.alpha = 1; } // Gentle hover effect self.y += Math.sin(LK.ticks * 0.05) * 0.5; }; self.shoot = function () { if (self.shootCooldown > 0) { return; } LK.getSound('shoot').play(); // Different shooting patterns based on weapon level if (self.weaponLevel === 1) { // Single shot var bullet = new Bullet(); bullet.x = self.x + 50; bullet.y = self.y; game.addChild(bullet); game.playerBullets.push(bullet); self.shootCooldown = 10; } else if (self.weaponLevel === 2) { // Double shot for (var i = -1; i <= 1; i += 2) { var bullet = new Bullet(); bullet.x = self.x + 50; bullet.y = self.y + i * 20; game.addChild(bullet); game.playerBullets.push(bullet); } self.shootCooldown = 8; } else if (self.weaponLevel >= 3) { // Triple shot var center = new Bullet(); center.x = self.x + 60; center.y = self.y; game.addChild(center); game.playerBullets.push(center); for (var i = -1; i <= 1; i += 2) { var side = new Bullet(); side.x = self.x + 40; side.y = self.y + i * 30; game.addChild(side); game.playerBullets.push(side); } self.shootCooldown = 6; } // Increase special meter slightly with each shot self.specialMeter = Math.min(self.specialMeter + 1, self.specialMax); game.updateSpecialMeter(); }; self.activateSpecial = function () { if (self.specialMeter < self.specialMax) { return; } LK.getSound('special').play(); // Create special attack var special = new SpecialAttack(); special.x = self.x; special.y = self.y; game.addChild(special); game.specialAttacks.push(special); // Make player briefly invulnerable self.invulnerable = 60; // Reset special meter self.specialMeter = 0; game.updateSpecialMeter(); }; self.takeDamage = function () { if (self.invulnerable > 0) { return; } // Shield absorbs damage first if (self.shield > 0) { self.shield--; LK.getSound('damage').play(); LK.effects.flashObject(self, 0x3498db, 300); // Blue flash for shield hit } else { self.health--; LK.getSound('damage').play(); LK.effects.flashObject(self, 0xff0000, 300); // Red flash for health hit // Set invulnerability frames self.invulnerable = 60; // Game over check if (self.health <= 0) { // Store score storage.lastScore = game.score; if (game.score > storage.highScore) { storage.highScore = game.score; } LK.showGameOver(); } } game.updateHealthDisplay(); }; self.collectPowerup = function (powerup) { LK.getSound('powerup').play(); if (powerup.type === 'health') { self.health = Math.min(self.health + 1, self.maxHealth); } else if (powerup.type === 'shield') { self.shield = Math.min(self.shield + 2, 3); // Max 3 shield points } else if (powerup.type === 'weapon') { self.weaponLevel = Math.min(self.weaponLevel + 1, 3); } else if (powerup.type === 'special') { self.specialMeter = self.specialMax; // Fill special meter } game.updateHealthDisplay(); game.updateSpecialMeter(); // Visual effect LK.effects.flashObject(self, 0xffffff, 300); }; // Touch/mouse controls self.down = function (x, y, obj) { game.isDragging = true; }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); self.powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -3; self.type = 'health'; // Default power-up type // Set color based on type if (self.type === 'health') { self.powerupGraphics.tint = 0x2ecc71; // Green } else if (self.type === 'shield') { self.powerupGraphics.tint = 0x3498db; // Blue } else if (self.type === 'weapon') { self.powerupGraphics.tint = 0xf1c40f; // Yellow } else if (self.type === 'special') { self.powerupGraphics.tint = 0x9b59b6; // Purple } self.update = function () { self.x += self.speed; // Gentle floating effect self.y += Math.sin(LK.ticks * 0.1) * 0.5; // Auto destroy when off screen if (self.x < -100) { self.destroy(); } }; return self; }); var SpecialAttack = Container.expand(function () { var self = Container.call(this); self.attackGraphics = self.attachAsset('specialAttack', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); self.duration = 60; // 1 second at 60fps self.counter = 0; self.damage = 5; self.update = function () { self.counter++; self.x += 10; // Flash effect if (self.counter % 5 === 0) { self.attackGraphics.alpha = self.attackGraphics.alpha === 0.7 ? 0.9 : 0.7; } // Auto destroy when duration ends if (self.counter >= self.duration) { self.destroy(); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x0e0e2a }); /**** * Game Code ****/ // Game variables game.score = 0; game.level = 1; game.waveTimer = 0; game.bossActive = false; game.spawnRate = 120; // Enemy spawn rate (frames) game.isDragging = false; game.autoShoot = true; game.autoShootTimer = 0; // Array containers for game objects game.playerBullets = []; game.enemyBullets = []; game.enemies = []; game.powerups = []; game.obstacles = []; game.specialAttacks = []; // Create background var background = game.addChild(LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 })); // Create player game.player = new Player(); game.player.x = 300; game.player.y = 1366; // Center vertically game.addChild(game.player); // Create UI // Score display var scoreTxt = new Text2('SCORE: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Create touch screen buttons for movement var leftBtn = game.addChild(LK.getAsset('powerup', { anchorX: 0.5, anchorY: 0.5, x: 100, y: 2500, scaleX: 2, scaleY: 2, tint: 0x3498db })); var rightBtn = game.addChild(LK.getAsset('powerup', { anchorX: 0.5, anchorY: 0.5, x: 400, y: 2500, scaleX: 2, scaleY: 2, tint: 0x3498db })); var upBtn = game.addChild(LK.getAsset('powerup', { anchorX: 0.5, anchorY: 0.5, x: 250, y: 2400, scaleX: 2, scaleY: 2, tint: 0x3498db })); var downBtn = game.addChild(LK.getAsset('powerup', { anchorX: 0.5, anchorY: 0.5, x: 250, y: 2600, scaleX: 2, scaleY: 2, tint: 0x3498db })); // Button event handlers leftBtn.down = function () { game.player.x = Math.max(85, game.player.x - 10); }; rightBtn.down = function () { game.player.x = Math.min(1963, game.player.x + 10); }; upBtn.down = function () { game.player.y = Math.max(85, game.player.y - 10); }; downBtn.down = function () { game.player.y = Math.min(2647, game.player.y + 10); }; // Health display var healthTxt = new Text2('HEALTH: 5', { size: 60, fill: 0x2ECC71 }); healthTxt.anchor.set(0, 0); healthTxt.x = 120; healthTxt.y = 100; LK.gui.addChild(healthTxt); // Shield display var shieldTxt = new Text2('SHIELD: 0', { size: 60, fill: 0x3498DB }); shieldTxt.anchor.set(0, 0); shieldTxt.x = 120; shieldTxt.y = 170; LK.gui.addChild(shieldTxt); // Special meter var specialTxt = new Text2('SPECIAL: 0%', { size: 60, fill: 0x9B59B6 }); specialTxt.anchor.set(0, 0); specialTxt.x = 120; specialTxt.y = 240; LK.gui.addChild(specialTxt); // Level display var levelTxt = new Text2('LEVEL 1', { size: 60, fill: 0xF1C40F }); levelTxt.anchor.set(1, 0); levelTxt.x = -120; levelTxt.y = 100; LK.gui.right.addChild(levelTxt); // Special attack button var specialBtn = game.addChild(LK.getAsset('powerup', { anchorX: 0.5, anchorY: 0.5, x: 1900, y: 2500, scaleX: 2, scaleY: 2, tint: 0x9b59b6 })); // Update UI functions game.updateScoreDisplay = function () { scoreTxt.setText('SCORE: ' + game.score); }; game.updateHealthDisplay = function () { healthTxt.setText('HEALTH: ' + game.player.health); shieldTxt.setText('SHIELD: ' + game.player.shield); }; game.updateSpecialMeter = function () { var percentage = Math.floor(game.player.specialMeter / game.player.specialMax * 100); specialTxt.setText('SPECIAL: ' + percentage + '%'); // Visual indication of special readiness if (percentage >= 100) { specialTxt.setStyle({ fill: 0xFFFFFF }); tween(specialTxt, { alpha: 0.5 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(specialTxt, { alpha: 1 }, { duration: 500, easing: tween.easeInOut }); } }); } else { specialTxt.setStyle({ fill: 0x9B59B6 }); specialTxt.alpha = 1; } }; game.updateLevelDisplay = function () { levelTxt.setText('LEVEL ' + game.level); }; // Spawn functions game.spawnEnemy = function (type) { var enemy = new Enemy(); enemy.x = 2148; // Just off-screen to the right enemy.y = 500 + Math.random() * 1400; // Random y position // Configure enemy type if (type === 'basic') { enemy.movePattern = 'none'; enemy.canShoot = false; } else if (type === 'shooter') { enemy.movePattern = 'none'; enemy.canShoot = true; enemy.enemyGraphics.tint = 0xe67e22; // Orange } else if (type === 'fast') { enemy.movePattern = 'zigzag'; enemy.speedX = -10; enemy.health = 2; enemy.enemyGraphics.tint = 0xe74c3c; // Red } else if (type === 'tank') { enemy.movePattern = 'sine'; enemy.speedX = -3; enemy.health = 12; enemy.score = 250; enemy.enemyGraphics.scaleX = 1.5; enemy.enemyGraphics.scaleY = 1.5; enemy.enemyGraphics.tint = 0x7f8c8d; // Gray } game.addChild(enemy); game.enemies.push(enemy); return enemy; }; game.spawnBoss = function () { // Only one boss at a time if (game.bossActive) { return; } game.bossActive = true; var boss = new Boss(); boss.x = 2300; // Start off-screen boss.y = 1366; // Center vertically game.addChild(boss); game.enemies.push(boss); return boss; }; game.spawnObstacle = function () { var obstacle = new Obstacle(); obstacle.x = 2148; // Just off-screen to the right obstacle.y = 400 + Math.random() * 1600; // Random y position game.addChild(obstacle); game.obstacles.push(obstacle); return obstacle; }; game.spawnPowerup = function (x, y) { var powerup = new PowerUp(); powerup.x = x; powerup.y = y; // Random powerup type var types = ['health', 'shield', 'weapon', 'special']; var weights = [0.3, 0.3, 0.2, 0.2]; // Higher chance for health/shield var total = 0; var random = Math.random(); for (var i = 0; i < types.length; i++) { total += weights[i]; if (random <= total) { powerup.type = types[i]; break; } } // Set color based on type if (powerup.type === 'health') { powerup.powerupGraphics.tint = 0x2ecc71; // Green } else if (powerup.type === 'shield') { powerup.powerupGraphics.tint = 0x3498db; // Blue } else if (powerup.type === 'weapon') { powerup.powerupGraphics.tint = 0xf1c40f; // Yellow } else if (powerup.type === 'special') { powerup.powerupGraphics.tint = 0x9b59b6; // Purple } game.addChild(powerup); game.powerups.push(powerup); return powerup; }; // Score function game.increaseScore = function (amount) { game.score += amount; game.updateScoreDisplay(); // Level up every 5000 points if (game.score > 0 && game.score % 5000 === 0) { game.levelUp(); } }; game.levelUp = function () { game.level++; game.updateLevelDisplay(); // Spawn boss every 3 levels if (game.level % 3 === 0) { game.spawnBoss(); } // Increase difficulty game.spawnRate = Math.max(60, game.spawnRate - 10); // Flash screen LK.effects.flashScreen(0xf1c40f, 500); // Yellow flash }; // Event handlers game.down = function (x, y, obj) { // Special button handling if (obj === specialBtn && game.player.specialMeter >= game.player.specialMax) { game.player.activateSpecial(); return; } // Player shooting game.player.shoot(); // Start dragging game.isDragging = true; }; game.up = function (x, y, obj) { game.isDragging = false; }; game.move = function (x, y, obj) { if (game.isDragging) { // Calculate movement based on touchpad input var deltaX = x - game.player.x; var deltaY = y - game.player.y; // Apply movement with a sensitivity factor game.player.x += deltaX * 0.1; game.player.y += deltaY * 0.1; // Ensure player stays within screen bounds game.player.x = Math.max(85, Math.min(game.player.x, 1963)); game.player.y = Math.max(85, Math.min(game.player.y, 2647)); } }; // Main game update loop game.update = function () { // Auto-shooting if (game.autoShoot) { game.autoShootTimer++; if (game.autoShootTimer >= 15) { // Every 15 frames (4 times per second) game.player.shoot(); game.autoShootTimer = 0; } } // Spawn enemies based on timer game.waveTimer++; if (!game.bossActive && game.waveTimer >= game.spawnRate) { game.waveTimer = 0; // Different enemy types based on level var types = ['basic']; if (game.level >= 2) { types.push('shooter'); } if (game.level >= 3) { types.push('fast'); } if (game.level >= 5) { types.push('tank'); } // Spawn random enemy type var type = types[Math.floor(Math.random() * types.length)]; game.spawnEnemy(type); // Occasionally spawn obstacles (10% chance) if (Math.random() < 0.1) { game.spawnObstacle(); } } // Check boss status if (game.bossActive) { var bossStillActive = false; for (var i = 0; i < game.enemies.length; i++) { if (game.enemies[i].isBoss) { bossStillActive = true; break; } } game.bossActive = bossStillActive; } // Check collisions // Player bullets vs enemies for (var i = game.playerBullets.length - 1; i >= 0; i--) { var bullet = game.playerBullets[i]; // Skip destroyed bullets if (!bullet.parent) { game.playerBullets.splice(i, 1); continue; } for (var j = game.enemies.length - 1; j >= 0; j--) { var enemy = game.enemies[j]; // Skip destroyed enemies if (!enemy.parent) { game.enemies.splice(j, 1); continue; } if (bullet.intersects(enemy)) { enemy.takeDamage(bullet.damage); bullet.destroy(); game.playerBullets.splice(i, 1); break; } } } // Special attacks vs enemies for (var i = game.specialAttacks.length - 1; i >= 0; i--) { var special = game.specialAttacks[i]; // Skip destroyed specials if (!special.parent) { game.specialAttacks.splice(i, 1); continue; } for (var j = game.enemies.length - 1; j >= 0; j--) { var enemy = game.enemies[j]; // Skip destroyed enemies if (!enemy.parent) { game.enemies.splice(j, 1); continue; } if (special.intersects(enemy)) { enemy.takeDamage(special.damage); } } // Special clears enemy bullets too for (var j = game.enemyBullets.length - 1; j >= 0; j--) { var bullet = game.enemyBullets[j]; // Skip destroyed bullets if (!bullet.parent) { game.enemyBullets.splice(j, 1); continue; } if (special.intersects(bullet)) { bullet.destroy(); game.enemyBullets.splice(j, 1); } } } // Enemy bullets vs player for (var i = game.enemyBullets.length - 1; i >= 0; i--) { var bullet = game.enemyBullets[i]; // Skip destroyed bullets if (!bullet.parent) { game.enemyBullets.splice(i, 1); continue; } if (bullet.intersects(game.player)) { game.player.takeDamage(); bullet.destroy(); game.enemyBullets.splice(i, 1); } } // Obstacles vs player for (var i = game.obstacles.length - 1; i >= 0; i--) { var obstacle = game.obstacles[i]; // Skip destroyed obstacles if (!obstacle.parent) { game.obstacles.splice(i, 1); continue; } if (obstacle.intersects(game.player)) { game.player.takeDamage(); obstacle.destroy(); game.obstacles.splice(i, 1); } } // Powerups vs player for (var i = game.powerups.length - 1; i >= 0; i--) { var powerup = game.powerups[i]; // Skip destroyed powerups if (!powerup.parent) { game.powerups.splice(i, 1); continue; } if (powerup.intersects(game.player)) { game.player.collectPowerup(powerup); powerup.destroy(); game.powerups.splice(i, 1); } } // Remove destroyed enemies from array for (var i = game.enemies.length - 1; i >= 0; i--) { if (!game.enemies[i].parent) { game.enemies.splice(i, 1); } } // Update arrays of objects that might be removed game.playerBullets = game.playerBullets.filter(function (bullet) { return bullet.parent !== null; }); game.enemyBullets = game.enemyBullets.filter(function (bullet) { return bullet.parent !== null; }); game.obstacles = game.obstacles.filter(function (obstacle) { return obstacle.parent !== null; }); game.powerups = game.powerups.filter(function (powerup) { return powerup.parent !== null; }); game.specialAttacks = game.specialAttacks.filter(function (special) { return special.parent !== null; }); // Gentle parallax scrolling for background background.x -= 0.5; if (background.x <= 0) { background.x = 1024; } }; // Initialize displays game.updateScoreDisplay(); game.updateHealthDisplay(); game.updateSpecialMeter(); game.updateLevelDisplay(); // Start background music LK.playMusic('bgm');
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
lastScore: 0
});
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
self.bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 20;
self.damage = 1;
self.isPlayerBullet = true;
self.update = function () {
self.x += self.speed;
// Auto destroy when off screen
if (self.x > 2148) {
self.destroy();
}
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
self.enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = -5;
self.speedY = 0;
self.health = 5;
self.score = 100;
self.canShoot = false;
self.shootTimer = 0;
self.shootInterval = 120; // 2 seconds at 60fps
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
// Simple movement pattern
if (self.movePattern === 'sine') {
self.y += Math.sin(LK.ticks * 0.05) * 2;
} else if (self.movePattern === 'zigzag') {
if (LK.ticks % 60 === 0) {
self.speedY = -self.speedY || (Math.random() > 0.5 ? 3 : -3);
}
}
// Shooting logic
if (self.canShoot) {
self.shootTimer++;
if (self.shootTimer >= self.shootInterval) {
self.shootTimer = 0;
self.shoot();
}
}
// Auto destroy when off screen
if (self.x < -100) {
self.destroy();
}
};
self.shoot = function () {
if (!game) {
return;
}
var bullet = new Bullet();
bullet.x = self.x - 20;
bullet.y = self.y;
bullet.speed = -15;
bullet.isPlayerBullet = false;
bullet.bulletGraphics.tint = 0xff0000; // Red enemy bullets
game.addChild(bullet);
game.enemyBullets.push(bullet);
};
self.takeDamage = function (damage) {
self.health -= damage;
// Flash red when taking damage
LK.effects.flashObject(self, 0xff0000, 200);
if (self.health <= 0) {
// Explosion effect
LK.getSound('explosion').play();
LK.effects.flashObject(self, 0xffffff, 300);
// Add score
game.increaseScore(self.score);
// Potentially drop powerup (20% chance)
if (Math.random() < 0.2) {
game.spawnPowerup(self.x, self.y);
}
self.destroy();
}
};
return self;
});
var Boss = Enemy.expand(function () {
var self = Enemy.call(this);
// Replace graphics with boss graphic
self.enemyGraphics.destroy();
self.enemyGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 75;
self.score = 2000;
self.speedX = -2;
self.canShoot = true;
self.shootInterval = 60; // 1 second at 60fps
self.phase = 1;
self.phaseTimer = 0;
self.isBoss = true;
// Override update function
self.update = function () {
self.phaseTimer++;
// Boss movement based on phases
if (self.phase === 1) {
// Enter the screen
if (self.x > 1600) {
self.x += self.speedX;
} else {
self.phase = 2;
self.phaseTimer = 0;
}
} else if (self.phase === 2) {
// Move up and down
self.y += Math.sin(self.phaseTimer * 0.03) * 4;
// Shooting pattern
if (self.phaseTimer % 20 === 0) {
self.shoot();
}
// Phase transition
if (self.phaseTimer > 300) {
self.phase = 3;
self.phaseTimer = 0;
}
} else if (self.phase === 3) {
// Charge at player
if (self.phaseTimer < 60) {
// Prepare
self.speedX = 0;
} else if (self.phaseTimer < 120) {
// Charge
self.x -= 15;
} else {
// Return to position
if (self.x < 1600) {
self.x += 5;
} else {
self.phase = 2;
self.phaseTimer = 0;
}
}
}
// Health-based phase changes
if (self.health < 25 && self.shootInterval > 40) {
self.shootInterval = 40; // Shoot faster when at low health
}
};
// Override shoot function for more complex patterns
self.shoot = function () {
if (!game) {
return;
}
// Different shooting patterns based on phase
if (self.phase === 2) {
// Spread shot
for (var i = -2; i <= 2; i++) {
var bullet = new Bullet();
bullet.x = self.x - 50;
bullet.y = self.y;
bullet.speed = -15;
bullet.speedY = i * 2;
bullet.isPlayerBullet = false;
bullet.bulletGraphics.tint = 0xff0000;
// Custom update for diagonal movement
var originalUpdate = bullet.update;
bullet.update = function () {
this.x += this.speed;
this.y += this.speedY;
// Off screen check
if (this.x < -100 || this.y < -100 || this.y > 2832) {
this.destroy();
}
};
game.addChild(bullet);
game.enemyBullets.push(bullet);
}
} else if (self.phase === 3) {
// Aimed shot at player
var bullet = new Bullet();
bullet.x = self.x - 50;
bullet.y = self.y;
// Calculate angle to player
var dx = game.player.x - bullet.x;
var dy = game.player.y - bullet.y;
var angle = Math.atan2(dy, dx);
bullet.speed = -15 * Math.cos(angle);
bullet.speedY = 15 * Math.sin(angle);
bullet.isPlayerBullet = false;
bullet.bulletGraphics.tint = 0xff5500; // Orange for aimed shots
// Custom update for angle-based movement
bullet.update = function () {
this.x += this.speed;
this.y += this.speedY;
// Off screen check
if (this.x < -100 || this.y < -100 || this.y > 2832) {
this.destroy();
}
};
game.addChild(bullet);
game.enemyBullets.push(bullet);
}
LK.getSound('shoot').play();
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
self.obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -8;
self.update = function () {
self.x += self.speed;
// Auto destroy when off screen
if (self.x < -100) {
self.destroy();
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
self.playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 5;
self.maxHealth = 5;
self.shield = 0;
self.weaponLevel = 1;
self.specialMeter = 0;
self.specialMax = 100;
self.shootCooldown = 0;
self.invulnerable = 0;
self.update = function () {
// Shooting cooldown
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
// Invulnerability frames
if (self.invulnerable > 0) {
self.invulnerable--;
// Flash effect during invulnerability
if (LK.ticks % 5 === 0) {
self.playerGraphics.alpha = self.playerGraphics.alpha === 1 ? 0.5 : 1;
}
} else {
self.playerGraphics.alpha = 1;
}
// Gentle hover effect
self.y += Math.sin(LK.ticks * 0.05) * 0.5;
};
self.shoot = function () {
if (self.shootCooldown > 0) {
return;
}
LK.getSound('shoot').play();
// Different shooting patterns based on weapon level
if (self.weaponLevel === 1) {
// Single shot
var bullet = new Bullet();
bullet.x = self.x + 50;
bullet.y = self.y;
game.addChild(bullet);
game.playerBullets.push(bullet);
self.shootCooldown = 10;
} else if (self.weaponLevel === 2) {
// Double shot
for (var i = -1; i <= 1; i += 2) {
var bullet = new Bullet();
bullet.x = self.x + 50;
bullet.y = self.y + i * 20;
game.addChild(bullet);
game.playerBullets.push(bullet);
}
self.shootCooldown = 8;
} else if (self.weaponLevel >= 3) {
// Triple shot
var center = new Bullet();
center.x = self.x + 60;
center.y = self.y;
game.addChild(center);
game.playerBullets.push(center);
for (var i = -1; i <= 1; i += 2) {
var side = new Bullet();
side.x = self.x + 40;
side.y = self.y + i * 30;
game.addChild(side);
game.playerBullets.push(side);
}
self.shootCooldown = 6;
}
// Increase special meter slightly with each shot
self.specialMeter = Math.min(self.specialMeter + 1, self.specialMax);
game.updateSpecialMeter();
};
self.activateSpecial = function () {
if (self.specialMeter < self.specialMax) {
return;
}
LK.getSound('special').play();
// Create special attack
var special = new SpecialAttack();
special.x = self.x;
special.y = self.y;
game.addChild(special);
game.specialAttacks.push(special);
// Make player briefly invulnerable
self.invulnerable = 60;
// Reset special meter
self.specialMeter = 0;
game.updateSpecialMeter();
};
self.takeDamage = function () {
if (self.invulnerable > 0) {
return;
}
// Shield absorbs damage first
if (self.shield > 0) {
self.shield--;
LK.getSound('damage').play();
LK.effects.flashObject(self, 0x3498db, 300); // Blue flash for shield hit
} else {
self.health--;
LK.getSound('damage').play();
LK.effects.flashObject(self, 0xff0000, 300); // Red flash for health hit
// Set invulnerability frames
self.invulnerable = 60;
// Game over check
if (self.health <= 0) {
// Store score
storage.lastScore = game.score;
if (game.score > storage.highScore) {
storage.highScore = game.score;
}
LK.showGameOver();
}
}
game.updateHealthDisplay();
};
self.collectPowerup = function (powerup) {
LK.getSound('powerup').play();
if (powerup.type === 'health') {
self.health = Math.min(self.health + 1, self.maxHealth);
} else if (powerup.type === 'shield') {
self.shield = Math.min(self.shield + 2, 3); // Max 3 shield points
} else if (powerup.type === 'weapon') {
self.weaponLevel = Math.min(self.weaponLevel + 1, 3);
} else if (powerup.type === 'special') {
self.specialMeter = self.specialMax; // Fill special meter
}
game.updateHealthDisplay();
game.updateSpecialMeter();
// Visual effect
LK.effects.flashObject(self, 0xffffff, 300);
};
// Touch/mouse controls
self.down = function (x, y, obj) {
game.isDragging = true;
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
self.powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -3;
self.type = 'health'; // Default power-up type
// Set color based on type
if (self.type === 'health') {
self.powerupGraphics.tint = 0x2ecc71; // Green
} else if (self.type === 'shield') {
self.powerupGraphics.tint = 0x3498db; // Blue
} else if (self.type === 'weapon') {
self.powerupGraphics.tint = 0xf1c40f; // Yellow
} else if (self.type === 'special') {
self.powerupGraphics.tint = 0x9b59b6; // Purple
}
self.update = function () {
self.x += self.speed;
// Gentle floating effect
self.y += Math.sin(LK.ticks * 0.1) * 0.5;
// Auto destroy when off screen
if (self.x < -100) {
self.destroy();
}
};
return self;
});
var SpecialAttack = Container.expand(function () {
var self = Container.call(this);
self.attackGraphics = self.attachAsset('specialAttack', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7
});
self.duration = 60; // 1 second at 60fps
self.counter = 0;
self.damage = 5;
self.update = function () {
self.counter++;
self.x += 10;
// Flash effect
if (self.counter % 5 === 0) {
self.attackGraphics.alpha = self.attackGraphics.alpha === 0.7 ? 0.9 : 0.7;
}
// Auto destroy when duration ends
if (self.counter >= self.duration) {
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0e0e2a
});
/****
* Game Code
****/
// Game variables
game.score = 0;
game.level = 1;
game.waveTimer = 0;
game.bossActive = false;
game.spawnRate = 120; // Enemy spawn rate (frames)
game.isDragging = false;
game.autoShoot = true;
game.autoShootTimer = 0;
// Array containers for game objects
game.playerBullets = [];
game.enemyBullets = [];
game.enemies = [];
game.powerups = [];
game.obstacles = [];
game.specialAttacks = [];
// Create background
var background = game.addChild(LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
}));
// Create player
game.player = new Player();
game.player.x = 300;
game.player.y = 1366; // Center vertically
game.addChild(game.player);
// Create UI
// Score display
var scoreTxt = new Text2('SCORE: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create touch screen buttons for movement
var leftBtn = game.addChild(LK.getAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
x: 100,
y: 2500,
scaleX: 2,
scaleY: 2,
tint: 0x3498db
}));
var rightBtn = game.addChild(LK.getAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
x: 400,
y: 2500,
scaleX: 2,
scaleY: 2,
tint: 0x3498db
}));
var upBtn = game.addChild(LK.getAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
x: 250,
y: 2400,
scaleX: 2,
scaleY: 2,
tint: 0x3498db
}));
var downBtn = game.addChild(LK.getAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
x: 250,
y: 2600,
scaleX: 2,
scaleY: 2,
tint: 0x3498db
}));
// Button event handlers
leftBtn.down = function () {
game.player.x = Math.max(85, game.player.x - 10);
};
rightBtn.down = function () {
game.player.x = Math.min(1963, game.player.x + 10);
};
upBtn.down = function () {
game.player.y = Math.max(85, game.player.y - 10);
};
downBtn.down = function () {
game.player.y = Math.min(2647, game.player.y + 10);
};
// Health display
var healthTxt = new Text2('HEALTH: 5', {
size: 60,
fill: 0x2ECC71
});
healthTxt.anchor.set(0, 0);
healthTxt.x = 120;
healthTxt.y = 100;
LK.gui.addChild(healthTxt);
// Shield display
var shieldTxt = new Text2('SHIELD: 0', {
size: 60,
fill: 0x3498DB
});
shieldTxt.anchor.set(0, 0);
shieldTxt.x = 120;
shieldTxt.y = 170;
LK.gui.addChild(shieldTxt);
// Special meter
var specialTxt = new Text2('SPECIAL: 0%', {
size: 60,
fill: 0x9B59B6
});
specialTxt.anchor.set(0, 0);
specialTxt.x = 120;
specialTxt.y = 240;
LK.gui.addChild(specialTxt);
// Level display
var levelTxt = new Text2('LEVEL 1', {
size: 60,
fill: 0xF1C40F
});
levelTxt.anchor.set(1, 0);
levelTxt.x = -120;
levelTxt.y = 100;
LK.gui.right.addChild(levelTxt);
// Special attack button
var specialBtn = game.addChild(LK.getAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
x: 1900,
y: 2500,
scaleX: 2,
scaleY: 2,
tint: 0x9b59b6
}));
// Update UI functions
game.updateScoreDisplay = function () {
scoreTxt.setText('SCORE: ' + game.score);
};
game.updateHealthDisplay = function () {
healthTxt.setText('HEALTH: ' + game.player.health);
shieldTxt.setText('SHIELD: ' + game.player.shield);
};
game.updateSpecialMeter = function () {
var percentage = Math.floor(game.player.specialMeter / game.player.specialMax * 100);
specialTxt.setText('SPECIAL: ' + percentage + '%');
// Visual indication of special readiness
if (percentage >= 100) {
specialTxt.setStyle({
fill: 0xFFFFFF
});
tween(specialTxt, {
alpha: 0.5
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(specialTxt, {
alpha: 1
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
} else {
specialTxt.setStyle({
fill: 0x9B59B6
});
specialTxt.alpha = 1;
}
};
game.updateLevelDisplay = function () {
levelTxt.setText('LEVEL ' + game.level);
};
// Spawn functions
game.spawnEnemy = function (type) {
var enemy = new Enemy();
enemy.x = 2148; // Just off-screen to the right
enemy.y = 500 + Math.random() * 1400; // Random y position
// Configure enemy type
if (type === 'basic') {
enemy.movePattern = 'none';
enemy.canShoot = false;
} else if (type === 'shooter') {
enemy.movePattern = 'none';
enemy.canShoot = true;
enemy.enemyGraphics.tint = 0xe67e22; // Orange
} else if (type === 'fast') {
enemy.movePattern = 'zigzag';
enemy.speedX = -10;
enemy.health = 2;
enemy.enemyGraphics.tint = 0xe74c3c; // Red
} else if (type === 'tank') {
enemy.movePattern = 'sine';
enemy.speedX = -3;
enemy.health = 12;
enemy.score = 250;
enemy.enemyGraphics.scaleX = 1.5;
enemy.enemyGraphics.scaleY = 1.5;
enemy.enemyGraphics.tint = 0x7f8c8d; // Gray
}
game.addChild(enemy);
game.enemies.push(enemy);
return enemy;
};
game.spawnBoss = function () {
// Only one boss at a time
if (game.bossActive) {
return;
}
game.bossActive = true;
var boss = new Boss();
boss.x = 2300; // Start off-screen
boss.y = 1366; // Center vertically
game.addChild(boss);
game.enemies.push(boss);
return boss;
};
game.spawnObstacle = function () {
var obstacle = new Obstacle();
obstacle.x = 2148; // Just off-screen to the right
obstacle.y = 400 + Math.random() * 1600; // Random y position
game.addChild(obstacle);
game.obstacles.push(obstacle);
return obstacle;
};
game.spawnPowerup = function (x, y) {
var powerup = new PowerUp();
powerup.x = x;
powerup.y = y;
// Random powerup type
var types = ['health', 'shield', 'weapon', 'special'];
var weights = [0.3, 0.3, 0.2, 0.2]; // Higher chance for health/shield
var total = 0;
var random = Math.random();
for (var i = 0; i < types.length; i++) {
total += weights[i];
if (random <= total) {
powerup.type = types[i];
break;
}
}
// Set color based on type
if (powerup.type === 'health') {
powerup.powerupGraphics.tint = 0x2ecc71; // Green
} else if (powerup.type === 'shield') {
powerup.powerupGraphics.tint = 0x3498db; // Blue
} else if (powerup.type === 'weapon') {
powerup.powerupGraphics.tint = 0xf1c40f; // Yellow
} else if (powerup.type === 'special') {
powerup.powerupGraphics.tint = 0x9b59b6; // Purple
}
game.addChild(powerup);
game.powerups.push(powerup);
return powerup;
};
// Score function
game.increaseScore = function (amount) {
game.score += amount;
game.updateScoreDisplay();
// Level up every 5000 points
if (game.score > 0 && game.score % 5000 === 0) {
game.levelUp();
}
};
game.levelUp = function () {
game.level++;
game.updateLevelDisplay();
// Spawn boss every 3 levels
if (game.level % 3 === 0) {
game.spawnBoss();
}
// Increase difficulty
game.spawnRate = Math.max(60, game.spawnRate - 10);
// Flash screen
LK.effects.flashScreen(0xf1c40f, 500); // Yellow flash
};
// Event handlers
game.down = function (x, y, obj) {
// Special button handling
if (obj === specialBtn && game.player.specialMeter >= game.player.specialMax) {
game.player.activateSpecial();
return;
}
// Player shooting
game.player.shoot();
// Start dragging
game.isDragging = true;
};
game.up = function (x, y, obj) {
game.isDragging = false;
};
game.move = function (x, y, obj) {
if (game.isDragging) {
// Calculate movement based on touchpad input
var deltaX = x - game.player.x;
var deltaY = y - game.player.y;
// Apply movement with a sensitivity factor
game.player.x += deltaX * 0.1;
game.player.y += deltaY * 0.1;
// Ensure player stays within screen bounds
game.player.x = Math.max(85, Math.min(game.player.x, 1963));
game.player.y = Math.max(85, Math.min(game.player.y, 2647));
}
};
// Main game update loop
game.update = function () {
// Auto-shooting
if (game.autoShoot) {
game.autoShootTimer++;
if (game.autoShootTimer >= 15) {
// Every 15 frames (4 times per second)
game.player.shoot();
game.autoShootTimer = 0;
}
}
// Spawn enemies based on timer
game.waveTimer++;
if (!game.bossActive && game.waveTimer >= game.spawnRate) {
game.waveTimer = 0;
// Different enemy types based on level
var types = ['basic'];
if (game.level >= 2) {
types.push('shooter');
}
if (game.level >= 3) {
types.push('fast');
}
if (game.level >= 5) {
types.push('tank');
}
// Spawn random enemy type
var type = types[Math.floor(Math.random() * types.length)];
game.spawnEnemy(type);
// Occasionally spawn obstacles (10% chance)
if (Math.random() < 0.1) {
game.spawnObstacle();
}
}
// Check boss status
if (game.bossActive) {
var bossStillActive = false;
for (var i = 0; i < game.enemies.length; i++) {
if (game.enemies[i].isBoss) {
bossStillActive = true;
break;
}
}
game.bossActive = bossStillActive;
}
// Check collisions
// Player bullets vs enemies
for (var i = game.playerBullets.length - 1; i >= 0; i--) {
var bullet = game.playerBullets[i];
// Skip destroyed bullets
if (!bullet.parent) {
game.playerBullets.splice(i, 1);
continue;
}
for (var j = game.enemies.length - 1; j >= 0; j--) {
var enemy = game.enemies[j];
// Skip destroyed enemies
if (!enemy.parent) {
game.enemies.splice(j, 1);
continue;
}
if (bullet.intersects(enemy)) {
enemy.takeDamage(bullet.damage);
bullet.destroy();
game.playerBullets.splice(i, 1);
break;
}
}
}
// Special attacks vs enemies
for (var i = game.specialAttacks.length - 1; i >= 0; i--) {
var special = game.specialAttacks[i];
// Skip destroyed specials
if (!special.parent) {
game.specialAttacks.splice(i, 1);
continue;
}
for (var j = game.enemies.length - 1; j >= 0; j--) {
var enemy = game.enemies[j];
// Skip destroyed enemies
if (!enemy.parent) {
game.enemies.splice(j, 1);
continue;
}
if (special.intersects(enemy)) {
enemy.takeDamage(special.damage);
}
}
// Special clears enemy bullets too
for (var j = game.enemyBullets.length - 1; j >= 0; j--) {
var bullet = game.enemyBullets[j];
// Skip destroyed bullets
if (!bullet.parent) {
game.enemyBullets.splice(j, 1);
continue;
}
if (special.intersects(bullet)) {
bullet.destroy();
game.enemyBullets.splice(j, 1);
}
}
}
// Enemy bullets vs player
for (var i = game.enemyBullets.length - 1; i >= 0; i--) {
var bullet = game.enemyBullets[i];
// Skip destroyed bullets
if (!bullet.parent) {
game.enemyBullets.splice(i, 1);
continue;
}
if (bullet.intersects(game.player)) {
game.player.takeDamage();
bullet.destroy();
game.enemyBullets.splice(i, 1);
}
}
// Obstacles vs player
for (var i = game.obstacles.length - 1; i >= 0; i--) {
var obstacle = game.obstacles[i];
// Skip destroyed obstacles
if (!obstacle.parent) {
game.obstacles.splice(i, 1);
continue;
}
if (obstacle.intersects(game.player)) {
game.player.takeDamage();
obstacle.destroy();
game.obstacles.splice(i, 1);
}
}
// Powerups vs player
for (var i = game.powerups.length - 1; i >= 0; i--) {
var powerup = game.powerups[i];
// Skip destroyed powerups
if (!powerup.parent) {
game.powerups.splice(i, 1);
continue;
}
if (powerup.intersects(game.player)) {
game.player.collectPowerup(powerup);
powerup.destroy();
game.powerups.splice(i, 1);
}
}
// Remove destroyed enemies from array
for (var i = game.enemies.length - 1; i >= 0; i--) {
if (!game.enemies[i].parent) {
game.enemies.splice(i, 1);
}
}
// Update arrays of objects that might be removed
game.playerBullets = game.playerBullets.filter(function (bullet) {
return bullet.parent !== null;
});
game.enemyBullets = game.enemyBullets.filter(function (bullet) {
return bullet.parent !== null;
});
game.obstacles = game.obstacles.filter(function (obstacle) {
return obstacle.parent !== null;
});
game.powerups = game.powerups.filter(function (powerup) {
return powerup.parent !== null;
});
game.specialAttacks = game.specialAttacks.filter(function (special) {
return special.parent !== null;
});
// Gentle parallax scrolling for background
background.x -= 0.5;
if (background.x <= 0) {
background.x = 1024;
}
};
// Initialize displays
game.updateScoreDisplay();
game.updateHealthDisplay();
game.updateSpecialMeter();
game.updateLevelDisplay();
// Start background music
LK.playMusic('bgm');
2d anime style image about earth from space with full of stars Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
red robot look like gundam shoot enemy. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
asteroid with fire cracks. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
electrical alien amoeba. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
amazing gold stone. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
horizontal branch of red light thunder anime style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
black hole with evil face. anime style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows