User prompt
not working
User prompt
Ok its great but I want the center of the spiral they are moving around to be the screens center ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
They are still directly going to player. I want them to move like a spiral and slowly move to center ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The crayz zombie should walk VERY weird so player have a hard time to hit it. And this version doesnt work its just shakes a little on the way ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
PERFECT! Lets add new zombies: After wave 15 there is a %10 of a fast zombie can replace with a crayz zombie. Crayz zombies not directly run to player they go like a spiral until they reach the player make a assent for crayz zombie too ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
İTS NOW WORKİNG BUT PLAYER CAN SHOOT SO FAST AT THE BEGİNİNG OF THE GAME!
User prompt
STİLL NOT WORKİNG!
User prompt
Its not working its not stacking! I need it to make me shoot even faster every time ı picked up!
User prompt
Rapid fire will divide the shooting cooldown to 2 every time its picked
User prompt
Its not working its not get more powerfull everytime its picked again!
User prompt
Rapid fire will divine the shooting cooldown to 2 every time its picked
User prompt
Make the rapid fire twice our bullet shooting speed everytime its picked
User prompt
make the stack even more powerfull like if firerate is 10 without rapid fire. 1 rapid fire will make it 15. 2 rapid fire will make it 30, 3 rapid fire will make 60 4 will make it 80
User prompt
İts doesnt stack a lot. Make it shoot even more faster every time its picked again
User prompt
İf rapid fire got choosen multiable time make it stack and shoot more faster every time player picks it
User prompt
make rapid fire stackable too
User prompt
PERFECT! Now the multi shot is op so now it will add one more bullet every time player picks it
User prompt
Its not working
User prompt
İf the player pick the bouncy bullets again it will stack and it will be able to bounce one more before disappearing
User prompt
THANK YOU! and dont turn the bullet green when bounces pls
User prompt
Its not working! I want it to bounce to nearest next zombi no matter how far it is and kill it! Then bullet will disappear too
User prompt
Its just pierces... I want it to bounce to a different nearest zombi and kill it too
User prompt
Bouncy bullet card work wrong. After hiting a zombie ıt should point at the nearest zombi and hit it too.
User prompt
Ok balance change time! Bouncy bullets works like this: When your bullet hits a zombie the bullet go to nearest other zombie and hit it then it will disappear. İf you take the bouncy bullets more then once for every time you take your bullet bounce one for from zombies
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'destroy')' in or related to this line: 'cardContainer.destroy();' Line Number: 549
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var BloodSplat = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('blood', { anchorX: 0.5, anchorY: 0.5 }); self.lifetime = 300; // 5 seconds at 60fps self.fadeStartTime = 0; self.isFading = false; self.update = function () { self.lifetime--; // Start fading after 10 seconds if (self.lifetime <= 0 && !self.isFading) { self.isFading = true; tween(graphics, { alpha: 0 }, { duration: 3000, onFinish: function onFinish() { self.destroy(); } }); } }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 20; self.dx = 0; self.dy = 0; self.active = true; self.bounced = false; self.bounceCount = 0; // Track number of bounces performed self.update = function () { if (!self.active) return; self.x += self.dx; self.y += self.dy; if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) { self.active = false; } }; self.setDirection = function (targetX, targetY) { var dx = targetX - self.x; var dy = targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.dx = dx / distance * self.speed; self.dy = dy / distance * self.speed; // Rotate bullet to face direction of travel graphics.rotation = Math.atan2(dy, dx) + Math.PI / 2; } }; self.bounce = function (hitMonster) { // Increment bounce count first self.bounceCount++; // Check if we've reached the bounce limit if (self.bounceCount >= bouncyBulletCount) { self.active = false; return; } // Find nearest monster regardless of distance var nearestMonster = null; var nearestDistance = Infinity; // No distance limit for (var i = 0; i < monsters.length; i++) { var monster = monsters[i]; if (!monster.active || monster === hitMonster) continue; var dx = monster.x - self.x; var dy = monster.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestMonster = monster; } } if (nearestMonster) { self.bounced = true; self.bounceTarget = nearestMonster; // Store the target self.setDirection(nearestMonster.x, nearestMonster.y); } else { // No target found, deactivate bullet self.active = false; } }; return self; }); var Card = Container.expand(function (powerType) { var self = Container.call(this); // Card background var cardBg = LK.getAsset('player', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 1.5 }); cardBg.tint = 0x2c3e50; self.addChild(cardBg); // Card title text var titleText = new Text2(getPowerTitle(powerType), { size: 50, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.y = -40; self.addChild(titleText); // Card description text var descText = new Text2(getPowerDescription(powerType), { size: 30, fill: 0xECF0F1 }); descText.anchor.set(0.5, 0.5); descText.y = 20; self.addChild(descText); self.powerType = powerType; // Card selection handler self.down = function (x, y, obj) { selectCard(self.powerType); }; return self; }); var CrayzZombie = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('crayzZombie', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3; // Speed between normal and fast zombie self.health = 1; self.damage = 12; self.active = true; self.lastPlayerDistance = 0; self.spiralAngle = 0; // Angle for spiral movement self.crazyTimer = 0; // Timer for random direction changes self.suddenChangeX = 0; // Sudden movement offset X self.suddenChangeY = 0; // Sudden movement offset Y self.isChangingDirection = false; // Flag for direction change animation // Start with a random crazy movement pattern immediately self.startCrazyMovement = function () { if (self.isChangingDirection) return; self.isChangingDirection = true; // Random sudden movement direction var randomAngle = Math.random() * Math.PI * 2; var randomDistance = 100 + Math.random() * 200; var targetX = Math.cos(randomAngle) * randomDistance; var targetY = Math.sin(randomAngle) * randomDistance; // Animate sudden direction change tween(self, { suddenChangeX: targetX, suddenChangeY: targetY }, { duration: 300 + Math.random() * 400, easing: tween.easeInOut, onFinish: function onFinish() { // Reset and prepare for next crazy movement self.suddenChangeX = 0; self.suddenChangeY = 0; self.isChangingDirection = false; } }); }; self.update = function () { if (!self.active) return; // Screen center coordinates var screenCenterX = 1024; // Half of 2048 var screenCenterY = 1366; // Half of 2732 // Calculate distance from screen center var dxToCenter = screenCenterX - self.x; var dyToCenter = screenCenterY - self.y; var distanceToCenter = Math.sqrt(dxToCenter * dxToCenter + dyToCenter * dyToCenter); // Calculate distance to player for damage detection var dxToPlayer = player.x - self.x; var dyToPlayer = player.y - self.y; var distanceToPlayer = Math.sqrt(dxToPlayer * dxToPlayer + dyToPlayer * dyToPlayer); if (distanceToCenter > 0) { // Spiral movement that gradually moves toward screen center self.spiralAngle += 0.15; // Spiral rotation speed // Calculate spiral radius that decreases over time (gets closer to center) var maxSpiralRadius = Math.min(200, distanceToCenter * 0.3); // Maximum spiral radius based on distance to center var spiralRadius = maxSpiralRadius * Math.max(0.1, distanceToCenter / 500); // Radius shrinks as we get closer to center // Calculate spiral offset from direct path to screen center var spiralOffsetX = Math.cos(self.spiralAngle) * spiralRadius; var spiralOffsetY = Math.sin(self.spiralAngle) * spiralRadius; // Calculate direction toward screen center (slower movement toward center) var centerPullStrength = 0.8; // How strong the pull toward center is var dirX = dxToCenter / distanceToCenter; var dirY = dyToCenter / distanceToCenter; // Combine spiral movement with gradual movement toward screen center var moveX = dirX * self.speed * centerPullStrength + spiralOffsetX * 0.05; var moveY = dirY * self.speed * centerPullStrength + spiralOffsetY * 0.05; // Apply movement self.x += moveX; self.y += moveY; // Rotate zombie to face movement direction graphics.rotation = Math.atan2(moveY, moveX) + Math.PI / 2; } var currentDistance = distanceToPlayer; if (self.lastPlayerDistance > 50 && currentDistance <= 50) { player.takeDamage(self.damage); self.active = false; } self.lastPlayerDistance = currentDistance; }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.active = false; // Create blood explosion with spreading effect for (var i = 0; i < 15; i++) { var bloodSplat = new BloodSplat(); // Start at monster position bloodSplat.x = self.x; bloodSplat.y = self.y; bloodSplat.graphics = bloodSplat.children[0]; var scale = 0.3 + Math.random() * 1.2; bloodSplat.graphics.scaleX = scale; bloodSplat.graphics.scaleY = scale; // Calculate random spread destination var angle = Math.random() * Math.PI * 2; var distance = 150 + Math.random() * 300; var targetX = self.x + Math.cos(angle) * distance; var targetY = self.y + Math.sin(angle) * distance; // Keep within game bounds targetX = Math.max(50, Math.min(1998, targetX)); targetY = Math.max(50, Math.min(2682, targetY)); // Animate spreading with random delay and duration var delay = Math.random() * 200; var duration = 300 + Math.random() * 400; tween(bloodSplat, { x: targetX, y: targetY }, { duration: duration, easing: tween.easeOut }); bloodSplats.push(bloodSplat); game.addChild(bloodSplat); } LK.setScore(LK.getScore() + 15); // Score between normal and fast zombie LK.getSound('hit').play(); return true; } return false; }; return self; }); var FastZombie = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('fastZombie', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 4; // Faster than normal zombie (2) self.health = 1; self.damage = 10; self.active = true; self.lastPlayerDistance = 0; self.update = function () { if (!self.active) return; var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; // Rotate monster to face the player graphics.rotation = Math.atan2(dy, dx) + Math.PI / 2; } var currentDistance = distance; if (self.lastPlayerDistance > 50 && currentDistance <= 50) { player.takeDamage(self.damage); self.active = false; } self.lastPlayerDistance = currentDistance; }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.active = false; // Create blood explosion with spreading effect for (var i = 0; i < 15; i++) { var bloodSplat = new BloodSplat(); // Start at monster position bloodSplat.x = self.x; bloodSplat.y = self.y; bloodSplat.graphics = bloodSplat.children[0]; var scale = 0.3 + Math.random() * 1.2; bloodSplat.graphics.scaleX = scale; bloodSplat.graphics.scaleY = scale; // Calculate random spread destination var angle = Math.random() * Math.PI * 2; var distance = 150 + Math.random() * 300; var targetX = self.x + Math.cos(angle) * distance; var targetY = self.y + Math.sin(angle) * distance; // Keep within game bounds targetX = Math.max(50, Math.min(1998, targetX)); targetY = Math.max(50, Math.min(2682, targetY)); // Animate spreading with random delay and duration var delay = Math.random() * 200; var duration = 300 + Math.random() * 400; tween(bloodSplat, { x: targetX, y: targetY }, { duration: duration, easing: tween.easeOut }); bloodSplats.push(bloodSplat); game.addChild(bloodSplat); } LK.setScore(LK.getScore() + 10); LK.getSound('hit').play(); return true; } return false; }; return self; }); var Monster = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('monster', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.health = 1; self.damage = 10; self.active = true; self.lastPlayerDistance = 0; self.update = function () { if (!self.active) return; var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; // Rotate monster to face the player graphics.rotation = Math.atan2(dy, dx) + Math.PI / 2; } var currentDistance = distance; if (self.lastPlayerDistance > 50 && currentDistance <= 50) { player.takeDamage(self.damage); self.active = false; } self.lastPlayerDistance = currentDistance; }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.active = false; // Create blood explosion with spreading effect for (var i = 0; i < 15; i++) { var bloodSplat = new BloodSplat(); // Start at monster position bloodSplat.x = self.x; bloodSplat.y = self.y; bloodSplat.graphics = bloodSplat.children[0]; var scale = 0.3 + Math.random() * 1.2; bloodSplat.graphics.scaleX = scale; bloodSplat.graphics.scaleY = scale; // Calculate random spread destination var angle = Math.random() * Math.PI * 2; var distance = 150 + Math.random() * 300; var targetX = self.x + Math.cos(angle) * distance; var targetY = self.y + Math.sin(angle) * distance; // Keep within game bounds targetX = Math.max(50, Math.min(1998, targetX)); targetY = Math.max(50, Math.min(2682, targetY)); // Animate spreading with random delay and duration var delay = Math.random() * 200; var duration = 300 + Math.random() * 400; tween(bloodSplat, { x: targetX, y: targetY }, { duration: duration, easing: tween.easeOut }); bloodSplats.push(bloodSplat); game.addChild(bloodSplat); } LK.setScore(LK.getScore() + 10); LK.getSound('hit').play(); return true; } return false; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100; self.maxHealth = 100; self.fireRate = 30; // Slower initial fire rate self.fireTimer = 0; self.update = function () { if (self.fireTimer > 0) { self.fireTimer--; } }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.health = 0; LK.showGameOver(); } LK.effects.flashObject(self, 0xff0000, 300); }; self.canFire = function () { return self.fireTimer <= 0; }; self.fire = function () { if (self.canFire()) { self.fireTimer = self.fireRate; return true; } return false; }; return self; }); var ToughZombie = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('toughZombie', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 1.5; // Slower than normal zombie self.health = 2; // Much tougher self.damage = 15; // Higher damage self.active = true; self.lastPlayerDistance = 0; self.update = function () { if (!self.active) return; var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; // Rotate monster to face the player graphics.rotation = Math.atan2(dy, dx) + Math.PI / 2; } var currentDistance = distance; if (self.lastPlayerDistance > 50 && currentDistance <= 50) { player.takeDamage(self.damage); self.active = false; } self.lastPlayerDistance = currentDistance; }; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.active = false; // Create blood explosion with spreading effect for (var i = 0; i < 15; i++) { var bloodSplat = new BloodSplat(); // Start at monster position bloodSplat.x = self.x; bloodSplat.y = self.y; bloodSplat.graphics = bloodSplat.children[0]; var scale = 0.3 + Math.random() * 1.2; bloodSplat.graphics.scaleX = scale; bloodSplat.graphics.scaleY = scale; // Calculate random spread destination var angle = Math.random() * Math.PI * 2; var distance = 150 + Math.random() * 300; var targetX = self.x + Math.cos(angle) * distance; var targetY = self.y + Math.sin(angle) * distance; // Keep within game bounds targetX = Math.max(50, Math.min(1998, targetX)); targetY = Math.max(50, Math.min(2682, targetY)); // Animate spreading with random delay and duration var delay = Math.random() * 200; var duration = 300 + Math.random() * 400; tween(bloodSplat, { x: targetX, y: targetY }, { duration: duration, easing: tween.easeOut }); bloodSplats.push(bloodSplat); game.addChild(bloodSplat); } LK.setScore(LK.getScore() + 20); // Higher score for tough zombie LK.getSound('hit').play(); return true; } return false; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2c3e50 }); /**** * Game Code ****/ var player = null; var bullets = []; var monsters = []; var bloodSplats = []; var waveNumber = 1; var monstersInWave = 5; var monstersSpawned = 0; var monstersKilled = 0; var spawnTimer = 0; var waveDelay = 180; var bulletCooldown = 30; // Start with cooldown to prevent immediate shooting // Secret wave skip variables (hidden from normal players) var secretTapCount = 0; var secretTapTimer = 0; var secretZone = { x: 1900, y: 2600, width: 148, height: 132 }; // Bottom-right corner // Fast zombie spawn chance (starts at 10%, increases 1% per wave, max 80%) var fastZombieChance = 10; // Tough zombie spawn chance (starts at 5% after wave 5, increases 1% per wave, max 90%) var toughZombieChance = 5; // Crayz zombie spawn chance (10% after wave 15 to replace fast zombies) var crayzZombieChance = 10; // Card system variables var isCardSelectionActive = false; var cardContainer = null; var selectedPower = null; var availablePowers = ['bouncy', 'rapidfire', 'multishot']; var activePowers = []; var bouncyBulletCount = 1; // Number of bounces for bouncy bullets var multishotBulletCount = 1; // Number of bullets to fire for multishot var scoreText = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); var healthText = new Text2('Health: 100', { size: 50, fill: 0xFF4444 }); healthText.anchor.set(0, 0); healthText.x = 120; healthText.y = 20; LK.gui.topLeft.addChild(healthText); var waveText = new Text2('Wave: 1', { size: 50, fill: 0x4A90E2 }); waveText.anchor.set(1, 0); LK.gui.topRight.addChild(waveText); // Power utility functions function getPowerTitle(powerType) { switch (powerType) { case 'bouncy': return 'Bouncy Bullets'; case 'rapidfire': return 'Rapid Fire'; case 'multishot': return 'Multi Shot'; default: return 'Unknown Power'; } } function getPowerDescription(powerType) { switch (powerType) { case 'bouncy': return 'Bullets bounce to nearby enemies'; case 'rapidfire': return 'Faster shooting speed'; case 'multishot': return 'Shoot 3 bullets at once'; default: return 'Unknown effect'; } } function showCardSelection() { isCardSelectionActive = true; // Create card container cardContainer = new Container(); game.addChild(cardContainer); // Create dark overlay var overlay = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, alpha: 0.8 }); overlay.tint = 0x000000; cardContainer.addChild(overlay); // Select 3 random powers var shuffledPowers = availablePowers.slice(); for (var i = shuffledPowers.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = shuffledPowers[i]; shuffledPowers[i] = shuffledPowers[j]; shuffledPowers[j] = temp; } var selectedPowers = shuffledPowers.slice(0, 3); // Create cards for (var i = 0; i < 3; i++) { var card = new Card(selectedPowers[i]); card.x = 512 + i * 512; card.y = 1366; cardContainer.addChild(card); // Animate cards in tween(card, { y: 1000 }, { duration: 500, easing: tween.easeOut }); } // Add title text var titleText = new Text2('Choose Your Power!', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 600; cardContainer.addChild(titleText); } function selectCard(powerType) { if (!isCardSelectionActive) return; // Add power to active powers activePowers.push(powerType); // Apply power effect applyPowerEffect(powerType); // Animate cards out and clean up if (cardContainer) { tween(cardContainer, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { if (cardContainer) { cardContainer.destroy(); } cardContainer = null; isCardSelectionActive = false; } }); } } function applyPowerEffect(powerType) { switch (powerType) { case 'rapidfire': player.fireRate = Math.max(1, Math.floor(player.fireRate / 2)); break; case 'multishot': // Increase bullet count for multishot multishotBulletCount++; break; case 'bouncy': // Increase bounce count for all future bullets bouncyBulletCount++; break; } } var background = game.addChild(LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0 })); player = game.addChild(new Player()); player.x = 1024; player.y = 1366; function spawnMonster() { if (monstersSpawned >= monstersInWave) return; // Spawn multiple monsters at once based on wave number - more balanced progression var monstersToSpawn = 1; if (waveNumber >= 3) monstersToSpawn = 2; if (waveNumber >= 6) monstersToSpawn = 3; if (waveNumber >= 10) monstersToSpawn = Math.min(4, Math.floor(waveNumber / 3)); var actualSpawn = Math.min(monstersToSpawn, monstersInWave - monstersSpawned); for (var spawnIndex = 0; spawnIndex < actualSpawn; spawnIndex++) { // Calculate current tough zombie chance (5% base + 1% per wave after wave 10, max 90%) var currentToughZombieChance = waveNumber >= 10 ? Math.min(5 + (waveNumber - 10), 90) : 0; // Determine zombie type with priority: tough > crayz > fast > normal var randomChance = Math.random() * 100; var monster; if (waveNumber >= 10 && randomChance < currentToughZombieChance) { monster = new ToughZombie(); } else if (waveNumber >= 15 && randomChance < currentToughZombieChance + crayzZombieChance) { // 10% chance to spawn crayz zombie instead of fast zombie after wave 15 monster = new CrayzZombie(); } else if (waveNumber >= 5 && randomChance < currentToughZombieChance + crayzZombieChance + fastZombieChance) { monster = new FastZombie(); } else { monster = new Monster(); } var side = Math.floor(Math.random() * 4); switch (side) { case 0: // Top monster.x = Math.random() * 2048; monster.y = -30; break; case 1: // Right monster.x = 2078; monster.y = Math.random() * 2732; break; case 2: // Bottom monster.x = Math.random() * 2048; monster.y = 2762; break; case 3: // Left monster.x = -30; monster.y = Math.random() * 2732; break; } // Speed is already set in the class constructors monsters.push(monster); game.addChild(monster); monstersSpawned++; } } function cleanupBullets() { for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (!bullet.active) { bullet.destroy(); bullets.splice(i, 1); } } } function cleanupMonsters() { for (var i = monsters.length - 1; i >= 0; i--) { var monster = monsters[i]; if (!monster.active) { monster.destroy(); monsters.splice(i, 1); monstersKilled++; } } } function cleanupBloodSplats() { for (var i = bloodSplats.length - 1; i >= 0; i--) { var bloodSplat = bloodSplats[i]; if (!bloodSplat.parent) { bloodSplats.splice(i, 1); } } } function checkBulletCollisions() { for (var i = 0; i < bullets.length; i++) { var bullet = bullets[i]; if (!bullet.active) continue; for (var j = 0; j < monsters.length; j++) { var monster = monsters[j]; if (!monster.active) continue; if (bullet.intersects(monster)) { monster.takeDamage(1); // Try to bounce bullet if bouncy power is active and bullet hasn't exceeded bounce limit if (bullet.bounceCount < bouncyBulletCount && activePowers.indexOf('bouncy') !== -1) { bullet.bounce(monster); // If bounce was successful (found a target), keep bullet active if (bullet.bounced) { break; // Stop checking other monsters for this bullet this frame } } // Only deactivate bullet if it reached bounce limit or bouncy power is not active if (bullet.bounceCount >= bouncyBulletCount || activePowers.indexOf('bouncy') === -1) { bullet.active = false; } break; } } } } function nextWave() { waveNumber++; // Check for card selection every 5 waves if (waveNumber % 5 === 0 && waveNumber > 0) { showCardSelection(); return; // Don't start next wave until card is selected } // More balanced wave size progression: slower growth after wave 10 if (waveNumber <= 10) { monstersInWave = 3 + waveNumber * 2; } else { monstersInWave = 23 + Math.floor((waveNumber - 10) / 2); } monstersSpawned = 0; monstersKilled = 0; spawnTimer = 0; waveDelay = 180; // Increase fast zombie chance by 1% each wave, max 80% fastZombieChance = Math.min(10 + waveNumber, 80); waveText.setText('Wave: ' + waveNumber); } game.down = function (x, y, obj) { // Secret wave skip check (bottom-right corner taps) if (x >= secretZone.x && x <= secretZone.x + secretZone.width && y >= secretZone.y && y <= secretZone.y + secretZone.height) { secretTapCount++; secretTapTimer = 120; // 2 seconds to complete sequence if (secretTapCount >= 5) { // Skip 3 waves var skipAmount = 3; // Skip waves instantly for (var skipCount = 0; skipCount < skipAmount; skipCount++) { waveNumber++; } // Calculate wave size using balanced progression if (waveNumber <= 10) { monstersInWave = 3 + waveNumber * 2; } else { monstersInWave = 23 + Math.floor((waveNumber - 10) / 2); } // Update fast zombie chance for the new wave fastZombieChance = Math.min(10 + waveNumber, 80); monstersSpawned = 0; monstersKilled = monstersInWave; // Clear all current monsters for (var i = 0; i < monsters.length; i++) { if (monsters[i].active) { monsters[i].active = false; } } secretTapCount = 0; waveText.setText('Wave: ' + waveNumber); // Visual feedback (brief flash) LK.effects.flashScreen(0x00ff00, 200); } return; } if (bulletCooldown <= 0 && player.fire()) { // Check if multishot is active var shotCount = activePowers.indexOf('multishot') !== -1 ? multishotBulletCount : 1; for (var shotIndex = 0; shotIndex < shotCount; shotIndex++) { var bullet = new Bullet(); bullet.x = player.x; bullet.y = player.y; if (shotCount === 1) { // Single shot - aim directly at target bullet.setDirection(x, y); } else { // Multishot - spread bullets var baseAngle = Math.atan2(y - player.y, x - player.x); var spreadAngle = (shotIndex - (shotCount - 1) / 2) * 0.3; // Center the spread var finalAngle = baseAngle + spreadAngle; var targetX = player.x + Math.cos(finalAngle) * 500; var targetY = player.y + Math.sin(finalAngle) * 500; bullet.setDirection(targetX, targetY); } bullets.push(bullet); game.addChild(bullet); } LK.getSound('shoot').play(); bulletCooldown = player.fireRate; } }; LK.playMusic('bgmusic'); game.update = function () { // Pause game during card selection if (isCardSelectionActive) { return; } // Secret wave skip timer if (secretTapTimer > 0) { secretTapTimer--; if (secretTapTimer <= 0) { secretTapCount = 0; // Reset if too slow } } if (bulletCooldown > 0) { bulletCooldown--; } if (waveDelay > 0) { waveDelay--; return; } spawnTimer++; if (spawnTimer >= 60 && monstersSpawned < monstersInWave) { spawnMonster(); spawnTimer = 0; } checkBulletCollisions(); cleanupBullets(); cleanupMonsters(); cleanupBloodSplats(); if (monstersKilled >= monstersInWave && monsters.length === 0) { nextWave(); } scoreText.setText('Score: ' + LK.getScore()); healthText.setText('Health: ' + player.health); };
===================================================================
--- original.js
+++ change.js
@@ -171,34 +171,42 @@
});
};
self.update = function () {
if (!self.active) return;
- var dx = player.x - self.x;
- var dy = player.y - self.y;
- var distance = Math.sqrt(dx * dx + dy * dy);
- if (distance > 0) {
- // Spiral movement that gradually moves toward player
+ // Screen center coordinates
+ var screenCenterX = 1024; // Half of 2048
+ var screenCenterY = 1366; // Half of 2732
+ // Calculate distance from screen center
+ var dxToCenter = screenCenterX - self.x;
+ var dyToCenter = screenCenterY - self.y;
+ var distanceToCenter = Math.sqrt(dxToCenter * dxToCenter + dyToCenter * dyToCenter);
+ // Calculate distance to player for damage detection
+ var dxToPlayer = player.x - self.x;
+ var dyToPlayer = player.y - self.y;
+ var distanceToPlayer = Math.sqrt(dxToPlayer * dxToPlayer + dyToPlayer * dyToPlayer);
+ if (distanceToCenter > 0) {
+ // Spiral movement that gradually moves toward screen center
self.spiralAngle += 0.15; // Spiral rotation speed
// Calculate spiral radius that decreases over time (gets closer to center)
- var maxSpiralRadius = Math.min(200, distance * 0.3); // Maximum spiral radius based on distance
- var spiralRadius = maxSpiralRadius * Math.max(0.1, distance / 500); // Radius shrinks as we get closer
- // Calculate spiral offset from direct path to player
+ var maxSpiralRadius = Math.min(200, distanceToCenter * 0.3); // Maximum spiral radius based on distance to center
+ var spiralRadius = maxSpiralRadius * Math.max(0.1, distanceToCenter / 500); // Radius shrinks as we get closer to center
+ // Calculate spiral offset from direct path to screen center
var spiralOffsetX = Math.cos(self.spiralAngle) * spiralRadius;
var spiralOffsetY = Math.sin(self.spiralAngle) * spiralRadius;
- // Calculate direction toward player (slower movement toward center)
+ // Calculate direction toward screen center (slower movement toward center)
var centerPullStrength = 0.8; // How strong the pull toward center is
- var dirX = dx / distance;
- var dirY = dy / distance;
- // Combine spiral movement with gradual movement toward player
+ var dirX = dxToCenter / distanceToCenter;
+ var dirY = dyToCenter / distanceToCenter;
+ // Combine spiral movement with gradual movement toward screen center
var moveX = dirX * self.speed * centerPullStrength + spiralOffsetX * 0.05;
var moveY = dirY * self.speed * centerPullStrength + spiralOffsetY * 0.05;
// Apply movement
self.x += moveX;
self.y += moveY;
// Rotate zombie to face movement direction
graphics.rotation = Math.atan2(moveY, moveX) + Math.PI / 2;
}
- var currentDistance = distance;
+ var currentDistance = distanceToPlayer;
if (self.lastPlayerDistance > 50 && currentDistance <= 50) {
player.takeDamage(self.damage);
self.active = false;
}
Bullet. In-Game asset. 2d. High contrast. No shadows
A extremly basic zombie look from top. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
A round drop of blood. In-Game asset. 2d. High contrast. No shadows
Make it simple no blood or object
Make its skin blue and make it smile
A happier version of this zombie but its will be purple
Make it green
small rock. In-Game asset. 2d. High contrast. No shadows
Yellow version of it
make it white
Explosion!. In-Game asset. 2d. High contrast. No shadows
Lightning. In-Game asset. 2d. High contrast. No shadows
Make it rainbow and extremly happy
A cowboy hat from top. In-Game asset. 2d. High contrast. No shadows
Hake his skin red and add horns
A card. In-Game asset. 2d. High contrast. No shadows