User prompt
lower the enemy frequency by%50
User prompt
Increase the range of experience points required to level up
User prompt
make it 5
User prompt
and make it spawn every 30 seconds after first spawn
User prompt
make it 30 seconds
User prompt
make first boss spawns 15 secons after the game starts
User prompt
first spawn after after 15 seconds
User prompt
dont calculate it from waves make it every 15 seconds
User prompt
lower the frequency of zombie boss by %100
User prompt
set maximum lives 5 shouldnt be above this
Code edit (1 edits merged)
Please save this source code
User prompt
In even numbered bullets, the 2 bullets in the center should always go straight and parallel and the others should scatter.
User prompt
when firing 2 bullet dont make it spread but make it go parallel with each other just for 2 bullets others can remain same
User prompt
sycnhronize it with game'S time
User prompt
make magnet 10 seconds duration
User prompt
make magnet times same as game timer the time flow is not equal
User prompt
make magnet time 2000 frames
User prompt
make the magnet time 10 sec
User prompt
now same thing but this time get rid of hero's turn latency
User prompt
but now the zombies coming from right is not turnig to right fix that please
User prompt
now with the same way can u get rid of the latench with the enemy_right and enemy_left
User prompt
now make the same thing with other enemies
User prompt
can u get rid of from this latency
User prompt
yes now make it same with the zombie boss I add an boss left asset
User prompt
decrease it again by%50
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // BossEnemy class (big zombie boss) var BossEnemy = Container.expand(function () { var self = Container.call(this); var bossSprite = self.attachAsset('boss_enemy', { anchorX: 0.5, anchorY: 0.5 }); self.radius = 120; self.speed = 0.7; self.hp = 30; self.update = function () { var dx = hero.x - self.x; var dy = hero.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } }; return self; }); // 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 = 18; self.speed = 9.5; self.dirX = 1; self.dirY = 0; self.pierce = 1; self.update = function () { self.x += self.dirX * self.speed; self.y += self.dirY * self.speed; }; return self; }); // Enemy class var Enemy = Container.expand(function () { var self = Container.call(this); var enemySprite = self.attachAsset('enemy_right', { anchorX: 0.5, anchorY: 0.5 }); self.radius = 50; self.speed = 1.5 + Math.random(); self.update = function () { var dx = hero.x - self.x; var dy = hero.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } if (self.children && self.children.length > 0) { var currentSprite = self.children[0]; var shouldFaceRight = hero.x > self.x; var isLeftSprite = currentSprite.assetId === 'enemy_left'; var isRightSprite = currentSprite.assetId === 'enemy_right'; if (shouldFaceRight && !isRightSprite) { self.removeChild(currentSprite); var newSprite = self.attachAsset('enemy_right', { anchorX: 0.5, anchorY: 0.5 }); newSprite.assetId = 'enemy_right'; } else if (!shouldFaceRight && !isLeftSprite) { self.removeChild(currentSprite); var newSprite = self.attachAsset('enemy_left', { anchorX: 0.5, anchorY: 0.5 }); newSprite.assetId = 'enemy_left'; } } }; return self; }); // Experience Gem class (handles both normal and big XP gems) var Gem = Container.expand(function (opts) { var self = Container.call(this); // Default to normal gem self.type = opts && opts.type || 'xp'; if (self.type === 'big') { var gemSprite = self.attachAsset('big_xp_gem', { anchorX: 0.5, anchorY: 0.5 }); self.radius = 30; } else { var gemSprite = self.attachAsset('xp_gem', { anchorX: 0.5, anchorY: 0.5 }); self.radius = 20; } self.update = function () {}; return self; }); // Hero class var Hero = Container.expand(function () { var self = Container.call(this); var heroSprite = self.attachAsset('hero_right', { anchorX: 0.5, anchorY: 0.5 }); self.radius = 60; self.speed = 15; self.targetX = 1024; self.targetY = 1366; self.magnetActive = false; self.magnetDuration = 0; self.magnetRange = 300; self.magnetRangeBoosted = 800; self.update = function () { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 10) { var move = Math.min(self.speed, dist); var prevX = self.x; self.x += dx / dist * move; self.y += dy / dist * move; if (self.children && self.children.length > 0) { var currentSprite = self.children[0]; var isLeftSprite = currentSprite.assetId === 'hero_left'; var isRightSprite = currentSprite.assetId === 'hero_right'; if (self.x < prevX && !isLeftSprite) { self.removeChild(currentSprite); var newSprite = self.attachAsset('hero_left', { anchorX: 0.5, anchorY: 0.5 }); newSprite.assetId = 'hero_left'; } else if (self.x > prevX && !isRightSprite) { self.removeChild(currentSprite); var newSprite = self.attachAsset('hero_right', { anchorX: 0.5, anchorY: 0.5 }); newSprite.assetId = 'hero_right'; } } } if (self.magnetActive) { // Make hero glow blue while magnet is active if (!self._magnetGlowActive) { LK.effects.flashObject(self, 0x00ffff, 60000); // long duration, will be reset when deactivated self._magnetGlowActive = true; } self.magnetDuration--; if (self.magnetDuration <= 0) { self.magnetActive = false; self._magnetGlowActive = false; LK.effects.flashObject(self, 0xff0000, 600); } } else { self._magnetGlowActive = false; } }; return self; }); // Powerup class (now only for magnet) var Powerup = Container.expand(function (opts) { var self = Container.call(this); self.isMagnet = opts && opts.isMagnet || false; if (self.isMagnet) { self.attachAsset('magnet_powerup', { anchorX: 0.5, anchorY: 0.5 }); } self.radius = 30; self.update = function () {}; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x444444 }); /**** * Game Code ****/ var hero; var heroLives = 5; var enemies = []; var bullets = []; var gems = []; var powerups = []; var spawnTimer = 0; var spawnInterval = 90; var wave = 1; var xp = 0; var xpToLevel = 10; var level = 1; var dragging = false; var lastGameOver = false; var scoreTxt, xpTxt, levelTxt; var centerX = 2048 / 2; var centerY = 2732 / 2; hero = new Hero(); hero.x = centerX; hero.y = centerY; game.addChild(hero); scoreTxt = new Text2('Score: 0', { size: 54, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var livesTxt = new Text2('Lives: ' + heroLives, { size: 36, fill: 0xFF5555 }); livesTxt.anchor.set(0.5, 0); livesTxt.y = 60; LK.gui.top.addChild(livesTxt); var timerTxt = new Text2('00:00', { size: 54, fill: "#fff" }); timerTxt.anchor.set(1, 0); LK.gui.topRight.addChild(timerTxt); var magnetTimerTxt = new Text2('', { size: 44, fill: 0x00FFFF }); magnetTimerTxt.anchor.set(1, 0); magnetTimerTxt.y = 60; LK.gui.topRight.addChild(magnetTimerTxt); xpTxt = new Text2('XP: 0/10', { size: 36, fill: 0x7BE495 }); xpTxt.anchor.set(0.5, 0); LK.gui.top.addChild(xpTxt); xpTxt.y = 110; levelTxt = new Text2('Level: 1', { size: 36, fill: 0xF7E967 }); levelTxt.anchor.set(0.5, 0); LK.gui.top.addChild(levelTxt); levelTxt.y = 180; function spawnEnemy() { var edge = Math.floor(Math.random() * 4); var x, y; var useRight = false; if (edge === 0) { x = Math.random() * 2048; y = -100; if (x > 1024) { useRight = true; } } else if (edge === 1) { x = 2048 + 100; y = Math.random() * 2732; useRight = true; } else if (edge === 2) { x = Math.random() * 2048; y = 2732 + 100; if (x > 1024) { useRight = true; } } else { x = -100; y = Math.random() * 2732; } var enemy = new Enemy(); if (useRight && enemy.children && enemy.children.length > 0) { var oldSprite = enemy.children[0]; enemy.removeChild(oldSprite); var enemyLeftSprite = enemy.attachAsset('enemy_left', { anchorX: 0.5, anchorY: 0.5 }); } enemy.x = x; enemy.y = y; enemies.push(enemy); game.addChild(enemy); } function spawnGem(x, y, opts) { var gem = new Gem(opts); gem.x = x; gem.y = y; gems.push(gem); game.addChild(gem); } function spawnMagnetPowerup(x, y) { var powerup = new Powerup({ isMagnet: true }); // isMagnet parametresiyle oluştur powerup.x = x; powerup.y = y; powerups.push(powerup); game.addChild(powerup); } function spawnPowerup(x, y) { var powerup = new Powerup({ isMagnet: false }); // Diğer poweruplar powerup.x = x; powerup.y = y; powerups.push(powerup); // Remove and re-add to ensure it's above any background (if present) if (game.children && game.children.length > 0) { game.removeChild(powerup); game.addChild(powerup); } else { game.addChild(powerup); } } function fireBullet(dx, dy) { var bullet = new Bullet(); bullet.x = hero.x; bullet.y = hero.y; bullet.pierce = Bullet.prototype.pierce || 1; var dist = Math.sqrt(dx * dx + dy * dy); if (dist === 0) { bullet.dirX = 1; bullet.dirY = 0; } else { bullet.dirX = dx / dist; bullet.dirY = dy / dist; } bullet.rotation = Math.atan2(bullet.dirY, bullet.dirX); bullets.push(bullet); game.addChild(bullet); } function randomDir() { var angle = Math.random() * Math.PI * 2; return { x: Math.cos(angle), y: Math.sin(angle) }; } function dist2(a, b) { var dx = a.x - b.x; var dy = a.y - b.y; return Math.sqrt(dx * dx + dy * dy); } game.down = function (x, y, obj) { if (x < 100 && y < 100) { return; } hero.targetX = x; hero.targetY = y; dragging = true; }; game.move = function (x, y, obj) { hero.targetX = x; hero.targetY = y; }; game.up = function (x, y, obj) { dragging = false; }; var ticksSurvived = 0; var autoAttackTimer = 0; var autoAttackInterval = 96; game.update = function () { hero.update(); for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; e.update(); // Track lastWasTouchingHero for exact frame detection if (typeof e.lastWasTouchingHero === "undefined") e.lastWasTouchingHero = false; var isTouchingHero = dist2(e, hero) < e.radius + hero.radius; if (!e.lastWasTouchingHero && isTouchingHero) { LK.effects.flashScreen(0xff0000, 1000); heroLives--; livesTxt.setText('Lives: ' + heroLives); if (heroLives <= 0) { LK.showGameOver(); lastGameOver = true; } } e.lastWasTouchingHero = isTouchingHero; } for (var i = bullets.length - 1; i >= 0; i--) { var b = bullets[i]; b.update(); if (b.x < -100 || b.x > 2148 || b.y < -100 || b.y > 2832) { b.destroy(); bullets.splice(i, 1); continue; } for (var j = enemies.length - 1; j >= 0; j--) { var e = enemies[j]; if (dist2(b, e) < b.radius + e.radius) { // Boss enemy logic if (typeof e.hp === "number" && e.hp > 0) { e.hp -= 1; LK.effects.flashObject(e, 0xffffff, 120); if (e.hp <= 0) { // Boss defeated: drop multiple big gems and normal gems for (var drop = 0; drop < 3; drop++) { var angle = Math.random() * Math.PI * 2; var dist = 60 + Math.random() * 40; var gemX = e.x + Math.cos(angle) * dist; var gemY = e.y + Math.sin(angle) * dist; spawnGem(gemX, gemY, { type: 'big' }); } for (var drop = 0; drop < 5; drop++) { var angle = Math.random() * Math.PI * 2; var dist = 80 + Math.random() * 60; var gemX = e.x + Math.cos(angle) * dist; var gemY = e.y + Math.sin(angle) * dist; spawnGem(gemX, gemY); } // Always drop a magnet powerup spawnMagnetPowerup(e.x, e.y); e.destroy(); enemies.splice(j, 1); } } else { var bigGemSpawned = false; if (Math.random() < 0.10) { // Drop big xp gem at 10% rate spawnGem(e.x, e.y, { type: 'big' }); bigGemSpawned = true; } // Offset the normal gem if big gem was spawned to avoid overlap if (bigGemSpawned) { var offsetAngle = Math.random() * Math.PI * 2; var offsetDist = 40; var gemX = e.x + Math.cos(offsetAngle) * offsetDist; var gemY = e.y + Math.sin(offsetAngle) * offsetDist; spawnGem(gemX, gemY); } else { spawnGem(e.x, e.y); } // Set magnet drop rate to 5% (1 in 20 chance) if (Math.random() < 0.05) { spawnMagnetPowerup(e.x, e.y); } e.destroy(); enemies.splice(j, 1); } b.pierce -= 1; if (b.pierce <= 0) { b.destroy(); bullets.splice(i, 1); } break; } } } for (var i = gems.length - 1; i >= 0; i--) { var g = gems[i]; // Set XP gem attraction area to 800 pixels when magnet is active, otherwise 150 var xpAttractRange = hero.magnetActive ? 800 : 150; var d = dist2(g, hero); if (d < xpAttractRange) { var dx = hero.x - g.x; var dy = hero.y - g.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { g.x += dx / dist * 18; g.y += dy / dist * 18; } } if (dist2(g, hero) < g.radius + hero.radius) { // Big XP gem gives 5 XP, normal gives 1 if (g.type === 'big') { xp += 5; } else { xp += 1; } g.destroy(); gems.splice(i, 1); if (xp >= xpToLevel) { level += 1; xp = 0; xpToLevel = 10 + level * 4; LK.effects.flashObject(hero, 0xf7e967, 600); // On level up, spawn a big XP gem near hero spawnGem(hero.x + (Math.random() - 0.5) * 200, hero.y + (Math.random() - 0.5) * 200, { type: 'big' }); autoAttackInterval = Math.max(12, autoAttackInterval - 4); Bullet.prototype.pierce = (Bullet.prototype.pierce || 1) + 1; } } } for (var i = powerups.length - 1; i >= 0; i--) { var p = powerups[i]; // Magnet powerup attraction area: 800 if magnet is active, else 150 (same as XP gems) var magnetPowerupAttractRange = hero.magnetActive ? 800 : 150; var d = dist2(p, hero); // Prevent magnet powerup from being attracted by magnet effect if (!p.isMagnet && d < magnetPowerupAttractRange) { var dx = hero.x - p.x; var dy = hero.y - p.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { p.x += dx / dist * 18; p.y += dy / dist * 18; } } // Magnet powerup pickup radius (same as attract range) if (p.isMagnet && d < p.radius + hero.radius) { hero.magnetActive = true; hero.magnetDuration = 300; hero._magnetGlowActive = false; // force re-apply blue glow in Hero.update LK.effects.flashObject(hero, 0x00ffff, 800); p.destroy(); powerups.splice(i, 1); } } autoAttackTimer++; if (autoAttackTimer >= autoAttackInterval) { autoAttackTimer = 0; var nearest = null, minDist = 99999; for (var i = 0; i < enemies.length; i++) { var e = enemies[i]; var d = dist2(hero, e); if (d < minDist) { minDist = d; nearest = e; } } if (nearest) { var dx = nearest.x - hero.x; var dy = nearest.y - hero.y; var extraBullets = Math.max(0, level - 1); var totalBullets = 1 + extraBullets; var spread; if (level === 2) { spread = Math.PI / 32; } else if (level > 2) { spread = Math.PI / 32 + (level - 2) * Math.PI / 48; if (spread > Math.PI / 4) { spread = Math.PI / 4; } } else { spread = Math.PI / 16; } var baseAngle = Math.atan2(dy, dx); for (var b = 0; b < totalBullets; b++) { var angle = baseAngle; if (totalBullets > 1) { angle = baseAngle - spread / 2 + spread * b / (totalBullets - 1); } var dirX = Math.cos(angle); var dirY = Math.sin(angle); fireBullet(dirX, dirY); } } else { var extraBullets = Math.max(0, level - 1); var totalBullets = 1 + extraBullets; var spread; if (level === 2) { spread = Math.PI / 32; } else if (level > 2) { spread = Math.PI / 32 + (level - 2) * Math.PI / 48; if (spread > Math.PI / 4) { spread = Math.PI / 4; } } else { spread = Math.PI / 16; } var baseAngle = Math.random() * Math.PI * 2; for (var b = 0; b < totalBullets; b++) { var angle = baseAngle; if (totalBullets > 1) { angle = baseAngle - spread / 2 + spread * b / (totalBullets - 1); } var dirX = Math.cos(angle); var dirY = Math.sin(angle); fireBullet(dirX, dirY); } } } spawnTimer++; if (spawnTimer >= spawnInterval) { spawnTimer = 0; var toSpawn = Math.max(1, Math.floor((1 + Math.floor(wave / 3)) / 4)); for (var i = 0; i < toSpawn; i++) { spawnEnemy(); } // Spawn boss every 5th wave if (wave % 5 === 0) { var boss = new BossEnemy(); // Spawn boss at a random edge var edge = Math.floor(Math.random() * 4); if (edge === 0) { boss.x = Math.random() * 2048; boss.y = -200; } else if (edge === 1) { boss.x = 2048 + 200; boss.y = Math.random() * 2732; } else if (edge === 2) { boss.x = Math.random() * 2048; boss.y = 2732 + 200; } else { boss.x = -200; boss.y = Math.random() * 2732; } enemies.push(boss); game.addChild(boss); } wave++; spawnInterval = Math.max(24, 90 - Math.floor(wave / 2)); } ticksSurvived++; scoreTxt.setText('Score: ' + Math.floor(ticksSurvived / 60)); xpTxt.setText('XP: ' + xp + '/' + xpToLevel); levelTxt.setText('Level: ' + level); var totalSeconds = Math.floor(ticksSurvived / 60); var minutes = Math.floor(totalSeconds / 60); var seconds = totalSeconds % 60; var minStr = minutes < 10 ? '0' + minutes : '' + minutes; var secStr = seconds < 10 ? '0' + seconds : '' + seconds; timerTxt.setText(minStr + ':' + secStr); // Only reset heroLives and livesTxt on game restart, not every frame if (lastGameOver && hero && hero.parent) { lastGameOver = false; heroLives = 5; if (livesTxt) livesTxt.setText('Lives: ' + heroLives); } // Magnet timer display if (hero.magnetActive && hero.magnetDuration > 0) { var magnetSeconds = Math.ceil(hero.magnetDuration / 60); magnetTimerTxt.setText('Magnet: ' + magnetSeconds + 's'); } else { magnetTimerTxt.setText(''); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// BossEnemy class (big zombie boss)
var BossEnemy = Container.expand(function () {
var self = Container.call(this);
var bossSprite = self.attachAsset('boss_enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = 120;
self.speed = 0.7;
self.hp = 30;
self.update = function () {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
};
return self;
});
// 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 = 18;
self.speed = 9.5;
self.dirX = 1;
self.dirY = 0;
self.pierce = 1;
self.update = function () {
self.x += self.dirX * self.speed;
self.y += self.dirY * self.speed;
};
return self;
});
// Enemy class
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemySprite = self.attachAsset('enemy_right', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = 50;
self.speed = 1.5 + Math.random();
self.update = function () {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
if (self.children && self.children.length > 0) {
var currentSprite = self.children[0];
var shouldFaceRight = hero.x > self.x;
var isLeftSprite = currentSprite.assetId === 'enemy_left';
var isRightSprite = currentSprite.assetId === 'enemy_right';
if (shouldFaceRight && !isRightSprite) {
self.removeChild(currentSprite);
var newSprite = self.attachAsset('enemy_right', {
anchorX: 0.5,
anchorY: 0.5
});
newSprite.assetId = 'enemy_right';
} else if (!shouldFaceRight && !isLeftSprite) {
self.removeChild(currentSprite);
var newSprite = self.attachAsset('enemy_left', {
anchorX: 0.5,
anchorY: 0.5
});
newSprite.assetId = 'enemy_left';
}
}
};
return self;
});
// Experience Gem class (handles both normal and big XP gems)
var Gem = Container.expand(function (opts) {
var self = Container.call(this);
// Default to normal gem
self.type = opts && opts.type || 'xp';
if (self.type === 'big') {
var gemSprite = self.attachAsset('big_xp_gem', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = 30;
} else {
var gemSprite = self.attachAsset('xp_gem', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = 20;
}
self.update = function () {};
return self;
});
// Hero class
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroSprite = self.attachAsset('hero_right', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = 60;
self.speed = 15;
self.targetX = 1024;
self.targetY = 1366;
self.magnetActive = false;
self.magnetDuration = 0;
self.magnetRange = 300;
self.magnetRangeBoosted = 800;
self.update = function () {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 10) {
var move = Math.min(self.speed, dist);
var prevX = self.x;
self.x += dx / dist * move;
self.y += dy / dist * move;
if (self.children && self.children.length > 0) {
var currentSprite = self.children[0];
var isLeftSprite = currentSprite.assetId === 'hero_left';
var isRightSprite = currentSprite.assetId === 'hero_right';
if (self.x < prevX && !isLeftSprite) {
self.removeChild(currentSprite);
var newSprite = self.attachAsset('hero_left', {
anchorX: 0.5,
anchorY: 0.5
});
newSprite.assetId = 'hero_left';
} else if (self.x > prevX && !isRightSprite) {
self.removeChild(currentSprite);
var newSprite = self.attachAsset('hero_right', {
anchorX: 0.5,
anchorY: 0.5
});
newSprite.assetId = 'hero_right';
}
}
}
if (self.magnetActive) {
// Make hero glow blue while magnet is active
if (!self._magnetGlowActive) {
LK.effects.flashObject(self, 0x00ffff, 60000); // long duration, will be reset when deactivated
self._magnetGlowActive = true;
}
self.magnetDuration--;
if (self.magnetDuration <= 0) {
self.magnetActive = false;
self._magnetGlowActive = false;
LK.effects.flashObject(self, 0xff0000, 600);
}
} else {
self._magnetGlowActive = false;
}
};
return self;
});
// Powerup class (now only for magnet)
var Powerup = Container.expand(function (opts) {
var self = Container.call(this);
self.isMagnet = opts && opts.isMagnet || false;
if (self.isMagnet) {
self.attachAsset('magnet_powerup', {
anchorX: 0.5,
anchorY: 0.5
});
}
self.radius = 30;
self.update = function () {};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x444444
});
/****
* Game Code
****/
var hero;
var heroLives = 5;
var enemies = [];
var bullets = [];
var gems = [];
var powerups = [];
var spawnTimer = 0;
var spawnInterval = 90;
var wave = 1;
var xp = 0;
var xpToLevel = 10;
var level = 1;
var dragging = false;
var lastGameOver = false;
var scoreTxt, xpTxt, levelTxt;
var centerX = 2048 / 2;
var centerY = 2732 / 2;
hero = new Hero();
hero.x = centerX;
hero.y = centerY;
game.addChild(hero);
scoreTxt = new Text2('Score: 0', {
size: 54,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var livesTxt = new Text2('Lives: ' + heroLives, {
size: 36,
fill: 0xFF5555
});
livesTxt.anchor.set(0.5, 0);
livesTxt.y = 60;
LK.gui.top.addChild(livesTxt);
var timerTxt = new Text2('00:00', {
size: 54,
fill: "#fff"
});
timerTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(timerTxt);
var magnetTimerTxt = new Text2('', {
size: 44,
fill: 0x00FFFF
});
magnetTimerTxt.anchor.set(1, 0);
magnetTimerTxt.y = 60;
LK.gui.topRight.addChild(magnetTimerTxt);
xpTxt = new Text2('XP: 0/10', {
size: 36,
fill: 0x7BE495
});
xpTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(xpTxt);
xpTxt.y = 110;
levelTxt = new Text2('Level: 1', {
size: 36,
fill: 0xF7E967
});
levelTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(levelTxt);
levelTxt.y = 180;
function spawnEnemy() {
var edge = Math.floor(Math.random() * 4);
var x, y;
var useRight = false;
if (edge === 0) {
x = Math.random() * 2048;
y = -100;
if (x > 1024) {
useRight = true;
}
} else if (edge === 1) {
x = 2048 + 100;
y = Math.random() * 2732;
useRight = true;
} else if (edge === 2) {
x = Math.random() * 2048;
y = 2732 + 100;
if (x > 1024) {
useRight = true;
}
} else {
x = -100;
y = Math.random() * 2732;
}
var enemy = new Enemy();
if (useRight && enemy.children && enemy.children.length > 0) {
var oldSprite = enemy.children[0];
enemy.removeChild(oldSprite);
var enemyLeftSprite = enemy.attachAsset('enemy_left', {
anchorX: 0.5,
anchorY: 0.5
});
}
enemy.x = x;
enemy.y = y;
enemies.push(enemy);
game.addChild(enemy);
}
function spawnGem(x, y, opts) {
var gem = new Gem(opts);
gem.x = x;
gem.y = y;
gems.push(gem);
game.addChild(gem);
}
function spawnMagnetPowerup(x, y) {
var powerup = new Powerup({
isMagnet: true
}); // isMagnet parametresiyle oluştur
powerup.x = x;
powerup.y = y;
powerups.push(powerup);
game.addChild(powerup);
}
function spawnPowerup(x, y) {
var powerup = new Powerup({
isMagnet: false
}); // Diğer poweruplar
powerup.x = x;
powerup.y = y;
powerups.push(powerup);
// Remove and re-add to ensure it's above any background (if present)
if (game.children && game.children.length > 0) {
game.removeChild(powerup);
game.addChild(powerup);
} else {
game.addChild(powerup);
}
}
function fireBullet(dx, dy) {
var bullet = new Bullet();
bullet.x = hero.x;
bullet.y = hero.y;
bullet.pierce = Bullet.prototype.pierce || 1;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist === 0) {
bullet.dirX = 1;
bullet.dirY = 0;
} else {
bullet.dirX = dx / dist;
bullet.dirY = dy / dist;
}
bullet.rotation = Math.atan2(bullet.dirY, bullet.dirX);
bullets.push(bullet);
game.addChild(bullet);
}
function randomDir() {
var angle = Math.random() * Math.PI * 2;
return {
x: Math.cos(angle),
y: Math.sin(angle)
};
}
function dist2(a, b) {
var dx = a.x - b.x;
var dy = a.y - b.y;
return Math.sqrt(dx * dx + dy * dy);
}
game.down = function (x, y, obj) {
if (x < 100 && y < 100) {
return;
}
hero.targetX = x;
hero.targetY = y;
dragging = true;
};
game.move = function (x, y, obj) {
hero.targetX = x;
hero.targetY = y;
};
game.up = function (x, y, obj) {
dragging = false;
};
var ticksSurvived = 0;
var autoAttackTimer = 0;
var autoAttackInterval = 96;
game.update = function () {
hero.update();
for (var i = enemies.length - 1; i >= 0; i--) {
var e = enemies[i];
e.update();
// Track lastWasTouchingHero for exact frame detection
if (typeof e.lastWasTouchingHero === "undefined") e.lastWasTouchingHero = false;
var isTouchingHero = dist2(e, hero) < e.radius + hero.radius;
if (!e.lastWasTouchingHero && isTouchingHero) {
LK.effects.flashScreen(0xff0000, 1000);
heroLives--;
livesTxt.setText('Lives: ' + heroLives);
if (heroLives <= 0) {
LK.showGameOver();
lastGameOver = true;
}
}
e.lastWasTouchingHero = isTouchingHero;
}
for (var i = bullets.length - 1; i >= 0; i--) {
var b = bullets[i];
b.update();
if (b.x < -100 || b.x > 2148 || b.y < -100 || b.y > 2832) {
b.destroy();
bullets.splice(i, 1);
continue;
}
for (var j = enemies.length - 1; j >= 0; j--) {
var e = enemies[j];
if (dist2(b, e) < b.radius + e.radius) {
// Boss enemy logic
if (typeof e.hp === "number" && e.hp > 0) {
e.hp -= 1;
LK.effects.flashObject(e, 0xffffff, 120);
if (e.hp <= 0) {
// Boss defeated: drop multiple big gems and normal gems
for (var drop = 0; drop < 3; drop++) {
var angle = Math.random() * Math.PI * 2;
var dist = 60 + Math.random() * 40;
var gemX = e.x + Math.cos(angle) * dist;
var gemY = e.y + Math.sin(angle) * dist;
spawnGem(gemX, gemY, {
type: 'big'
});
}
for (var drop = 0; drop < 5; drop++) {
var angle = Math.random() * Math.PI * 2;
var dist = 80 + Math.random() * 60;
var gemX = e.x + Math.cos(angle) * dist;
var gemY = e.y + Math.sin(angle) * dist;
spawnGem(gemX, gemY);
}
// Always drop a magnet powerup
spawnMagnetPowerup(e.x, e.y);
e.destroy();
enemies.splice(j, 1);
}
} else {
var bigGemSpawned = false;
if (Math.random() < 0.10) {
// Drop big xp gem at 10% rate
spawnGem(e.x, e.y, {
type: 'big'
});
bigGemSpawned = true;
}
// Offset the normal gem if big gem was spawned to avoid overlap
if (bigGemSpawned) {
var offsetAngle = Math.random() * Math.PI * 2;
var offsetDist = 40;
var gemX = e.x + Math.cos(offsetAngle) * offsetDist;
var gemY = e.y + Math.sin(offsetAngle) * offsetDist;
spawnGem(gemX, gemY);
} else {
spawnGem(e.x, e.y);
}
// Set magnet drop rate to 5% (1 in 20 chance)
if (Math.random() < 0.05) {
spawnMagnetPowerup(e.x, e.y);
}
e.destroy();
enemies.splice(j, 1);
}
b.pierce -= 1;
if (b.pierce <= 0) {
b.destroy();
bullets.splice(i, 1);
}
break;
}
}
}
for (var i = gems.length - 1; i >= 0; i--) {
var g = gems[i];
// Set XP gem attraction area to 800 pixels when magnet is active, otherwise 150
var xpAttractRange = hero.magnetActive ? 800 : 150;
var d = dist2(g, hero);
if (d < xpAttractRange) {
var dx = hero.x - g.x;
var dy = hero.y - g.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
g.x += dx / dist * 18;
g.y += dy / dist * 18;
}
}
if (dist2(g, hero) < g.radius + hero.radius) {
// Big XP gem gives 5 XP, normal gives 1
if (g.type === 'big') {
xp += 5;
} else {
xp += 1;
}
g.destroy();
gems.splice(i, 1);
if (xp >= xpToLevel) {
level += 1;
xp = 0;
xpToLevel = 10 + level * 4;
LK.effects.flashObject(hero, 0xf7e967, 600);
// On level up, spawn a big XP gem near hero
spawnGem(hero.x + (Math.random() - 0.5) * 200, hero.y + (Math.random() - 0.5) * 200, {
type: 'big'
});
autoAttackInterval = Math.max(12, autoAttackInterval - 4);
Bullet.prototype.pierce = (Bullet.prototype.pierce || 1) + 1;
}
}
}
for (var i = powerups.length - 1; i >= 0; i--) {
var p = powerups[i];
// Magnet powerup attraction area: 800 if magnet is active, else 150 (same as XP gems)
var magnetPowerupAttractRange = hero.magnetActive ? 800 : 150;
var d = dist2(p, hero);
// Prevent magnet powerup from being attracted by magnet effect
if (!p.isMagnet && d < magnetPowerupAttractRange) {
var dx = hero.x - p.x;
var dy = hero.y - p.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
p.x += dx / dist * 18;
p.y += dy / dist * 18;
}
}
// Magnet powerup pickup radius (same as attract range)
if (p.isMagnet && d < p.radius + hero.radius) {
hero.magnetActive = true;
hero.magnetDuration = 300;
hero._magnetGlowActive = false; // force re-apply blue glow in Hero.update
LK.effects.flashObject(hero, 0x00ffff, 800);
p.destroy();
powerups.splice(i, 1);
}
}
autoAttackTimer++;
if (autoAttackTimer >= autoAttackInterval) {
autoAttackTimer = 0;
var nearest = null,
minDist = 99999;
for (var i = 0; i < enemies.length; i++) {
var e = enemies[i];
var d = dist2(hero, e);
if (d < minDist) {
minDist = d;
nearest = e;
}
}
if (nearest) {
var dx = nearest.x - hero.x;
var dy = nearest.y - hero.y;
var extraBullets = Math.max(0, level - 1);
var totalBullets = 1 + extraBullets;
var spread;
if (level === 2) {
spread = Math.PI / 32;
} else if (level > 2) {
spread = Math.PI / 32 + (level - 2) * Math.PI / 48;
if (spread > Math.PI / 4) {
spread = Math.PI / 4;
}
} else {
spread = Math.PI / 16;
}
var baseAngle = Math.atan2(dy, dx);
for (var b = 0; b < totalBullets; b++) {
var angle = baseAngle;
if (totalBullets > 1) {
angle = baseAngle - spread / 2 + spread * b / (totalBullets - 1);
}
var dirX = Math.cos(angle);
var dirY = Math.sin(angle);
fireBullet(dirX, dirY);
}
} else {
var extraBullets = Math.max(0, level - 1);
var totalBullets = 1 + extraBullets;
var spread;
if (level === 2) {
spread = Math.PI / 32;
} else if (level > 2) {
spread = Math.PI / 32 + (level - 2) * Math.PI / 48;
if (spread > Math.PI / 4) {
spread = Math.PI / 4;
}
} else {
spread = Math.PI / 16;
}
var baseAngle = Math.random() * Math.PI * 2;
for (var b = 0; b < totalBullets; b++) {
var angle = baseAngle;
if (totalBullets > 1) {
angle = baseAngle - spread / 2 + spread * b / (totalBullets - 1);
}
var dirX = Math.cos(angle);
var dirY = Math.sin(angle);
fireBullet(dirX, dirY);
}
}
}
spawnTimer++;
if (spawnTimer >= spawnInterval) {
spawnTimer = 0;
var toSpawn = Math.max(1, Math.floor((1 + Math.floor(wave / 3)) / 4));
for (var i = 0; i < toSpawn; i++) {
spawnEnemy();
}
// Spawn boss every 5th wave
if (wave % 5 === 0) {
var boss = new BossEnemy();
// Spawn boss at a random edge
var edge = Math.floor(Math.random() * 4);
if (edge === 0) {
boss.x = Math.random() * 2048;
boss.y = -200;
} else if (edge === 1) {
boss.x = 2048 + 200;
boss.y = Math.random() * 2732;
} else if (edge === 2) {
boss.x = Math.random() * 2048;
boss.y = 2732 + 200;
} else {
boss.x = -200;
boss.y = Math.random() * 2732;
}
enemies.push(boss);
game.addChild(boss);
}
wave++;
spawnInterval = Math.max(24, 90 - Math.floor(wave / 2));
}
ticksSurvived++;
scoreTxt.setText('Score: ' + Math.floor(ticksSurvived / 60));
xpTxt.setText('XP: ' + xp + '/' + xpToLevel);
levelTxt.setText('Level: ' + level);
var totalSeconds = Math.floor(ticksSurvived / 60);
var minutes = Math.floor(totalSeconds / 60);
var seconds = totalSeconds % 60;
var minStr = minutes < 10 ? '0' + minutes : '' + minutes;
var secStr = seconds < 10 ? '0' + seconds : '' + seconds;
timerTxt.setText(minStr + ':' + secStr);
// Only reset heroLives and livesTxt on game restart, not every frame
if (lastGameOver && hero && hero.parent) {
lastGameOver = false;
heroLives = 5;
if (livesTxt) livesTxt.setText('Lives: ' + heroLives);
}
// Magnet timer display
if (hero.magnetActive && hero.magnetDuration > 0) {
var magnetSeconds = Math.ceil(hero.magnetDuration / 60);
magnetTimerTxt.setText('Magnet: ' + magnetSeconds + 's');
} else {
magnetTimerTxt.setText('');
}
};
16x16 pixel wounded guy holding pistol. In-Game asset. 2d. High contrast. No shadows. pixel art. retro arcade game
3x3 pixel green coin. In-Game asset. 2d. High contrast. No shadows. retro arcade. Pixel art
3x3 pixel blue coin. In-Game asset. 2d. High contrast. No shadows. Pixel art. retro arcade
4x4 pixel art heart. In-Game asset. 2d. High contrast. No shadows. retro arcade. Pixel art. 8 bit
fill the circle with yellow colour
remove cars and buildings
Create an 8-bit style effect representing a magnetic power-up area. The effect should be a circular, glowing field with a soft, pulsing light. The colors should be green and blue, with a slight gradient effect to indicate the area where objects (such as coins or experience points) are attracted towards the character. The circle should have a subtle flicker to show the magnetic pull, and it should be designed to fit within the retro, pixel-art aesthetic of an 8-bit game. In-Game asset. 2d. High contrast. No shadows
Vertical windowed filled rectangle HUD for the 2d zombie theme game. Use green colours. Do not make it too much pixelated. In-Game asset. 2d. High contrast. No shadows. No text. No icon. No background Transparent.Retro arcade theme.
windowed filled rectangle HUD button for the 2d pixel art zombie theme game. Use dark green colours. In-Game asset. 2d. High contrast. No shadows. No text. No icon. No background Transparent.Retro arcade theme.
pixelart magnet In-Game asset. 2d. High contrast. No shadows. Pixel art
pixelart red circular enemy projectile to dodge In-Game asset. 2d. High contrast. No shadows. Pixel art
pixelart yellow circular bullet to shoot enemies In-Game asset. 2d. High contrast. No shadows. Pixel art
pixelart blue circular enemy projectile to dodge In-Game asset. 2d. High contrast. No shadows. Pixel art
4x4pixel bow and arrow. In-Game asset. 2d. High contrast. No shadows. Black outline
8x8 pixel movement speed powerup icon. boot with wings. In-Game asset. 2d. High contrast. No shadows. Black outline