User prompt
%25 ihtimalle mermiler kritik vurur ve 2 kat hasar verir
User prompt
wave 2 geçilmiyor düzelt
User prompt
oyunun yapısı bozulmuş wave geçemiyorun
User prompt
düşükte olsa rejen ekle
User prompt
zombilerden 10 saniyeliğine sonsuz mermi düşme olasılığı olsun
User prompt
geri al oyuna girmeden bir ekran istemiyorum orijinale çevir
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'player.lastX = player.x; // Track lastX before moving' Line Number: 576
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'player.lastX = player.x; // Track lastX before moving' Line Number: 578
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'player.lastX = player.x; // Track lastX before moving' Line Number: 576
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'player.lastX = player.x; // Track lastX before moving' Line Number: 574
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'moveTowards')' in or related to this line: 'player.moveTowards(targetPosition.x, targetPosition.y);' Line Number: 572
User prompt
oyuna girmeden önce bir ekran ekle
User prompt
köşelere dekor ekle
User prompt
kutuları mapin köşelerine koy
User prompt
Please fix the bug: 'ReferenceError: obstacles is not defined' in or related to this line: 'obstacles.forEach(function (obstacle) {' Line Number: 555
User prompt
çalı ve kutu gibi şeyler ekleyebilirsin
Code edit (1 edits merged)
Please save this source code
User prompt
Zombie Survival: Wave Defender
Initial prompt
waveler olacak gittikçe güçlenen zombie saldırıları ve biz ateş edebiliyoruz zombie bosları falan gelecek
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highscore: 0,
weaponLevel: 1
});
/****
* Classes
****/
var Bullet = Container.expand(function (startX, startY, targetX, targetY, damage) {
var self = Container.call(this);
var bulletGraphic = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 15;
self.damage = damage || 10;
// Calculate direction vector
var dx = targetX - startX;
var dy = targetY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
self.vx = dx / distance * self.speed;
self.vy = dy / distance * self.speed;
self.x = startX;
self.y = startY;
self.update = function () {
self.x += self.vx;
self.y += self.vy;
// Check if bullet is out of bounds
if (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) {
return true; // Remove bullet
}
return false;
};
return self;
});
var Obstacle = Container.expand(function (x, y, type) {
var self = Container.call(this);
var obstacleGraphic = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
return self;
});
var Pickup = Container.expand(function (x, y, type) {
var self = Container.call(this);
var pickupGraphic = self.attachAsset(type === 'health' ? 'healthPack' : 'ammoBox', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = type; // 'health' or 'ammo'
self.x = x;
self.y = y;
self.lifespan = 10000; // milliseconds until pickup disappears
self.creationTime = Date.now();
self.update = function () {
// Make pickup pulse
var age = Date.now() - self.creationTime;
var pulse = Math.sin(age / 200) * 0.2 + 1;
self.scale.set(pulse, pulse);
// Check if pickup should expire
if (age > self.lifespan) {
return true; // Remove pickup
}
return false;
};
self.collect = function (player) {
LK.getSound('pickup').play();
if (self.type === 'health') {
player.heal(25);
} else if (self.type === 'ammo') {
player.ammo = player.maxAmmo;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphic = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.ammo = 30;
self.maxAmmo = 30;
self.reloadTime = 1000; // milliseconds
self.isReloading = false;
self.speed = 7;
self.weaponLevel = storage.weaponLevel || 1;
self.bulletDamage = 10 * self.weaponLevel;
self.lastShotTime = 0;
self.shootDelay = 300; // milliseconds between shots
self.moveTowards = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.speed) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else {
self.x = targetX;
self.y = targetY;
}
// Keep player within bounds
self.x = Math.max(50, Math.min(2048 - 50, self.x));
self.y = Math.max(50, Math.min(2732 - 50, self.y));
};
self.shoot = function (targetX, targetY) {
var currentTime = Date.now();
if (self.ammo <= 0) {
self.reload();
return null;
}
if (self.isReloading) {
return null;
}
if (currentTime - self.lastShotTime < self.shootDelay) {
return null;
}
self.lastShotTime = currentTime;
self.ammo--;
LK.getSound('shoot').play();
var bullet = new Bullet(self.x, self.y, targetX, targetY, self.bulletDamage);
return bullet;
};
self.reload = function () {
if (!self.isReloading && self.ammo < self.maxAmmo) {
self.isReloading = true;
LK.setTimeout(function () {
self.ammo = self.maxAmmo;
self.isReloading = false;
}, self.reloadTime);
}
};
self.takeDamage = function (damage) {
LK.getSound('playerHit').play();
LK.effects.flashObject(self, 0xff0000, 300);
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
return true; // player died
}
return false; // player still alive
};
self.heal = function (amount) {
self.health = Math.min(self.maxHealth, self.health + amount);
};
self.upgradeWeapon = function () {
self.weaponLevel++;
self.bulletDamage = 10 * self.weaponLevel;
storage.weaponLevel = self.weaponLevel;
};
return self;
});
var Zombie = Container.expand(function (x, y, health, speed, damage) {
var self = Container.call(this);
var zombieGraphic = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = health || 30;
self.maxHealth = self.health;
self.speed = speed || 2;
self.damage = damage || 10;
self.attackCooldown = 1000; // milliseconds
self.lastAttackTime = 0;
self.x = x;
self.y = y;
self.moveTowards = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
self.attack = function (player) {
var currentTime = Date.now();
if (currentTime - self.lastAttackTime >= self.attackCooldown) {
self.lastAttackTime = currentTime;
return player.takeDamage(self.damage);
}
return false;
};
self.takeDamage = function (damage) {
self.health -= damage;
// Flash zombie when hit
LK.effects.flashObject(self, 0xff0000, 200);
LK.getSound('zombieHit').play();
// Change color based on health percentage
var healthPercentage = self.health / self.maxHealth;
var green = Math.floor(204 * healthPercentage);
zombieGraphic.tint = 0 << 16 | green << 8 | 0;
if (self.health <= 0) {
return true; // zombie died
}
return false; // zombie still alive
};
return self;
});
var BossZombie = Zombie.expand(function (x, y, waveNumber) {
var self = Zombie.call(this, x, y, bossHealth, bossSpeed, bossDamage);
// Calculate boss stats based on wave number
var bossHealth = 100 + waveNumber * 50;
var bossSpeed = 1.5 + waveNumber * 0.1;
var bossDamage = 20 + waveNumber * 5;
// Replace the zombie graphic with a boss graphic
self.removeChild(self.getChildAt(0)); // Remove the zombie graphic
var bossGraphic = self.attachAsset('bossZombie', {
anchorX: 0.5,
anchorY: 0.5
});
self.scoreValue = 100; // More points for killing a boss
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x111111
});
/****
* Game Code
****/
// Game state variables
var player;
var obstacles = [];
var bullets = [];
var zombies = [];
var pickups = [];
var wave = 1;
var zombiesKilled = 0;
var score = 0;
var gameStartTime;
var waveStartTime;
var isWaveActive = false;
var targetPosition = {
x: 0,
y: 0
};
var isGameOver = false;
// UI elements
var scoreText;
var waveText;
var healthBar;
var healthBarBg;
var ammoBar;
var ammoBarBg;
var gameStatusText;
function initGame() {
// Reset game state
wave = 1;
zombiesKilled = 0;
score = 0;
bullets = [];
zombies = [];
pickups = [];
isWaveActive = false;
isGameOver = false;
gameStartTime = Date.now();
// Set background
game.setBackgroundColor(0x111111);
// Play background music
LK.playMusic('gameMusic', {
fade: {
start: 0,
end: 0.3,
duration: 1000
}
});
// Create player at center of screen
player = new Player();
player.x = 2048 / 2;
player.y = 2732 / 2;
if (player) {
player.lastX = player.x; // Initialize lastX for tracking
player.lastY = player.y; // Initialize lastY for tracking
}
game.addChild(player);
// Add obstacles
var obstacles = [];
obstacles.push(new Obstacle(50, 50, 'crate')); // Top-left corner
obstacles.push(new Obstacle(1998, 50, 'crate')); // Top-right corner
obstacles.push(new Obstacle(50, 2682, 'crate')); // Bottom-left corner
obstacles.push(new Obstacle(1998, 2682, 'crate')); // Bottom-right corner
// Add decorative elements to the corners
obstacles.push(new Obstacle(150, 150, 'bush')); // Near top-left corner
obstacles.push(new Obstacle(1898, 150, 'bush')); // Near top-right corner
obstacles.push(new Obstacle(150, 2582, 'bush')); // Near bottom-left corner
obstacles.push(new Obstacle(1898, 2582, 'bush')); // Near bottom-right corner
obstacles.push(new Obstacle(500, 500, 'bush'));
obstacles.forEach(function (obstacle) {
game.addChild(obstacle);
});
// Initialize UI
createUI();
// Start first wave
startWave();
}
function createUI() {
// Score text
scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -scoreText.width - 20;
scoreText.y = 20;
// Wave text
waveText = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0);
LK.gui.top.addChild(waveText);
waveText.y = 20;
// Health bar background
healthBarBg = LK.getAsset('healthBarBg', {
anchorX: 0,
anchorY: 0.5
});
LK.gui.bottomLeft.addChild(healthBarBg);
healthBarBg.x = 20;
healthBarBg.y = -50;
// Health bar
healthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0.5
});
LK.gui.bottomLeft.addChild(healthBar);
healthBar.x = 20;
healthBar.y = -50;
// Ammo bar background
ammoBarBg = LK.getAsset('ammoBarBg', {
anchorX: 0,
anchorY: 0.5
});
LK.gui.bottomLeft.addChild(ammoBarBg);
ammoBarBg.x = 20;
ammoBarBg.y = -100;
// Ammo bar
ammoBar = LK.getAsset('ammoBar', {
anchorX: 0,
anchorY: 0.5
});
LK.gui.bottomLeft.addChild(ammoBar);
ammoBar.x = 20;
ammoBar.y = -100;
// Game status text (wave start, game over, etc.)
gameStatusText = new Text2('', {
size: 100,
fill: 0xFFFFFF
});
gameStatusText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(gameStatusText);
gameStatusText.alpha = 0;
}
function updateUI() {
// Update score
scoreText.setText('Score: ' + score);
// Update wave
waveText.setText('Wave: ' + wave);
// Update health bar
var healthPercent = player.health / player.maxHealth;
healthBar.scale.x = healthPercent;
// Update ammo bar
var ammoPercent = player.ammo / player.maxAmmo;
ammoBar.scale.x = ammoPercent;
// Change ammo bar color when reloading
if (player.isReloading) {
ammoBar.tint = 0xff6600;
} else {
ammoBar.tint = 0xcc9900;
}
}
function startWave() {
waveStartTime = Date.now();
isWaveActive = true;
// Display wave start message
gameStatusText.setText('WAVE ' + wave);
gameStatusText.alpha = 1;
tween(gameStatusText, {
alpha: 0
}, {
duration: 1500,
easing: tween.easeIn
});
LK.getSound('newWave').play();
// Spawn zombies based on wave number
var zombieCount = 5 + wave * 2;
var zombieHealth = 30 + wave * 5;
var zombieSpeed = 2 + wave * 0.1;
var zombieDamage = 10 + wave * 2;
// Schedule zombie spawns over time
var spawnInterval = LK.setInterval(function () {
if (zombies.length < zombieCount) {
spawnZombie(zombieHealth, zombieSpeed, zombieDamage);
} else {
LK.clearInterval(spawnInterval);
}
}, 1000);
// Spawn a boss every 5 waves
if (wave % 5 === 0) {
LK.setTimeout(function () {
spawnBossZombie();
}, 5000);
}
}
function spawnZombie(health, speed, damage) {
var edge = Math.floor(Math.random() * 4); // 0: top, 1: right, 2: bottom, 3: left
var x, y;
switch (edge) {
case 0:
// top
x = Math.random() * 2048;
y = -100;
break;
case 1:
// right
x = 2048 + 100;
y = Math.random() * 2732;
break;
case 2:
// bottom
x = Math.random() * 2048;
y = 2732 + 100;
break;
case 3:
// left
x = -100;
y = Math.random() * 2732;
break;
}
var zombie = new Zombie(x, y, health, speed, damage);
zombies.push(zombie);
game.addChild(zombie);
}
function spawnBossZombie() {
// Spawn boss at a random edge
var edge = Math.floor(Math.random() * 4);
var x, y;
switch (edge) {
case 0:
// top
x = Math.random() * 2048;
y = -150;
break;
case 1:
// right
x = 2048 + 150;
y = Math.random() * 2732;
break;
case 2:
// bottom
x = Math.random() * 2048;
y = 2732 + 150;
break;
case 3:
// left
x = -150;
y = Math.random() * 2732;
break;
}
var boss = new BossZombie(x, y, wave);
zombies.push(boss);
game.addChild(boss);
// Play boss appear sound
LK.getSound('bossAppear').play();
// Show boss alert
gameStatusText.setText('BOSS ZOMBIE APPEARED!');
gameStatusText.alpha = 1;
tween(gameStatusText, {
alpha: 0
}, {
duration: 2000,
easing: tween.easeIn
});
}
function spawnPickup(x, y) {
// 30% chance for health, 70% for ammo
var type = Math.random() < 0.3 ? 'health' : 'ammo';
var pickup = new Pickup(x, y, type);
pickups.push(pickup);
game.addChild(pickup);
}
function checkWaveCompletion() {
if (isWaveActive && zombies.length === 0) {
isWaveActive = false;
// Display wave complete message
gameStatusText.setText('WAVE ' + wave + ' COMPLETE!');
gameStatusText.alpha = 1;
// Give player a weapon upgrade every 3 waves
if (wave % 3 === 0) {
player.upgradeWeapon();
// Show upgrade message
LK.setTimeout(function () {
gameStatusText.setText('WEAPON UPGRADED!');
}, 2000);
}
// Start next wave after a delay
LK.setTimeout(function () {
wave++;
gameStatusText.alpha = 0;
startWave();
}, 4000);
}
}
// Event handling
game.down = function (x, y) {
if (isGameOver) {
return;
}
targetPosition.x = x;
targetPosition.y = y;
// Player shoots at clicked position
var bullet = player.shoot(x, y);
if (bullet) {
bullets.push(bullet);
game.addChild(bullet);
}
};
game.move = function (x, y) {
targetPosition.x = x;
targetPosition.y = y;
};
game.up = function () {
// Not needed for this game
};
// Main game update loop
game.update = function () {
if (isGameOver) {
return;
}
// Check for player collision with obstacles
obstacles.forEach(function (obstacle) {
if (player.intersects(obstacle)) {
// Prevent player from moving through the obstacle
player.x = player.lastX;
player.y = player.lastY;
}
});
// Update player movement
player.lastX = player.x; // Track lastX before moving
player.lastY = player.y; // Track lastY before moving
player.moveTowards(targetPosition.x, targetPosition.y);
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var shouldRemove = bullets[i].update();
if (shouldRemove) {
bullets[i].destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet collision with zombies
for (var j = zombies.length - 1; j >= 0; j--) {
if (bullets[i] && bullets[i].intersects(zombies[j])) {
var zombieDied = zombies[j].takeDamage(bullets[i].damage);
// Remove bullet after hit
bullets[i].destroy();
bullets.splice(i, 1);
if (zombieDied) {
// Increase score and zombie kill counter
var scoreToAdd = zombies[j] instanceof BossZombie ? 100 : 10;
score += scoreToAdd;
zombiesKilled++;
// Chance to drop pickup
if (Math.random() < 0.3) {
spawnPickup(zombies[j].x, zombies[j].y);
}
// Remove zombie
zombies[j].destroy();
zombies.splice(j, 1);
}
break;
}
}
}
// Update zombies
for (var i = zombies.length - 1; i >= 0; i--) {
// Move zombie towards player
zombies[i].moveTowards(player.x, player.y);
// Check if zombie reached player
if (zombies[i].intersects(player)) {
var playerDied = zombies[i].attack(player);
if (playerDied) {
handleGameOver();
}
}
}
// Update pickups
for (var i = pickups.length - 1; i >= 0; i--) {
var shouldRemove = pickups[i].update();
if (shouldRemove) {
pickups[i].destroy();
pickups.splice(i, 1);
continue;
}
// Check if player collects pickup
if (player.intersects(pickups[i])) {
pickups[i].collect(player);
pickups[i].destroy();
pickups.splice(i, 1);
}
}
// Update UI
updateUI();
// Check if wave is complete
checkWaveCompletion();
// Auto-reload when empty and not already reloading
if (player.ammo === 0 && !player.isReloading) {
player.reload();
}
};
function handleGameOver() {
isGameOver = true;
// Fade out background music
LK.playMusic('gameMusic', {
fade: {
start: 0.3,
end: 0,
duration: 1000
}
});
// Update high score if needed
if (score > storage.highscore) {
storage.highscore = score;
}
// Show score in game over dialog
LK.setScore(score);
// Show game over screen after a short delay
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
// Pre-game screen setup
function showPreGameScreen() {
var preGameText = new Text2('Tap to Start', {
size: 100,
fill: 0xFFFFFF
});
preGameText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(preGameText);
// Wait for user interaction to start the game
game.down = function () {
LK.gui.center.removeChild(preGameText);
game.down = originalGameDown; // Restore original game down function
initGame(); // Start the game
};
}
// Store the original game down function
var originalGameDown = game.down;
// Show the pre-game screen
showPreGameScreen(); ===================================================================
--- original.js
+++ change.js
@@ -280,10 +280,12 @@
// Create player at center of screen
player = new Player();
player.x = 2048 / 2;
player.y = 2732 / 2;
- player.lastX = player.x; // Initialize lastX for tracking
- player.lastY = player.y; // Initialize lastY for tracking
+ if (player) {
+ player.lastX = player.x; // Initialize lastX for tracking
+ player.lastY = player.y; // Initialize lastY for tracking
+ }
game.addChild(player);
// Add obstacles
var obstacles = [];
obstacles.push(new Obstacle(50, 50, 'crate')); // Top-left corner