User prompt
the release distance per bullet is 0.5 seconds
User prompt
bullet interval 0,5 second
User prompt
smooth swipe control
User prompt
add background
User prompt
delete multiple rapid bullet
User prompt
delete multiple bullet
User prompt
delete multiple bullet
Code edit (1 edits merged)
Please save this source code
User prompt
Thunder Wizard: Arcane Defense
Initial prompt
make 2d vertical shooter game. wizard spell thunder fom bottom. attac enemy from upper
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0 }); /**** * Classes ****/ var Enemy = Container.expand(function () { var self = Container.call(this); var graphic = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2 + Math.random() * 1.5; self.health = 1; self.points = 10; self.canShoot = Math.random() > 0.7; self.shotDelay = 60 + Math.floor(Math.random() * 120); self.shotTimer = self.shotDelay; self.movePattern = Math.floor(Math.random() * 3); self.amplitude = 30 + Math.random() * 50; self.frequency = 0.01 + Math.random() * 0.02; self.baseX = 0; self.angle = Math.random() * Math.PI * 2; self.init = function (x, y) { self.x = x; self.y = y; self.baseX = x; }; self.hit = function (power) { self.health -= power; // Visual feedback for hit tween(graphic, { alpha: 0.2 }, { duration: 100, easing: tween.linear, onFinish: function onFinish() { tween(graphic, { alpha: 1 }, { duration: 100, easing: tween.linear }); } }); return self.health <= 0; }; self.update = function () { self.y += self.speed; // Different movement patterns if (self.movePattern === 0) { // Sine wave movement self.x = self.baseX + Math.sin(self.angle) * self.amplitude; self.angle += self.frequency; } else if (self.movePattern === 1) { // Zig-zag movement if (Math.abs(self.x - self.baseX) > self.amplitude) { self.frequency = -self.frequency; } self.x += self.frequency * 5; } // Handle shooting if (self.canShoot) { self.shotTimer--; if (self.shotTimer <= 0) { self.shotTimer = self.shotDelay; return true; // Signal to create projectile } } return false; }; return self; }); var BossEnemy = Enemy.expand(function () { var self = Enemy.call(this); // Replace the graphic with boss graphic self.removeChildren(); var graphic = self.attachAsset('enemyBoss', { anchorX: 0.5, anchorY: 0.5 }); self.health = 10; self.points = 100; self.speed = 1; self.canShoot = true; self.shotDelay = 40; self.shotTimer = self.shotDelay; self.movePattern = 0; // Override the update method to add boss-specific behavior var parentUpdate = self.update; self.update = function () { // First few seconds, boss moves down slowly if (self.y < 300) { self.y += self.speed; return false; } // Then use parent update logic for movement and shooting return parentUpdate.call(self); }; return self; }); var EnemyProjectile = Container.expand(function () { var self = Container.call(this); var graphic = self.attachAsset('enemyProjectile', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 6; self.angle = 0; self.init = function (x, y, targetX, targetY) { self.x = x; self.y = y; // Calculate angle to target (usually the player) if (targetX !== undefined && targetY !== undefined) { var dx = targetX - x; var dy = targetY - y; self.angle = Math.atan2(dy, dx); } else { self.angle = Math.PI / 2; // Default: straight down } }; self.update = function () { self.x += Math.cos(self.angle) * self.speed; self.y += Math.sin(self.angle) * self.speed; }; return self; }); var Explosion = Container.expand(function () { var self = Container.call(this); var graphic = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5, alpha: 0.9 }); self.lifetime = 20; self.init = function (x, y, size) { self.x = x; self.y = y; if (size) { graphic.scale.set(size, size); } // Start with small scale and grow quickly graphic.scale.set(0.2, 0.2); tween(graphic.scale, { x: 1, y: 1 }, { duration: 300, easing: tween.easeOut }); // Fade out tween(graphic, { alpha: 0 }, { duration: 500, easing: tween.linear }); }; self.update = function () { self.lifetime--; return self.lifetime <= 0; }; return self; }); var Lightning = Container.expand(function () { var self = Container.call(this); var bolt = self.attachAsset('lightning', { anchorX: 0.5, anchorY: 1.0, alpha: 0.9 }); self.speed = -15; self.power = 1; self.chainLightningEnabled = false; // Branch lightning for power attacks self.createBranches = function (numBranches) { for (var i = 0; i < numBranches; i++) { var branch = self.attachAsset('lightningBranch', { anchorX: 0.5, anchorY: 1.0, alpha: 0.7, rotation: Math.random() * 0.5 - 0.25 + (i % 2 ? 0.3 : -0.3) }); branch.x = Math.random() * 20 - 10; branch.y = bolt.height * (0.3 + Math.random() * 0.4); } }; self.update = function () { self.y += self.speed; // Add flicker effect to lightning bolt.alpha = 0.7 + Math.random() * 0.3; // Add slight random movement for natural feel bolt.rotation = Math.random() * 0.1 - 0.05; }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var graphic = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3; self.type = Math.floor(Math.random() * 3); // 0: chain lightning, 1: increased power, 2: rapid fire // Set different colors based on powerup type if (self.type === 0) { graphic.tint = 0x00ffff; // Cyan for chain lightning } else if (self.type === 1) { graphic.tint = 0xff00ff; // Purple for increased power } else { graphic.tint = 0xffff00; // Yellow for rapid fire } self.init = function (x, y) { self.x = x; self.y = y; }; self.update = function () { self.y += self.speed; // Pulsate effect var scale = 0.9 + 0.2 * Math.sin(LK.ticks * 0.1); graphic.scale.set(scale, scale); }; return self; }); var Wizard = Container.expand(function () { var self = Container.call(this); // Create wizard body var body = self.attachAsset('wizard', { anchorX: 0.5, anchorY: 0.5 }); // Create wizard hat var hat = self.attachAsset('wizardHat', { anchorX: 0.5, anchorY: 1.0, y: -body.height / 2 }); self.fireCooldown = 0; self.fireRate = 20; // Lower = faster firing self.powerLevel = 1; self.chainLightning = false; self.powerupTimer = 0; self.invulnerable = false; self.invulnerableTimer = 0; self.update = function () { if (self.fireCooldown > 0) { self.fireCooldown--; } if (self.powerupTimer > 0) { self.powerupTimer--; // Visual indicator for active powerup body.alpha = 0.7 + 0.3 * Math.sin(LK.ticks * 0.2); // Reset powerups when timer expires if (self.powerupTimer === 0) { self.powerLevel = 1; self.chainLightning = false; self.fireRate = 20; body.alpha = 1; } } if (self.invulnerable) { self.invulnerableTimer--; if (self.invulnerableTimer <= 0) { self.invulnerable = false; body.alpha = 1; hat.alpha = 1; } else { // Flicker effect for invulnerability body.alpha = hat.alpha = LK.ticks % 4 < 2 ? 0.3 : 0.8; } } }; self.fire = function () { if (self.fireCooldown <= 0) { self.fireCooldown = self.fireRate; return true; } return false; }; self.applyPowerup = function (type) { self.powerupTimer = 600; // 10 seconds at 60fps if (type === 0) { // Chain lightning self.chainLightning = true; } else if (type === 1) { // Increased power self.powerLevel += 1; } else if (type === 2) { // Rapid fire self.fireRate = Math.max(5, self.fireRate - 5); } }; self.hit = function () { if (!self.invulnerable) { self.invulnerable = true; self.invulnerableTimer = 120; // 2 seconds invulnerability return true; } return false; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000022 }); /**** * Game Code ****/ // Game state variables var wizard; var lightnings = []; var enemies = []; var explosions = []; var powerups = []; var enemyProjectiles = []; var lives = 3; var score = 0; var highScore = storage.highScore || 0; var level = 1; var enemiesDefeated = 0; var enemySpawnTimer = 0; var bossActive = false; var levelClearDelay = 0; var gameActive = true; var shakeIntensity = 0; // UI elements var scoreText; var livesText; var levelText; // Game initialization function initGame() { // Add background var background = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5 }); background.x = 2048 / 2; background.y = 2732 / 2; game.addChild(background); // Initialize wizard wizard = new Wizard(); wizard.fireRate = 30; // Set fireRate to 30 ticks, equivalent to 0.5 seconds at 60 FPS wizard.x = 2048 / 2; wizard.y = 2732 - 200; game.addChild(wizard); // Setup UI scoreText = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); LK.gui.topRight.addChild(scoreText); livesText = new Text2('Lives: ' + lives, { size: 80, fill: 0xFFFFFF }); livesText.anchor.set(0, 0); LK.gui.top.addChild(livesText); levelText = new Text2('Level: ' + level, { size: 80, fill: 0xFFFFFF }); levelText.anchor.set(1, 0); LK.gui.topLeft.addChild(levelText); levelText.x = 200; // Move away from top-left corner // Start initial enemy spawn enemySpawnTimer = 60; // Start game music LK.playMusic('gameMusic', { fade: { start: 0, end: 0.7, duration: 1000 } }); } function updateScore(points) { score += points; scoreText.setText('Score: ' + score); // Update high score if needed if (score > highScore) { highScore = score; storage.highScore = highScore; } } function spawnEnemy() { // Determine if we should spawn a boss if (enemiesDefeated >= 20 * level && !bossActive) { var boss = new BossEnemy(); boss.init(2048 / 2, -100); enemies.push(boss); game.addChild(boss); bossActive = true; // Screen shake effect for boss entrance shakeIntensity = 10; return; } // Regular enemy spawn var enemy = new Enemy(); var x = 100 + Math.random() * (2048 - 200); var y = -100; enemy.init(x, y); enemies.push(enemy); game.addChild(enemy); } function nextLevel() { level++; levelText.setText('Level: ' + level); // Reset level variables enemiesDefeated = 0; bossActive = false; // Increase difficulty Enemy.prototype.speed += 0.3; // Visual effect for level transition LK.effects.flashScreen(0x0000ff, 500); } function createLightning(x, y) { var lightning = new Lightning(); lightning.x = x; lightning.y = y; lightning.power = wizard.powerLevel; lightning.chainLightningEnabled = wizard.chainLightning; // Add branches for higher power levels if (wizard.powerLevel > 1) { lightning.createBranches(wizard.powerLevel - 1); } lightnings.push(lightning); game.addChild(lightning); // Play lightning sound LK.getSound('lightning').play(); } function createExplosion(x, y, size) { var explosion = new Explosion(); explosion.init(x, y, size); explosions.push(explosion); game.addChild(explosion); // Play explosion sound LK.getSound('explosion').play(); } // Initialize the game initGame(); // Touch/mouse handlers var dragging = false; var lastX = null; game.down = function (x, y) { dragging = true; lastX = x; }; game.move = function (x, y) { if (dragging) { var deltaX = x - lastX; wizard.x += deltaX; // Keep wizard within bounds wizard.x = Math.max(50, Math.min(2048 - 50, wizard.x)); lastX = x; } }; game.up = function () { dragging = false; lastX = null; }; // Main game update game.update = function () { if (!gameActive) { return; } // Screen shake effect if (shakeIntensity > 0) { game.x = (Math.random() * 2 - 1) * shakeIntensity; game.y = (Math.random() * 2 - 1) * shakeIntensity; shakeIntensity *= 0.9; if (shakeIntensity < 0.5) { shakeIntensity = 0; game.x = 0; game.y = 0; } } // Update wizard wizard.update(); // Auto-fire if (wizard.fire()) { createLightning(wizard.x, wizard.y - 50); } // Level transition if (levelClearDelay > 0) { levelClearDelay--; if (levelClearDelay === 0) { nextLevel(); } return; // Pause other updates during level transition } // Enemy spawn logic if (enemySpawnTimer > 0) { enemySpawnTimer--; } else { spawnEnemy(); // Adjust spawn rate based on level enemySpawnTimer = bossActive ? 120 : Math.max(20, 60 - level * 5); } // Update lightnings for (var i = lightnings.length - 1; i >= 0; i--) { var lightning = lightnings[i]; lightning.update(); // Remove lightning if off screen if (lightning.y < -100) { lightning.destroy(); lightnings.splice(i, 1); continue; } // Check for hits with enemies var hitEnemy = false; for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (lightning.intersects(enemy)) { hitEnemy = true; // Enemy takes damage if (enemy.hit(lightning.power)) { // Enemy defeated createExplosion(enemy.x, enemy.y, enemy instanceof BossEnemy ? 2 : 1); updateScore(enemy.points); enemiesDefeated++; // Check if boss was defeated if (enemy instanceof BossEnemy) { bossActive = false; levelClearDelay = 120; // 2 second delay before next level LK.effects.flashScreen(0xffffff, 300); } // Chance to drop power-up if (Math.random() < 0.2) { var powerup = new PowerUp(); powerup.init(enemy.x, enemy.y); powerups.push(powerup); game.addChild(powerup); } enemy.destroy(); enemies.splice(j, 1); } else { // Enemy hit but not defeated LK.getSound('enemyHit').play(); } // Remove lightning unless it has chain lightning if (!lightning.chainLightningEnabled) { lightning.destroy(); lightnings.splice(i, 1); continue; // Use continue to check other enemies } } } } // Update enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; var shouldShoot = enemy.update(); // Check if enemy has moved off screen if (enemy.y > 2732 + 100) { enemy.destroy(); enemies.splice(i, 1); continue; } // Enemy shoots projectile if (shouldShoot) { var projectile = new EnemyProjectile(); projectile.init(enemy.x, enemy.y, wizard.x, wizard.y); enemyProjectiles.push(projectile); game.addChild(projectile); } } // Update enemy projectiles for (var i = enemyProjectiles.length - 1; i >= 0; i--) { var projectile = enemyProjectiles[i]; projectile.update(); // Check if projectile is off screen if (projectile.y > 2732 + 20 || projectile.y < -20 || projectile.x > 2048 + 20 || projectile.x < -20) { projectile.destroy(); enemyProjectiles.splice(i, 1); continue; } // Check for collision with wizard if (projectile.intersects(wizard)) { if (wizard.hit()) { // Player was hit LK.getSound('playerHit').play(); lives--; livesText.setText('Lives: ' + lives); // Create explosion effect createExplosion(projectile.x, projectile.y, 0.5); // Screen shake shakeIntensity = 5; // Check for game over if (lives <= 0) { gameActive = false; LK.effects.flashScreen(0xff0000, 1000); LK.setTimeout(function () { LK.showGameOver(); }, 1500); } } // Remove projectile projectile.destroy(); enemyProjectiles.splice(i, 1); } } // Update powerups for (var i = powerups.length - 1; i >= 0; i--) { var powerup = powerups[i]; powerup.update(); // Check if powerup is off screen if (powerup.y > 2732 + 30) { powerup.destroy(); powerups.splice(i, 1); continue; } // Check for collision with wizard if (powerup.intersects(wizard)) { // Apply powerup effect wizard.applyPowerup(powerup.type); // Play sound LK.getSound('powerupCollect').play(); // Visual feedback LK.effects.flashObject(wizard, 0x00ffff, 500); // Remove powerup powerup.destroy(); powerups.splice(i, 1); } } // Update explosions for (var i = explosions.length - 1; i >= 0; i--) { if (explosions[i].update()) { explosions[i].destroy(); explosions.splice(i, 1); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var Enemy = Container.expand(function () {
var self = Container.call(this);
var graphic = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2 + Math.random() * 1.5;
self.health = 1;
self.points = 10;
self.canShoot = Math.random() > 0.7;
self.shotDelay = 60 + Math.floor(Math.random() * 120);
self.shotTimer = self.shotDelay;
self.movePattern = Math.floor(Math.random() * 3);
self.amplitude = 30 + Math.random() * 50;
self.frequency = 0.01 + Math.random() * 0.02;
self.baseX = 0;
self.angle = Math.random() * Math.PI * 2;
self.init = function (x, y) {
self.x = x;
self.y = y;
self.baseX = x;
};
self.hit = function (power) {
self.health -= power;
// Visual feedback for hit
tween(graphic, {
alpha: 0.2
}, {
duration: 100,
easing: tween.linear,
onFinish: function onFinish() {
tween(graphic, {
alpha: 1
}, {
duration: 100,
easing: tween.linear
});
}
});
return self.health <= 0;
};
self.update = function () {
self.y += self.speed;
// Different movement patterns
if (self.movePattern === 0) {
// Sine wave movement
self.x = self.baseX + Math.sin(self.angle) * self.amplitude;
self.angle += self.frequency;
} else if (self.movePattern === 1) {
// Zig-zag movement
if (Math.abs(self.x - self.baseX) > self.amplitude) {
self.frequency = -self.frequency;
}
self.x += self.frequency * 5;
}
// Handle shooting
if (self.canShoot) {
self.shotTimer--;
if (self.shotTimer <= 0) {
self.shotTimer = self.shotDelay;
return true; // Signal to create projectile
}
}
return false;
};
return self;
});
var BossEnemy = Enemy.expand(function () {
var self = Enemy.call(this);
// Replace the graphic with boss graphic
self.removeChildren();
var graphic = self.attachAsset('enemyBoss', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 10;
self.points = 100;
self.speed = 1;
self.canShoot = true;
self.shotDelay = 40;
self.shotTimer = self.shotDelay;
self.movePattern = 0;
// Override the update method to add boss-specific behavior
var parentUpdate = self.update;
self.update = function () {
// First few seconds, boss moves down slowly
if (self.y < 300) {
self.y += self.speed;
return false;
}
// Then use parent update logic for movement and shooting
return parentUpdate.call(self);
};
return self;
});
var EnemyProjectile = Container.expand(function () {
var self = Container.call(this);
var graphic = self.attachAsset('enemyProjectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.angle = 0;
self.init = function (x, y, targetX, targetY) {
self.x = x;
self.y = y;
// Calculate angle to target (usually the player)
if (targetX !== undefined && targetY !== undefined) {
var dx = targetX - x;
var dy = targetY - y;
self.angle = Math.atan2(dy, dx);
} else {
self.angle = Math.PI / 2; // Default: straight down
}
};
self.update = function () {
self.x += Math.cos(self.angle) * self.speed;
self.y += Math.sin(self.angle) * self.speed;
};
return self;
});
var Explosion = Container.expand(function () {
var self = Container.call(this);
var graphic = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.9
});
self.lifetime = 20;
self.init = function (x, y, size) {
self.x = x;
self.y = y;
if (size) {
graphic.scale.set(size, size);
}
// Start with small scale and grow quickly
graphic.scale.set(0.2, 0.2);
tween(graphic.scale, {
x: 1,
y: 1
}, {
duration: 300,
easing: tween.easeOut
});
// Fade out
tween(graphic, {
alpha: 0
}, {
duration: 500,
easing: tween.linear
});
};
self.update = function () {
self.lifetime--;
return self.lifetime <= 0;
};
return self;
});
var Lightning = Container.expand(function () {
var self = Container.call(this);
var bolt = self.attachAsset('lightning', {
anchorX: 0.5,
anchorY: 1.0,
alpha: 0.9
});
self.speed = -15;
self.power = 1;
self.chainLightningEnabled = false;
// Branch lightning for power attacks
self.createBranches = function (numBranches) {
for (var i = 0; i < numBranches; i++) {
var branch = self.attachAsset('lightningBranch', {
anchorX: 0.5,
anchorY: 1.0,
alpha: 0.7,
rotation: Math.random() * 0.5 - 0.25 + (i % 2 ? 0.3 : -0.3)
});
branch.x = Math.random() * 20 - 10;
branch.y = bolt.height * (0.3 + Math.random() * 0.4);
}
};
self.update = function () {
self.y += self.speed;
// Add flicker effect to lightning
bolt.alpha = 0.7 + Math.random() * 0.3;
// Add slight random movement for natural feel
bolt.rotation = Math.random() * 0.1 - 0.05;
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var graphic = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.type = Math.floor(Math.random() * 3); // 0: chain lightning, 1: increased power, 2: rapid fire
// Set different colors based on powerup type
if (self.type === 0) {
graphic.tint = 0x00ffff; // Cyan for chain lightning
} else if (self.type === 1) {
graphic.tint = 0xff00ff; // Purple for increased power
} else {
graphic.tint = 0xffff00; // Yellow for rapid fire
}
self.init = function (x, y) {
self.x = x;
self.y = y;
};
self.update = function () {
self.y += self.speed;
// Pulsate effect
var scale = 0.9 + 0.2 * Math.sin(LK.ticks * 0.1);
graphic.scale.set(scale, scale);
};
return self;
});
var Wizard = Container.expand(function () {
var self = Container.call(this);
// Create wizard body
var body = self.attachAsset('wizard', {
anchorX: 0.5,
anchorY: 0.5
});
// Create wizard hat
var hat = self.attachAsset('wizardHat', {
anchorX: 0.5,
anchorY: 1.0,
y: -body.height / 2
});
self.fireCooldown = 0;
self.fireRate = 20; // Lower = faster firing
self.powerLevel = 1;
self.chainLightning = false;
self.powerupTimer = 0;
self.invulnerable = false;
self.invulnerableTimer = 0;
self.update = function () {
if (self.fireCooldown > 0) {
self.fireCooldown--;
}
if (self.powerupTimer > 0) {
self.powerupTimer--;
// Visual indicator for active powerup
body.alpha = 0.7 + 0.3 * Math.sin(LK.ticks * 0.2);
// Reset powerups when timer expires
if (self.powerupTimer === 0) {
self.powerLevel = 1;
self.chainLightning = false;
self.fireRate = 20;
body.alpha = 1;
}
}
if (self.invulnerable) {
self.invulnerableTimer--;
if (self.invulnerableTimer <= 0) {
self.invulnerable = false;
body.alpha = 1;
hat.alpha = 1;
} else {
// Flicker effect for invulnerability
body.alpha = hat.alpha = LK.ticks % 4 < 2 ? 0.3 : 0.8;
}
}
};
self.fire = function () {
if (self.fireCooldown <= 0) {
self.fireCooldown = self.fireRate;
return true;
}
return false;
};
self.applyPowerup = function (type) {
self.powerupTimer = 600; // 10 seconds at 60fps
if (type === 0) {
// Chain lightning
self.chainLightning = true;
} else if (type === 1) {
// Increased power
self.powerLevel += 1;
} else if (type === 2) {
// Rapid fire
self.fireRate = Math.max(5, self.fireRate - 5);
}
};
self.hit = function () {
if (!self.invulnerable) {
self.invulnerable = true;
self.invulnerableTimer = 120; // 2 seconds invulnerability
return true;
}
return false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000022
});
/****
* Game Code
****/
// Game state variables
var wizard;
var lightnings = [];
var enemies = [];
var explosions = [];
var powerups = [];
var enemyProjectiles = [];
var lives = 3;
var score = 0;
var highScore = storage.highScore || 0;
var level = 1;
var enemiesDefeated = 0;
var enemySpawnTimer = 0;
var bossActive = false;
var levelClearDelay = 0;
var gameActive = true;
var shakeIntensity = 0;
// UI elements
var scoreText;
var livesText;
var levelText;
// Game initialization
function initGame() {
// Add background
var background = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5
});
background.x = 2048 / 2;
background.y = 2732 / 2;
game.addChild(background);
// Initialize wizard
wizard = new Wizard();
wizard.fireRate = 30; // Set fireRate to 30 ticks, equivalent to 0.5 seconds at 60 FPS
wizard.x = 2048 / 2;
wizard.y = 2732 - 200;
game.addChild(wizard);
// Setup UI
scoreText = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreText);
livesText = new Text2('Lives: ' + lives, {
size: 80,
fill: 0xFFFFFF
});
livesText.anchor.set(0, 0);
LK.gui.top.addChild(livesText);
levelText = new Text2('Level: ' + level, {
size: 80,
fill: 0xFFFFFF
});
levelText.anchor.set(1, 0);
LK.gui.topLeft.addChild(levelText);
levelText.x = 200; // Move away from top-left corner
// Start initial enemy spawn
enemySpawnTimer = 60;
// Start game music
LK.playMusic('gameMusic', {
fade: {
start: 0,
end: 0.7,
duration: 1000
}
});
}
function updateScore(points) {
score += points;
scoreText.setText('Score: ' + score);
// Update high score if needed
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
}
}
function spawnEnemy() {
// Determine if we should spawn a boss
if (enemiesDefeated >= 20 * level && !bossActive) {
var boss = new BossEnemy();
boss.init(2048 / 2, -100);
enemies.push(boss);
game.addChild(boss);
bossActive = true;
// Screen shake effect for boss entrance
shakeIntensity = 10;
return;
}
// Regular enemy spawn
var enemy = new Enemy();
var x = 100 + Math.random() * (2048 - 200);
var y = -100;
enemy.init(x, y);
enemies.push(enemy);
game.addChild(enemy);
}
function nextLevel() {
level++;
levelText.setText('Level: ' + level);
// Reset level variables
enemiesDefeated = 0;
bossActive = false;
// Increase difficulty
Enemy.prototype.speed += 0.3;
// Visual effect for level transition
LK.effects.flashScreen(0x0000ff, 500);
}
function createLightning(x, y) {
var lightning = new Lightning();
lightning.x = x;
lightning.y = y;
lightning.power = wizard.powerLevel;
lightning.chainLightningEnabled = wizard.chainLightning;
// Add branches for higher power levels
if (wizard.powerLevel > 1) {
lightning.createBranches(wizard.powerLevel - 1);
}
lightnings.push(lightning);
game.addChild(lightning);
// Play lightning sound
LK.getSound('lightning').play();
}
function createExplosion(x, y, size) {
var explosion = new Explosion();
explosion.init(x, y, size);
explosions.push(explosion);
game.addChild(explosion);
// Play explosion sound
LK.getSound('explosion').play();
}
// Initialize the game
initGame();
// Touch/mouse handlers
var dragging = false;
var lastX = null;
game.down = function (x, y) {
dragging = true;
lastX = x;
};
game.move = function (x, y) {
if (dragging) {
var deltaX = x - lastX;
wizard.x += deltaX;
// Keep wizard within bounds
wizard.x = Math.max(50, Math.min(2048 - 50, wizard.x));
lastX = x;
}
};
game.up = function () {
dragging = false;
lastX = null;
};
// Main game update
game.update = function () {
if (!gameActive) {
return;
}
// Screen shake effect
if (shakeIntensity > 0) {
game.x = (Math.random() * 2 - 1) * shakeIntensity;
game.y = (Math.random() * 2 - 1) * shakeIntensity;
shakeIntensity *= 0.9;
if (shakeIntensity < 0.5) {
shakeIntensity = 0;
game.x = 0;
game.y = 0;
}
}
// Update wizard
wizard.update();
// Auto-fire
if (wizard.fire()) {
createLightning(wizard.x, wizard.y - 50);
}
// Level transition
if (levelClearDelay > 0) {
levelClearDelay--;
if (levelClearDelay === 0) {
nextLevel();
}
return; // Pause other updates during level transition
}
// Enemy spawn logic
if (enemySpawnTimer > 0) {
enemySpawnTimer--;
} else {
spawnEnemy();
// Adjust spawn rate based on level
enemySpawnTimer = bossActive ? 120 : Math.max(20, 60 - level * 5);
}
// Update lightnings
for (var i = lightnings.length - 1; i >= 0; i--) {
var lightning = lightnings[i];
lightning.update();
// Remove lightning if off screen
if (lightning.y < -100) {
lightning.destroy();
lightnings.splice(i, 1);
continue;
}
// Check for hits with enemies
var hitEnemy = false;
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (lightning.intersects(enemy)) {
hitEnemy = true;
// Enemy takes damage
if (enemy.hit(lightning.power)) {
// Enemy defeated
createExplosion(enemy.x, enemy.y, enemy instanceof BossEnemy ? 2 : 1);
updateScore(enemy.points);
enemiesDefeated++;
// Check if boss was defeated
if (enemy instanceof BossEnemy) {
bossActive = false;
levelClearDelay = 120; // 2 second delay before next level
LK.effects.flashScreen(0xffffff, 300);
}
// Chance to drop power-up
if (Math.random() < 0.2) {
var powerup = new PowerUp();
powerup.init(enemy.x, enemy.y);
powerups.push(powerup);
game.addChild(powerup);
}
enemy.destroy();
enemies.splice(j, 1);
} else {
// Enemy hit but not defeated
LK.getSound('enemyHit').play();
}
// Remove lightning unless it has chain lightning
if (!lightning.chainLightningEnabled) {
lightning.destroy();
lightnings.splice(i, 1);
continue; // Use continue to check other enemies
}
}
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
var shouldShoot = enemy.update();
// Check if enemy has moved off screen
if (enemy.y > 2732 + 100) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Enemy shoots projectile
if (shouldShoot) {
var projectile = new EnemyProjectile();
projectile.init(enemy.x, enemy.y, wizard.x, wizard.y);
enemyProjectiles.push(projectile);
game.addChild(projectile);
}
}
// Update enemy projectiles
for (var i = enemyProjectiles.length - 1; i >= 0; i--) {
var projectile = enemyProjectiles[i];
projectile.update();
// Check if projectile is off screen
if (projectile.y > 2732 + 20 || projectile.y < -20 || projectile.x > 2048 + 20 || projectile.x < -20) {
projectile.destroy();
enemyProjectiles.splice(i, 1);
continue;
}
// Check for collision with wizard
if (projectile.intersects(wizard)) {
if (wizard.hit()) {
// Player was hit
LK.getSound('playerHit').play();
lives--;
livesText.setText('Lives: ' + lives);
// Create explosion effect
createExplosion(projectile.x, projectile.y, 0.5);
// Screen shake
shakeIntensity = 5;
// Check for game over
if (lives <= 0) {
gameActive = false;
LK.effects.flashScreen(0xff0000, 1000);
LK.setTimeout(function () {
LK.showGameOver();
}, 1500);
}
}
// Remove projectile
projectile.destroy();
enemyProjectiles.splice(i, 1);
}
}
// Update powerups
for (var i = powerups.length - 1; i >= 0; i--) {
var powerup = powerups[i];
powerup.update();
// Check if powerup is off screen
if (powerup.y > 2732 + 30) {
powerup.destroy();
powerups.splice(i, 1);
continue;
}
// Check for collision with wizard
if (powerup.intersects(wizard)) {
// Apply powerup effect
wizard.applyPowerup(powerup.type);
// Play sound
LK.getSound('powerupCollect').play();
// Visual feedback
LK.effects.flashObject(wizard, 0x00ffff, 500);
// Remove powerup
powerup.destroy();
powerups.splice(i, 1);
}
}
// Update explosions
for (var i = explosions.length - 1; i >= 0; i--) {
if (explosions[i].update()) {
explosions[i].destroy();
explosions.splice(i, 1);
}
}
};
2d 16 bit classic image jellyfish. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
2d 16 bit image classic image evil jellyfish. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
epic blue 16 bit bubble pieces explode. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
shining plankton. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
15 bit image red crab. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
32 bit image anime style of beautyfull quite empty under sea water. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
2d 16 bit silver pearl shell top down. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
shining sea bubble. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows