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;
});
// 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
****/
// Music
// Sound for shooting
// Powerup: purple ellipse
// Base: blue box
// Bullet: yellow box
// Zombie: green ellipse
// Hero: red box
// Game area
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;
// Score
var score = 0;
var scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Bullet count text (top left, avoid 100x100 area)
var bulletCountTxt = new Text2('20', {
size: 90,
fill: "#fff"
});
bulletCountTxt.anchor.set(0, 0);
LK.gui.top.addChild(bulletCountTxt);
bulletCountTxt.x = 120; // leave 120px margin from left
bulletCountTxt.y = 10; // leave 10px margin from top
// 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;
// Hero refresh after 10 shots
var heroShots = 0;
var heroNeedsRefresh = false;
// Zombie spawn
var zombieSpawnTimer = 0;
var zombieSpawnInterval = 90; // frames (1.5s)
var zombiesPerWave = 6;
var zombiesSpawned = 0;
var zombiesToSpawn = zombiesPerWave;
// 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: shoot bullet towards (tx, ty)
function shootBullet(tx, ty) {
if (shootCooldown > 0) return;
if (heroNeedsRefresh) return;
// Count shots and check for refresh
heroShots++;
bulletCountTxt.setText(20 - heroShots); // update bullet count display
if (heroShots >= 20) {
heroNeedsRefresh = true;
// Optionally, flash hero to indicate refresh needed
LK.effects.flashObject(hero, 0x888888, 800);
// Automatically refresh after 20 shots for şampiyon
LK.setTimeout(function () {
heroNeedsRefresh = false;
heroShots = 0;
bulletCountTxt.setText(20); // reset bullet count display after refresh
}, 800); // 800ms matches the flash duration
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;
// Play shoot sound every time a bullet is fired
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) {
// Drag hero if dragNode is set
if (dragNode === hero) {
hero.x = x;
hero.y = y;
clampHero();
// Reset hero refresh after dragging
if (heroNeedsRefresh) {
heroNeedsRefresh = false;
heroShots = 0;
bulletCountTxt.setText(20); // reset bullet count display after drag refresh
}
}
}
// 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);
}
}
// Zombie spawn
if (zombiesToSpawn > 0) {
zombieSpawnTimer++;
if (zombieSpawnTimer >= zombieSpawnInterval) {
zombieSpawnTimer = 0;
spawnZombie();
zombiesToSpawn--;
zombiesSpawned++;
}
} else if (zombies.length === 0) {
// Next wave
if (wave >= 10) {
// End game at wave 10
LK.effects.flashScreen(0x00ff00, 1000);
LK.showYouWin();
gameOver = true;
return;
}
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);
}
}
};
// Start first wave
startWave(); ===================================================================
--- original.js
+++ change.js
@@ -117,16 +117,16 @@
/****
* Game Code
****/
-// Game area
-// Hero: red box
-// Zombie: green ellipse
-// Bullet: yellow box
-// Base: blue box
-// Powerup: purple ellipse
-// Sound for shooting
// Music
+// Sound for shooting
+// Powerup: purple ellipse
+// Base: blue box
+// Bullet: yellow box
+// Zombie: green ellipse
+// Hero: red box
+// Game area
var GAME_W = 2048;
var GAME_H = 2732;
// Base
var base = game.addChild(LK.getAsset('base', {
@@ -148,9 +148,9 @@
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Bullet count text (top left, avoid 100x100 area)
-var bulletCountTxt = new Text2('10', {
+var bulletCountTxt = new Text2('20', {
size: 90,
fill: "#fff"
});
bulletCountTxt.anchor.set(0, 0);
@@ -276,18 +276,18 @@
if (shootCooldown > 0) return;
if (heroNeedsRefresh) return;
// Count shots and check for refresh
heroShots++;
- bulletCountTxt.setText(10 - heroShots); // update bullet count display
- if (heroShots >= 10) {
+ bulletCountTxt.setText(20 - heroShots); // update bullet count display
+ if (heroShots >= 20) {
heroNeedsRefresh = true;
// Optionally, flash hero to indicate refresh needed
LK.effects.flashObject(hero, 0x888888, 800);
- // Automatically refresh after 10 shots for şampiyon
+ // Automatically refresh after 20 shots for şampiyon
LK.setTimeout(function () {
heroNeedsRefresh = false;
heroShots = 0;
- bulletCountTxt.setText(10); // reset bullet count display after refresh
+ bulletCountTxt.setText(20); // reset bullet count display after refresh
}, 800); // 800ms matches the flash duration
return;
}
var b = new Bullet();
@@ -337,9 +337,9 @@
// Reset hero refresh after dragging
if (heroNeedsRefresh) {
heroNeedsRefresh = false;
heroShots = 0;
- bulletCountTxt.setText(10); // reset bullet count display after drag refresh
+ bulletCountTxt.setText(20); // reset bullet count display after drag refresh
}
}
}
// Down: start dragging hero or shoot if tap on zombie
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