/**** * 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