Code edit (1 edits merged)
Please save this source code
User prompt
add sound for each event.
User prompt
write a small orange βGlaudβ in a logical place on the screen.
User prompt
Make the text visible on the screen. The design should be good.
User prompt
Identify and solve some basic logic errors in the game.
User prompt
Identify and solve some basic logic errors in the game.
User prompt
Identify the features that will make it better and implement them in an optimized way, don't make any mistakes, it's clean and playable. Make it a user-friendly game. βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
Identify the features that will make it better and implement them in an optimized way, don't make any mistakes, it's clean and playable. Make it a user-friendly game.
User prompt
Identify the features that will make it better and implement them in an optimized way, don't make any mistakes, it's clean and playable. Make it a user-friendly game. βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
Identify the features that will make it better and implement them in an optimized way, don't make any mistakes, it's clean and playable. Make it a user-friendly game. βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Space Defender
Initial prompt
game
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
level: 1
});
/****
* Classes
****/
var Asteroid = Container.expand(function () {
var self = Container.call(this);
// Random size asteroid
var size = Math.random() * 0.7 + 0.7; // 0.7 to 1.4
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: size,
scaleY: size
});
self.health = 30 * size;
self.speed = 3 / size; // Bigger asteroids move slower
self.rotationSpeed = (Math.random() - 0.5) * 0.05;
self.points = Math.floor(50 * size);
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0x888888, 200);
if (self.health <= 0) {
self.onDestroyed();
}
};
self.onDestroyed = function () {
// Add points to score
LK.setScore(LK.getScore() + self.points);
// Create explosion
var explosion = new Explosion(self.x, self.y, size);
game.addChild(explosion);
LK.getSound('explosion').play();
// Remove from game
var index = asteroids.indexOf(self);
if (index > -1) {
asteroids.splice(index, 1);
self.destroy();
}
};
self.update = function () {
self.y += self.speed;
asteroidGraphics.rotation += self.rotationSpeed;
// Check if asteroid is off-screen
if (self.y > 2732 + 100) {
var index = asteroids.indexOf(self);
if (index > -1) {
asteroids.splice(index, 1);
self.destroy();
}
}
};
return self;
});
var Boss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 500;
self.maxHealth = 500;
self.speed = 2;
self.points = 2000;
self.active = false;
self.phase = 1;
self.directionX = 1;
self.shootCooldown = 30;
self.specialAttackCooldown = 300;
// Health bar
self.healthBar = self.attachAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
y: -150
});
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xff0000, 200);
// Update health bar scale
self.healthBar.scaleX = Math.max(0, self.health / self.maxHealth);
// Phase transition at 50% health
if (self.health <= self.maxHealth / 2 && self.phase === 1) {
self.phase = 2;
self.speed = 4;
LK.effects.flashObject(self, 0xff00ff, 1000); // Purple flash for phase transition
}
if (self.health <= 0) {
self.onDestroyed();
}
};
self.onDestroyed = function () {
// Add points to score
LK.setScore(LK.getScore() + self.points);
// Create multiple explosions
for (var i = 0; i < 8; i++) {
var explosionX = self.x + (Math.random() * 300 - 150);
var explosionY = self.y + (Math.random() * 200 - 100);
var explosion = new Explosion(explosionX, explosionY, 2);
game.addChild(explosion);
// Stagger the explosions
(function (delay) {
LK.setTimeout(function () {
LK.getSound('explosion').play();
}, delay * 200);
})(i);
}
// Complete level
level++;
if (level > storage.level) {
storage.level = level;
}
// Check high score
if (LK.getScore() > storage.highScore) {
storage.highScore = LK.getScore();
}
// Show win screen
LK.showYouWin();
// Remove from game
var index = bosses.indexOf(self);
if (index > -1) {
bosses.splice(index, 1);
self.destroy();
}
};
self.shoot = function () {
// Basic attack - 3 bullets
for (var i = -1; i <= 1; i++) {
var bullet = new EnemyBullet();
bullet.x = self.x + i * 80;
bullet.y = self.y + 100;
game.addChild(bullet);
enemyBullets.push(bullet);
}
LK.getSound('enemyShoot').play();
};
self.specialAttack = function () {
// Special attack based on phase
if (self.phase === 1) {
// Phase 1: Circle of 8 bullets
for (var i = 0; i < 8; i++) {
var angle = i / 8 * Math.PI * 2;
var bullet = new EnemyBullet();
bullet.x = self.x + Math.cos(angle) * 100;
bullet.y = self.y + Math.sin(angle) * 100;
bullet.directionX = Math.cos(angle);
bullet.directionY = Math.sin(angle);
game.addChild(bullet);
enemyBullets.push(bullet);
}
} else {
// Phase 2: Targeted volley at player
for (var i = 0; i < 5; i++) {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + 100;
// Target the player
var dx = player.x - bullet.x;
var dy = player.y - bullet.y;
var dist = Math.sqrt(dx * dx + dy * dy);
bullet.directionX = dx / dist;
bullet.directionY = dy / dist;
bullet.speed = 8 + i;
game.addChild(bullet);
enemyBullets.push(bullet);
// Stagger the bullets slightly
(function (b, delay) {
LK.setTimeout(function () {
game.addChild(b);
enemyBullets.push(b);
}, delay * 100);
})(bullet, i);
}
}
LK.getSound('enemyShoot').play();
};
self.update = function () {
if (!self.active) {
return;
}
// Movement
self.x += self.speed * self.directionX;
// Bounce at screen edges
if (self.x < 300) {
self.x = 300;
self.directionX = 1;
} else if (self.x > 2048 - 300) {
self.x = 2048 - 300;
self.directionX = -1;
}
// Regular attacks
self.shootCooldown--;
if (self.shootCooldown <= 0) {
self.shoot();
self.shootCooldown = self.phase === 1 ? 60 : 40;
}
// Special attacks
self.specialAttackCooldown--;
if (self.specialAttackCooldown <= 0) {
self.specialAttack();
self.specialAttackCooldown = 300;
}
};
self.activate = function () {
self.active = true;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 20;
self.speed = 2;
self.shootCooldown = Math.floor(Math.random() * 120) + 60;
self.points = 100;
self.movementPattern = "straight"; // Default movement pattern
self.directionX = 0;
self.directionChangeTimer = 0;
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xff0000, 200);
if (self.health <= 0) {
self.onDestroyed();
}
};
self.onDestroyed = function () {
// Add points to score
LK.setScore(LK.getScore() + self.points);
// Create explosion
var explosion = new Explosion(self.x, self.y, 1);
game.addChild(explosion);
LK.getSound('explosion').play();
// Increment enemies defeated count for level progression
enemiesDefeated++;
// Check if should drop powerup (20% chance)
if (Math.random() < 0.2) {
var powerup = new Powerup();
powerup.x = self.x;
powerup.y = self.y;
game.addChild(powerup);
powerups.push(powerup);
}
// Remove from game
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
self.destroy();
}
};
self.shoot = function () {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + 50;
game.addChild(bullet);
enemyBullets.push(bullet);
LK.getSound('enemyShoot').play();
};
self.setMovementPattern = function (pattern) {
self.movementPattern = pattern;
if (pattern === "zigzag") {
self.directionX = Math.random() < 0.5 ? -1 : 1;
self.speed = 3;
} else if (pattern === "circle") {
self.angle = Math.random() * Math.PI * 2;
self.centerX = self.x;
self.centerY = self.y;
self.radius = 100;
self.speed = 0.02;
} else if (pattern === "sine") {
self.startX = self.x;
self.amplitude = 150;
self.frequency = 0.01;
self.angle = Math.random() * Math.PI * 2;
}
};
self.update = function () {
// Movement based on pattern
if (self.movementPattern === "straight") {
self.y += self.speed;
} else if (self.movementPattern === "zigzag") {
self.y += self.speed;
self.x += self.speed * 2 * self.directionX;
self.directionChangeTimer++;
if (self.directionChangeTimer > 60) {
self.directionX *= -1;
self.directionChangeTimer = 0;
}
// Bounce off screen edges
if (self.x < 50) {
self.x = 50;
self.directionX = 1;
} else if (self.x > 2048 - 50) {
self.x = 2048 - 50;
self.directionX = -1;
}
} else if (self.movementPattern === "circle") {
self.angle += self.speed;
self.x = self.centerX + Math.cos(self.angle) * self.radius;
self.y = self.centerY + Math.sin(self.angle) * self.radius + self.speed * 20;
} else if (self.movementPattern === "sine") {
self.y += self.speed * 2;
self.angle += self.frequency;
self.x = self.startX + Math.sin(self.angle) * self.amplitude;
}
// Shooting
self.shootCooldown--;
if (self.shootCooldown <= 0) {
self.shoot();
self.shootCooldown = Math.floor(Math.random() * 120) + 120;
}
// Remove if off screen
if (self.y > 2732 + 100) {
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
self.destroy();
}
}
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.damage = 10;
self.directionX = 0;
self.directionY = 1;
self.update = function () {
// Move based on direction
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
// Check if bullet is off-screen
if (self.y > 2732 + 50 || self.y < -50 || self.x < -50 || self.x > 2048 + 50) {
self.removeFromGame();
}
};
self.removeFromGame = function () {
var index = enemyBullets.indexOf(self);
if (index > -1) {
enemyBullets.splice(index, 1);
self.destroy();
}
};
return self;
});
var Explosion = Container.expand(function (x, y, size) {
var self = Container.call(this);
self.x = x;
self.y = y;
var explosionGraphics = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: size || 1,
scaleY: size || 1,
alpha: 0.9
});
// Animation for explosion
self.duration = 30; // 0.5 seconds at 60fps
self.timer = 0;
self.update = function () {
self.timer++;
// Scale up and fade out
var progress = self.timer / self.duration;
explosionGraphics.scaleX = (size || 1) * (1 + progress);
explosionGraphics.scaleY = (size || 1) * (1 + progress);
explosionGraphics.alpha = 1 - progress;
if (self.timer >= self.duration) {
self.destroy();
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.speed = 15;
self.shootCooldown = 0;
self.invulnerable = false;
self.powerupTimer = 0;
self.powerupActive = false;
self.takeDamage = function (amount) {
if (self.invulnerable) {
return;
}
self.health -= amount;
if (self.health <= 0) {
self.health = 0;
self.onDestroyed();
} else {
// Flash player when hit
self.invulnerable = true;
LK.effects.flashObject(self, 0xffffff, 500);
// Screen shake on hit
LK.effects.flashScreen(0xFF0000, 300);
// Create small explosions around player for visual feedback
for (var i = 0; i < 3; i++) {
var explosionX = self.x + (Math.random() * 150 - 75);
var explosionY = self.y + (Math.random() * 150 - 75);
var smallExplosion = new Explosion(explosionX, explosionY, 0.5);
game.addChild(smallExplosion);
}
// Add a brief visual impact to the player graphic itself
tween(playerGraphics, {
tint: 0xFF0000
}, {
duration: 100,
onFinish: function onFinish() {
playerGraphics.tint = 0xFFFFFF;
}
});
LK.setTimeout(function () {
self.invulnerable = false;
}, 1000);
}
};
self.applyPowerup = function () {
self.powerupActive = true;
self.powerupTimer = 300; // 5 seconds at 60fps
playerGraphics.tint = 0x00ff00; // Green tint for powered up
LK.getSound('powerup').play();
// Visual effect for power-up
tween(playerGraphics, {
alpha: 0.5,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(playerGraphics, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
});
// Create a powerup aura
if (!self.powerupAura) {
self.powerupAura = LK.getAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
alpha: 0.3,
tint: 0x00FFAA
});
self.addChild(self.powerupAura);
} else {
self.powerupAura.alpha = 0.3;
}
};
self.shoot = function () {
if (self.shootCooldown <= 0) {
var bullet = new PlayerBullet();
bullet.x = self.x;
bullet.y = self.y - 70;
game.addChild(bullet);
bullets.push(bullet);
LK.getSound('playerShoot').play();
// If powered up, shoot 3 bullets instead of 1
if (self.powerupActive) {
var bulletLeft = new PlayerBullet();
bulletLeft.x = self.x - 40;
bulletLeft.y = self.y - 50;
var bulletRight = new PlayerBullet();
bulletRight.x = self.x + 40;
bulletRight.y = self.y - 50;
game.addChild(bulletLeft);
game.addChild(bulletRight);
bullets.push(bulletLeft);
bullets.push(bulletRight);
}
self.shootCooldown = self.powerupActive ? 10 : 15;
}
};
self.onDestroyed = function () {
var explosion = new Explosion(self.x, self.y, 2);
game.addChild(explosion);
LK.getSound('explosion').play();
// Show game over
LK.showGameOver();
};
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
if (self.powerupActive) {
self.powerupTimer--;
// Animate the powerup aura
if (self.powerupAura) {
self.powerupAura.rotation += 0.02;
// Pulse the aura
self.powerupAuraTime = (self.powerupAuraTime || 0) + 0.05;
self.powerupAura.alpha = 0.2 + Math.sin(self.powerupAuraTime) * 0.1;
self.powerupAura.scale.set(1.8 + Math.sin(self.powerupAuraTime) * 0.2);
}
// Warning animation when powerup is about to expire
if (self.powerupTimer < 60) {
// Flash the player when powerup is about to end
playerGraphics.alpha = 0.5 + Math.sin(self.powerupTimer * 0.2) * 0.5;
}
if (self.powerupTimer <= 0) {
self.powerupActive = false;
playerGraphics.tint = 0xffffff; // Reset tint
playerGraphics.alpha = 1;
// Remove powerup aura
if (self.powerupAura) {
self.powerupAura.destroy();
self.powerupAura = null;
}
}
}
};
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -15; // Move upwards
self.damage = 10;
self.update = function () {
self.y += self.speed;
// Check if bullet is off-screen
if (self.y < -50) {
self.removeFromGame();
}
};
self.removeFromGame = function () {
var index = bullets.indexOf(self);
if (index > -1) {
bullets.splice(index, 1);
self.destroy();
}
};
return self;
});
var Powerup = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.pulsateTimer = 0;
self.update = function () {
self.y += self.speed;
// Pulsate effect
self.pulsateTimer += 0.05;
var scale = 1 + Math.sin(self.pulsateTimer) * 0.2;
powerupGraphics.scaleX = scale;
powerupGraphics.scaleY = scale;
// Remove if off screen
if (self.y > 2732 + 50) {
self.removeFromGame();
}
};
self.removeFromGame = function () {
var index = powerups.indexOf(self);
if (index > -1) {
powerups.splice(index, 1);
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000011 // Deep space blue
});
/****
* Game Code
****/
// Game state variables
var player;
var bullets = [];
var enemies = [];
var enemyBullets = [];
var asteroids = [];
var powerups = [];
var bosses = [];
var level = storage.level || 1;
var enemySpawnTimer = 0;
var asteroidSpawnTimer = 0;
var bossSpawned = false;
var gameStarted = false;
var levelEnemiesRequired;
var enemiesDefeated = 0;
var dragNode = null;
// Set up UI
var scoreTxt = new Text2('Score: 0', {
size: 70,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
var highScoreTxt = new Text2('High Score: ' + storage.highScore, {
size: 50,
fill: 0xFFFFFF
});
highScoreTxt.anchor.set(0, 0);
highScoreTxt.y = 80;
LK.gui.topRight.addChild(highScoreTxt);
var levelTxt = new Text2('Level: ' + level, {
size: 70,
fill: 0xFFFFFF
});
levelTxt.anchor.set(1, 0);
LK.gui.topLeft.addChild(levelTxt);
levelTxt.x = 250; // Make sure it's not in the top-left corner
levelTxt.y = 50; // Adjust Y position as well
var healthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0.5,
scaleX: 1,
scaleY: 0.6
});
healthBar.x = 200;
LK.gui.bottom.addChild(healthBar);
var healthTxt = new Text2('Health', {
size: 60,
fill: 0xFFFFFF
});
healthTxt.anchor.set(0.5, 0.5);
healthTxt.x = 100;
LK.gui.bottom.addChild(healthTxt);
// Progress bar for level completion
var progressBarBg = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 0.4,
tint: 0x555555
});
progressBarBg.x = 2048 / 2;
progressBarBg.y = 100;
LK.gui.top.addChild(progressBarBg);
var progressBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0.5,
scaleX: 0,
scaleY: 0.3,
tint: 0x00FFFF
});
progressBar.x = 2048 / 2 - progressBarBg.width / 2;
progressBar.y = 100;
LK.gui.top.addChild(progressBar);
var progressTxt = new Text2('Progress', {
size: 40,
fill: 0xFFFFFF
});
progressTxt.anchor.set(0.5, 0.5);
progressTxt.x = 2048 / 2;
progressTxt.y = 40;
LK.gui.top.addChild(progressTxt);
// Initialize player
function initPlayer() {
player = new Player();
player.x = 2048 / 2;
player.y = 2732 - 200;
game.addChild(player);
}
// Initialize level
function initLevel() {
// Clear any existing enemies and bullets
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].destroy();
}
for (var i = enemyBullets.length - 1; i >= 0; i--) {
enemyBullets[i].destroy();
}
for (var i = asteroids.length - 1; i >= 0; i--) {
asteroids[i].destroy();
}
for (var i = powerups.length - 1; i >= 0; i--) {
powerups[i].destroy();
}
for (var i = bosses.length - 1; i >= 0; i--) {
bosses[i].destroy();
}
enemies = [];
enemyBullets = [];
asteroids = [];
powerups = [];
bosses = [];
bossSpawned = false;
enemiesDefeated = 0;
// Set level difficulty
levelEnemiesRequired = level * 15;
enemySpawnTimer = 60;
asteroidSpawnTimer = 180;
// Update UI
levelTxt.setText('Level: ' + level);
// Start music
LK.playMusic('bgMusic');
}
// Spawn enemy with random pattern
function spawnEnemy() {
var enemy = new Enemy();
// Random x position
enemy.x = Math.random() * (2048 - 200) + 100;
enemy.y = -100;
// Set health and pattern based on level
enemy.health = 20 + level * 5;
// Choose movement pattern
var patterns = ["straight", "zigzag", "sine"];
if (level >= 3) {
patterns.push("circle");
}
var pattern = patterns[Math.floor(Math.random() * patterns.length)];
enemy.setMovementPattern(pattern);
// Add spawn animation
enemy.alpha = 0;
enemy.scale.set(0.5);
game.addChild(enemy);
enemies.push(enemy);
// Animate entrance
tween(enemy, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeOutBack
});
}
// Spawn asteroid
function spawnAsteroid() {
var asteroid = new Asteroid();
// Random x position
asteroid.x = Math.random() * (2048 - 200) + 100;
asteroid.y = -100;
game.addChild(asteroid);
asteroids.push(asteroid);
// Add entry animation
asteroid.alpha = 0.5;
tween(asteroid, {
alpha: 1,
rotation: Math.random() * Math.PI * 2
}, {
duration: 800,
easing: tween.easeOut
});
}
// Spawn boss
function spawnBoss() {
var boss = new Boss();
boss.x = 2048 / 2;
boss.y = 300;
// Adjust boss health based on level
boss.health = 500 + level * 100;
boss.maxHealth = boss.health;
game.addChild(boss);
bosses.push(boss);
// Activate boss after entrance animation
tween(boss, {
y: 300
}, {
duration: 2000,
easing: tween.easeOutBack,
onFinish: function onFinish() {
boss.activate();
}
});
}
// Check collisions
function checkCollisions() {
// Player bullets vs enemies
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Check against enemies
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
// Create small impact effect
var impact = new Explosion(bullet.x, bullet.y, 0.3);
impact.duration = 15; // Shorter duration for impact
game.addChild(impact);
enemy.takeDamage(bullet.damage);
bullet.removeFromGame();
// Add a brief visual impact to the enemy
tween(enemy, {
tint: 0xFFFFFF
}, {
duration: 50,
onFinish: function onFinish() {
enemy.tint = 0xFF0000;
}
});
break;
}
}
// Check against asteroids
for (var j = asteroids.length - 1; j >= 0; j--) {
var asteroid = asteroids[j];
if (bullet.intersects(asteroid)) {
// Create small impact effect
var impact = new Explosion(bullet.x, bullet.y, 0.3);
impact.duration = 15; // Shorter duration for impact
game.addChild(impact);
asteroid.takeDamage(bullet.damage);
bullet.removeFromGame();
// Add a brief visual impact to the asteroid
tween(asteroid, {
tint: 0xFFFFFF
}, {
duration: 50,
onFinish: function onFinish() {
asteroid.tint = 0x999999;
}
});
break;
}
}
// Check against bosses
for (var j = bosses.length - 1; j >= 0; j--) {
var boss = bosses[j];
if (bullet.intersects(boss) && boss.active) {
// Create small impact effect
var impact = new Explosion(bullet.x, bullet.y, 0.3);
impact.duration = 15; // Shorter duration for impact
game.addChild(impact);
boss.takeDamage(bullet.damage);
bullet.removeFromGame();
// Add a brief visual impact to the boss
tween(boss, {
tint: 0xFFFFFF
}, {
duration: 50,
onFinish: function onFinish() {
boss.tint = 0xff3300;
}
});
break;
}
}
}
// Enemy bullets vs player
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
if (bullet.intersects(player)) {
player.takeDamage(bullet.damage);
bullet.removeFromGame();
}
}
// Player vs enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (player.intersects(enemy)) {
player.takeDamage(20);
enemy.takeDamage(enemy.health); // Destroy enemy
}
}
// Player vs asteroids
for (var i = asteroids.length - 1; i >= 0; i--) {
var asteroid = asteroids[i];
if (player.intersects(asteroid)) {
player.takeDamage(30);
asteroid.takeDamage(asteroid.health); // Destroy asteroid
}
}
// Player vs powerups
for (var i = powerups.length - 1; i >= 0; i--) {
var powerup = powerups[i];
if (player.intersects(powerup)) {
player.applyPowerup();
powerup.removeFromGame();
}
}
}
// Handle player movement
function handleDrag(x, y) {
if (dragNode) {
dragNode.x = x;
dragNode.y = y;
// Constrain player to screen bounds
if (dragNode.x < 50) {
dragNode.x = 50;
}
if (dragNode.x > 2048 - 50) {
dragNode.x = 2048 - 50;
}
if (dragNode.y < 50) {
dragNode.y = 50;
}
if (dragNode.y > 2732 - 50) {
dragNode.y = 2732 - 50;
}
}
}
// Event handlers
game.down = function (x, y, obj) {
// Only set drag if we're started
if (gameStarted) {
dragNode = player;
handleDrag(x, y);
} else {
// Start game on first touch
gameStarted = true;
initPlayer();
initLevel();
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
game.move = function (x, y, obj) {
handleDrag(x, y);
};
// Main game update loop
game.update = function () {
if (!gameStarted) {
// Show start screen text
if (!game.startText) {
game.startText = new Text2('Tap to Start\nSpace Defender', {
size: 150,
fill: 0xFFFFFF
});
game.startText.anchor.set(0.5, 0.5);
game.startText.x = 2048 / 2;
game.startText.y = 2732 / 2;
game.addChild(game.startText);
// Add background stars for start screen
game.stars = [];
for (var i = 0; i < 50; i++) {
var star = LK.getAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: Math.random() * 0.3 + 0.1,
scaleY: Math.random() * 0.3 + 0.1,
alpha: Math.random() * 0.7 + 0.3,
tint: 0xFFFFFF
});
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
star.speed = Math.random() * 2 + 1;
game.addChild(star);
game.stars.push(star);
}
// Add pulsating effect to start text
game.pulseValue = 0;
// Add pulsing to the start text using tween
tween(game.startText, {
alpha: 0.5
}, {
duration: 1000,
easing: tween.easeInOut,
loop: true,
yoyo: true
});
}
// Animate stars in start screen
if (game.stars) {
game.pulseValue += 0.05;
game.startText.scale.set(1 + Math.sin(game.pulseValue) * 0.05);
for (var i = 0; i < game.stars.length; i++) {
var star = game.stars[i];
star.y += star.speed;
if (star.y > 2732) {
star.y = 0;
star.x = Math.random() * 2048;
}
}
}
return;
} else if (game.startText) {
game.startText.destroy();
game.startText = null;
// Clean up stars
if (game.stars) {
for (var i = 0; i < game.stars.length; i++) {
game.stars[i].destroy();
}
game.stars = null;
}
}
// Update UI
scoreTxt.setText('Score: ' + LK.getScore());
// Update high score if needed
if (LK.getScore() > storage.highScore) {
storage.highScore = LK.getScore();
highScoreTxt.setText('High Score: ' + storage.highScore);
}
// Update progress bar
if (!bossSpawned) {
var progress = enemiesDefeated / levelEnemiesRequired;
progressBar.scaleX = progress;
progressTxt.setText('Level Progress: ' + Math.floor(progress * 100) + '%');
} else {
progressTxt.setText('BOSS FIGHT!');
if (!progressTxt.pulsating) {
progressTxt.pulsating = true;
progressTxt.pulseValue = 0;
tween(progressTxt.scale, {
x: 1.2,
y: 1.2
}, {
duration: 300,
easing: tween.easeInOut,
loop: true,
yoyo: true
});
}
progressBar.tint = 0xFF0000;
progressBar.scaleX = 1;
}
if (player) {
// Update health bar
healthBar.scaleX = Math.max(0, player.health / 100);
// Auto-fire
player.shoot();
}
// Spawn enemies
if (!bossSpawned) {
enemySpawnTimer--;
if (enemySpawnTimer <= 0) {
spawnEnemy();
// Spawn rate increases with level
enemySpawnTimer = Math.max(20, 100 - level * 10);
}
// Spawn asteroids
asteroidSpawnTimer--;
if (asteroidSpawnTimer <= 0) {
spawnAsteroid();
asteroidSpawnTimer = Math.max(60, 300 - level * 20);
}
// Check if we should spawn boss
if (enemiesDefeated >= levelEnemiesRequired) {
bossSpawned = true;
spawnBoss();
}
}
// Update all game objects
for (var i = bullets.length - 1; i >= 0; i--) {
bullets[i].update();
}
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].update();
}
for (var i = enemyBullets.length - 1; i >= 0; i--) {
enemyBullets[i].update();
}
for (var i = asteroids.length - 1; i >= 0; i--) {
asteroids[i].update();
}
for (var i = powerups.length - 1; i >= 0; i--) {
powerups[i].update();
}
for (var i = bosses.length - 1; i >= 0; i--) {
bosses[i].update();
}
// Check for collisions
checkCollisions();
};
// Start game music
LK.playMusic('bgMusic', {
fade: {
start: 0,
end: 0.3,
duration: 1000
}
}); ===================================================================
--- original.js
+++ change.js
@@ -415,8 +415,17 @@
var explosionY = self.y + (Math.random() * 150 - 75);
var smallExplosion = new Explosion(explosionX, explosionY, 0.5);
game.addChild(smallExplosion);
}
+ // Add a brief visual impact to the player graphic itself
+ tween(playerGraphics, {
+ tint: 0xFF0000
+ }, {
+ duration: 100,
+ onFinish: function onFinish() {
+ playerGraphics.tint = 0xFFFFFF;
+ }
+ });
LK.setTimeout(function () {
self.invulnerable = false;
}, 1000);
}
@@ -427,22 +436,22 @@
playerGraphics.tint = 0x00ff00; // Green tint for powered up
LK.getSound('powerup').play();
// Visual effect for power-up
tween(playerGraphics, {
- alpha: 0.2,
- scaleX: 1.5,
- scaleY: 1.5
+ alpha: 0.5,
+ scaleX: 1.2,
+ scaleY: 1.2
}, {
- duration: 300,
- easing: tween.elasticOut,
+ duration: 200,
+ easing: tween.easeOut,
onFinish: function onFinish() {
tween(playerGraphics, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
- duration: 300,
- easing: tween.elasticOut
+ duration: 200,
+ easing: tween.easeOut
});
}
});
// Create a powerup aura
@@ -624,8 +633,9 @@
});
levelTxt.anchor.set(1, 0);
LK.gui.topLeft.addChild(levelTxt);
levelTxt.x = 250; // Make sure it's not in the top-left corner
+levelTxt.y = 50; // Adjust Y position as well
var healthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0.5,
scaleX: 1,
@@ -735,9 +745,9 @@
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
- duration: 300,
+ duration: 500,
easing: tween.easeOutBack
});
}
// Spawn asteroid
@@ -753,9 +763,9 @@
tween(asteroid, {
alpha: 1,
rotation: Math.random() * Math.PI * 2
}, {
- duration: 500,
+ duration: 800,
easing: tween.easeOut
});
}
// Spawn boss
@@ -793,26 +803,61 @@
impact.duration = 15; // Shorter duration for impact
game.addChild(impact);
enemy.takeDamage(bullet.damage);
bullet.removeFromGame();
+ // Add a brief visual impact to the enemy
+ tween(enemy, {
+ tint: 0xFFFFFF
+ }, {
+ duration: 50,
+ onFinish: function onFinish() {
+ enemy.tint = 0xFF0000;
+ }
+ });
break;
}
}
// Check against asteroids
for (var j = asteroids.length - 1; j >= 0; j--) {
var asteroid = asteroids[j];
if (bullet.intersects(asteroid)) {
+ // Create small impact effect
+ var impact = new Explosion(bullet.x, bullet.y, 0.3);
+ impact.duration = 15; // Shorter duration for impact
+ game.addChild(impact);
asteroid.takeDamage(bullet.damage);
bullet.removeFromGame();
+ // Add a brief visual impact to the asteroid
+ tween(asteroid, {
+ tint: 0xFFFFFF
+ }, {
+ duration: 50,
+ onFinish: function onFinish() {
+ asteroid.tint = 0x999999;
+ }
+ });
break;
}
}
// Check against bosses
for (var j = bosses.length - 1; j >= 0; j--) {
var boss = bosses[j];
if (bullet.intersects(boss) && boss.active) {
+ // Create small impact effect
+ var impact = new Explosion(bullet.x, bullet.y, 0.3);
+ impact.duration = 15; // Shorter duration for impact
+ game.addChild(impact);
boss.takeDamage(bullet.damage);
bullet.removeFromGame();
+ // Add a brief visual impact to the boss
+ tween(boss, {
+ tint: 0xFFFFFF
+ }, {
+ duration: 50,
+ onFinish: function onFinish() {
+ boss.tint = 0xff3300;
+ }
+ });
break;
}
}
}
@@ -919,8 +964,17 @@
game.stars.push(star);
}
// Add pulsating effect to start text
game.pulseValue = 0;
+ // Add pulsing to the start text using tween
+ tween(game.startText, {
+ alpha: 0.5
+ }, {
+ duration: 1000,
+ easing: tween.easeInOut,
+ loop: true,
+ yoyo: true
+ });
}
// Animate stars in start screen
if (game.stars) {
game.pulseValue += 0.05;
@@ -962,11 +1016,18 @@
progressTxt.setText('BOSS FIGHT!');
if (!progressTxt.pulsating) {
progressTxt.pulsating = true;
progressTxt.pulseValue = 0;
+ tween(progressTxt.scale, {
+ x: 1.2,
+ y: 1.2
+ }, {
+ duration: 300,
+ easing: tween.easeInOut,
+ loop: true,
+ yoyo: true
+ });
}
- progressTxt.pulseValue = (progressTxt.pulseValue || 0) + 0.1;
- progressTxt.scale.set(1 + Math.sin(progressTxt.pulseValue) * 0.2);
progressBar.tint = 0xFF0000;
progressBar.scaleX = 1;
}
if (player) {
asteroid. In-Game asset. 2d. High contrast. No shadows
spaceship enemy. In-Game asset. 2d. High contrast. No shadows
enemyBullet. In-Game asset. 2d. High contrast. No shadows
playerBullet. In-Game asset. 2d. High contrast. No shadows
explosion. In-Game asset. 2d. High contrast. No shadows
powerup. In-Game asset. 2d. High contrast. No shadows
boss spaceship. In-Game asset. 2d. High contrast. No shadows