User prompt
Put the minimap in the bottom right
User prompt
Add minimap
User prompt
güncelleme yap
User prompt
Make the player slow
User prompt
Oyuncunun hızını yavaş yap
User prompt
Zombilerin canını yükselt
User prompt
Optimize et
User prompt
Çok lag oluyor
User prompt
Mini harita yap
User prompt
Hız yavaş yap
User prompt
Herşeyı güncelle
User prompt
Oyuncunun hızını 0.5 yap
User prompt
Karakterın hızını 0.5 yap
User prompt
Karakterı yavaş yap
User prompt
Karakter çok hız lı
User prompt
Lan karakterimiz çok yavaş olsun
User prompt
Karakterimiz çok yavaş olsun
User prompt
Please fix the bug: 'ReferenceError: minimapPlayer is not defined' in or related to this line: 'if (minimapPlayer) {' Line Number: 529
User prompt
Oyundaki bütün kastıracak şeyleri sil
User prompt
Hızlı ateş etsin
User prompt
Karakterimize bir can barı ekle
User prompt
Oyuna çok detay koy
User prompt
Slow down the character
User prompt
Karakteri yavaş yap
User prompt
Make the character slow
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.directionX = 0;
self.directionY = 0;
self.update = function () {
// Store previous position for trail effect
if (self.lastX === undefined) {
self.lastX = self.x;
self.lastY = self.y;
}
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
// Create bullet trail effect
if (gameTime % 3 === 0) {
var trail = new Particle();
trail.x = self.lastX;
trail.y = self.lastY;
trail.tint = 0xFFFF00;
trail.life = 20;
trail.maxLife = 20;
trail.velocityX = (Math.random() - 0.5) * 2;
trail.velocityY = (Math.random() - 0.5) * 2;
trail.gravity = 0;
particles.push(trail);
gameContainer.addChild(trail);
}
// Bullet glow effect
bulletGraphics.tint = 0xFFFF00 + Math.floor(Math.random() * 50);
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
var Environment = Container.expand(function () {
var self = Container.call(this);
var envGraphics = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
self.type = 'tree'; // 'tree', 'rock', 'barrel'
self.health = 2;
self.maxHealth = 2;
self.isDestructible = true;
return self;
});
var Particle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3
});
self.velocityX = 0;
self.velocityY = 0;
self.life = 60;
self.maxLife = 60;
self.gravity = 0.1;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
self.life--;
// Fade out over time
self.alpha = self.life / self.maxLife;
// Scale down over time
var scale = self.life / self.maxLife * 0.5;
self.scaleX = scale;
self.scaleY = scale;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Add weapon to player
var weaponGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
weaponGraphics.x = 25; // Position weapon to the right of player
weaponGraphics.y = 0;
self.speed = 0.3;
self.health = 1;
self.lastShootTime = 0;
self.shootInterval = 500; // milliseconds
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
tint: 0x00FF00
});
self.type = 'speed'; // 'speed', 'damage', 'fireRate'
self.duration = 600; // 10 seconds at 60fps
self.bobOffset = Math.random() * Math.PI * 2;
self.update = function () {
// Bobbing animation removed
};
return self;
});
var Zombie = Container.expand(function () {
var self = Container.call(this);
var zombieGraphics = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.health = 1;
self.maxHealth = 1;
// Create health bar background
var healthBarBg = LK.getAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 0.5,
tint: 0x333333
});
healthBarBg.y = -140;
self.addChild(healthBarBg);
// Create health bar fill
var healthBarFill = LK.getAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 0.5,
tint: 0xFF0000
});
healthBarFill.y = -140;
self.addChild(healthBarFill);
self.healthBarFill = healthBarFill;
self.update = function () {
if (player) {
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;
// Zombie walking animation
zombieGraphics.rotation = Math.sin(gameTime * 0.2) * 0.1;
zombieGraphics.scaleX = 1 + Math.sin(gameTime * 0.3) * 0.05;
// Zombie breathing/pulsing effect
var pulse = 1 + Math.sin(gameTime * 0.1) * 0.02;
zombieGraphics.scaleY = pulse;
// Zombie eyes glow effect
if (gameTime % 60 === 0) {
zombieGraphics.tint = 0xFF4444;
tween(zombieGraphics, 0.5, {
tint: 0xFFFFFF
});
}
// Leave footprint particles
if (gameTime % 20 === 0) {
var footprint = new Particle();
footprint.x = self.x + (Math.random() - 0.5) * 20;
footprint.y = self.y + 20;
footprint.tint = 0x444444;
footprint.life = 180;
footprint.maxLife = 180;
footprint.velocityX = 0;
footprint.velocityY = 0;
footprint.gravity = 0;
particles.push(footprint);
gameContainer.addChild(footprint);
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2E2E2E
});
/****
* Game Code
****/
// Game state management
var gameState = 'menu'; // 'menu', 'playing', 'gameOver'
var menuContainer;
var playButton;
// Game variables
var player;
var zombies = [];
var bullets = [];
var powerUps = [];
var particles = [];
var environmentObjects = [];
var dragNode = null;
var gameTime = 0;
var zombieSpawnRate = 50; // frames between spawns
var zombieSpeed = 4;
var zombiesKilled = 0;
var waveNumber = 1;
var comboCount = 0;
var comboTimer = 0;
var comboDecayTime = 180; // 3 seconds at 60fps
var scoreMultiplier = 1;
var playerFireRate = 60; // frames between shots
var playerDamage = 1;
var playerSpeed = 4;
// Map system variables
var mapWidth = 6144; // 3x wider than screen
var mapHeight = 8196; // 3x taller than screen
var cameraOffsetX = 0;
var cameraOffsetY = 0;
var gameContainer;
// Minimap variables
var minimap;
var minimapContainer;
var minimapPlayer;
var minimapZombies = [];
var minimapSize = 200;
var minimapScale = minimapSize / Math.max(mapWidth, mapHeight);
// Create game container for camera system
gameContainer = new Container();
game.addChild(gameContainer);
// Create main menu
menuContainer = new Container();
game.addChild(menuContainer);
// Menu title
var titleTxt = new Text2('ZOMBIE SHOOTER', {
size: 120,
fill: 0xFF4444
});
titleTxt.anchor.set(0.5, 0.5);
titleTxt.x = 2048 / 2;
titleTxt.y = 2732 / 2 - 200;
menuContainer.addChild(titleTxt);
// Play button background
var playButtonBg = LK.getAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.8,
tint: 0x44AA44
});
playButtonBg.x = 2048 / 2;
playButtonBg.y = 2732 / 2 + 50;
menuContainer.addChild(playButtonBg);
// Play button text
var playButtonTxt = new Text2('PLAY', {
size: 80,
fill: 0xFFFFFF
});
playButtonTxt.anchor.set(0.5, 0.5);
playButtonTxt.x = 2048 / 2;
playButtonTxt.y = 2732 / 2 + 50;
menuContainer.addChild(playButtonTxt);
// Store reference to play button for event handling
playButton = playButtonBg;
// Make sure menu is visible at start
menuContainer.visible = true;
gameState = 'menu';
// Game UI Elements (initially hidden)
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.visible = false;
LK.gui.top.addChild(scoreTxt);
var waveTxt = new Text2('Wave: 1', {
size: 50,
fill: 0xFFFFFF
});
waveTxt.anchor.set(0, 0);
waveTxt.x = 120;
waveTxt.y = 20;
waveTxt.visible = false;
LK.gui.top.addChild(waveTxt);
var timeTxt = new Text2('Time: 0s', {
size: 50,
fill: 0xFFFFFF
});
timeTxt.anchor.set(1, 0);
timeTxt.x = -20;
timeTxt.y = 20;
timeTxt.visible = false;
LK.gui.topRight.addChild(timeTxt);
var comboTxt = new Text2('', {
size: 80,
fill: 0xFFAA00
});
comboTxt.anchor.set(0.5, 0.5);
comboTxt.visible = false;
LK.gui.center.addChild(comboTxt);
// Game initialization function
function initializeGame() {
// Reset game variables
gameTime = 0;
zombiesKilled = 0;
waveNumber = 1;
comboCount = 0;
comboTimer = 0;
scoreMultiplier = 1;
zombieSpawnRate = 50;
zombieSpeed = 4;
// Clear existing game objects
if (player) {
player.destroy();
}
for (var i = 0; i < zombies.length; i++) {
zombies[i].destroy();
}
for (var j = 0; j < bullets.length; j++) {
bullets[j].destroy();
}
for (var k = 0; k < particles.length; k++) {
particles[k].destroy();
}
for (var l = 0; l < environmentObjects.length; l++) {
environmentObjects[l].destroy();
}
zombies = [];
bullets = [];
particles = [];
environmentObjects = [];
// Generate environment objects
for (var env = 0; env < 50; env++) {
var envObj = new Environment();
envObj.x = Math.random() * (mapWidth - 200) + 100;
envObj.y = Math.random() * (mapHeight - 200) + 100;
var envTypes = ['tree', 'rock', 'barrel'];
envObj.type = envTypes[Math.floor(Math.random() * envTypes.length)];
switch (envObj.type) {
case 'tree':
envObj.tint = 0x228B22;
envObj.scaleX = 0.6;
envObj.scaleY = 1.2;
break;
case 'rock':
envObj.tint = 0x696969;
envObj.scaleX = 0.8;
envObj.scaleY = 0.5;
break;
case 'barrel':
envObj.tint = 0x8B4513;
envObj.scaleX = 0.5;
envObj.scaleY = 0.8;
break;
}
environmentObjects.push(envObj);
gameContainer.addChild(envObj);
}
// Initialize player
player = gameContainer.addChild(new Player());
player.x = mapWidth / 2;
player.y = mapHeight / 2;
// Create map boundary indicators
var mapBounds = [];
// Top boundary
var topBound = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0,
scaleX: mapWidth / 16,
scaleY: 2,
tint: 0x444444
});
topBound.x = 0;
topBound.y = 0;
gameContainer.addChild(topBound);
mapBounds.push(topBound);
// Bottom boundary
var bottomBound = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0,
scaleX: mapWidth / 16,
scaleY: 2,
tint: 0x444444
});
bottomBound.x = 0;
bottomBound.y = mapHeight - 32;
gameContainer.addChild(bottomBound);
mapBounds.push(bottomBound);
// Left boundary
var leftBound = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0,
scaleX: 2,
scaleY: mapHeight / 16,
tint: 0x444444
});
leftBound.x = 0;
leftBound.y = 0;
gameContainer.addChild(leftBound);
mapBounds.push(leftBound);
// Right boundary
var rightBound = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0,
scaleX: 2,
scaleY: mapHeight / 16,
tint: 0x444444
});
rightBound.x = mapWidth - 32;
rightBound.y = 0;
gameContainer.addChild(rightBound);
mapBounds.push(rightBound);
// Reset camera position
cameraOffsetX = 0;
cameraOffsetY = 0;
// Reset score
LK.setScore(0);
scoreTxt.setText('Score: 0');
// Show game UI
scoreTxt.visible = true;
waveTxt.visible = true;
timeTxt.visible = true;
comboTxt.visible = true;
// Create minimap
minimapContainer = new Container();
minimap = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0,
scaleX: minimapSize / 16,
scaleY: minimapSize / 16,
tint: 0x333333,
alpha: 0.8
});
minimap.x = 0;
minimap.y = 0;
minimapContainer.addChild(minimap);
// Create minimap player indicator
minimapPlayer = LK.getAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
tint: 0x00FF00
});
minimapContainer.addChild(minimapPlayer);
// Position minimap in bottom right
minimapContainer.x = -minimapSize - 20;
minimapContainer.y = -minimapSize - 20;
LK.gui.bottomRight.addChild(minimapContainer);
// Clear existing minimap zombies
minimapZombies = [];
// Show minimap
if (minimapContainer) {
minimapContainer.visible = true;
}
// Hide menu
menuContainer.visible = false;
// Set game state
gameState = 'playing';
}
// Don't initialize player immediately - wait for menu interaction
// Helper functions
function spawnZombie() {
var zombie = new Zombie();
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// top
zombie.x = Math.random() * mapWidth;
zombie.y = -50;
break;
case 1:
// right
zombie.x = mapWidth + 50;
zombie.y = Math.random() * mapHeight;
break;
case 2:
// bottom
zombie.x = Math.random() * mapWidth;
zombie.y = mapHeight + 50;
break;
case 3:
// left
zombie.x = -50;
zombie.y = Math.random() * mapHeight;
break;
}
// Create different zombie types based on level
var zombieType = Math.random();
if (waveNumber >= 3 && zombieType < 0.3) {
// Fast zombie
zombie.speed = zombieSpeed * 1.8;
zombie.health = 1;
zombie.maxHealth = 1;
zombie.tint = 0xFF8888;
zombie.scaleX = 0.8;
zombie.scaleY = 0.8;
} else if (waveNumber >= 5 && zombieType < 0.5) {
// Tank zombie
zombie.speed = zombieSpeed * 0.6;
zombie.health = 3;
zombie.maxHealth = 3;
zombie.tint = 0x888888;
zombie.scaleX = 1.3;
zombie.scaleY = 1.3;
} else {
// Normal zombie
zombie.speed = zombieSpeed;
zombie.health = 1;
zombie.maxHealth = 1;
}
// Spawn effects removed
zombies.push(zombie);
gameContainer.addChild(zombie);
// Add zombie to minimap
if (minimapContainer) {
var minimapZombie = LK.getAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.4,
tint: 0xFF4444
});
minimapZombie.x = zombie.x * minimapScale;
minimapZombie.y = zombie.y * minimapScale;
minimapContainer.addChild(minimapZombie);
minimapZombies.push(minimapZombie);
zombie.minimapRef = minimapZombie;
}
}
function findNearestZombie() {
var nearestZombie = null;
var nearestDistance = Infinity;
for (var i = 0; i < zombies.length; i++) {
var zombie = zombies[i];
var dx = zombie.x - player.x;
var dy = zombie.y - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestZombie = zombie;
}
}
return nearestZombie;
}
function shootBullet() {
var target = findNearestZombie();
if (!target) return;
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y;
// Calculate zombie's movement direction
var zombieDx = player.x - target.x;
var zombieDy = player.y - target.y;
var zombieDistance = Math.sqrt(zombieDx * zombieDx + zombieDy * zombieDy);
var zombieDirectionX = zombieDistance > 0 ? zombieDx / zombieDistance : 0;
var zombieDirectionY = zombieDistance > 0 ? zombieDy / zombieDistance : 0;
// Predict where zombie will be
var timeToTarget = zombieDistance / bullet.speed;
var predictedX = target.x + zombieDirectionX * target.speed * timeToTarget;
var predictedY = target.y + zombieDirectionY * target.speed * timeToTarget;
// Aim at predicted position
var dx = predictedX - player.x;
var dy = predictedY - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
bullet.directionX = dx / distance;
bullet.directionY = dy / distance;
}
// Create muzzle flash effect
for (var flash = 0; flash < 5; flash++) {
var muzzleFlash = new Particle();
muzzleFlash.x = player.x;
muzzleFlash.y = player.y;
muzzleFlash.tint = 0xFFFF00;
muzzleFlash.life = 10;
muzzleFlash.maxLife = 10;
muzzleFlash.velocityX = (Math.random() - 0.5) * 8;
muzzleFlash.velocityY = (Math.random() - 0.5) * 8;
muzzleFlash.gravity = 0;
particles.push(muzzleFlash);
gameContainer.addChild(muzzleFlash);
}
// Screen shake effect
if (gameContainer) {
var shakeX = (Math.random() - 0.5) * 10;
var shakeY = (Math.random() - 0.5) * 10;
gameContainer.x += shakeX;
gameContainer.y += shakeY;
tween(gameContainer, 0.1, {
x: gameContainer.x - shakeX,
y: gameContainer.y - shakeY
});
}
bullets.push(bullet);
gameContainer.addChild(bullet);
LK.getSound('shoot').play();
}
function updateDifficulty() {
waveNumber = Math.floor(gameTime / 1200) + 1; // New wave every 20 seconds
zombieSpawnRate = Math.max(15, 50 - waveNumber * 8);
zombieSpeed = 4 + (waveNumber - 1) * 1.2;
waveTxt.setText('Wave: ' + waveNumber);
}
// Event handlers
function handleMove(x, y, obj) {
if (dragNode) {
// Convert screen coordinates to world coordinates
var worldX = x - cameraOffsetX;
var worldY = y - cameraOffsetY;
// Keep player within map bounds
dragNode.x = Math.max(75, Math.min(mapWidth - 75, worldX));
dragNode.y = Math.max(75, Math.min(mapHeight - 75, worldY));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (gameState === 'menu') {
// Check if play button was clicked
var buttonBounds = playButton.getBounds();
var buttonCenterX = playButton.x;
var buttonCenterY = playButton.y;
var buttonWidth = buttonBounds.width;
var buttonHeight = buttonBounds.height;
// Simple bounds check
if (x >= buttonCenterX - buttonWidth / 2 && x <= buttonCenterX + buttonWidth / 2 && y >= buttonCenterY - buttonHeight / 2 && y <= buttonCenterY + buttonHeight / 2) {
initializeGame();
}
} else if (gameState === 'playing') {
// Normal gameplay - allow player movement
dragNode = player;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game loop
game.update = function () {
// Only update game logic when playing
if (gameState !== 'playing') {
return;
}
gameTime++;
// Update UI
timeTxt.setText('Time: ' + Math.floor(gameTime / 60) + 's');
// Update combo system
if (comboTimer > 0) {
comboTimer--;
if (comboTimer <= 0) {
comboCount = 0;
scoreMultiplier = 1;
comboTxt.setText('');
}
}
// Continuously increase difficulty based on score instead of waves
var currentScore = LK.getScore();
zombieSpawnRate = Math.max(10, 50 - Math.floor(currentScore / 100) * 2);
zombieSpeed = 4 + Math.floor(currentScore / 200) * 0.5;
waveNumber = Math.floor(currentScore / 500) + 1;
waveTxt.setText('Level: ' + waveNumber);
// Spawn zombies with dynamic frequency based on score
if (gameTime % zombieSpawnRate === 0) {
spawnZombie();
// Spawn additional zombies based on current level
var additionalSpawns = Math.floor(waveNumber / 2);
for (var spawn = 0; spawn < additionalSpawns; spawn++) {
if (gameTime % (zombieSpawnRate * (spawn + 2)) === 0) {
spawnZombie();
}
}
}
// Update camera to follow player
if (player) {
var targetCameraX = -(player.x - 2048 / 2);
var targetCameraY = -(player.y - 2732 / 2);
// Smooth camera movement
cameraOffsetX += (targetCameraX - cameraOffsetX) * 0.1;
cameraOffsetY += (targetCameraY - cameraOffsetY) * 0.1;
// Keep camera within map bounds
cameraOffsetX = Math.max(-(mapWidth - 2048), Math.min(0, cameraOffsetX));
cameraOffsetY = Math.max(-(mapHeight - 2732), Math.min(0, cameraOffsetY));
// Apply camera offset to game container
gameContainer.x = cameraOffsetX;
gameContainer.y = cameraOffsetY;
// Update minimap player position
if (minimapPlayer) {
minimapPlayer.x = player.x * minimapScale;
minimapPlayer.y = player.y * minimapScale;
}
}
// Spawn power-ups occasionally
if (gameTime % 1800 === 0) {
// Every 30 seconds
var powerUp = new PowerUp();
powerUp.x = Math.random() * (mapWidth - 200) + 100;
powerUp.y = Math.random() * (mapHeight - 200) + 100;
var powerTypes = ['speed', 'damage', 'fireRate'];
powerUp.type = powerTypes[Math.floor(Math.random() * powerTypes.length)];
switch (powerUp.type) {
case 'speed':
powerUp.tint = 0x00FF00;
break;
case 'damage':
powerUp.tint = 0xFF0000;
break;
case 'fireRate':
powerUp.tint = 0x0000FF;
break;
}
powerUps.push(powerUp);
gameContainer.addChild(powerUp);
}
// Auto-shoot with dynamic fire rate
if (gameTime % playerFireRate === 0) {
shootBullet();
}
// Update minimap zombie positions
for (var mz = 0; mz < zombies.length; mz++) {
var zombie = zombies[mz];
if (zombie.minimapRef) {
zombie.minimapRef.x = zombie.x * minimapScale;
zombie.minimapRef.y = zombie.y * minimapScale;
}
}
// Update particles
for (var p = particles.length - 1; p >= 0; p--) {
var particle = particles[p];
if (particle.life <= 0) {
particle.destroy();
particles.splice(p, 1);
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Remove bullets that are off screen (expanded map)
if (bullet.x < -200 || bullet.x > mapWidth + 200 || bullet.y < -200 || bullet.y > mapHeight + 200) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet-environment collisions
for (var env = environmentObjects.length - 1; env >= 0; env--) {
var envObj = environmentObjects[env];
if (bullet.intersects(envObj) && envObj.isDestructible) {
envObj.health--;
// Create destruction particles
for (var debris = 0; debris < 8; debris++) {
var debrisParticle = new Particle();
debrisParticle.x = envObj.x;
debrisParticle.y = envObj.y;
debrisParticle.tint = envObj.tint;
debrisParticle.life = 120;
debrisParticle.maxLife = 120;
debrisParticle.velocityX = (Math.random() - 0.5) * 10;
debrisParticle.velocityY = (Math.random() - 0.5) * 10;
particles.push(debrisParticle);
gameContainer.addChild(debrisParticle);
}
if (envObj.health <= 0) {
envObj.destroy();
environmentObjects.splice(env, 1);
} else {
// Damage visual effect
envObj.tint = 0x888888;
tween(envObj, 0.3, {
tint: envObj.tint
});
}
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
// Check bullet-zombie collisions
for (var j = zombies.length - 1; j >= 0; j--) {
var zombie = zombies[j];
if (bullet.intersects(zombie)) {
// Zombie hit
LK.getSound('zombieHit').play();
zombie.health -= playerDamage;
// Update health bar
if (zombie.healthBarFill) {
zombie.healthBarFill.scaleX = 3 * (zombie.health / zombie.maxHealth);
}
// Create blood splatter effect
for (var blood = 0; blood < 12; blood++) {
var bloodParticle = new Particle();
bloodParticle.x = zombie.x;
bloodParticle.y = zombie.y;
bloodParticle.tint = 0x8B0000;
bloodParticle.life = 90;
bloodParticle.maxLife = 90;
bloodParticle.velocityX = (Math.random() - 0.5) * 15;
bloodParticle.velocityY = (Math.random() - 0.5) * 15;
bloodParticle.gravity = 0.2;
particles.push(bloodParticle);
gameContainer.addChild(bloodParticle);
}
// Only destroy zombie if health reaches 0
if (zombie.health <= 0) {
// Create death explosion effect
for (var explosion = 0; explosion < 20; explosion++) {
var explosionParticle = new Particle();
explosionParticle.x = zombie.x;
explosionParticle.y = zombie.y;
explosionParticle.tint = 0xFF4444;
explosionParticle.life = 60;
explosionParticle.maxLife = 60;
explosionParticle.velocityX = (Math.random() - 0.5) * 20;
explosionParticle.velocityY = (Math.random() - 0.5) * 20;
explosionParticle.gravity = 0.1;
particles.push(explosionParticle);
gameContainer.addChild(explosionParticle);
}
// Update combo system
comboCount++;
comboTimer = comboDecayTime;
scoreMultiplier = Math.min(5, 1 + Math.floor(comboCount / 3));
// Show combo text
if (comboCount > 2) {
comboTxt.setText('COMBO x' + scoreMultiplier);
comboTxt.alpha = 1;
comboTxt.scaleX = 1;
comboTxt.scaleY = 1;
// Enhanced combo text animation
tween(comboTxt, 0.3, {
scaleX: 1.5,
scaleY: 1.5
});
tween(comboTxt, 0.3, {
scaleX: 1,
scaleY: 1
}, 0.3);
}
// Clean up minimap reference
if (zombie.minimapRef) {
zombie.minimapRef.destroy();
var minimapIndex = minimapZombies.indexOf(zombie.minimapRef);
if (minimapIndex !== -1) {
minimapZombies.splice(minimapIndex, 1);
}
}
zombie.destroy();
zombies.splice(j, 1);
zombiesKilled++;
LK.setScore(LK.getScore() + 10 * scoreMultiplier + Math.floor(gameTime / 60));
scoreTxt.setText('Score: ' + LK.getScore());
// Flash effects removed
} else {
// Zombie damaged but not destroyed
// Flash effects removed
}
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
}
// Add power-up glow and floating animation
for (var pu = 0; pu < powerUps.length; pu++) {
var powerUp = powerUps[pu];
powerUp.y += Math.sin(gameTime * 0.1 + pu) * 0.5;
powerUp.rotation += 0.02;
// Create sparkle particles around power-ups
if (gameTime % 30 === 0) {
var sparkle = new Particle();
sparkle.x = powerUp.x + (Math.random() - 0.5) * 60;
sparkle.y = powerUp.y + (Math.random() - 0.5) * 60;
sparkle.tint = powerUp.tint;
sparkle.life = 60;
sparkle.maxLife = 60;
sparkle.velocityX = (Math.random() - 0.5) * 2;
sparkle.velocityY = (Math.random() - 0.5) * 2;
sparkle.gravity = 0;
particles.push(sparkle);
gameContainer.addChild(sparkle);
}
}
// Check power-up collection
for (var p = powerUps.length - 1; p >= 0; p--) {
var powerUp = powerUps[p];
if (player.intersects(powerUp)) {
// Create collection burst effect
for (var burst = 0; burst < 15; burst++) {
var burstParticle = new Particle();
burstParticle.x = powerUp.x;
burstParticle.y = powerUp.y;
burstParticle.tint = powerUp.tint;
burstParticle.life = 40;
burstParticle.maxLife = 40;
burstParticle.velocityX = (Math.random() - 0.5) * 12;
burstParticle.velocityY = (Math.random() - 0.5) * 12;
burstParticle.gravity = 0;
particles.push(burstParticle);
gameContainer.addChild(burstParticle);
}
// Apply power-up effect
switch (powerUp.type) {
case 'speed':
player.speed = Math.min(8, player.speed + 1);
break;
case 'damage':
playerDamage += 1;
break;
case 'fireRate':
playerFireRate = Math.max(20, playerFireRate - 10);
break;
}
powerUp.destroy();
powerUps.splice(p, 1);
LK.setScore(LK.getScore() + 50);
scoreTxt.setText('Score: ' + LK.getScore());
}
}
// Check player-zombie collisions
for (var k = 0; k < zombies.length; k++) {
var zombie = zombies[k];
if (player.intersects(zombie)) {
// Player hit - game over
// Screen shake effect removed
LK.effects.flashScreen(0xFF0000, 1000);
// Reset to menu state
gameState = 'menu';
menuContainer.visible = true;
scoreTxt.visible = false;
waveTxt.visible = false;
timeTxt.visible = false;
comboTxt.visible = false;
if (minimapContainer) {
minimapContainer.visible = false;
}
LK.showGameOver();
return;
}
}
// Remove zombies that are too far off screen (cleanup)
for (var l = zombies.length - 1; l >= 0; l--) {
var zombie = zombies[l];
if (zombie.x < -400 || zombie.x > mapWidth + 400 || zombie.y < -400 || zombie.y > mapHeight + 400) {
zombie.destroy();
zombies.splice(l, 1);
}
}
};
// Start background music
LK.playMusic('bgmusic'); ===================================================================
--- original.js
+++ change.js
@@ -22,14 +22,70 @@
self.lastY = self.y;
}
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
- // Trail particles removed
+ // Create bullet trail effect
+ if (gameTime % 3 === 0) {
+ var trail = new Particle();
+ trail.x = self.lastX;
+ trail.y = self.lastY;
+ trail.tint = 0xFFFF00;
+ trail.life = 20;
+ trail.maxLife = 20;
+ trail.velocityX = (Math.random() - 0.5) * 2;
+ trail.velocityY = (Math.random() - 0.5) * 2;
+ trail.gravity = 0;
+ particles.push(trail);
+ gameContainer.addChild(trail);
+ }
+ // Bullet glow effect
+ bulletGraphics.tint = 0xFFFF00 + Math.floor(Math.random() * 50);
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
+var Environment = Container.expand(function () {
+ var self = Container.call(this);
+ var envGraphics = self.attachAsset('zombie', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.8,
+ scaleY: 0.8
+ });
+ self.type = 'tree'; // 'tree', 'rock', 'barrel'
+ self.health = 2;
+ self.maxHealth = 2;
+ self.isDestructible = true;
+ return self;
+});
+var Particle = Container.expand(function () {
+ var self = Container.call(this);
+ var particleGraphics = self.attachAsset('bullet', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.3,
+ scaleY: 0.3
+ });
+ self.velocityX = 0;
+ self.velocityY = 0;
+ self.life = 60;
+ self.maxLife = 60;
+ self.gravity = 0.1;
+ self.update = function () {
+ self.x += self.velocityX;
+ self.y += self.velocityY;
+ self.velocityY += self.gravity;
+ self.life--;
+ // Fade out over time
+ self.alpha = self.life / self.maxLife;
+ // Scale down over time
+ var scale = self.life / self.maxLife * 0.5;
+ self.scaleX = scale;
+ self.scaleY = scale;
+ };
+ return self;
+});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
@@ -104,10 +160,36 @@
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
+ // Zombie walking animation
+ zombieGraphics.rotation = Math.sin(gameTime * 0.2) * 0.1;
+ zombieGraphics.scaleX = 1 + Math.sin(gameTime * 0.3) * 0.05;
+ // Zombie breathing/pulsing effect
+ var pulse = 1 + Math.sin(gameTime * 0.1) * 0.02;
+ zombieGraphics.scaleY = pulse;
+ // Zombie eyes glow effect
+ if (gameTime % 60 === 0) {
+ zombieGraphics.tint = 0xFF4444;
+ tween(zombieGraphics, 0.5, {
+ tint: 0xFFFFFF
+ });
+ }
+ // Leave footprint particles
+ if (gameTime % 20 === 0) {
+ var footprint = new Particle();
+ footprint.x = self.x + (Math.random() - 0.5) * 20;
+ footprint.y = self.y + 20;
+ footprint.tint = 0x444444;
+ footprint.life = 180;
+ footprint.maxLife = 180;
+ footprint.velocityX = 0;
+ footprint.velocityY = 0;
+ footprint.gravity = 0;
+ particles.push(footprint);
+ gameContainer.addChild(footprint);
+ }
}
- // Pulsing and tint effects removed
}
};
return self;
});
@@ -130,8 +212,10 @@
var player;
var zombies = [];
var bullets = [];
var powerUps = [];
+var particles = [];
+var environmentObjects = [];
var dragNode = null;
var gameTime = 0;
var zombieSpawnRate = 50; // frames between spawns
var zombieSpeed = 4;
@@ -250,10 +334,45 @@
}
for (var j = 0; j < bullets.length; j++) {
bullets[j].destroy();
}
+ for (var k = 0; k < particles.length; k++) {
+ particles[k].destroy();
+ }
+ for (var l = 0; l < environmentObjects.length; l++) {
+ environmentObjects[l].destroy();
+ }
zombies = [];
bullets = [];
+ particles = [];
+ environmentObjects = [];
+ // Generate environment objects
+ for (var env = 0; env < 50; env++) {
+ var envObj = new Environment();
+ envObj.x = Math.random() * (mapWidth - 200) + 100;
+ envObj.y = Math.random() * (mapHeight - 200) + 100;
+ var envTypes = ['tree', 'rock', 'barrel'];
+ envObj.type = envTypes[Math.floor(Math.random() * envTypes.length)];
+ switch (envObj.type) {
+ case 'tree':
+ envObj.tint = 0x228B22;
+ envObj.scaleX = 0.6;
+ envObj.scaleY = 1.2;
+ break;
+ case 'rock':
+ envObj.tint = 0x696969;
+ envObj.scaleX = 0.8;
+ envObj.scaleY = 0.5;
+ break;
+ case 'barrel':
+ envObj.tint = 0x8B4513;
+ envObj.scaleX = 0.5;
+ envObj.scaleY = 0.8;
+ break;
+ }
+ environmentObjects.push(envObj);
+ gameContainer.addChild(envObj);
+ }
// Initialize player
player = gameContainer.addChild(new Player());
player.x = mapWidth / 2;
player.y = mapHeight / 2;
@@ -463,9 +582,33 @@
if (distance > 0) {
bullet.directionX = dx / distance;
bullet.directionY = dy / distance;
}
- // Muzzle flash effect removed
+ // Create muzzle flash effect
+ for (var flash = 0; flash < 5; flash++) {
+ var muzzleFlash = new Particle();
+ muzzleFlash.x = player.x;
+ muzzleFlash.y = player.y;
+ muzzleFlash.tint = 0xFFFF00;
+ muzzleFlash.life = 10;
+ muzzleFlash.maxLife = 10;
+ muzzleFlash.velocityX = (Math.random() - 0.5) * 8;
+ muzzleFlash.velocityY = (Math.random() - 0.5) * 8;
+ muzzleFlash.gravity = 0;
+ particles.push(muzzleFlash);
+ gameContainer.addChild(muzzleFlash);
+ }
+ // Screen shake effect
+ if (gameContainer) {
+ var shakeX = (Math.random() - 0.5) * 10;
+ var shakeY = (Math.random() - 0.5) * 10;
+ gameContainer.x += shakeX;
+ gameContainer.y += shakeY;
+ tween(gameContainer, 0.1, {
+ x: gameContainer.x - shakeX,
+ y: gameContainer.y - shakeY
+ });
+ }
bullets.push(bullet);
gameContainer.addChild(bullet);
LK.getSound('shoot').play();
}
@@ -595,8 +738,16 @@
zombie.minimapRef.x = zombie.x * minimapScale;
zombie.minimapRef.y = zombie.y * minimapScale;
}
}
+ // Update particles
+ for (var p = particles.length - 1; p >= 0; p--) {
+ var particle = particles[p];
+ if (particle.life <= 0) {
+ particle.destroy();
+ particles.splice(p, 1);
+ }
+ }
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Remove bullets that are off screen (expanded map)
@@ -604,8 +755,41 @@
bullet.destroy();
bullets.splice(i, 1);
continue;
}
+ // Check bullet-environment collisions
+ for (var env = environmentObjects.length - 1; env >= 0; env--) {
+ var envObj = environmentObjects[env];
+ if (bullet.intersects(envObj) && envObj.isDestructible) {
+ envObj.health--;
+ // Create destruction particles
+ for (var debris = 0; debris < 8; debris++) {
+ var debrisParticle = new Particle();
+ debrisParticle.x = envObj.x;
+ debrisParticle.y = envObj.y;
+ debrisParticle.tint = envObj.tint;
+ debrisParticle.life = 120;
+ debrisParticle.maxLife = 120;
+ debrisParticle.velocityX = (Math.random() - 0.5) * 10;
+ debrisParticle.velocityY = (Math.random() - 0.5) * 10;
+ particles.push(debrisParticle);
+ gameContainer.addChild(debrisParticle);
+ }
+ if (envObj.health <= 0) {
+ envObj.destroy();
+ environmentObjects.splice(env, 1);
+ } else {
+ // Damage visual effect
+ envObj.tint = 0x888888;
+ tween(envObj, 0.3, {
+ tint: envObj.tint
+ });
+ }
+ bullet.destroy();
+ bullets.splice(i, 1);
+ break;
+ }
+ }
// Check bullet-zombie collisions
for (var j = zombies.length - 1; j >= 0; j--) {
var zombie = zombies[j];
if (bullet.intersects(zombie)) {
@@ -615,10 +799,38 @@
// Update health bar
if (zombie.healthBarFill) {
zombie.healthBarFill.scaleX = 3 * (zombie.health / zombie.maxHealth);
}
+ // Create blood splatter effect
+ for (var blood = 0; blood < 12; blood++) {
+ var bloodParticle = new Particle();
+ bloodParticle.x = zombie.x;
+ bloodParticle.y = zombie.y;
+ bloodParticle.tint = 0x8B0000;
+ bloodParticle.life = 90;
+ bloodParticle.maxLife = 90;
+ bloodParticle.velocityX = (Math.random() - 0.5) * 15;
+ bloodParticle.velocityY = (Math.random() - 0.5) * 15;
+ bloodParticle.gravity = 0.2;
+ particles.push(bloodParticle);
+ gameContainer.addChild(bloodParticle);
+ }
// Only destroy zombie if health reaches 0
if (zombie.health <= 0) {
+ // Create death explosion effect
+ for (var explosion = 0; explosion < 20; explosion++) {
+ var explosionParticle = new Particle();
+ explosionParticle.x = zombie.x;
+ explosionParticle.y = zombie.y;
+ explosionParticle.tint = 0xFF4444;
+ explosionParticle.life = 60;
+ explosionParticle.maxLife = 60;
+ explosionParticle.velocityX = (Math.random() - 0.5) * 20;
+ explosionParticle.velocityY = (Math.random() - 0.5) * 20;
+ explosionParticle.gravity = 0.1;
+ particles.push(explosionParticle);
+ gameContainer.addChild(explosionParticle);
+ }
// Update combo system
comboCount++;
comboTimer = comboDecayTime;
scoreMultiplier = Math.min(5, 1 + Math.floor(comboCount / 3));
@@ -627,11 +839,18 @@
comboTxt.setText('COMBO x' + scoreMultiplier);
comboTxt.alpha = 1;
comboTxt.scaleX = 1;
comboTxt.scaleY = 1;
- // Combo text animation removed
+ // Enhanced combo text animation
+ tween(comboTxt, 0.3, {
+ scaleX: 1.5,
+ scaleY: 1.5
+ });
+ tween(comboTxt, 0.3, {
+ scaleX: 1,
+ scaleY: 1
+ }, 0.3);
}
- // Explosion particles removed
// Clean up minimap reference
if (zombie.minimapRef) {
zombie.minimapRef.destroy();
var minimapIndex = minimapZombies.indexOf(zombie.minimapRef);
@@ -654,12 +873,46 @@
break;
}
}
}
+ // Add power-up glow and floating animation
+ for (var pu = 0; pu < powerUps.length; pu++) {
+ var powerUp = powerUps[pu];
+ powerUp.y += Math.sin(gameTime * 0.1 + pu) * 0.5;
+ powerUp.rotation += 0.02;
+ // Create sparkle particles around power-ups
+ if (gameTime % 30 === 0) {
+ var sparkle = new Particle();
+ sparkle.x = powerUp.x + (Math.random() - 0.5) * 60;
+ sparkle.y = powerUp.y + (Math.random() - 0.5) * 60;
+ sparkle.tint = powerUp.tint;
+ sparkle.life = 60;
+ sparkle.maxLife = 60;
+ sparkle.velocityX = (Math.random() - 0.5) * 2;
+ sparkle.velocityY = (Math.random() - 0.5) * 2;
+ sparkle.gravity = 0;
+ particles.push(sparkle);
+ gameContainer.addChild(sparkle);
+ }
+ }
// Check power-up collection
for (var p = powerUps.length - 1; p >= 0; p--) {
var powerUp = powerUps[p];
if (player.intersects(powerUp)) {
+ // Create collection burst effect
+ for (var burst = 0; burst < 15; burst++) {
+ var burstParticle = new Particle();
+ burstParticle.x = powerUp.x;
+ burstParticle.y = powerUp.y;
+ burstParticle.tint = powerUp.tint;
+ burstParticle.life = 40;
+ burstParticle.maxLife = 40;
+ burstParticle.velocityX = (Math.random() - 0.5) * 12;
+ burstParticle.velocityY = (Math.random() - 0.5) * 12;
+ burstParticle.gravity = 0;
+ particles.push(burstParticle);
+ gameContainer.addChild(burstParticle);
+ }
// Apply power-up effect
switch (powerUp.type) {
case 'speed':
player.speed = Math.min(8, player.speed + 1);
@@ -670,9 +923,8 @@
case 'fireRate':
playerFireRate = Math.max(20, playerFireRate - 10);
break;
}
- // Power-up collection effect removed
powerUp.destroy();
powerUps.splice(p, 1);
LK.setScore(LK.getScore() + 50);
scoreTxt.setText('Score: ' + LK.getScore());