/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 50; self.damage = 1; self.active = true; self.update = function () { if (!self.active) { return; } self.x += self.xVelocity; self.y += self.yVelocity; // Remove if off screen if (self.y < -100) { self.active = false; } }; return self; }); var Cannon = Container.expand(function () { var self = Container.call(this); // Create base var base = self.attachAsset('cannonBase', { anchorX: 0.5, anchorY: 0.5, y: 50 }); // Create cannon var cannon = self.attachAsset('cannon', { anchorX: 0.5, anchorY: 0.8, y: 0 }); self.canFire = true; self.cooldown = 500; // ms self.rotateCannon = function (targetX) { // Calculate rotation angle based on target x position var dx = targetX - self.x; var maxRotation = Math.PI / 4; // 45 degrees // Limit rotation to +/- 45 degrees var rotation = Math.max(-maxRotation, Math.min(maxRotation, dx / 500)); // Apply rotation tween(cannon, { rotation: rotation }, { duration: 100, easing: tween.easeOut }); }; self.fire = function () { if (!self.canFire) { return null; } // Calculate bullet spawn position based on cannon rotation var spawnX = self.x + Math.sin(cannon.rotation) * 70; var spawnY = self.y - Math.cos(cannon.rotation) * 70 - 30; var directions = [-0.2, 0, 0.2]; // Adjust angles for reduced bullet storm for (var i = 0; i < directions.length; i++) { var angle = cannon.rotation + directions[i]; var bullet = new Bullet(); bullet.x = spawnX; bullet.y = spawnY; bullet.rotation = angle; // Apply velocity vector based on adjusted angle bullet.xVelocity = Math.sin(angle) * bullet.speed; bullet.yVelocity = -Math.cos(angle) * bullet.speed; bullets.push(bullet); game.addChild(bullet); } // Start cooldown self.canFire = false; LK.setTimeout(function () { self.canFire = true; }, self.cooldown); LK.getSound('shoot').play(); return bullet; }; self.down = function (x, y, obj) { // Allow cannon to move horizontally based on touch/click position self.x = x; }; return self; }); var UFO = Container.expand(function () { var self = Container.call(this); var ufoGraphics = self.attachAsset('ufo', { anchorX: 0.5, anchorY: 0.5 }); self.health = 1; self.speed = 2; self.points = 10; self.active = true; // Random horizontal movement pattern self.xDirection = Math.random() > 0.5 ? 1 : -1; self.xSpeed = Math.random() * 2 + 1; self.wobbleAmount = Math.random() * 30; self.wobbleSpeed = Math.random() * 0.1; self.initialX = 0; self.update = function () { if (!self.active) { return; } // Move downward self.y += self.speed; // Horizontal wobble movement if (self.initialX === 0) { self.initialX = self.x; } self.x += self.xDirection * self.xSpeed; self.x = self.initialX + Math.sin(LK.ticks * self.wobbleSpeed) * self.wobbleAmount; // Rotate slightly for visual effect self.rotation = Math.sin(LK.ticks * 0.05) * 0.1; // Reverse direction if reaching screen edges if (self.x < 0 || self.x > 2048) { self.xDirection *= -1; } if (self.y > 2800) { self.active = false; } }; self.takeDamage = function (amount) { self.health -= amount; // Flash the UFO when hit LK.effects.flashObject(self, 0xffffff, 300); if (self.health <= 0) { self.explode(); } return self.health <= 0; }; self.explode = function () { self.active = false; LK.getSound('explosion').play(); // Create explosion effect var explosion = LK.getAsset('explosion', { anchorX: 0.5, anchorY: 0.5, x: self.x, y: self.y, alpha: 0.8 }); game.addChild(explosion); // Animate explosion tween(explosion, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { explosion.destroy(); } }); }; return self; }); var EliteUFO = UFO.expand(function () { var self = UFO.call(this); // Override UFO properties self.health = 3; self.speed = 1.5; self.points = 30; // Change color to indicate elite status self.children[0].tint = 0xff00ff; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000022 }); /**** * Game Code ****/ // Game state var cannon; var bullets = []; var ufos = []; var score = 0; var wave = 1; var waveTimer = 0; var waveDelay = 180; // 3 seconds at 60 fps var gameActive = true; // UI elements var scoreTxt; var waveTxt; // Initialize game background function setupBackground() { // Stars background var stars = LK.getAsset('stars', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); game.addChild(stars); // Moon surface var moon = LK.getAsset('moon', { anchorX: 0.5, anchorY: 0, x: 2048 / 2, y: 2732 - 400 }); game.addChild(moon); } // Initialize game UI function setupUI() { // Score display scoreTxt = new Text2('Score: 0', { size: 70, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); scoreTxt.x = -300; scoreTxt.y = 50; // Wave display waveTxt = new Text2('Wave: 1', { size: 60, fill: 0xFFFFFF }); waveTxt.anchor.set(0, 0); LK.gui.topRight.addChild(waveTxt); waveTxt.x = -300; waveTxt.y = 120; } // Spawn a new wave of UFOs function spawnWave() { var ufoCount = 5 + Math.floor(wave * 1.5); var eliteCount = Math.floor(wave / 3); for (var i = 0; i < ufoCount; i++) { // Determine if this should be an elite UFO var isElite = i < eliteCount; var ufo = isElite ? new EliteUFO() : new UFO(); // Position randomly across top of screen ufo.x = Math.random() * (2048 - 300) + 150; ufo.y = -100 - Math.random() * 500; // Stagger vertical starting positions // Adjust speed based on wave ufo.speed = ufo.speed * (1 + wave * 0.1); ufos.push(ufo); game.addChild(ufo); } // Update wave counter wave++; waveTxt.setText('Wave: ' + wave); // Show wave notification var waveNotification = new Text2('WAVE ' + wave, { size: 120, fill: 0xFFCC00 }); waveNotification.anchor.set(0.5, 0.5); waveNotification.x = 2048 / 2; waveNotification.y = 2732 / 2 - 200; LK.gui.center.addChild(waveNotification); // Animate wave notification tween(waveNotification, { scaleX: 1.5, scaleY: 1.5 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { tween(waveNotification, { alpha: 0 }, { duration: 500, easing: tween.easeIn, onFinish: function onFinish() { waveNotification.destroy(); } }); } }); } // Update special weapon charge display // Initialize the game function initGame() { setupBackground(); // Create player cannon cannon = new Cannon(); cannon.x = 2048 / 2; cannon.y = 2732 - 100; game.addChild(cannon); setupUI(); // Start background music LK.playMusic('gameBgm', { fade: { start: 0, end: 0.3, duration: 1000 } }); // Spawn initial wave spawnWave(); } // Handle game input function handleInput(x, y) { if (!gameActive || !cannon) { return; } // Rotate cannon toward cursor/touch position cannon.rotateCannon(x); } // Fire a bullet function fireBullet() { if (!gameActive || !cannon) { return; } var bullet = cannon.fire(); if (bullet) { bullets.push(bullet); game.addChild(bullet); } } // Fire special weapon // Process collisions between bullets and UFOs function processCollisions() { // Check regular bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (!bullet.active) { continue; } for (var j = ufos.length - 1; j >= 0; j--) { var ufo = ufos[j]; if (!ufo.active) { continue; } if (bullet.intersects(ufo)) { if (ufo.takeDamage(bullet.damage)) { // UFO destroyed score += ufo.points; scoreTxt.setText('Score: ' + score); // Remove UFO ufo.explode(); // Trigger explosion effect ufos.splice(j, 1); ufo.destroy(); // Ensure UFO is destroyed } // Remove bullet bullet.active = false; bullets.splice(i, 1); bullet.destroy(); break; } } } } // Check if any UFOs reached the moon base function checkMoonBaseCollisions() { for (var i = ufos.length - 1; i >= 0; i--) { var ufo = ufos[i]; if (!ufo.active) { continue; } // Check if UFO reached the moon's surface if (ufo.y > 2732 - 400) { // Game over if UFO touches the moon gameActive = false; // Flash the screen red LK.effects.flashScreen(0xff0000, 1000); // Show game over after a short delay LK.setTimeout(function () { // Removed final score display LK.showGameOver(); }, 1500); break; } } } // Clean up inactive objects function cleanupObjects() { // Clean up bullets for (var i = bullets.length - 1; i >= 0; i--) { if (!bullets[i].active) { bullets[i].destroy(); bullets.splice(i, 1); } } // Clean up UFOs for (var i = ufos.length - 1; i >= 0; i--) { if (!ufos[i].active) { ufos[i].destroy(); ufos.splice(i, 1); } } } // Move handler for tracking input position function handleMove(x, y, obj) { handleInput(x, y); } // Down handler for firing function handleDown(x, y, obj) { handleInput(x, y); fireBullet(); } // Set up event handlers game.move = handleMove; game.down = handleDown; function handleUp(x, y, obj) { // Add any necessary logic for handling the 'up' event here } game.up = handleUp; // Main game update loop game.update = function () { if (!gameActive) { return; } // Update special weapon UI function updateSpecialWeaponUI() { // Placeholder for updating special weapon UI logic // This function can be expanded with actual UI update logic if needed } updateSpecialWeaponUI(); // Update bullets for (var i = 0; i < bullets.length; i++) { bullets[i].update(); } // Update UFOs for (var i = 0; i < ufos.length; i++) { ufos[i].update(); } // Process collisions processCollisions(); // Check if UFOs reached the moon base checkMoonBaseCollisions(); // Clean up inactive objects cleanupObjects(); // Spawn a new wave if all UFOs are destroyed if (ufos.length === 0) { if (waveTimer < waveDelay) { waveTimer++; } else { waveTimer = 0; spawnWave(); } } // Win condition (example: after wave 10) if (wave > 10 && ufos.length === 0) { gameActive = false; LK.setTimeout(function () { LK.showYouWin(); }, 1000); } }; // Initialize the game initGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 50;
self.damage = 1;
self.active = true;
self.update = function () {
if (!self.active) {
return;
}
self.x += self.xVelocity;
self.y += self.yVelocity;
// Remove if off screen
if (self.y < -100) {
self.active = false;
}
};
return self;
});
var Cannon = Container.expand(function () {
var self = Container.call(this);
// Create base
var base = self.attachAsset('cannonBase', {
anchorX: 0.5,
anchorY: 0.5,
y: 50
});
// Create cannon
var cannon = self.attachAsset('cannon', {
anchorX: 0.5,
anchorY: 0.8,
y: 0
});
self.canFire = true;
self.cooldown = 500; // ms
self.rotateCannon = function (targetX) {
// Calculate rotation angle based on target x position
var dx = targetX - self.x;
var maxRotation = Math.PI / 4; // 45 degrees
// Limit rotation to +/- 45 degrees
var rotation = Math.max(-maxRotation, Math.min(maxRotation, dx / 500));
// Apply rotation
tween(cannon, {
rotation: rotation
}, {
duration: 100,
easing: tween.easeOut
});
};
self.fire = function () {
if (!self.canFire) {
return null;
}
// Calculate bullet spawn position based on cannon rotation
var spawnX = self.x + Math.sin(cannon.rotation) * 70;
var spawnY = self.y - Math.cos(cannon.rotation) * 70 - 30;
var directions = [-0.2, 0, 0.2]; // Adjust angles for reduced bullet storm
for (var i = 0; i < directions.length; i++) {
var angle = cannon.rotation + directions[i];
var bullet = new Bullet();
bullet.x = spawnX;
bullet.y = spawnY;
bullet.rotation = angle;
// Apply velocity vector based on adjusted angle
bullet.xVelocity = Math.sin(angle) * bullet.speed;
bullet.yVelocity = -Math.cos(angle) * bullet.speed;
bullets.push(bullet);
game.addChild(bullet);
}
// Start cooldown
self.canFire = false;
LK.setTimeout(function () {
self.canFire = true;
}, self.cooldown);
LK.getSound('shoot').play();
return bullet;
};
self.down = function (x, y, obj) {
// Allow cannon to move horizontally based on touch/click position
self.x = x;
};
return self;
});
var UFO = Container.expand(function () {
var self = Container.call(this);
var ufoGraphics = self.attachAsset('ufo', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 1;
self.speed = 2;
self.points = 10;
self.active = true;
// Random horizontal movement pattern
self.xDirection = Math.random() > 0.5 ? 1 : -1;
self.xSpeed = Math.random() * 2 + 1;
self.wobbleAmount = Math.random() * 30;
self.wobbleSpeed = Math.random() * 0.1;
self.initialX = 0;
self.update = function () {
if (!self.active) {
return;
}
// Move downward
self.y += self.speed;
// Horizontal wobble movement
if (self.initialX === 0) {
self.initialX = self.x;
}
self.x += self.xDirection * self.xSpeed;
self.x = self.initialX + Math.sin(LK.ticks * self.wobbleSpeed) * self.wobbleAmount;
// Rotate slightly for visual effect
self.rotation = Math.sin(LK.ticks * 0.05) * 0.1;
// Reverse direction if reaching screen edges
if (self.x < 0 || self.x > 2048) {
self.xDirection *= -1;
}
if (self.y > 2800) {
self.active = false;
}
};
self.takeDamage = function (amount) {
self.health -= amount;
// Flash the UFO when hit
LK.effects.flashObject(self, 0xffffff, 300);
if (self.health <= 0) {
self.explode();
}
return self.health <= 0;
};
self.explode = function () {
self.active = false;
LK.getSound('explosion').play();
// Create explosion effect
var explosion = LK.getAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x,
y: self.y,
alpha: 0.8
});
game.addChild(explosion);
// Animate explosion
tween(explosion, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
explosion.destroy();
}
});
};
return self;
});
var EliteUFO = UFO.expand(function () {
var self = UFO.call(this);
// Override UFO properties
self.health = 3;
self.speed = 1.5;
self.points = 30;
// Change color to indicate elite status
self.children[0].tint = 0xff00ff;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000022
});
/****
* Game Code
****/
// Game state
var cannon;
var bullets = [];
var ufos = [];
var score = 0;
var wave = 1;
var waveTimer = 0;
var waveDelay = 180; // 3 seconds at 60 fps
var gameActive = true;
// UI elements
var scoreTxt;
var waveTxt;
// Initialize game background
function setupBackground() {
// Stars background
var stars = LK.getAsset('stars', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(stars);
// Moon surface
var moon = LK.getAsset('moon', {
anchorX: 0.5,
anchorY: 0,
x: 2048 / 2,
y: 2732 - 400
});
game.addChild(moon);
}
// Initialize game UI
function setupUI() {
// Score display
scoreTxt = new Text2('Score: 0', {
size: 70,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -300;
scoreTxt.y = 50;
// Wave display
waveTxt = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFFFF
});
waveTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(waveTxt);
waveTxt.x = -300;
waveTxt.y = 120;
}
// Spawn a new wave of UFOs
function spawnWave() {
var ufoCount = 5 + Math.floor(wave * 1.5);
var eliteCount = Math.floor(wave / 3);
for (var i = 0; i < ufoCount; i++) {
// Determine if this should be an elite UFO
var isElite = i < eliteCount;
var ufo = isElite ? new EliteUFO() : new UFO();
// Position randomly across top of screen
ufo.x = Math.random() * (2048 - 300) + 150;
ufo.y = -100 - Math.random() * 500; // Stagger vertical starting positions
// Adjust speed based on wave
ufo.speed = ufo.speed * (1 + wave * 0.1);
ufos.push(ufo);
game.addChild(ufo);
}
// Update wave counter
wave++;
waveTxt.setText('Wave: ' + wave);
// Show wave notification
var waveNotification = new Text2('WAVE ' + wave, {
size: 120,
fill: 0xFFCC00
});
waveNotification.anchor.set(0.5, 0.5);
waveNotification.x = 2048 / 2;
waveNotification.y = 2732 / 2 - 200;
LK.gui.center.addChild(waveNotification);
// Animate wave notification
tween(waveNotification, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(waveNotification, {
alpha: 0
}, {
duration: 500,
easing: tween.easeIn,
onFinish: function onFinish() {
waveNotification.destroy();
}
});
}
});
}
// Update special weapon charge display
// Initialize the game
function initGame() {
setupBackground();
// Create player cannon
cannon = new Cannon();
cannon.x = 2048 / 2;
cannon.y = 2732 - 100;
game.addChild(cannon);
setupUI();
// Start background music
LK.playMusic('gameBgm', {
fade: {
start: 0,
end: 0.3,
duration: 1000
}
});
// Spawn initial wave
spawnWave();
}
// Handle game input
function handleInput(x, y) {
if (!gameActive || !cannon) {
return;
}
// Rotate cannon toward cursor/touch position
cannon.rotateCannon(x);
}
// Fire a bullet
function fireBullet() {
if (!gameActive || !cannon) {
return;
}
var bullet = cannon.fire();
if (bullet) {
bullets.push(bullet);
game.addChild(bullet);
}
}
// Fire special weapon
// Process collisions between bullets and UFOs
function processCollisions() {
// Check regular bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (!bullet.active) {
continue;
}
for (var j = ufos.length - 1; j >= 0; j--) {
var ufo = ufos[j];
if (!ufo.active) {
continue;
}
if (bullet.intersects(ufo)) {
if (ufo.takeDamage(bullet.damage)) {
// UFO destroyed
score += ufo.points;
scoreTxt.setText('Score: ' + score);
// Remove UFO
ufo.explode(); // Trigger explosion effect
ufos.splice(j, 1);
ufo.destroy(); // Ensure UFO is destroyed
}
// Remove bullet
bullet.active = false;
bullets.splice(i, 1);
bullet.destroy();
break;
}
}
}
}
// Check if any UFOs reached the moon base
function checkMoonBaseCollisions() {
for (var i = ufos.length - 1; i >= 0; i--) {
var ufo = ufos[i];
if (!ufo.active) {
continue;
}
// Check if UFO reached the moon's surface
if (ufo.y > 2732 - 400) {
// Game over if UFO touches the moon
gameActive = false;
// Flash the screen red
LK.effects.flashScreen(0xff0000, 1000);
// Show game over after a short delay
LK.setTimeout(function () {
// Removed final score display
LK.showGameOver();
}, 1500);
break;
}
}
}
// Clean up inactive objects
function cleanupObjects() {
// Clean up bullets
for (var i = bullets.length - 1; i >= 0; i--) {
if (!bullets[i].active) {
bullets[i].destroy();
bullets.splice(i, 1);
}
}
// Clean up UFOs
for (var i = ufos.length - 1; i >= 0; i--) {
if (!ufos[i].active) {
ufos[i].destroy();
ufos.splice(i, 1);
}
}
}
// Move handler for tracking input position
function handleMove(x, y, obj) {
handleInput(x, y);
}
// Down handler for firing
function handleDown(x, y, obj) {
handleInput(x, y);
fireBullet();
}
// Set up event handlers
game.move = handleMove;
game.down = handleDown;
function handleUp(x, y, obj) {
// Add any necessary logic for handling the 'up' event here
}
game.up = handleUp;
// Main game update loop
game.update = function () {
if (!gameActive) {
return;
}
// Update special weapon UI
function updateSpecialWeaponUI() {
// Placeholder for updating special weapon UI logic
// This function can be expanded with actual UI update logic if needed
}
updateSpecialWeaponUI();
// Update bullets
for (var i = 0; i < bullets.length; i++) {
bullets[i].update();
}
// Update UFOs
for (var i = 0; i < ufos.length; i++) {
ufos[i].update();
}
// Process collisions
processCollisions();
// Check if UFOs reached the moon base
checkMoonBaseCollisions();
// Clean up inactive objects
cleanupObjects();
// Spawn a new wave if all UFOs are destroyed
if (ufos.length === 0) {
if (waveTimer < waveDelay) {
waveTimer++;
} else {
waveTimer = 0;
spawnWave();
}
}
// Win condition (example: after wave 10)
if (wave > 10 && ufos.length === 0) {
gameActive = false;
LK.setTimeout(function () {
LK.showYouWin();
}, 1000);
}
};
// Initialize the game
initGame();
vertical scifi metal canon tube. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
space with some stars. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
footage of moon surface. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
battle ship scifi scifi black canon base Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
red light. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
dark gray war fligt scifi crescent ufo. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
dark electric wave explosive. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows