User prompt
do not display final score
User prompt
very fast bullet
User prompt
remove score display to left bottom
User prompt
add final score display add bottom left
User prompt
Please fix the bug: 'Timeout.tick error: Cannot set properties of undefined (setting 'size')' in or related to this line: 'scoreTxt.style.size = 50; // Reduce font size' Line Number: 395
User prompt
small font size final score
User prompt
repair final score
User prompt
increase speed of bullet
User prompt
fix final score
User prompt
Please fix the bug: 'ReferenceError: updateSpecialWeaponUI is not defined' in or related to this line: 'updateSpecialWeaponUI();' Line Number: 439
User prompt
Please fix the bug: 'handleUp is not defined' in or related to this line: 'game.up = handleUp;' Line Number: 429
User prompt
repair
User prompt
erase special
User prompt
canon cant move
User prompt
decrease bullet storm
User prompt
fix
User prompt
make bullet storm
User prompt
fix bug any ufo
User prompt
fix ufo bug
User prompt
ufo must destroy after get shoot
User prompt
fix ufo
User prompt
make canon capable shoot multiple direction
Code edit (1 edits merged)
Please save this source code
User prompt
Lunar Defense: Moon Base Alpha
Initial prompt
make scifi game. moon military base defend ufo attack
/****
* 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 = 15;
self.damage = 1;
self.active = true;
self.update = function () {
if (!self.active) {
return;
}
self.y -= self.speed;
// 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.specialWeaponCharge = 0;
self.specialWeaponThreshold = 5;
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 bullet = new Bullet();
bullet.x = spawnX;
bullet.y = spawnY;
bullet.rotation = cannon.rotation;
// Apply velocity vector based on cannon rotation
bullet.xVelocity = Math.sin(cannon.rotation) * bullet.speed;
bullet.yVelocity = -Math.cos(cannon.rotation) * bullet.speed;
// Start cooldown
self.canFire = false;
LK.setTimeout(function () {
self.canFire = true;
}, self.cooldown);
LK.getSound('shoot').play();
// Increment special weapon charge
self.specialWeaponCharge++;
return bullet;
};
self.fireSpecialWeapon = function () {
if (self.specialWeaponCharge < self.specialWeaponThreshold) {
return null;
}
var special = new SpecialWeapon();
special.x = self.x;
special.y = self.y - 50;
// Reset special weapon charge
self.specialWeaponCharge = 0;
LK.getSound('special').play();
// Apply recoil effect
tween(self, {
y: self.y + 20
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: self.y - 20
}, {
duration: 300,
easing: tween.easeInOut
});
}
});
return special;
};
self.down = function (x, y, obj) {
// Handle touch/click on cannon
};
return self;
});
var SpecialWeapon = Container.expand(function () {
var self = Container.call(this);
var specialGraphics = self.attachAsset('specialWeapon', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.damage = 5;
self.active = true;
self.update = function () {
if (!self.active) {
return;
}
self.y -= self.speed;
// Grow as it moves - create an expanding effect
if (self.scaleX < 4) {
self.scaleX += 0.05;
self.scaleY += 0.05;
}
// Remove if off screen
if (self.y < -100) {
self.active = false;
}
};
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.initialX + Math.sin(LK.ticks * self.wobbleSpeed) * self.wobbleAmount;
// Rotate slightly for visual effect
self.rotation = Math.sin(LK.ticks * 0.05) * 0.1;
// Remove if off bottom of screen
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 specialWeapons = [];
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;
var specialChargeBar;
var specialChargeText;
// 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;
// Special weapon charge bar background
var chargeBarBg = LK.getAsset('cannonBase', {
anchorX: 0,
anchorY: 0.5,
x: 150,
y: 50,
width: 250,
height: 30,
tint: 0x333333
});
LK.gui.top.addChild(chargeBarBg);
// Special weapon charge bar foreground
specialChargeBar = LK.getAsset('cannonBase', {
anchorX: 0,
anchorY: 0.5,
x: 150,
y: 50,
width: 0,
height: 30,
tint: 0xff3300
});
LK.gui.top.addChild(specialChargeBar);
// Special weapon charge text
specialChargeText = new Text2('Special: 0/' + 5, {
size: 40,
fill: 0xFFFFFF
});
specialChargeText.anchor.set(0, 0.5);
LK.gui.top.addChild(specialChargeText);
specialChargeText.x = 420;
specialChargeText.y = 50;
}
// 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
function updateSpecialWeaponUI() {
if (!cannon) {
return;
}
var chargePercent = cannon.specialWeaponCharge / cannon.specialWeaponThreshold;
var barWidth = 250 * Math.min(1, chargePercent);
specialChargeBar.width = barWidth;
specialChargeText.setText('Special: ' + cannon.specialWeaponCharge + '/' + cannon.specialWeaponThreshold);
// Color changes as it charges
if (chargePercent >= 1) {
specialChargeBar.tint = 0x00ff00; // Full charge: green
} else if (chargePercent >= 0.5) {
specialChargeBar.tint = 0xffcc00; // Half charge: yellow
} else {
specialChargeBar.tint = 0xff3300; // Low charge: red
}
}
// 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
function fireSpecialWeapon() {
if (!gameActive || !cannon) {
return;
}
var special = cannon.fireSpecialWeapon();
if (special) {
specialWeapons.push(special);
game.addChild(special);
}
}
// 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
ufos.splice(j, 1);
}
// Remove bullet
bullet.active = false;
bullets.splice(i, 1);
bullet.destroy();
break;
}
}
}
// Check special weapons
for (var i = specialWeapons.length - 1; i >= 0; i--) {
var special = specialWeapons[i];
if (!special.active) {
continue;
}
for (var j = ufos.length - 1; j >= 0; j--) {
var ufo = ufos[j];
if (!ufo.active) {
continue;
}
if (special.intersects(ufo)) {
if (ufo.takeDamage(special.damage)) {
// UFO destroyed
score += ufo.points;
scoreTxt.setText('Score: ' + score);
// Remove UFO
ufos.splice(j, 1);
}
// Special weapon continues (doesn't get destroyed on contact)
}
}
// Clean up off-screen special weapons
if (!special.active) {
specialWeapons.splice(i, 1);
special.destroy();
}
}
}
// 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 () {
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 special weapons
for (var i = specialWeapons.length - 1; i >= 0; i--) {
if (!specialWeapons[i].active) {
specialWeapons[i].destroy();
specialWeapons.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();
}
// Up handler for special weapon
function handleUp(x, y, obj) {
if (cannon && cannon.specialWeaponCharge >= cannon.specialWeaponThreshold) {
fireSpecialWeapon();
}
}
// Set up event handlers
game.move = handleMove;
game.down = handleDown;
game.up = handleUp;
// Main game update loop
game.update = function () {
if (!gameActive) {
return;
}
// Update special weapon UI
updateSpecialWeaponUI();
// Update bullets
for (var i = 0; i < bullets.length; i++) {
bullets[i].update();
}
// Update special weapons
for (var i = 0; i < specialWeapons.length; i++) {
specialWeapons[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(); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,603 @@
-/****
+/****
+* 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 = 15;
+ self.damage = 1;
+ self.active = true;
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ self.y -= self.speed;
+ // 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.specialWeaponCharge = 0;
+ self.specialWeaponThreshold = 5;
+ 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 bullet = new Bullet();
+ bullet.x = spawnX;
+ bullet.y = spawnY;
+ bullet.rotation = cannon.rotation;
+ // Apply velocity vector based on cannon rotation
+ bullet.xVelocity = Math.sin(cannon.rotation) * bullet.speed;
+ bullet.yVelocity = -Math.cos(cannon.rotation) * bullet.speed;
+ // Start cooldown
+ self.canFire = false;
+ LK.setTimeout(function () {
+ self.canFire = true;
+ }, self.cooldown);
+ LK.getSound('shoot').play();
+ // Increment special weapon charge
+ self.specialWeaponCharge++;
+ return bullet;
+ };
+ self.fireSpecialWeapon = function () {
+ if (self.specialWeaponCharge < self.specialWeaponThreshold) {
+ return null;
+ }
+ var special = new SpecialWeapon();
+ special.x = self.x;
+ special.y = self.y - 50;
+ // Reset special weapon charge
+ self.specialWeaponCharge = 0;
+ LK.getSound('special').play();
+ // Apply recoil effect
+ tween(self, {
+ y: self.y + 20
+ }, {
+ duration: 100,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(self, {
+ y: self.y - 20
+ }, {
+ duration: 300,
+ easing: tween.easeInOut
+ });
+ }
+ });
+ return special;
+ };
+ self.down = function (x, y, obj) {
+ // Handle touch/click on cannon
+ };
+ return self;
+});
+var SpecialWeapon = Container.expand(function () {
+ var self = Container.call(this);
+ var specialGraphics = self.attachAsset('specialWeapon', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 10;
+ self.damage = 5;
+ self.active = true;
+ self.update = function () {
+ if (!self.active) {
+ return;
+ }
+ self.y -= self.speed;
+ // Grow as it moves - create an expanding effect
+ if (self.scaleX < 4) {
+ self.scaleX += 0.05;
+ self.scaleY += 0.05;
+ }
+ // Remove if off screen
+ if (self.y < -100) {
+ self.active = false;
+ }
+ };
+ 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.initialX + Math.sin(LK.ticks * self.wobbleSpeed) * self.wobbleAmount;
+ // Rotate slightly for visual effect
+ self.rotation = Math.sin(LK.ticks * 0.05) * 0.1;
+ // Remove if off bottom of screen
+ 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: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x000022
+});
+
+/****
+* Game Code
+****/
+// Game state
+var cannon;
+var bullets = [];
+var specialWeapons = [];
+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;
+var specialChargeBar;
+var specialChargeText;
+// 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;
+ // Special weapon charge bar background
+ var chargeBarBg = LK.getAsset('cannonBase', {
+ anchorX: 0,
+ anchorY: 0.5,
+ x: 150,
+ y: 50,
+ width: 250,
+ height: 30,
+ tint: 0x333333
+ });
+ LK.gui.top.addChild(chargeBarBg);
+ // Special weapon charge bar foreground
+ specialChargeBar = LK.getAsset('cannonBase', {
+ anchorX: 0,
+ anchorY: 0.5,
+ x: 150,
+ y: 50,
+ width: 0,
+ height: 30,
+ tint: 0xff3300
+ });
+ LK.gui.top.addChild(specialChargeBar);
+ // Special weapon charge text
+ specialChargeText = new Text2('Special: 0/' + 5, {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ specialChargeText.anchor.set(0, 0.5);
+ LK.gui.top.addChild(specialChargeText);
+ specialChargeText.x = 420;
+ specialChargeText.y = 50;
+}
+// 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
+function updateSpecialWeaponUI() {
+ if (!cannon) {
+ return;
+ }
+ var chargePercent = cannon.specialWeaponCharge / cannon.specialWeaponThreshold;
+ var barWidth = 250 * Math.min(1, chargePercent);
+ specialChargeBar.width = barWidth;
+ specialChargeText.setText('Special: ' + cannon.specialWeaponCharge + '/' + cannon.specialWeaponThreshold);
+ // Color changes as it charges
+ if (chargePercent >= 1) {
+ specialChargeBar.tint = 0x00ff00; // Full charge: green
+ } else if (chargePercent >= 0.5) {
+ specialChargeBar.tint = 0xffcc00; // Half charge: yellow
+ } else {
+ specialChargeBar.tint = 0xff3300; // Low charge: red
+ }
+}
+// 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
+function fireSpecialWeapon() {
+ if (!gameActive || !cannon) {
+ return;
+ }
+ var special = cannon.fireSpecialWeapon();
+ if (special) {
+ specialWeapons.push(special);
+ game.addChild(special);
+ }
+}
+// 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
+ ufos.splice(j, 1);
+ }
+ // Remove bullet
+ bullet.active = false;
+ bullets.splice(i, 1);
+ bullet.destroy();
+ break;
+ }
+ }
+ }
+ // Check special weapons
+ for (var i = specialWeapons.length - 1; i >= 0; i--) {
+ var special = specialWeapons[i];
+ if (!special.active) {
+ continue;
+ }
+ for (var j = ufos.length - 1; j >= 0; j--) {
+ var ufo = ufos[j];
+ if (!ufo.active) {
+ continue;
+ }
+ if (special.intersects(ufo)) {
+ if (ufo.takeDamage(special.damage)) {
+ // UFO destroyed
+ score += ufo.points;
+ scoreTxt.setText('Score: ' + score);
+ // Remove UFO
+ ufos.splice(j, 1);
+ }
+ // Special weapon continues (doesn't get destroyed on contact)
+ }
+ }
+ // Clean up off-screen special weapons
+ if (!special.active) {
+ specialWeapons.splice(i, 1);
+ special.destroy();
+ }
+ }
+}
+// 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 () {
+ 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 special weapons
+ for (var i = specialWeapons.length - 1; i >= 0; i--) {
+ if (!specialWeapons[i].active) {
+ specialWeapons[i].destroy();
+ specialWeapons.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();
+}
+// Up handler for special weapon
+function handleUp(x, y, obj) {
+ if (cannon && cannon.specialWeaponCharge >= cannon.specialWeaponThreshold) {
+ fireSpecialWeapon();
+ }
+}
+// Set up event handlers
+game.move = handleMove;
+game.down = handleDown;
+game.up = handleUp;
+// Main game update loop
+game.update = function () {
+ if (!gameActive) {
+ return;
+ }
+ // Update special weapon UI
+ updateSpecialWeaponUI();
+ // Update bullets
+ for (var i = 0; i < bullets.length; i++) {
+ bullets[i].update();
+ }
+ // Update special weapons
+ for (var i = 0; i < specialWeapons.length; i++) {
+ specialWeapons[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();
\ No newline at end of file
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