User prompt
mermi sayısı 20 olsun
User prompt
ekranın sol üst köşesinde kaç adet mermi kaldığını göster
User prompt
mermi attıkça ses gelsin
User prompt
oyun 10. dalgada bitsin
User prompt
güçlendirmeyi oyundan sil
User prompt
10 atıştan sonra mermisini yenilesin
User prompt
güçlendirmeyi düzelt
User prompt
Please fix the bug: 'Uncaught TypeError: setTimeout is not a function' in or related to this line: 'setTimeout(function () {' Line Number: 360
User prompt
şampiyon 5 atıştan sonra mermi yenilesin
User prompt
Hero refresh after 5 shots
User prompt
hero can use power up
User prompt
hero can move
User prompt
can reach the reinforcements via arrow
User prompt
As the wave rises, mega zombies come
User prompt
add time to the game, zombies increase as time goes by, earn gold as you kill zombies
Code edit (1 edits merged)
Please save this source code
User prompt
Zombie Rush: Survival Defense
Initial prompt
zombie game
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Bullet class var Bullet = Container.expand(function () { var self = Container.call(this); var bulletSprite = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.radius = bulletSprite.width / 2; self.speed = 32; self.dirX = 0; self.dirY = 0; self.lastIntersecting = false; self.lastY = self.y; return self; }); // Hero class var Hero = Container.expand(function () { var self = Container.call(this); var heroSprite = self.attachAsset('hero', { anchorX: 0.5, anchorY: 0.5 }); self.radius = heroSprite.width / 2; // For powerup state self.powered = false; self.powerTimer = 0; // Flash effect for powerup self.flashTween = null; // Powerup visual effect self.setPowered = function (on) { if (on) { self.powered = true; // Flash hero yellow if (self.flashTween) tween.stop(heroSprite, { tint: true }); heroSprite.tint = 0xffff00; self.flashTween = tween(heroSprite, { tint: 0xd83318 }, { duration: 400, easing: tween.linear, onFinish: function onFinish() { heroSprite.tint = 0xffff00; self.flashTween = tween(heroSprite, { tint: 0xd83318 }, { duration: 400, easing: tween.linear, onFinish: function onFinish() { heroSprite.tint = 0xffff00; } }); } }); } else { self.powered = false; if (self.flashTween) tween.stop(heroSprite, { tint: true }); heroSprite.tint = 0xd83318; } }; return self; }); // MegaZombie class var MegaZombie = Container.expand(function () { var self = Container.call(this); var megaZombieSprite = self.attachAsset('zombie', { anchorX: 0.5, anchorY: 0.5 }); // Make it visually bigger megaZombieSprite.scaleX = 2; megaZombieSprite.scaleY = 2; self.radius = megaZombieSprite.width; // much bigger self.speed = 1.2; // slower than normal zombies self.targetX = 0; self.targetY = 0; self.alive = true; self.hp = 8; // takes 8 hits to kill self.lastIntersecting = false; self.lastY = self.y; return self; }); // Powerup class var Powerup = Container.expand(function () { var self = Container.call(this); var powerupSprite = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.radius = powerupSprite.width / 2; self.type = 'rapid'; // Only one type for now self.lastIntersecting = false; return self; }); // Zombie class var Zombie = Container.expand(function () { var self = Container.call(this); var zombieSprite = self.attachAsset('zombie', { anchorX: 0.5, anchorY: 0.5 }); self.radius = zombieSprite.width / 2; self.speed = 2; // Will be set on spawn self.targetX = 0; self.targetY = 0; self.alive = true; self.lastIntersecting = false; self.lastY = self.y; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Game area // Hero: red box // Zombie: green ellipse // Bullet: yellow box // Base: blue box // Powerup: purple ellipse // Sound for shooting // Music var GAME_W = 2048; var GAME_H = 2732; // Base var base = game.addChild(LK.getAsset('base', { anchorX: 0.5, anchorY: 0.5 })); base.x = GAME_W / 2; base.y = GAME_H - 120; // Hero var hero = new Hero(); game.addChild(hero); hero.x = GAME_W / 2; hero.y = GAME_H - 350; // Arrow to reinforcements (base) var arrowLength = 180; var arrowWidth = 40; var arrow = LK.getAsset('arrow', { anchorX: 0.0, anchorY: 0.5 }); arrow.alpha = 0.7; game.addChild(arrow); arrow.visible = true; // Score var score = 0; var scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // High Score (not persistent, just for session) var highScore = 0; // Timer var elapsedFrames = 0; var timeTxt = new Text2('00:00', { size: 70, fill: "#fff" }); timeTxt.anchor.set(0.5, 0); LK.gui.top.addChild(timeTxt); timeTxt.y = 200; // Wave var wave = 1; var waveTxt = new Text2('Wave 1', { size: 70, fill: "#fff" }); waveTxt.anchor.set(0.5, 0); LK.gui.top.addChild(waveTxt); waveTxt.y = 120; // Arrays for game objects var zombies = []; var megaZombies = []; var bullets = []; var powerups = []; // Gold var gold = 0; var goldTxt = new Text2('Gold: 0', { size: 70, fill: 0xFFE066 }); goldTxt.anchor.set(0.5, 0); LK.gui.top.addChild(goldTxt); goldTxt.y = 320; // Dragging var dragNode = null; // Shooting cooldown var shootCooldown = 0; var shootInterval = 18; // frames (0.3s at 60fps) var rapidFire = false; // Powerup timer var powerupTimer = 0; // Zombie spawn var zombieSpawnTimer = 0; var zombieSpawnInterval = 90; // frames (1.5s) var zombiesPerWave = 6; var zombiesSpawned = 0; var zombiesToSpawn = zombiesPerWave; // Powerup spawn var powerupSpawnTimer = 0; var powerupSpawnInterval = 600; // 10s // Game state var gameOver = false; // Start music LK.playMusic('bgmusic', { fade: { start: 0, end: 1, duration: 1000 } }); // Helper: clamp hero inside game area function clampHero() { var margin = hero.radius + 20; if (hero.x < margin) hero.x = margin; if (hero.x > GAME_W - margin) hero.x = GAME_W - margin; if (hero.y < margin + 100) hero.y = margin + 100; // avoid top menu if (hero.y > base.y - hero.radius - 40) hero.y = base.y - hero.radius - 40; } // Helper: spawn a zombie at random edge, target base function spawnZombie() { // Decide if this should be a mega zombie var isMega = false; // Start spawning mega zombies at wave 4, increase chance as wave rises if (wave >= 4) { // 10% at wave 4, 20% at wave 6, 30% at wave 8, max 40% var megaChance = Math.min(0.1 + 0.05 * (wave - 4), 0.4); if (Math.random() < megaChance) isMega = true; } // Random edge: 0=top, 1=left, 2=right var edge = Math.floor(Math.random() * 3); var zx, zy; if (edge === 0) { // top zx = 200 + Math.random() * (GAME_W - 400); zy = -80; } else if (edge === 1) { // left zx = -80; zy = 400 + Math.random() * (GAME_H - 1000); } else { // right zx = GAME_W + 80; zy = 400 + Math.random() * (GAME_H - 1000); } if (isMega) { var mz = new MegaZombie(); mz.x = zx; mz.y = zy; mz.targetX = base.x; mz.targetY = base.y; // Slightly increase speed with wave, but always slower than normal zombies mz.speed = 1.2 + (wave - 4) * 0.1 + Math.random() * 0.2; megaZombies.push(mz); game.addChild(mz); } else { var z = new Zombie(); z.x = zx; z.y = zy; z.targetX = base.x; z.targetY = base.y; z.speed = 2 + wave * 0.5 + Math.random(); zombies.push(z); game.addChild(z); } } // Helper: spawn a powerup at random location function spawnPowerup() { var p = new Powerup(); p.x = 200 + Math.random() * (GAME_W - 400); p.y = 400 + Math.random() * (GAME_H - 1200); powerups.push(p); game.addChild(p); } // Helper: shoot bullet towards (tx, ty) function shootBullet(tx, ty) { if (shootCooldown > 0) return; var b = new Bullet(); b.x = hero.x; b.y = hero.y; // Direction var dx = tx - hero.x; var dy = ty - hero.y; var len = Math.sqrt(dx * dx + dy * dy); if (len === 0) { b.dirX = 0; b.dirY = -1; } else { b.dirX = dx / len; b.dirY = dy / len; } // If powered, increase speed b.speed = hero.powered ? 48 : 32; bullets.push(b); game.addChild(b); shootCooldown = hero.powered ? 6 : shootInterval; LK.getSound('shoot').play(); } // Helper: start new wave function startWave() { waveTxt.setText('Wave ' + wave); zombiesPerWave = 6 + (wave - 1) * 2; zombiesToSpawn = zombiesPerWave; zombiesSpawned = 0; zombieSpawnInterval = Math.max(40, 90 - wave * 5); // Clean up any remaining mega zombies (shouldn't be any, but for safety) for (var i = megaZombies.length - 1; i >= 0; i--) { if (megaZombies[i]) { megaZombies[i].destroy(); } } megaZombies = []; } // Move handler: drag hero, shoot on tap function handleMove(x, y, obj) { if (dragNode) { dragNode.x = x; dragNode.y = y; clampHero(); } } // Down: start dragging hero or shoot if tap on zombie game.down = function (x, y, obj) { // Check if tap on zombie for (var i = 0; i < zombies.length; i++) { var z = zombies[i]; var dx = x - z.x; var dy = y - z.y; if (dx * dx + dy * dy < z.radius * z.radius) { // Shoot at zombie shootBullet(z.x, z.y); return; } } // Otherwise, drag hero var dxh = x - hero.x; var dyh = y - hero.y; if (dxh * dxh + dyh * dyh < hero.radius * hero.radius) { dragNode = hero; } // Also allow shooting by tapping anywhere else if (!dragNode) { shootBullet(x, y); } handleMove(x, y, obj); }; game.move = handleMove; game.up = function (x, y, obj) { dragNode = null; }; // Main update loop game.update = function () { if (gameOver) return; // Timer update elapsedFrames++; var seconds = Math.floor(elapsedFrames / 60); var min = Math.floor(seconds / 60); var sec = seconds % 60; var timeStr = (min < 10 ? "0" : "") + min + ":" + (sec < 10 ? "0" : "") + sec; timeTxt.setText(timeStr); // Every 20 seconds, increase zombies per wave and make them spawn faster if (elapsedFrames % (60 * 20) === 0 && elapsedFrames > 0) { zombiesPerWave += 2; zombieSpawnInterval = Math.max(20, zombieSpawnInterval - 5); } // Cooldowns if (shootCooldown > 0) shootCooldown--; // Powerup timer if (hero.powered) { hero.powerTimer--; if (hero.powerTimer <= 0) { hero.setPowered(false); } } // Powerup spawn powerupSpawnTimer++; if (powerupSpawnTimer >= powerupSpawnInterval) { powerupSpawnTimer = 0; spawnPowerup(); } // Zombie spawn if (zombiesToSpawn > 0) { zombieSpawnTimer++; if (zombieSpawnTimer >= zombieSpawnInterval) { zombieSpawnTimer = 0; spawnZombie(); zombiesToSpawn--; zombiesSpawned++; } } else if (zombies.length === 0) { // Next wave wave++; startWave(); waveTxt.setText('Wave ' + wave + (wave >= 4 ? ' - Mega Zombies!' : '')); } // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var b = bullets[i]; b.x += b.dirX * b.speed; b.y += b.dirY * b.speed; // Remove if off screen if (b.x < -100 || b.x > GAME_W + 100 || b.y < -100 || b.y > GAME_H + 100) { b.destroy(); bullets.splice(i, 1); continue; } // Check collision with zombies var bulletDestroyed = false; for (var j = zombies.length - 1; j >= 0; j--) { var z = zombies[j]; var dx = b.x - z.x; var dy = b.y - z.y; var dist2 = dx * dx + dy * dy; var r2 = (b.radius + z.radius) * (b.radius + z.radius); if (dist2 < r2) { // Hit! LK.getSound('zombiehit').play(); score++; scoreTxt.setText(score); if (score > highScore) highScore = score; // Earn gold for killing zombie gold += 5; goldTxt.setText('Gold: ' + gold); // Remove zombie and bullet z.destroy(); zombies.splice(j, 1); b.destroy(); bullets.splice(i, 1); bulletDestroyed = true; break; } } if (bulletDestroyed) continue; // Check collision with mega zombies for (var j = megaZombies.length - 1; j >= 0; j--) { var mz = megaZombies[j]; var dx = b.x - mz.x; var dy = b.y - mz.y; var dist2 = dx * dx + dy * dy; var r2 = (b.radius + mz.radius) * (b.radius + mz.radius); if (dist2 < r2) { // Hit mega zombie! LK.getSound('zombiehit').play(); mz.hp--; // Flash mega zombie on hit LK.effects.flashObject(mz, 0xffff00, 200); if (mz.hp <= 0) { // Kill mega zombie score += 5; // Worth more points scoreTxt.setText(score); if (score > highScore) highScore = score; gold += 25; // More gold goldTxt.setText('Gold: ' + gold); mz.destroy(); megaZombies.splice(j, 1); } // Destroy bullet b.destroy(); bullets.splice(i, 1); break; } } } // Update zombies for (var i = zombies.length - 1; i >= 0; i--) { var z = zombies[i]; // Move towards base var dx = base.x - z.x; var dy = base.y - z.y; var len = Math.sqrt(dx * dx + dy * dy); if (len > 0) { z.x += dx / len * z.speed; z.y += dy / len * z.speed; } // Check collision with base var dbx = z.x - base.x; var dby = z.y - base.y; var baseR = base.width / 2 + z.radius - 10; if (dbx * dbx + dby * dby < baseR * baseR) { // Game over LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); gameOver = true; return; } // Check collision with hero (for fun, just flash) var dhx = z.x - hero.x; var dhy = z.y - hero.y; var heroR = hero.radius + z.radius; if (dhx * dhx + dhy * dhy < heroR * heroR) { LK.effects.flashObject(hero, 0xff0000, 300); } } // Update mega zombies for (var i = megaZombies.length - 1; i >= 0; i--) { var mz = megaZombies[i]; // Move towards base var dx = base.x - mz.x; var dy = base.y - mz.y; var len = Math.sqrt(dx * dx + dy * dy); if (len > 0) { mz.x += dx / len * mz.speed; mz.y += dy / len * mz.speed; } // Check collision with base var dbx = mz.x - base.x; var dby = mz.y - base.y; var baseR = base.width / 2 + mz.radius - 10; if (dbx * dbx + dby * dby < baseR * baseR) { // Game over LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); gameOver = true; return; } // Check collision with hero (for fun, just flash) var dhx = mz.x - hero.x; var dhy = mz.y - hero.y; var heroR = hero.radius + mz.radius; if (dhx * dhx + dhy * dhy < heroR * heroR) { LK.effects.flashObject(hero, 0xff0000, 300); } } // --- Arrow update and hero reaching base for reinforcements --- // Update arrow to point from hero to base if (arrow && hero && base) { var adx = base.x - hero.x; var ady = base.y - hero.y; var alen = Math.sqrt(adx * adx + ady * ady); if (alen > 0) { arrow.x = hero.x; arrow.y = hero.y; arrow.rotation = Math.atan2(ady, adx); arrow.visible = true; // Optionally, scale arrow based on distance (not required) // arrow.scaleX = Math.min(1, alen / 400); } else { arrow.visible = false; } } // Allow hero to reach base for reinforcements if (!gameOver) { var hbx = hero.x - base.x; var hby = hero.y - base.y; var heroBaseDist = Math.sqrt(hbx * hbx + hby * hby); var reinforceRadius = base.width / 2 + hero.radius + 10; if (hero.lastAtBase === undefined) hero.lastAtBase = false; var atBaseNow = heroBaseDist < reinforceRadius; if (!hero.lastAtBase && atBaseNow) { // Reached base for reinforcements! // Give bonus: restore powerup, gold, and flash hero hero.setPowered(true); hero.powerTimer = 180; // 3s rapid fire gold += 50; goldTxt.setText('Gold: ' + gold); LK.effects.flashObject(hero, 0x00ff00, 800); // Optionally, show a message (not required) } hero.lastAtBase = atBaseNow; } // Update powerups for (var i = powerups.length - 1; i >= 0; i--) { var p = powerups[i]; var dx = p.x - hero.x; var dy = p.y - hero.y; var dist2 = dx * dx + dy * dy; var r2 = (p.radius + hero.radius) * (p.radius + hero.radius); if (dist2 < r2) { // Collect powerup LK.getSound('powerup').play(); p.destroy(); powerups.splice(i, 1); // Powerup: rapid fire for 5 seconds hero.setPowered(true); hero.powerTimer = 300; // 5s at 60fps } } }; // Start first wave startWave();
===================================================================
--- original.js
+++ change.js
@@ -151,8 +151,18 @@
var hero = new Hero();
game.addChild(hero);
hero.x = GAME_W / 2;
hero.y = GAME_H - 350;
+// Arrow to reinforcements (base)
+var arrowLength = 180;
+var arrowWidth = 40;
+var arrow = LK.getAsset('arrow', {
+ anchorX: 0.0,
+ anchorY: 0.5
+});
+arrow.alpha = 0.7;
+game.addChild(arrow);
+arrow.visible = true;
// Score
var score = 0;
var scoreTxt = new Text2('0', {
size: 120,
@@ -532,8 +542,45 @@
if (dhx * dhx + dhy * dhy < heroR * heroR) {
LK.effects.flashObject(hero, 0xff0000, 300);
}
}
+ // --- Arrow update and hero reaching base for reinforcements ---
+ // Update arrow to point from hero to base
+ if (arrow && hero && base) {
+ var adx = base.x - hero.x;
+ var ady = base.y - hero.y;
+ var alen = Math.sqrt(adx * adx + ady * ady);
+ if (alen > 0) {
+ arrow.x = hero.x;
+ arrow.y = hero.y;
+ arrow.rotation = Math.atan2(ady, adx);
+ arrow.visible = true;
+ // Optionally, scale arrow based on distance (not required)
+ // arrow.scaleX = Math.min(1, alen / 400);
+ } else {
+ arrow.visible = false;
+ }
+ }
+ // Allow hero to reach base for reinforcements
+ if (!gameOver) {
+ var hbx = hero.x - base.x;
+ var hby = hero.y - base.y;
+ var heroBaseDist = Math.sqrt(hbx * hbx + hby * hby);
+ var reinforceRadius = base.width / 2 + hero.radius + 10;
+ if (hero.lastAtBase === undefined) hero.lastAtBase = false;
+ var atBaseNow = heroBaseDist < reinforceRadius;
+ if (!hero.lastAtBase && atBaseNow) {
+ // Reached base for reinforcements!
+ // Give bonus: restore powerup, gold, and flash hero
+ hero.setPowered(true);
+ hero.powerTimer = 180; // 3s rapid fire
+ gold += 50;
+ goldTxt.setText('Gold: ' + gold);
+ LK.effects.flashObject(hero, 0x00ff00, 800);
+ // Optionally, show a message (not required)
+ }
+ hero.lastAtBase = atBaseNow;
+ }
// Update powerups
for (var i = powerups.length - 1; i >= 0; i--) {
var p = powerups[i];
var dx = p.x - hero.x;
zombie. In-Game asset. 2d. High contrast. No shadows
straight line. In-Game asset. 2d. High contrast. No shadows
Create a game character with a crossbow in hand. In-Game asset. 2d. High contrast. No shadows
purple potion bottle filled with purple liquid. In-Game asset. 2d. High contrast. No shadows
mermi. In-Game asset. 2d. High contrast. No shadows