User prompt
May it give you exactly 100 lives and renew your life.
User prompt
Health restoration spell costs 130 mana ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Cast a spell that costs 100 mana and increases health, cooldown is 20 seconds. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
It leaves a poison cloud after the storm is over. Block, delete and fix this!
User prompt
The poison cloud disappears instantly and its ground dwell time is Make it 3.5 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (2 edits merged)
Please save this source code
User prompt
the particles coming out of the storm should follow the storm and disappear when the storm is over and a poison cloud comes out of the storm remove this add a 6.5 second cooldown to the poison cloud and The poison cloud will disappear in 3.5 seconds. Also, make the effects in the game better, for example, when the enemy is poisoned, they take a little damage every 0.3 seconds and their color is green, this effect goes away after 2 seconds, and when you throw ice at the enemy, they slow down and their color turns blue. and others ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When the wizard character uses storm power, he will start spinning and shrink and small particles will come out of the storm. When the storm power is finished, the wizard returns to normal size and finally the poison cloud remains on the ground for 3.2 seconds. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
use a new asset for the storm effect
User prompt
remove crystal wall ability
User prompt
Make the crystal wall bigger and increase the spacing of the walls so that 3.5 seconds enemies can't break it.
Code edit (2 edits merged)
Please save this source code
User prompt
Storm Force pushes enemies much further away
Code edit (1 edits merged)
Please save this source code
User prompt
Add a spell called mana restorer, the spell does not require mana, it instantly fills our mana when used. but it adds 6 seconds of incapacity to all powers and it has a 10 second cooldown.
User prompt
Increase the size of the spell buttons a bit and also the spell button texts and arrange them at appropriate intervals.
User prompt
The newly added power (storm) does not have a button or is not visible
User prompt
Add storm power, when you use it, our character will start spinning and create a storm that follows itself, this storm will push everything back a lot and deal a little damage Let it take 3.5 seconds, the waiting time is 8.7 seconds ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Crystal Wall Power: Spawns a large, shiny, purple triangle-shaped stone that lasts for 3.5 seconds and blocks enemies
User prompt
Manas are filling up very fast, reduce the speed
User prompt
There is a bug in the game, the enemies suddenly become immortal, and also change the time slowing power to stop power, make everything stop for 1.5 seconds, add a 4.5 second cooldown When you use a spell with a cooldown, the name of the spell should be duration and the crystal wall power should stun the enemies that touch the walls for 0.7 seconds and finally the poison power should damage the enemies for 1 second every 0.3 seconds Let it damage
User prompt
add mana to the game if mana runs out the player cannot use spells depending on the power of the spells they will spend less or more mana the mana is automatically renewed there will be a blue colored bar the mana bar will have a maximum of 180 mana
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Enemy = Container.expand(function (enemyType) { var self = Container.call(this); self.enemyType = enemyType; self.health = 1; self.speed = 2; self.damage = 1; self.points = 10; self.lastHitTime = 0; self.slowedTimer = 0; self.originalSpeed = 0; var enemyGraphics; if (enemyType === 'goblin') { enemyGraphics = self.attachAsset('goblin', { anchorX: 0.5, anchorY: 0.5 }); self.health = 1; self.speed = 3; self.points = 10; } else if (enemyType === 'demon') { enemyGraphics = self.attachAsset('demon', { anchorX: 0.5, anchorY: 0.5 }); self.health = 3; self.speed = 1.5; self.points = 30; } else if (enemyType === 'flyingEye') { enemyGraphics = self.attachAsset('flyingEye', { anchorX: 0.5, anchorY: 0.5 }); self.health = 1; self.speed = 4; self.points = 20; } else if (enemyType === 'golem') { enemyGraphics = self.attachAsset('golem', { anchorX: 0.5, anchorY: 0.5 }); self.health = 5; self.speed = 1; self.points = 50; } else if (enemyType === 'skeleton') { enemyGraphics = self.attachAsset('skeleton', { anchorX: 0.5, anchorY: 0.5 }); self.health = 2; self.speed = 2; self.points = 20; } else if (enemyType === 'mushroom') { enemyGraphics = self.attachAsset('mushroom', { anchorX: 0.5, anchorY: 0.5 }); self.health = 1; self.speed = 1; self.points = 15; } else if (enemyType === 'hellhound') { enemyGraphics = self.attachAsset('hellhound', { anchorX: 0.5, anchorY: 0.5 }); self.health = 2; self.speed = 5; self.points = 25; } else if (enemyType === 'darkSorcerer') { enemyGraphics = self.attachAsset('darkSorcerer', { anchorX: 0.5, anchorY: 0.5 }); self.health = 3; self.speed = 1.5; self.points = 40; } self.maxHealth = self.health; // Spawn from random edge var edge = Math.floor(Math.random() * 4); if (edge === 0) { // Top self.x = Math.random() * 2048; self.y = -50; } else if (edge === 1) { // Right self.x = 2048 + 50; self.y = Math.random() * 2732; } else if (edge === 2) { // Bottom self.x = Math.random() * 2048; self.y = 2732 + 50; } else { // Left self.x = -50; self.y = Math.random() * 2732; } self.applySlowEffect = function () { if (self.slowedTimer <= 0) { self.originalSpeed = self.speed; } self.slowedTimer = 180; // 3 seconds self.speed = self.originalSpeed * 0.3; // 70% speed reduction tween(enemyGraphics, { tint: 0x87CEEB }, { duration: 200 }); }; self.takeDamage = function (damage) { self.health -= damage; self.lastHitTime = LK.ticks; // Flash red when hit tween(enemyGraphics, { tint: 0xFF0000 }, { duration: 100, onFinish: function onFinish() { tween(enemyGraphics, { tint: 0xFFFFFF }, { duration: 100 }); } }); LK.getSound('enemyHit').play(); if (self.health <= 0) { return true; // Enemy is dead } return false; }; self.update = function () { // Handle slow effect if (self.slowedTimer > 0) { self.slowedTimer--; if (self.slowedTimer <= 0) { self.speed = self.originalSpeed; tween(enemyGraphics, { tint: 0xFFFFFF }, { duration: 200 }); } } // Move towards wizard var dx = wizard.x - self.x; var dy = wizard.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { var moveX = dx / distance * self.speed; var moveY = dy / distance * self.speed; // Flying eye has erratic movement if (self.enemyType === 'flyingEye') { moveX += (Math.random() - 0.5) * 2; moveY += (Math.random() - 0.5) * 2; } self.x += moveX; self.y += moveY; } }; return self; }); var Spell = Container.expand(function (spellType, startX, startY, targetX, targetY) { var self = Container.call(this); self.spellType = spellType; self.speed = 8; self.damage = 1; self.lifeTime = 180; // 3 seconds at 60fps self.age = 0; var spellGraphics; if (spellType === 'fireball') { spellGraphics = self.attachAsset('fireball', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 2; } else if (spellType === 'iceShard') { spellGraphics = self.attachAsset('iceShard', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 1; self.slowEffect = true; } else if (spellType === 'lightning') { spellGraphics = self.attachAsset('lightning', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 3; self.speed = 15; } else if (spellType === 'poisonCloud') { spellGraphics = self.attachAsset('poisonCloud', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 1; self.speed = 0; self.lifeTime = 300; spellGraphics.alpha = 0.6; } else if (spellType === 'explosion') { spellGraphics = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 4; self.speed = 0; self.lifeTime = 30; spellGraphics.alpha = 0.8; } self.x = startX; self.y = startY; // Calculate direction var dx = targetX - startX; var dy = targetY - startY; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.velocityX = dx / distance * self.speed; self.velocityY = dy / distance * self.speed; } else { self.velocityX = 0; self.velocityY = 0; } self.createExplosion = function () { var explosion = new Spell('explosion', self.x, self.y, self.x, self.y); spells.push(explosion); game.addChild(explosion); }; self.update = function () { self.age++; if (self.spellType !== 'poisonCloud' && self.spellType !== 'explosion') { self.x += self.velocityX; self.y += self.velocityY; } if (self.spellType === 'explosion') { var scale = 1 + self.age / 30 * 2; spellGraphics.scaleX = scale; spellGraphics.scaleY = scale; } }; return self; }); var SpellButton = Container.expand(function (spellType, buttonX, buttonY) { var self = Container.call(this); self.spellType = spellType; self.cooldown = 0; self.maxCooldown = 60; // 1 second self.manaCost = 10; // Default mana cost var buttonBg = self.attachAsset('spellButton', { anchorX: 0.5, anchorY: 0.5 }); var spellNames = { 'fireball': 'Fire', 'iceShard': 'Ice', 'lightning': 'Bolt', 'shield': 'Shield', 'teleport': 'Port', 'poisonCloud': 'Poison', 'mindControl': 'Mind', 'crystalWall': 'Wall', 'explosion': 'Boom', 'timeSlow': 'Slow' }; var buttonText = new Text2(spellNames[spellType] || spellType, { size: 24, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.x = buttonX; self.y = buttonY; // Set different cooldowns and mana costs for different spells if (spellType === 'fireball') { self.maxCooldown = 30; self.manaCost = 15; } else if (spellType === 'iceShard') { self.maxCooldown = 25; self.manaCost = 10; } else if (spellType === 'lightning') { self.maxCooldown = 45; self.manaCost = 25; } else if (spellType === 'shield') { self.maxCooldown = 180; self.manaCost = 40; } else if (spellType === 'teleport') { self.maxCooldown = 120; self.manaCost = 30; } else if (spellType === 'poisonCloud') { self.maxCooldown = 90; self.manaCost = 35; } else if (spellType === 'mindControl') { self.maxCooldown = 150; self.manaCost = 50; } else if (spellType === 'crystalWall') { self.maxCooldown = 100; self.manaCost = 35; } else if (spellType === 'explosion') { self.maxCooldown = 80; self.manaCost = 45; } else if (spellType === 'timeSlow') { self.maxCooldown = 200; self.manaCost = 60; } self.canCast = function () { return self.cooldown <= 0 && wizardMana >= self.manaCost; }; self.cast = function () { if (self.canCast()) { self.cooldown = self.maxCooldown; return true; } return false; }; self.update = function () { if (self.cooldown > 0) { self.cooldown--; buttonBg.tint = 0x666666; buttonText.fill = 0x999999; } else if (wizardMana < self.manaCost) { // Not enough mana - show blue tint buttonBg.tint = 0x4444FF; buttonText.fill = 0x8888FF; } else { buttonBg.tint = 0xFFFFFF; buttonText.fill = 0xFFFFFF; } }; self.down = function (x, y, obj) { if (self.canCast()) { castSpell(self.spellType); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ // Sounds // UI Elements // Enemies // Spells // Wizard // Game variables var wizard; var enemies = []; var spells = []; var spellButtons = []; var waveNumber = 1; var enemiesSpawned = 0; var enemiesPerWave = 5; var spawnTimer = 0; var spawnDelay = 120; // 2 seconds var gameTime = 0; var shieldActive = false; var shieldObject = null; var timeSlowActive = false; var timeSlowTimer = 0; var wizardHealth = 100; var wizardMaxHealth = 100; var wizardMana = 180; var wizardMaxMana = 180; var manaRegenRate = 0.5; // Mana regenerated per frame var healthBar = null; var healthBarFill = null; var manaBar = null; var manaBarFill = null; // Enemy types for spawning var enemyTypes = ['goblin', 'demon', 'flyingEye', 'golem', 'skeleton', 'mushroom', 'hellhound', 'darkSorcerer']; // Create wizard wizard = game.addChild(new Container()); var wizardGraphics = wizard.attachAsset('wizard', { anchorX: 0.5, anchorY: 0.5 }); wizard.x = 1024; wizard.y = 1366; // Create spell buttons var spellTypes = ['fireball', 'iceShard', 'lightning', 'shield', 'teleport', 'poisonCloud', 'mindControl', 'crystalWall', 'explosion', 'timeSlow']; for (var i = 0; i < spellTypes.length; i++) { var buttonX = 150 + i % 5 * 140; var buttonY = 2600 + Math.floor(i / 5) * 100; var button = new SpellButton(spellTypes[i], buttonX, buttonY); spellButtons.push(button); game.addChild(button); } // Create score display var scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); scoreTxt.x = 150; scoreTxt.y = 100; game.addChild(scoreTxt); // Create wave display var waveTxt = new Text2('Wave: 1', { size: 50, fill: 0xFFFF00 }); waveTxt.anchor.set(0, 0); waveTxt.x = 150; waveTxt.y = 180; game.addChild(waveTxt); // Create health bar healthBar = game.addChild(new Container()); var healthBarBg = healthBar.attachAsset('healthBarBg', { anchorX: 0, anchorY: 0 }); healthBarFill = healthBar.attachAsset('healthBarFill', { anchorX: 0, anchorY: 0 }); healthBar.x = 150; healthBar.y = 250; // Health bar text var healthTxt = new Text2('Health: 100/100', { size: 40, fill: 0xFFFFFF }); healthTxt.anchor.set(0, 0); healthTxt.x = 150; healthTxt.y = 280; game.addChild(healthTxt); // Create mana bar manaBar = game.addChild(new Container()); var manaBarBg = manaBar.attachAsset('manaBarBg', { anchorX: 0, anchorY: 0 }); manaBarFill = manaBar.attachAsset('manaBarFill', { anchorX: 0, anchorY: 0 }); manaBar.x = 150; manaBar.y = 330; // Mana bar text var manaTxt = new Text2('Mana: 180/180', { size: 40, fill: 0x0080FF }); manaTxt.anchor.set(0, 0); manaTxt.x = 150; manaTxt.y = 360; game.addChild(manaTxt); function castSpell(spellType) { // Find the button and check cooldown var button = null; for (var i = 0; i < spellButtons.length; i++) { if (spellButtons[i].spellType === spellType) { button = spellButtons[i]; break; } } if (!button || !button.cast()) return; // Consume mana wizardMana -= button.manaCost; if (wizardMana < 0) wizardMana = 0; // Update mana display var manaPercent = wizardMana / wizardMaxMana; manaBarFill.scaleX = manaPercent; manaTxt.setText('Mana: ' + Math.floor(wizardMana) + '/' + wizardMaxMana); LK.getSound('spellCast').play(); if (spellType === 'shield') { activateShield(); } else if (spellType === 'teleport') { teleportWizard(); } else if (spellType === 'timeSlow') { activateTimeSlow(); } else if (spellType === 'mindControl') { mindControlEnemies(); } else if (spellType === 'crystalWall') { createCrystalWall(); } else if (spellType === 'explosion') { // Explosion at wizard location var spell = new Spell(spellType, wizard.x, wizard.y, wizard.x, wizard.y); spells.push(spell); game.addChild(spell); } else { // Targeted spells - cast towards nearest enemy var nearestEnemy = findNearestEnemy(); if (nearestEnemy) { var spell = new Spell(spellType, wizard.x, wizard.y, nearestEnemy.x, nearestEnemy.y); spell.targetX = nearestEnemy.x; spell.targetY = nearestEnemy.y; spells.push(spell); game.addChild(spell); } } } function findNearestEnemy() { var nearest = null; var minDistance = Infinity; for (var i = 0; i < enemies.length; i++) { var dx = enemies[i].x - wizard.x; var dy = enemies[i].y - wizard.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < minDistance) { minDistance = distance; nearest = enemies[i]; } } return nearest; } function activateShield() { if (shieldObject) { shieldObject.destroy(); } shieldObject = game.addChild(new Container()); var shieldGraphics = shieldObject.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5 }); shieldGraphics.alpha = 0.5; shieldActive = true; LK.setTimeout(function () { if (shieldObject) { shieldObject.destroy(); shieldObject = null; } shieldActive = false; }, 3000); } function teleportWizard() { // Teleport to a safe random location var attempts = 0; var newX, newY; do { newX = 200 + Math.random() * (2048 - 400); newY = 200 + Math.random() * (2200 - 400); attempts++; } while (attempts < 10 && isLocationUnsafe(newX, newY)); wizard.x = newX; wizard.y = newY; // Teleport effect LK.effects.flashObject(wizard, 0x00FFFF, 500); } function isLocationUnsafe(x, y) { for (var i = 0; i < enemies.length; i++) { var dx = enemies[i].x - x; var dy = enemies[i].y - y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 150) return true; } return false; } function activateTimeSlow() { timeSlowActive = true; timeSlowTimer = 300; // 5 seconds LK.effects.flashScreen(0x0066FF, 200); // Visual effect on all enemies for (var i = 0; i < enemies.length; i++) { tween(enemies[i], { tint: 0x6666FF }, { duration: 300, onFinish: function onFinish() { if (!timeSlowActive) { tween(this, { tint: 0xFFFFFF }, { duration: 200 }); } } }); } } function mindControlEnemies() { var controlled = 0; for (var i = 0; i < enemies.length && controlled < 3; i++) { var dx = enemies[i].x - wizard.x; var dy = enemies[i].y - wizard.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 300) { // Mind control effect - purple flash then instant kill tween(enemies[i], { tint: 0x9932CC }, { duration: 200, onFinish: function onFinish() { tween(this, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 300, onFinish: function onFinish() { enemies[i].takeDamage(enemies[i].health); } }); } }); controlled++; } } } function createCrystalWall() { for (var i = 0; i < 5; i++) { var wallX = wizard.x - 100 + i * 50; var wallY = wizard.y - 150; var wall = new Container(); var wallGraphics = wall.attachAsset('crystalWall', { anchorX: 0.5, anchorY: 0.5 }); wall.x = wallX; wall.y = wallY; wall.health = 10; // Increased from 3 to 10 wall.lifeTime = 600; // 10 seconds wall.age = 0; wall.isWall = true; // Crystal sparkle effect tween(wallGraphics, { alpha: 0.7 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(wallGraphics, { alpha: 1 }, { duration: 1000, easing: tween.easeInOut }); } }); wall.update = function () { this.age++; if (this.age >= this.lifeTime) { var wallToDestroy = this; tween(wallGraphics, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 200, onFinish: function onFinish() { wallToDestroy.destroy(); } }); } }; spells.push(wall); game.addChild(wall); } } function damageWizard(damage) { wizardHealth -= damage; if (wizardHealth < 0) wizardHealth = 0; // Update health bar var healthPercent = wizardHealth / wizardMaxHealth; healthBarFill.scaleX = healthPercent; // Change color based on health if (healthPercent > 0.6) { healthBarFill.tint = 0x00ff00; // Green } else if (healthPercent > 0.3) { healthBarFill.tint = 0xffff00; // Yellow } else { healthBarFill.tint = 0xff0000; // Red } // Update health text healthTxt.setText('Health: ' + wizardHealth + '/' + wizardMaxHealth); if (wizardHealth <= 0) { LK.effects.flashScreen(0xFF0000, 500); LK.showGameOver(); } } function spawnEnemy() { if (enemiesSpawned < enemiesPerWave) { var enemyType = enemyTypes[Math.floor(Math.random() * Math.min(enemyTypes.length, 2 + Math.floor(waveNumber / 2)))]; var enemy = new Enemy(enemyType); enemies.push(enemy); game.addChild(enemy); enemiesSpawned++; } } function checkCollisions() { // Spells vs Enemies for (var s = spells.length - 1; s >= 0; s--) { var spell = spells[s]; // Area damage spells (explosion, poison cloud) if (spell.spellType === 'explosion' || spell.spellType === 'poisonCloud') { for (var e = enemies.length - 1; e >= 0; e--) { var enemy = enemies[e]; var dx = enemy.x - spell.x; var dy = enemy.y - spell.y; var distance = Math.sqrt(dx * dx + dy * dy); var damageRadius = spell.spellType === 'explosion' ? 120 : 80; if (distance < damageRadius) { var isDead = enemy.takeDamage(spell.damage); if (isDead) { LK.setScore(LK.getScore() + enemy.points); scoreTxt.setText('Score: ' + LK.getScore()); enemy.destroy(); enemies.splice(e, 1); LK.getSound('enemyDeath').play(); } } } } else { // Single target spells for (var e = enemies.length - 1; e >= 0; e--) { var enemy = enemies[e]; if (spell.intersects && spell.intersects(enemy)) { // Apply ice shard slow effect if (spell.slowEffect) { enemy.applySlowEffect(); } var isDead = enemy.takeDamage(spell.damage); if (isDead) { LK.setScore(LK.getScore() + enemy.points); scoreTxt.setText('Score: ' + LK.getScore()); enemy.destroy(); enemies.splice(e, 1); LK.getSound('enemyDeath').play(); } // Fireball creates explosion on impact if (spell.spellType === 'fireball') { spell.createExplosion(); } if (spell.spellType !== 'poisonCloud') { spell.destroy(); spells.splice(s, 1); break; } } } } } // Enemies vs Crystal Walls for (var w = spells.length - 1; w >= 0; w--) { var wall = spells[w]; if (wall.isWall) { for (var e = enemies.length - 1; e >= 0; e--) { var enemy = enemies[e]; if (enemy.intersects && enemy.intersects(wall)) { // Enemy damages wall wall.health -= 1; // Knock back enemy var dx = enemy.x - wall.x; var dy = enemy.y - wall.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { enemy.x += dx / distance * 50; enemy.y += dy / distance * 50; } // Destroy wall if health depleted if (wall.health <= 0) { wall.destroy(); spells.splice(w, 1); } // Flash wall when hit tween(wall, { tint: 0xFF0000 }, { duration: 100, onFinish: function onFinish() { tween(wall, { tint: 0xFFFFFF }, { duration: 100 }); } }); break; } } } } // Enemies vs Wizard for (var e = enemies.length - 1; e >= 0; e--) { var enemy = enemies[e]; if (enemy.intersects && enemy.intersects(wizard)) { if (!shieldActive) { // Only damage if enough time has passed since last hit if (LK.ticks - enemy.lastHitTime > 60) { // 1 second cooldown damageWizard(enemy.damage * 10); // Scale damage for visibility enemy.lastHitTime = LK.ticks; } } else { // Shield absorbs hit enemy.destroy(); enemies.splice(e, 1); if (shieldObject) { shieldObject.destroy(); shieldObject = null; shieldActive = false; } } } } } game.move = function (x, y, obj) { if (x > 100 && x < 1948 && y > 100 && y < 2200) { wizard.x = x; wizard.y = y; } }; game.update = function () { gameTime++; // Regenerate mana if (wizardMana < wizardMaxMana) { wizardMana += manaRegenRate; if (wizardMana > wizardMaxMana) { wizardMana = wizardMaxMana; } // Update mana display var manaPercent = wizardMana / wizardMaxMana; manaBarFill.scaleX = manaPercent; manaTxt.setText('Mana: ' + Math.floor(wizardMana) + '/' + wizardMaxMana); } // Update time slow if (timeSlowActive) { timeSlowTimer--; if (timeSlowTimer <= 0) { timeSlowActive = false; } } // Update shield position if (shieldObject) { shieldObject.x = wizard.x; shieldObject.y = wizard.y; } // Spawn enemies spawnTimer++; var actualSpawnDelay = timeSlowActive ? spawnDelay * 2 : spawnDelay; if (spawnTimer >= actualSpawnDelay) { spawnEnemy(); spawnTimer = 0; } // Update spells for (var s = spells.length - 1; s >= 0; s--) { var spell = spells[s]; spell.age++; if (spell.age >= spell.lifeTime || spell.x < -100 || spell.x > 2148 || spell.y < -100 || spell.y > 2832) { spell.destroy(); spells.splice(s, 1); } } // Update enemies with proper time slow effect for (var e = 0; e < enemies.length; e++) { if (timeSlowActive && !enemies[e].timeSlowApplied) { enemies[e].originalSpeed = enemies[e].speed; enemies[e].speed *= 0.3; // 70% speed reduction enemies[e].timeSlowApplied = true; } else if (!timeSlowActive && enemies[e].timeSlowApplied) { enemies[e].speed = enemies[e].originalSpeed; enemies[e].timeSlowApplied = false; } } // Check for wave completion if (enemiesSpawned >= enemiesPerWave && enemies.length === 0) { waveNumber++; enemiesSpawned = 0; enemiesPerWave = 5 + waveNumber * 2; spawnDelay = Math.max(30, 120 - waveNumber * 5); waveTxt.setText('Wave: ' + waveNumber); // Bonus points for completing wave LK.setScore(LK.getScore() + waveNumber * 50); scoreTxt.setText('Score: ' + LK.getScore()); } checkCollisions(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Enemy = Container.expand(function (enemyType) {
var self = Container.call(this);
self.enemyType = enemyType;
self.health = 1;
self.speed = 2;
self.damage = 1;
self.points = 10;
self.lastHitTime = 0;
self.slowedTimer = 0;
self.originalSpeed = 0;
var enemyGraphics;
if (enemyType === 'goblin') {
enemyGraphics = self.attachAsset('goblin', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 1;
self.speed = 3;
self.points = 10;
} else if (enemyType === 'demon') {
enemyGraphics = self.attachAsset('demon', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.speed = 1.5;
self.points = 30;
} else if (enemyType === 'flyingEye') {
enemyGraphics = self.attachAsset('flyingEye', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 1;
self.speed = 4;
self.points = 20;
} else if (enemyType === 'golem') {
enemyGraphics = self.attachAsset('golem', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 5;
self.speed = 1;
self.points = 50;
} else if (enemyType === 'skeleton') {
enemyGraphics = self.attachAsset('skeleton', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 2;
self.speed = 2;
self.points = 20;
} else if (enemyType === 'mushroom') {
enemyGraphics = self.attachAsset('mushroom', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 1;
self.speed = 1;
self.points = 15;
} else if (enemyType === 'hellhound') {
enemyGraphics = self.attachAsset('hellhound', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 2;
self.speed = 5;
self.points = 25;
} else if (enemyType === 'darkSorcerer') {
enemyGraphics = self.attachAsset('darkSorcerer', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.speed = 1.5;
self.points = 40;
}
self.maxHealth = self.health;
// Spawn from random edge
var edge = Math.floor(Math.random() * 4);
if (edge === 0) {
// Top
self.x = Math.random() * 2048;
self.y = -50;
} else if (edge === 1) {
// Right
self.x = 2048 + 50;
self.y = Math.random() * 2732;
} else if (edge === 2) {
// Bottom
self.x = Math.random() * 2048;
self.y = 2732 + 50;
} else {
// Left
self.x = -50;
self.y = Math.random() * 2732;
}
self.applySlowEffect = function () {
if (self.slowedTimer <= 0) {
self.originalSpeed = self.speed;
}
self.slowedTimer = 180; // 3 seconds
self.speed = self.originalSpeed * 0.3; // 70% speed reduction
tween(enemyGraphics, {
tint: 0x87CEEB
}, {
duration: 200
});
};
self.takeDamage = function (damage) {
self.health -= damage;
self.lastHitTime = LK.ticks;
// Flash red when hit
tween(enemyGraphics, {
tint: 0xFF0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(enemyGraphics, {
tint: 0xFFFFFF
}, {
duration: 100
});
}
});
LK.getSound('enemyHit').play();
if (self.health <= 0) {
return true; // Enemy is dead
}
return false;
};
self.update = function () {
// Handle slow effect
if (self.slowedTimer > 0) {
self.slowedTimer--;
if (self.slowedTimer <= 0) {
self.speed = self.originalSpeed;
tween(enemyGraphics, {
tint: 0xFFFFFF
}, {
duration: 200
});
}
}
// Move towards wizard
var dx = wizard.x - self.x;
var dy = wizard.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var moveX = dx / distance * self.speed;
var moveY = dy / distance * self.speed;
// Flying eye has erratic movement
if (self.enemyType === 'flyingEye') {
moveX += (Math.random() - 0.5) * 2;
moveY += (Math.random() - 0.5) * 2;
}
self.x += moveX;
self.y += moveY;
}
};
return self;
});
var Spell = Container.expand(function (spellType, startX, startY, targetX, targetY) {
var self = Container.call(this);
self.spellType = spellType;
self.speed = 8;
self.damage = 1;
self.lifeTime = 180; // 3 seconds at 60fps
self.age = 0;
var spellGraphics;
if (spellType === 'fireball') {
spellGraphics = self.attachAsset('fireball', {
anchorX: 0.5,
anchorY: 0.5
});
self.damage = 2;
} else if (spellType === 'iceShard') {
spellGraphics = self.attachAsset('iceShard', {
anchorX: 0.5,
anchorY: 0.5
});
self.damage = 1;
self.slowEffect = true;
} else if (spellType === 'lightning') {
spellGraphics = self.attachAsset('lightning', {
anchorX: 0.5,
anchorY: 0.5
});
self.damage = 3;
self.speed = 15;
} else if (spellType === 'poisonCloud') {
spellGraphics = self.attachAsset('poisonCloud', {
anchorX: 0.5,
anchorY: 0.5
});
self.damage = 1;
self.speed = 0;
self.lifeTime = 300;
spellGraphics.alpha = 0.6;
} else if (spellType === 'explosion') {
spellGraphics = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
});
self.damage = 4;
self.speed = 0;
self.lifeTime = 30;
spellGraphics.alpha = 0.8;
}
self.x = startX;
self.y = startY;
// Calculate direction
var dx = targetX - startX;
var dy = targetY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.velocityX = dx / distance * self.speed;
self.velocityY = dy / distance * self.speed;
} else {
self.velocityX = 0;
self.velocityY = 0;
}
self.createExplosion = function () {
var explosion = new Spell('explosion', self.x, self.y, self.x, self.y);
spells.push(explosion);
game.addChild(explosion);
};
self.update = function () {
self.age++;
if (self.spellType !== 'poisonCloud' && self.spellType !== 'explosion') {
self.x += self.velocityX;
self.y += self.velocityY;
}
if (self.spellType === 'explosion') {
var scale = 1 + self.age / 30 * 2;
spellGraphics.scaleX = scale;
spellGraphics.scaleY = scale;
}
};
return self;
});
var SpellButton = Container.expand(function (spellType, buttonX, buttonY) {
var self = Container.call(this);
self.spellType = spellType;
self.cooldown = 0;
self.maxCooldown = 60; // 1 second
self.manaCost = 10; // Default mana cost
var buttonBg = self.attachAsset('spellButton', {
anchorX: 0.5,
anchorY: 0.5
});
var spellNames = {
'fireball': 'Fire',
'iceShard': 'Ice',
'lightning': 'Bolt',
'shield': 'Shield',
'teleport': 'Port',
'poisonCloud': 'Poison',
'mindControl': 'Mind',
'crystalWall': 'Wall',
'explosion': 'Boom',
'timeSlow': 'Slow'
};
var buttonText = new Text2(spellNames[spellType] || spellType, {
size: 24,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.x = buttonX;
self.y = buttonY;
// Set different cooldowns and mana costs for different spells
if (spellType === 'fireball') {
self.maxCooldown = 30;
self.manaCost = 15;
} else if (spellType === 'iceShard') {
self.maxCooldown = 25;
self.manaCost = 10;
} else if (spellType === 'lightning') {
self.maxCooldown = 45;
self.manaCost = 25;
} else if (spellType === 'shield') {
self.maxCooldown = 180;
self.manaCost = 40;
} else if (spellType === 'teleport') {
self.maxCooldown = 120;
self.manaCost = 30;
} else if (spellType === 'poisonCloud') {
self.maxCooldown = 90;
self.manaCost = 35;
} else if (spellType === 'mindControl') {
self.maxCooldown = 150;
self.manaCost = 50;
} else if (spellType === 'crystalWall') {
self.maxCooldown = 100;
self.manaCost = 35;
} else if (spellType === 'explosion') {
self.maxCooldown = 80;
self.manaCost = 45;
} else if (spellType === 'timeSlow') {
self.maxCooldown = 200;
self.manaCost = 60;
}
self.canCast = function () {
return self.cooldown <= 0 && wizardMana >= self.manaCost;
};
self.cast = function () {
if (self.canCast()) {
self.cooldown = self.maxCooldown;
return true;
}
return false;
};
self.update = function () {
if (self.cooldown > 0) {
self.cooldown--;
buttonBg.tint = 0x666666;
buttonText.fill = 0x999999;
} else if (wizardMana < self.manaCost) {
// Not enough mana - show blue tint
buttonBg.tint = 0x4444FF;
buttonText.fill = 0x8888FF;
} else {
buttonBg.tint = 0xFFFFFF;
buttonText.fill = 0xFFFFFF;
}
};
self.down = function (x, y, obj) {
if (self.canCast()) {
castSpell(self.spellType);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Sounds
// UI Elements
// Enemies
// Spells
// Wizard
// Game variables
var wizard;
var enemies = [];
var spells = [];
var spellButtons = [];
var waveNumber = 1;
var enemiesSpawned = 0;
var enemiesPerWave = 5;
var spawnTimer = 0;
var spawnDelay = 120; // 2 seconds
var gameTime = 0;
var shieldActive = false;
var shieldObject = null;
var timeSlowActive = false;
var timeSlowTimer = 0;
var wizardHealth = 100;
var wizardMaxHealth = 100;
var wizardMana = 180;
var wizardMaxMana = 180;
var manaRegenRate = 0.5; // Mana regenerated per frame
var healthBar = null;
var healthBarFill = null;
var manaBar = null;
var manaBarFill = null;
// Enemy types for spawning
var enemyTypes = ['goblin', 'demon', 'flyingEye', 'golem', 'skeleton', 'mushroom', 'hellhound', 'darkSorcerer'];
// Create wizard
wizard = game.addChild(new Container());
var wizardGraphics = wizard.attachAsset('wizard', {
anchorX: 0.5,
anchorY: 0.5
});
wizard.x = 1024;
wizard.y = 1366;
// Create spell buttons
var spellTypes = ['fireball', 'iceShard', 'lightning', 'shield', 'teleport', 'poisonCloud', 'mindControl', 'crystalWall', 'explosion', 'timeSlow'];
for (var i = 0; i < spellTypes.length; i++) {
var buttonX = 150 + i % 5 * 140;
var buttonY = 2600 + Math.floor(i / 5) * 100;
var button = new SpellButton(spellTypes[i], buttonX, buttonY);
spellButtons.push(button);
game.addChild(button);
}
// Create score display
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
scoreTxt.x = 150;
scoreTxt.y = 100;
game.addChild(scoreTxt);
// Create wave display
var waveTxt = new Text2('Wave: 1', {
size: 50,
fill: 0xFFFF00
});
waveTxt.anchor.set(0, 0);
waveTxt.x = 150;
waveTxt.y = 180;
game.addChild(waveTxt);
// Create health bar
healthBar = game.addChild(new Container());
var healthBarBg = healthBar.attachAsset('healthBarBg', {
anchorX: 0,
anchorY: 0
});
healthBarFill = healthBar.attachAsset('healthBarFill', {
anchorX: 0,
anchorY: 0
});
healthBar.x = 150;
healthBar.y = 250;
// Health bar text
var healthTxt = new Text2('Health: 100/100', {
size: 40,
fill: 0xFFFFFF
});
healthTxt.anchor.set(0, 0);
healthTxt.x = 150;
healthTxt.y = 280;
game.addChild(healthTxt);
// Create mana bar
manaBar = game.addChild(new Container());
var manaBarBg = manaBar.attachAsset('manaBarBg', {
anchorX: 0,
anchorY: 0
});
manaBarFill = manaBar.attachAsset('manaBarFill', {
anchorX: 0,
anchorY: 0
});
manaBar.x = 150;
manaBar.y = 330;
// Mana bar text
var manaTxt = new Text2('Mana: 180/180', {
size: 40,
fill: 0x0080FF
});
manaTxt.anchor.set(0, 0);
manaTxt.x = 150;
manaTxt.y = 360;
game.addChild(manaTxt);
function castSpell(spellType) {
// Find the button and check cooldown
var button = null;
for (var i = 0; i < spellButtons.length; i++) {
if (spellButtons[i].spellType === spellType) {
button = spellButtons[i];
break;
}
}
if (!button || !button.cast()) return;
// Consume mana
wizardMana -= button.manaCost;
if (wizardMana < 0) wizardMana = 0;
// Update mana display
var manaPercent = wizardMana / wizardMaxMana;
manaBarFill.scaleX = manaPercent;
manaTxt.setText('Mana: ' + Math.floor(wizardMana) + '/' + wizardMaxMana);
LK.getSound('spellCast').play();
if (spellType === 'shield') {
activateShield();
} else if (spellType === 'teleport') {
teleportWizard();
} else if (spellType === 'timeSlow') {
activateTimeSlow();
} else if (spellType === 'mindControl') {
mindControlEnemies();
} else if (spellType === 'crystalWall') {
createCrystalWall();
} else if (spellType === 'explosion') {
// Explosion at wizard location
var spell = new Spell(spellType, wizard.x, wizard.y, wizard.x, wizard.y);
spells.push(spell);
game.addChild(spell);
} else {
// Targeted spells - cast towards nearest enemy
var nearestEnemy = findNearestEnemy();
if (nearestEnemy) {
var spell = new Spell(spellType, wizard.x, wizard.y, nearestEnemy.x, nearestEnemy.y);
spell.targetX = nearestEnemy.x;
spell.targetY = nearestEnemy.y;
spells.push(spell);
game.addChild(spell);
}
}
}
function findNearestEnemy() {
var nearest = null;
var minDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var dx = enemies[i].x - wizard.x;
var dy = enemies[i].y - wizard.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
minDistance = distance;
nearest = enemies[i];
}
}
return nearest;
}
function activateShield() {
if (shieldObject) {
shieldObject.destroy();
}
shieldObject = game.addChild(new Container());
var shieldGraphics = shieldObject.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5
});
shieldGraphics.alpha = 0.5;
shieldActive = true;
LK.setTimeout(function () {
if (shieldObject) {
shieldObject.destroy();
shieldObject = null;
}
shieldActive = false;
}, 3000);
}
function teleportWizard() {
// Teleport to a safe random location
var attempts = 0;
var newX, newY;
do {
newX = 200 + Math.random() * (2048 - 400);
newY = 200 + Math.random() * (2200 - 400);
attempts++;
} while (attempts < 10 && isLocationUnsafe(newX, newY));
wizard.x = newX;
wizard.y = newY;
// Teleport effect
LK.effects.flashObject(wizard, 0x00FFFF, 500);
}
function isLocationUnsafe(x, y) {
for (var i = 0; i < enemies.length; i++) {
var dx = enemies[i].x - x;
var dy = enemies[i].y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 150) return true;
}
return false;
}
function activateTimeSlow() {
timeSlowActive = true;
timeSlowTimer = 300; // 5 seconds
LK.effects.flashScreen(0x0066FF, 200);
// Visual effect on all enemies
for (var i = 0; i < enemies.length; i++) {
tween(enemies[i], {
tint: 0x6666FF
}, {
duration: 300,
onFinish: function onFinish() {
if (!timeSlowActive) {
tween(this, {
tint: 0xFFFFFF
}, {
duration: 200
});
}
}
});
}
}
function mindControlEnemies() {
var controlled = 0;
for (var i = 0; i < enemies.length && controlled < 3; i++) {
var dx = enemies[i].x - wizard.x;
var dy = enemies[i].y - wizard.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 300) {
// Mind control effect - purple flash then instant kill
tween(enemies[i], {
tint: 0x9932CC
}, {
duration: 200,
onFinish: function onFinish() {
tween(this, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
enemies[i].takeDamage(enemies[i].health);
}
});
}
});
controlled++;
}
}
}
function createCrystalWall() {
for (var i = 0; i < 5; i++) {
var wallX = wizard.x - 100 + i * 50;
var wallY = wizard.y - 150;
var wall = new Container();
var wallGraphics = wall.attachAsset('crystalWall', {
anchorX: 0.5,
anchorY: 0.5
});
wall.x = wallX;
wall.y = wallY;
wall.health = 10; // Increased from 3 to 10
wall.lifeTime = 600; // 10 seconds
wall.age = 0;
wall.isWall = true;
// Crystal sparkle effect
tween(wallGraphics, {
alpha: 0.7
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(wallGraphics, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeInOut
});
}
});
wall.update = function () {
this.age++;
if (this.age >= this.lifeTime) {
var wallToDestroy = this;
tween(wallGraphics, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
wallToDestroy.destroy();
}
});
}
};
spells.push(wall);
game.addChild(wall);
}
}
function damageWizard(damage) {
wizardHealth -= damage;
if (wizardHealth < 0) wizardHealth = 0;
// Update health bar
var healthPercent = wizardHealth / wizardMaxHealth;
healthBarFill.scaleX = healthPercent;
// Change color based on health
if (healthPercent > 0.6) {
healthBarFill.tint = 0x00ff00; // Green
} else if (healthPercent > 0.3) {
healthBarFill.tint = 0xffff00; // Yellow
} else {
healthBarFill.tint = 0xff0000; // Red
}
// Update health text
healthTxt.setText('Health: ' + wizardHealth + '/' + wizardMaxHealth);
if (wizardHealth <= 0) {
LK.effects.flashScreen(0xFF0000, 500);
LK.showGameOver();
}
}
function spawnEnemy() {
if (enemiesSpawned < enemiesPerWave) {
var enemyType = enemyTypes[Math.floor(Math.random() * Math.min(enemyTypes.length, 2 + Math.floor(waveNumber / 2)))];
var enemy = new Enemy(enemyType);
enemies.push(enemy);
game.addChild(enemy);
enemiesSpawned++;
}
}
function checkCollisions() {
// Spells vs Enemies
for (var s = spells.length - 1; s >= 0; s--) {
var spell = spells[s];
// Area damage spells (explosion, poison cloud)
if (spell.spellType === 'explosion' || spell.spellType === 'poisonCloud') {
for (var e = enemies.length - 1; e >= 0; e--) {
var enemy = enemies[e];
var dx = enemy.x - spell.x;
var dy = enemy.y - spell.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var damageRadius = spell.spellType === 'explosion' ? 120 : 80;
if (distance < damageRadius) {
var isDead = enemy.takeDamage(spell.damage);
if (isDead) {
LK.setScore(LK.getScore() + enemy.points);
scoreTxt.setText('Score: ' + LK.getScore());
enemy.destroy();
enemies.splice(e, 1);
LK.getSound('enemyDeath').play();
}
}
}
} else {
// Single target spells
for (var e = enemies.length - 1; e >= 0; e--) {
var enemy = enemies[e];
if (spell.intersects && spell.intersects(enemy)) {
// Apply ice shard slow effect
if (spell.slowEffect) {
enemy.applySlowEffect();
}
var isDead = enemy.takeDamage(spell.damage);
if (isDead) {
LK.setScore(LK.getScore() + enemy.points);
scoreTxt.setText('Score: ' + LK.getScore());
enemy.destroy();
enemies.splice(e, 1);
LK.getSound('enemyDeath').play();
}
// Fireball creates explosion on impact
if (spell.spellType === 'fireball') {
spell.createExplosion();
}
if (spell.spellType !== 'poisonCloud') {
spell.destroy();
spells.splice(s, 1);
break;
}
}
}
}
}
// Enemies vs Crystal Walls
for (var w = spells.length - 1; w >= 0; w--) {
var wall = spells[w];
if (wall.isWall) {
for (var e = enemies.length - 1; e >= 0; e--) {
var enemy = enemies[e];
if (enemy.intersects && enemy.intersects(wall)) {
// Enemy damages wall
wall.health -= 1;
// Knock back enemy
var dx = enemy.x - wall.x;
var dy = enemy.y - wall.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
enemy.x += dx / distance * 50;
enemy.y += dy / distance * 50;
}
// Destroy wall if health depleted
if (wall.health <= 0) {
wall.destroy();
spells.splice(w, 1);
}
// Flash wall when hit
tween(wall, {
tint: 0xFF0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(wall, {
tint: 0xFFFFFF
}, {
duration: 100
});
}
});
break;
}
}
}
}
// Enemies vs Wizard
for (var e = enemies.length - 1; e >= 0; e--) {
var enemy = enemies[e];
if (enemy.intersects && enemy.intersects(wizard)) {
if (!shieldActive) {
// Only damage if enough time has passed since last hit
if (LK.ticks - enemy.lastHitTime > 60) {
// 1 second cooldown
damageWizard(enemy.damage * 10); // Scale damage for visibility
enemy.lastHitTime = LK.ticks;
}
} else {
// Shield absorbs hit
enemy.destroy();
enemies.splice(e, 1);
if (shieldObject) {
shieldObject.destroy();
shieldObject = null;
shieldActive = false;
}
}
}
}
}
game.move = function (x, y, obj) {
if (x > 100 && x < 1948 && y > 100 && y < 2200) {
wizard.x = x;
wizard.y = y;
}
};
game.update = function () {
gameTime++;
// Regenerate mana
if (wizardMana < wizardMaxMana) {
wizardMana += manaRegenRate;
if (wizardMana > wizardMaxMana) {
wizardMana = wizardMaxMana;
}
// Update mana display
var manaPercent = wizardMana / wizardMaxMana;
manaBarFill.scaleX = manaPercent;
manaTxt.setText('Mana: ' + Math.floor(wizardMana) + '/' + wizardMaxMana);
}
// Update time slow
if (timeSlowActive) {
timeSlowTimer--;
if (timeSlowTimer <= 0) {
timeSlowActive = false;
}
}
// Update shield position
if (shieldObject) {
shieldObject.x = wizard.x;
shieldObject.y = wizard.y;
}
// Spawn enemies
spawnTimer++;
var actualSpawnDelay = timeSlowActive ? spawnDelay * 2 : spawnDelay;
if (spawnTimer >= actualSpawnDelay) {
spawnEnemy();
spawnTimer = 0;
}
// Update spells
for (var s = spells.length - 1; s >= 0; s--) {
var spell = spells[s];
spell.age++;
if (spell.age >= spell.lifeTime || spell.x < -100 || spell.x > 2148 || spell.y < -100 || spell.y > 2832) {
spell.destroy();
spells.splice(s, 1);
}
}
// Update enemies with proper time slow effect
for (var e = 0; e < enemies.length; e++) {
if (timeSlowActive && !enemies[e].timeSlowApplied) {
enemies[e].originalSpeed = enemies[e].speed;
enemies[e].speed *= 0.3; // 70% speed reduction
enemies[e].timeSlowApplied = true;
} else if (!timeSlowActive && enemies[e].timeSlowApplied) {
enemies[e].speed = enemies[e].originalSpeed;
enemies[e].timeSlowApplied = false;
}
}
// Check for wave completion
if (enemiesSpawned >= enemiesPerWave && enemies.length === 0) {
waveNumber++;
enemiesSpawned = 0;
enemiesPerWave = 5 + waveNumber * 2;
spawnDelay = Math.max(30, 120 - waveNumber * 5);
waveTxt.setText('Wave: ' + waveNumber);
// Bonus points for completing wave
LK.setScore(LK.getScore() + waveNumber * 50);
scoreTxt.setText('Score: ' + LK.getScore());
}
checkCollisions();
};
A very mysterious and cool man with a purple hat a wizard character's head is purple and dark blue themed. In-Game asset. 2d. High contrast. No shadows
a mysterious and angry goblin. In-Game asset. 2d. High contrast. No shadows
2d mysterious and scary demon character's head. In-Game asset. 2d. High contrast. No shadows
2d mysterious and scary flying eye character's head. In-Game asset. 2d. High contrast. No shadows
2d mysterious and scary golem character's head. In-Game asset. 2d. High contrast. No shadows
2d mysterious and scary wizard character's head. In-Game asset. 2d. High contrast. No shadows
2d mysterious and scary skeleton character's head. In-Game asset. 2d. High contrast. No shadows
2d mysterious and scary hellhound character's head. In-Game asset. 2d. High contrast. No shadows
2d mysterious and scary mushroom character's head. In-Game asset. 2d. High contrast. No shadows
an old-style square long button in grey in a magical way. In-Game asset. 2d. High contrast. No shadows