User prompt
Develop a 2D top-down zombie survival maze game for PC. 🎮 Core Concept: The player controls a mysterious survivor with a bird’s head, trapped in a dark, maze-like facility filled with zombies. The objective is to eliminate as many zombies as possible and escape the labyrinth alive. Players earn points only by killing zombies — survival time does not increase score. 📌 Key Features: Top-down camera for full map awareness Maze-based level: tight corridors, dead ends, hidden paths Unlimited bullets, but player must manage space and avoid being cornered Zombies spawn continuously and become stronger over time A hidden escape exit allows players to end the game by escaping Skor sadece zombileri öldürdükçe artar (Score increases only by killing zombies) 🕹️ Controls (PC only): Move: W / A / S / D Aim: Mouse Cursor Shoot: Left Mouse Button 🧾 UI and Screens: Main Menu: Start Game, How to Play, Exit How to Play screen: Clear explanation of controls and objectives Game Over screen: Display total zombies killed (score) Minimalist HUD showing Kill Count, Health, and optional Map 🎨 Art Style: Stylized pixel-art or simple cartoon visuals Atmospheric lighting in maze corridors Placeholder sprites acceptable in prototype 🔧 Development Notes: Modular structure for adding enemy types, power-ups, or new maze levels Designed only for PC, with keyboard + mouse control Game ends either on death or successful escape
User prompt
Design a 2D top-down zombie survival maze game for PC only. 🎮 Core Concept: The player controls a mysterious survivor with a bird’s head, trapped in an abandoned labyrinth filled with undead threats. The objective is to navigate the maze, eliminate zombies, and ultimately escape through a hidden exit. There is no ammo limit — survival depends on reflexes, positioning, and map knowledge. 📌 Features: Top-down camera with clear visibility of the maze environment Labyrinth-style map: narrow corridors, blocked paths, multiple routes Waves of zombies increase in difficulty over time The player must find the correct path to escape while surviving constant pressure Escape zone is hidden and may change position in each round (optional) No ammo limit, but limited health — getting surrounded is fatal 🕹️ Controls (PC only): Move: W / A / S / D Shoot: Left Mouse Button Aim: Mouse Cursor 🧾 UI Elements: Main Menu with Start Game, How to Play, Exit "How to Play" screen explaining controls and objective Game Over screen showing time survived and zombies eliminated Clean, minimalist interface, designed for PC experience 🎨 Style: Simple pixel-art or cartoon aesthetic Dark and atmospheric color palette Placeholder assets allowed for initial build 💡 Expansion Potential: Dynamic lighting in the maze Power-ups and keys to unlock shortcut doors Multiple character types (future update) Global leaderboard for fastest escapes / most kills This game should be optimized for PC with keyboard + mouse controls only. Mobile support is not required.
User prompt
Create a 2D top-down zombie survival game with the following features: The main character has a bird’s head and can move freely. The map is designed as a maze (labyrinth) filled with paths, dead ends, and multiple routes. The player must survive as long as possible and optionally escape the maze to win. The character can shoot without ammo limits (infinite bullets). Zombies spawn randomly and chase the player with increasing difficulty. The camera uses a top-down view to show the entire environment from above. UI and Features: Include an English Main Menu with: Start Game, How to Play, Exit Add a "How to Play" screen explaining the controls and the escape objective Game Over screen showing survival time and option to restart Use placeholder sprites for character, zombies, and maze environment Art style: simple cartoon or pixel-art The game should work on both mobile and PC, with on-screen buttons for mobile Make the structure modular and beginner-friendly, allowing future expansion (more enemies, new weapons, timed escape, etc.).
User prompt
Create a 2D top-down zombie survival game with the following features: The main character has a bird’s head and can move freely. The map is designed as a maze (labyrinth) filled with paths, dead ends, and multiple routes. The player must survive as long as possible and optionally escape the maze to win. The character can shoot without ammo limits (infinite bullets). Zombies spawn randomly and chase the player with increasing difficulty. The camera uses a top-down view to show the entire environment from above. UI and Features: Include an English Main Menu with: Start Game, How to Play, Exit Add a "How to Play" screen explaining the controls and the escape objective Game Over screen showing survival time and option to restart Use placeholder sprites for character, zombies, and maze environment Art style: simple cartoon or pixel-art The game should work on both mobile and PC, with on-screen buttons for mobile Make the structure modular and beginner-friendly, allowing future expansion (more enemies, new weapons, timed escape, etc.)
User prompt
Create a 2D side-scrolling zombie survival game where the main character has a bird’s head. The character can move freely and shoot without ammo limits. Include a "How to Play" UI screen that clearly explains the controls and gameplay mechanics.
User prompt
Create a 2D side-scrolling zombie survival game where the character can move freely and shoot without ammo limits. Include a "How to Play" UI screen that clearly explains the controls and gameplay mechanics.
Code edit (1 edits merged)
Please save this source code
User prompt
Zombie Survival Rush
Initial prompt
Create a 2D side-scrolling zombie survival game that works on both mobile devices and PC. The player must survive as long as possible against endless waves of zombies. The game should include a scoring system based on survival time and zombie kills. Features: English user interface Main Menu with: Start Game, How to Play, High Scores, Exit “How to Play” screen explaining controls: PC: Move (A/D), Jump (Space), Shoot (Left Click), Change Weapon (1/2/3) Mobile: On-screen buttons for move, jump, shoot, and switch weapon Increasing difficulty with time (zombies become stronger and faster) Game Over screen showing score and a "Try Again" button Health and weapon pickups Responsive UI that works on both PC and mobile screen sizes Use placeholder sprites for player, zombies, and background Simple, cartoon or pixel-art style Beginner-friendly and modular structure for future expansion
/****
* 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.damage = 25;
self.directionX = 0;
self.directionY = 0;
self.update = function () {
self.x += self.speed * self.directionX;
self.y += self.speed * self.directionY;
// Check wall collisions
if (checkWallCollision(self.x, self.y)) {
self.destroyed = true;
}
};
return self;
});
var HealthPack = Container.expand(function () {
var self = Container.call(this);
var healthGraphics = self.attachAsset('healthPack', {
anchorX: 0.5,
anchorY: 0.5
});
self.healAmount = 30;
self.update = function () {
// Simple floating animation
self.y += Math.sin(LK.ticks * 0.1) * 0.5;
// Check pickup
if (self.intersects(player)) {
player.heal(self.healAmount);
LK.getSound('pickup').play();
self.collected = true;
}
};
return self;
});
var HowToPlay = Container.expand(function () {
var self = Container.call(this);
// Create background overlay
var background = LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732,
alpha: 0.9
});
self.addChild(background);
// Title
var titleText = new Text2('HOW TO PLAY', {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.x = 1024;
titleText.y = 200;
self.addChild(titleText);
// Controls section
var controlsTitle = new Text2('CONTROLS', {
size: 80,
fill: 0xFFFF00
});
controlsTitle.anchor.set(0.5, 0);
controlsTitle.x = 1024;
controlsTitle.y = 400;
self.addChild(controlsTitle);
// Mobile controls
var mobileText = new Text2('MOBILE:', {
size: 60,
fill: 0x00FF00
});
mobileText.anchor.set(0, 0);
mobileText.x = 200;
mobileText.y = 520;
self.addChild(mobileText);
var mobileControls = new Text2('• Touch direction buttons to move\n• Touch shoot button to fire\n• Touch anywhere to shoot in direction\n• Navigate the maze carefully', {
size: 45,
fill: 0xFFFFFF
});
mobileControls.anchor.set(0, 0);
mobileControls.x = 200;
mobileControls.y = 600;
self.addChild(mobileControls);
// Gameplay section
var gameplayTitle = new Text2('GAMEPLAY', {
size: 80,
fill: 0xFFFF00
});
gameplayTitle.anchor.set(0.5, 0);
gameplayTitle.x = 1024;
gameplayTitle.y = 950;
self.addChild(gameplayTitle);
var gameplayText = new Text2('• Navigate through the maze\n• Survive zombie attacks\n• Collect health packs (red circles)\n• Collect weapon upgrades (blue boxes)\n• Find the green exit to escape!', {
size: 45,
fill: 0xFFFFFF
});
gameplayText.anchor.set(0, 0);
gameplayText.x = 200;
gameplayText.y = 1050;
self.addChild(gameplayText);
// Objectives
var objectiveTitle = new Text2('OBJECTIVES', {
size: 80,
fill: 0xFFFF00
});
objectiveTitle.anchor.set(0.5, 0);
objectiveTitle.x = 1024;
objectiveTitle.y = 1400;
self.addChild(objectiveTitle);
var objectiveText = new Text2('• Escape the maze to win!\n• Survive zombie encounters\n• Use walls for protection\n• Collect items to stay alive longer', {
size: 45,
fill: 0xFFFFFF
});
objectiveText.anchor.set(0, 0);
objectiveText.x = 200;
objectiveText.y = 1500;
self.addChild(objectiveText);
// Close button
var closeButton = LK.getAsset('player', {
width: 200,
height: 100,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
closeButton.x = 1024;
closeButton.y = 1900;
self.addChild(closeButton);
var closeText = new Text2('TAP TO START', {
size: 60,
fill: 0x000000
});
closeText.anchor.set(0.5, 0.5);
closeText.x = 1024;
closeText.y = 1900;
self.addChild(closeText);
closeButton.down = function () {
self.visible = false;
gameStarted = true;
};
background.down = function () {
self.visible = false;
gameStarted = true;
};
return self;
});
var Maze = Container.expand(function () {
var self = Container.call(this);
self.tileSize = 64;
self.cols = 32; // 2048 / 64
self.rows = 42; // 2732 / 64
self.maze = [];
self.exitX = 0;
self.exitY = 0;
// Simple maze generation
self.generateMaze = function () {
// Initialize maze with walls
for (var y = 0; y < self.rows; y++) {
self.maze[y] = [];
for (var x = 0; x < self.cols; x++) {
self.maze[y][x] = 1; // 1 = wall, 0 = path
}
}
// Create paths using simple algorithm
for (var y = 1; y < self.rows - 1; y += 2) {
for (var x = 1; x < self.cols - 1; x += 2) {
self.maze[y][x] = 0; // Create room
// Create random connections
if (x < self.cols - 2 && Math.random() < 0.7) {
self.maze[y][x + 1] = 0; // Right corridor
}
if (y < self.rows - 2 && Math.random() < 0.7) {
self.maze[y + 1][x] = 0; // Down corridor
}
}
}
// Ensure player starting area is clear
self.maze[1][1] = 0;
self.maze[1][2] = 0;
self.maze[2][1] = 0;
// Place exit in opposite corner
self.exitX = self.cols - 2;
self.exitY = self.rows - 2;
self.maze[self.exitY][self.exitX] = 2; // 2 = exit
};
self.renderMaze = function () {
for (var y = 0; y < self.rows; y++) {
for (var x = 0; x < self.cols; x++) {
if (self.maze[y][x] === 1) {
// Wall
var wall = self.attachAsset('mazeWall', {
anchorX: 0,
anchorY: 0
});
wall.x = x * self.tileSize;
wall.y = y * self.tileSize;
} else if (self.maze[y][x] === 0) {
// Floor
var floor = self.attachAsset('mazeFloor', {
anchorX: 0,
anchorY: 0
});
floor.x = x * self.tileSize;
floor.y = y * self.tileSize;
} else if (self.maze[y][x] === 2) {
// Exit
var exit = self.attachAsset('mazeExit', {
anchorX: 0,
anchorY: 0
});
exit.x = x * self.tileSize;
exit.y = y * self.tileSize;
}
}
}
};
self.isWall = function (x, y) {
var gridX = Math.floor(x / self.tileSize);
var gridY = Math.floor(y / self.tileSize);
if (gridX < 0 || gridX >= self.cols || gridY < 0 || gridY >= self.rows) {
return true; // Out of bounds
}
return self.maze[gridY][gridX] === 1;
};
self.isExit = function (x, y) {
var gridX = Math.floor(x / self.tileSize);
var gridY = Math.floor(y / self.tileSize);
if (gridX < 0 || gridX >= self.cols || gridY < 0 || gridY >= self.rows) {
return false;
}
return self.maze[gridY][gridX] === 2;
};
self.generateMaze();
self.renderMaze();
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Add bird head
var birdHead = self.attachAsset('playerHead', {
anchorX: 0.5,
anchorY: 0.5
});
birdHead.x = 0;
birdHead.y = -8; // Position head above body
// Add bird beak
var birdBeak = self.attachAsset('playerBeak', {
anchorX: 0,
anchorY: 0.5
});
birdBeak.x = 15; // Position to right of head
birdBeak.y = -8; // Same height as head
self.health = 100;
self.maxHealth = 100;
self.speed = 4;
self.weapon = 1;
self.maxWeapon = 3;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
gameOver = true;
}
// Flash red when taking damage
LK.effects.flashObject(self, 0xFF0000, 500);
};
self.heal = function (amount) {
self.health = Math.min(self.maxHealth, self.health + amount);
};
self.upgradeWeapon = function () {
if (self.weapon < self.maxWeapon) {
self.weapon++;
}
};
self.move = function (dx, dy) {
var newX = self.x + dx;
var newY = self.y + dy;
// Check wall collision
if (!checkWallCollision(newX, newY)) {
self.x = newX;
self.y = newY;
}
// Check exit collision
if (maze.isExit(self.x, self.y)) {
gameWon = true;
}
};
self.update = function () {
// Top-down movement - no gravity needed
};
return self;
});
var WeaponPickup = Container.expand(function () {
var self = Container.call(this);
var weaponGraphics = self.attachAsset('weaponPickup', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Simple floating animation
self.y += Math.sin(LK.ticks * 0.1) * 0.5;
// Check pickup
if (self.intersects(player)) {
player.upgradeWeapon();
LK.getSound('pickup').play();
self.collected = true;
}
};
return self;
});
var Zombie = Container.expand(function () {
var self = Container.call(this);
var zombieGraphics = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 50;
self.speed = 1.5;
self.damage = 20;
self.lastAttackTime = 0;
self.moveTimer = 0;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
return true; // Zombie is dead
}
return false;
};
self.update = function () {
self.moveTimer++;
// Move towards player every few frames for performance
if (self.moveTimer % 10 === 0) {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var moveX = dx / distance * self.speed;
var moveY = dy / distance * self.speed;
// Try to move towards player
var newX = self.x + moveX;
var newY = self.y + moveY;
if (!checkWallCollision(newX, newY)) {
self.x = newX;
self.y = newY;
} else {
// Try moving only horizontally or vertically
if (!checkWallCollision(newX, self.y)) {
self.x = newX;
} else if (!checkWallCollision(self.x, newY)) {
self.y = newY;
}
}
}
}
// Check collision with player
if (self.intersects(player)) {
var currentTime = LK.ticks;
if (currentTime - self.lastAttackTime > 60) {
// Attack every second
player.takeDamage(self.damage);
self.lastAttackTime = currentTime;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var player;
var maze;
var zombies = [];
var bullets = [];
var healthPacks = [];
var weaponPickups = [];
var gameOver = false;
var gameStarted = false;
var gameWon = false;
var score = 0;
var waveNumber = 1;
var zombieSpawnTimer = 0;
var pickupSpawnTimer = 0;
var howToPlayScreen;
// Movement controls
var moveLeft = false;
var moveRight = false;
var moveUp = false;
var moveDown = false;
var shooting = false;
var shootTimer = 0;
// Utility function for wall collision
function checkWallCollision(x, y) {
return maze.isWall(x, y);
}
// Create maze
maze = game.addChild(new Maze());
// Create player at maze start
player = game.addChild(new Player());
player.x = 96; // Start in maze path
player.y = 96;
// UI Elements
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
scoreText.x = 150;
scoreText.y = 50;
LK.gui.topLeft.addChild(scoreText);
var healthText = new Text2('Health: 100', {
size: 60,
fill: 0xFF0000
});
healthText.anchor.set(0, 0);
healthText.x = 150;
healthText.y = 120;
LK.gui.topLeft.addChild(healthText);
var waveText = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFF00
});
waveText.anchor.set(1, 0);
LK.gui.topRight.addChild(waveText);
// Control buttons for mobile - 4 direction movement
var leftButton = LK.getAsset('player', {
width: 80,
height: 80,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
leftButton.x = 80;
leftButton.y = 2600;
LK.gui.addChild(leftButton);
var rightButton = LK.getAsset('player', {
width: 80,
height: 80,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
rightButton.x = 240;
rightButton.y = 2600;
LK.gui.addChild(rightButton);
var upButton = LK.getAsset('player', {
width: 80,
height: 80,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
upButton.x = 160;
upButton.y = 2520;
LK.gui.addChild(upButton);
var downButton = LK.getAsset('player', {
width: 80,
height: 80,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
downButton.x = 160;
downButton.y = 2680;
LK.gui.addChild(downButton);
var shootButton = LK.getAsset('bullet', {
width: 100,
height: 100,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
shootButton.x = 1900;
shootButton.y = 2600;
LK.gui.addChild(shootButton);
// Button event handlers
leftButton.down = function () {
moveLeft = true;
};
leftButton.up = function () {
moveLeft = false;
};
rightButton.down = function () {
moveRight = true;
};
rightButton.up = function () {
moveRight = false;
};
upButton.down = function () {
moveUp = true;
};
upButton.up = function () {
moveUp = false;
};
downButton.down = function () {
moveDown = true;
};
downButton.up = function () {
moveDown = false;
};
shootButton.down = function () {
shooting = true;
};
shootButton.up = function () {
shooting = false;
};
// Create How to Play screen
howToPlayScreen = game.addChild(new HowToPlay());
howToPlayScreen.visible = true;
// Game event handlers
game.down = function (x, y, obj) {
// Handle shooting in direction of touch
if (gameStarted && !gameOver && !gameWon) {
shootBullet(x, y);
}
};
game.up = function (x, y, obj) {
// Touch release events
};
// Spawn functions
function spawnZombie() {
var attempts = 0;
var zombie = new Zombie();
// Try to spawn in valid maze location
do {
zombie.x = Math.random() * 1800 + 124;
zombie.y = Math.random() * 2400 + 124;
attempts++;
} while (checkWallCollision(zombie.x, zombie.y) && attempts < 50);
// Scale difficulty based on wave
zombie.health += (waveNumber - 1) * 10;
zombie.speed += (waveNumber - 1) * 0.2;
zombie.damage += (waveNumber - 1) * 5;
zombies.push(zombie);
game.addChild(zombie);
}
function spawnHealthPack() {
var attempts = 0;
var healthPack = new HealthPack();
// Try to spawn in valid maze location
do {
healthPack.x = Math.random() * 1800 + 124;
healthPack.y = Math.random() * 2400 + 124;
attempts++;
} while (checkWallCollision(healthPack.x, healthPack.y) && attempts < 50);
healthPacks.push(healthPack);
game.addChild(healthPack);
}
function spawnWeaponPickup() {
var attempts = 0;
var weaponPickup = new WeaponPickup();
// Try to spawn in valid maze location
do {
weaponPickup.x = Math.random() * 1800 + 124;
weaponPickup.y = Math.random() * 2400 + 124;
attempts++;
} while (checkWallCollision(weaponPickup.x, weaponPickup.y) && attempts < 50);
weaponPickups.push(weaponPickup);
game.addChild(weaponPickup);
}
function shootBullet(targetX, targetY) {
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y;
bullet.damage = 25 * player.weapon; // More damage with better weapons
// Calculate direction to target
var dx = targetX - player.x;
var dy = targetY - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
bullet.directionX = dx / distance;
bullet.directionY = dy / distance;
} else {
bullet.directionX = 1;
bullet.directionY = 0;
}
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
}
// Main game update
game.update = function () {
if (!gameStarted) {
return; // Don't start game until player dismisses how to play screen
}
if (gameOver) {
LK.showGameOver();
return;
}
if (gameWon) {
LK.showYouWin();
return;
}
// Update score based on survival time
score += 1;
LK.setScore(score);
// Handle player movement - top-down 4-directional
if (moveLeft) {
player.move(-player.speed, 0);
}
if (moveRight) {
player.move(player.speed, 0);
}
if (moveUp) {
player.move(0, -player.speed);
}
if (moveDown) {
player.move(0, player.speed);
}
// Handle shooting
if (shooting && LK.ticks - shootTimer > 60 / player.weapon) {
// Find nearest zombie to shoot at
var nearestZombie = null;
var nearestDistance = Infinity;
for (var i = 0; i < zombies.length; i++) {
var dx = zombies[i].x - player.x;
var dy = zombies[i].y - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestZombie = zombies[i];
}
}
if (nearestZombie) {
shootBullet(nearestZombie.x, nearestZombie.y);
} else {
shootBullet(player.x + 50, player.y); // Default shoot right
}
shootTimer = LK.ticks;
}
// Spawn zombies
zombieSpawnTimer++;
var spawnRate = Math.max(120 - waveNumber * 10, 30); // Slower spawning for maze
if (zombieSpawnTimer >= spawnRate) {
spawnZombie();
zombieSpawnTimer = 0;
}
// Spawn pickups occasionally
pickupSpawnTimer++;
if (pickupSpawnTimer >= 900) {
// Every 15 seconds
if (Math.random() < 0.7) {
spawnHealthPack();
} else {
spawnWeaponPickup();
}
pickupSpawnTimer = 0;
}
// Update bullets and check collisions
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Check if bullet hit wall or is off screen
if (bullet.destroyed || bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet-zombie collisions
var hit = false;
for (var j = zombies.length - 1; j >= 0; j--) {
var zombie = zombies[j];
if (bullet.intersects(zombie)) {
if (zombie.takeDamage(bullet.damage)) {
// Zombie died
score += 50;
LK.getSound('zombieHit').play();
zombie.destroy();
zombies.splice(j, 1);
}
bullet.destroy();
bullets.splice(i, 1);
hit = true;
break;
}
}
}
// Update health packs
for (var i = healthPacks.length - 1; i >= 0; i--) {
var healthPack = healthPacks[i];
if (healthPack.collected) {
healthPack.destroy();
healthPacks.splice(i, 1);
}
}
// Update weapon pickups
for (var i = weaponPickups.length - 1; i >= 0; i--) {
var weaponPickup = weaponPickups[i];
if (weaponPickup.collected) {
weaponPickup.destroy();
weaponPickups.splice(i, 1);
}
}
// Update wave progression
if (LK.ticks % 1800 === 0) {
// Every 30 seconds
waveNumber++;
}
// Update UI
scoreText.setText('Score: ' + score);
healthText.setText('Health: ' + player.health);
waveText.setText('Wave: ' + waveNumber);
}; ===================================================================
--- original.js
+++ change.js
@@ -13,11 +13,17 @@
anchorY: 0.5
});
self.speed = 12;
self.damage = 25;
- self.direction = 1; // 1 for right, -1 for left
+ self.directionX = 0;
+ self.directionY = 0;
self.update = function () {
- self.x += self.speed * self.direction;
+ self.x += self.speed * self.directionX;
+ self.y += self.speed * self.directionY;
+ // Check wall collisions
+ if (checkWallCollision(self.x, self.y)) {
+ self.destroyed = true;
+ }
};
return self;
});
var HealthPack = Container.expand(function () {
@@ -78,9 +84,9 @@
mobileText.anchor.set(0, 0);
mobileText.x = 200;
mobileText.y = 520;
self.addChild(mobileText);
- var mobileControls = new Text2('• Touch left/right buttons to move\n• Touch jump button to jump\n• Touch shoot button to fire\n• Touch right side of screen to shoot', {
+ var mobileControls = new Text2('• Touch direction buttons to move\n• Touch shoot button to fire\n• Touch anywhere to shoot in direction\n• Navigate the maze carefully', {
size: 45,
fill: 0xFFFFFF
});
mobileControls.anchor.set(0, 0);
@@ -95,9 +101,9 @@
gameplayTitle.anchor.set(0.5, 0);
gameplayTitle.x = 1024;
gameplayTitle.y = 950;
self.addChild(gameplayTitle);
- var gameplayText = new Text2('• Survive endless zombie waves\n• Collect health packs (red circles)\n• Collect weapon upgrades (blue boxes)\n• Zombies get stronger each wave\n• Score points for survival time and kills', {
+ var gameplayText = new Text2('• Navigate through the maze\n• Survive zombie attacks\n• Collect health packs (red circles)\n• Collect weapon upgrades (blue boxes)\n• Find the green exit to escape!', {
size: 45,
fill: 0xFFFFFF
});
gameplayText.anchor.set(0, 0);
@@ -112,9 +118,9 @@
objectiveTitle.anchor.set(0.5, 0);
objectiveTitle.x = 1024;
objectiveTitle.y = 1400;
self.addChild(objectiveTitle);
- var objectiveText = new Text2('• Stay alive as long as possible\n• Kill zombies to earn points\n• Reach 10,000 points to win\n• Use terrain and movement to avoid damage', {
+ var objectiveText = new Text2('• Escape the maze to win!\n• Survive zombie encounters\n• Use walls for protection\n• Collect items to stay alive longer', {
size: 45,
fill: 0xFFFFFF
});
objectiveText.anchor.set(0, 0);
@@ -149,34 +155,121 @@
gameStarted = true;
};
return self;
});
+var Maze = Container.expand(function () {
+ var self = Container.call(this);
+ self.tileSize = 64;
+ self.cols = 32; // 2048 / 64
+ self.rows = 42; // 2732 / 64
+ self.maze = [];
+ self.exitX = 0;
+ self.exitY = 0;
+ // Simple maze generation
+ self.generateMaze = function () {
+ // Initialize maze with walls
+ for (var y = 0; y < self.rows; y++) {
+ self.maze[y] = [];
+ for (var x = 0; x < self.cols; x++) {
+ self.maze[y][x] = 1; // 1 = wall, 0 = path
+ }
+ }
+ // Create paths using simple algorithm
+ for (var y = 1; y < self.rows - 1; y += 2) {
+ for (var x = 1; x < self.cols - 1; x += 2) {
+ self.maze[y][x] = 0; // Create room
+ // Create random connections
+ if (x < self.cols - 2 && Math.random() < 0.7) {
+ self.maze[y][x + 1] = 0; // Right corridor
+ }
+ if (y < self.rows - 2 && Math.random() < 0.7) {
+ self.maze[y + 1][x] = 0; // Down corridor
+ }
+ }
+ }
+ // Ensure player starting area is clear
+ self.maze[1][1] = 0;
+ self.maze[1][2] = 0;
+ self.maze[2][1] = 0;
+ // Place exit in opposite corner
+ self.exitX = self.cols - 2;
+ self.exitY = self.rows - 2;
+ self.maze[self.exitY][self.exitX] = 2; // 2 = exit
+ };
+ self.renderMaze = function () {
+ for (var y = 0; y < self.rows; y++) {
+ for (var x = 0; x < self.cols; x++) {
+ if (self.maze[y][x] === 1) {
+ // Wall
+ var wall = self.attachAsset('mazeWall', {
+ anchorX: 0,
+ anchorY: 0
+ });
+ wall.x = x * self.tileSize;
+ wall.y = y * self.tileSize;
+ } else if (self.maze[y][x] === 0) {
+ // Floor
+ var floor = self.attachAsset('mazeFloor', {
+ anchorX: 0,
+ anchorY: 0
+ });
+ floor.x = x * self.tileSize;
+ floor.y = y * self.tileSize;
+ } else if (self.maze[y][x] === 2) {
+ // Exit
+ var exit = self.attachAsset('mazeExit', {
+ anchorX: 0,
+ anchorY: 0
+ });
+ exit.x = x * self.tileSize;
+ exit.y = y * self.tileSize;
+ }
+ }
+ }
+ };
+ self.isWall = function (x, y) {
+ var gridX = Math.floor(x / self.tileSize);
+ var gridY = Math.floor(y / self.tileSize);
+ if (gridX < 0 || gridX >= self.cols || gridY < 0 || gridY >= self.rows) {
+ return true; // Out of bounds
+ }
+ return self.maze[gridY][gridX] === 1;
+ };
+ self.isExit = function (x, y) {
+ var gridX = Math.floor(x / self.tileSize);
+ var gridY = Math.floor(y / self.tileSize);
+ if (gridX < 0 || gridX >= self.cols || gridY < 0 || gridY >= self.rows) {
+ return false;
+ }
+ return self.maze[gridY][gridX] === 2;
+ };
+ self.generateMaze();
+ self.renderMaze();
+ return self;
+});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
- anchorY: 1.0
+ anchorY: 0.5
});
// Add bird head
var birdHead = self.attachAsset('playerHead', {
anchorX: 0.5,
anchorY: 0.5
});
birdHead.x = 0;
- birdHead.y = -60; // Position head above body
+ birdHead.y = -8; // Position head above body
// Add bird beak
var birdBeak = self.attachAsset('playerBeak', {
anchorX: 0,
anchorY: 0.5
});
- birdBeak.x = 20; // Position to right of head
- birdBeak.y = -60; // Same height as head
+ birdBeak.x = 15; // Position to right of head
+ birdBeak.y = -8; // Same height as head
self.health = 100;
self.maxHealth = 100;
- self.speed = 8;
- self.jumpPower = 15;
- self.velocityY = 0;
- self.onGround = true;
+ self.speed = 4;
self.weapon = 1;
self.maxWeapon = 3;
self.takeDamage = function (damage) {
self.health -= damage;
@@ -194,22 +287,24 @@
if (self.weapon < self.maxWeapon) {
self.weapon++;
}
};
- self.update = function () {
- // Apply gravity
- if (!self.onGround) {
- self.velocityY += 0.8;
+ self.move = function (dx, dy) {
+ var newX = self.x + dx;
+ var newY = self.y + dy;
+ // Check wall collision
+ if (!checkWallCollision(newX, newY)) {
+ self.x = newX;
+ self.y = newY;
}
- // Update position
- self.y += self.velocityY;
- // Ground collision
- if (self.y >= groundY) {
- self.y = groundY;
- self.velocityY = 0;
- self.onGround = true;
+ // Check exit collision
+ if (maze.isExit(self.x, self.y)) {
+ gameWon = true;
}
};
+ self.update = function () {
+ // Top-down movement - no gravity needed
+ };
return self;
});
var WeaponPickup = Container.expand(function () {
var self = Container.call(this);
@@ -232,14 +327,15 @@
var Zombie = Container.expand(function () {
var self = Container.call(this);
var zombieGraphics = self.attachAsset('zombie', {
anchorX: 0.5,
- anchorY: 1.0
+ anchorY: 0.5
});
self.health = 50;
- self.speed = 2;
+ self.speed = 1.5;
self.damage = 20;
self.lastAttackTime = 0;
+ self.moveTimer = 0;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
@@ -247,13 +343,32 @@
}
return false;
};
self.update = function () {
- // Move towards player
- if (player.x > self.x) {
- self.x += self.speed;
- } else {
- self.x -= self.speed;
+ self.moveTimer++;
+ // Move towards player every few frames for performance
+ if (self.moveTimer % 10 === 0) {
+ var dx = player.x - self.x;
+ var dy = player.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance > 0) {
+ var moveX = dx / distance * self.speed;
+ var moveY = dy / distance * self.speed;
+ // Try to move towards player
+ var newX = self.x + moveX;
+ var newY = self.y + moveY;
+ if (!checkWallCollision(newX, newY)) {
+ self.x = newX;
+ self.y = newY;
+ } else {
+ // Try moving only horizontally or vertically
+ if (!checkWallCollision(newX, self.y)) {
+ self.x = newX;
+ } else if (!checkWallCollision(self.x, newY)) {
+ self.y = newY;
+ }
+ }
+ }
}
// Check collision with player
if (self.intersects(player)) {
var currentTime = LK.ticks;
@@ -278,36 +393,38 @@
* Game Code
****/
// Game variables
var player;
+var maze;
var zombies = [];
var bullets = [];
var healthPacks = [];
var weaponPickups = [];
var gameOver = false;
var gameStarted = false;
+var gameWon = false;
var score = 0;
var waveNumber = 1;
var zombieSpawnTimer = 0;
var pickupSpawnTimer = 0;
-var groundY = 2732 - 150;
var howToPlayScreen;
// Movement controls
var moveLeft = false;
var moveRight = false;
+var moveUp = false;
+var moveDown = false;
var shooting = false;
var shootTimer = 0;
-// Create ground
-var ground = game.addChild(LK.getAsset('ground', {
- anchorX: 0,
- anchorY: 0,
- x: 0,
- y: groundY + 50
-}));
-// Create player
+// Utility function for wall collision
+function checkWallCollision(x, y) {
+ return maze.isWall(x, y);
+}
+// Create maze
+maze = game.addChild(new Maze());
+// Create player at maze start
player = game.addChild(new Player());
-player.x = 300;
-player.y = groundY;
+player.x = 96; // Start in maze path
+player.y = 96;
// UI Elements
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
@@ -329,39 +446,49 @@
fill: 0xFFFF00
});
waveText.anchor.set(1, 0);
LK.gui.topRight.addChild(waveText);
-// Control buttons for mobile
+// Control buttons for mobile - 4 direction movement
var leftButton = LK.getAsset('player', {
- width: 100,
- height: 100,
+ width: 80,
+ height: 80,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
-leftButton.x = 100;
+leftButton.x = 80;
leftButton.y = 2600;
LK.gui.addChild(leftButton);
var rightButton = LK.getAsset('player', {
- width: 100,
- height: 100,
+ width: 80,
+ height: 80,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
-rightButton.x = 250;
+rightButton.x = 240;
rightButton.y = 2600;
LK.gui.addChild(rightButton);
-var jumpButton = LK.getAsset('player', {
- width: 100,
- height: 100,
+var upButton = LK.getAsset('player', {
+ width: 80,
+ height: 80,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
-jumpButton.x = 1900;
-jumpButton.y = 2500;
-LK.gui.addChild(jumpButton);
+upButton.x = 160;
+upButton.y = 2520;
+LK.gui.addChild(upButton);
+var downButton = LK.getAsset('player', {
+ width: 80,
+ height: 80,
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.3
+});
+downButton.x = 160;
+downButton.y = 2680;
+LK.gui.addChild(downButton);
var shootButton = LK.getAsset('bullet', {
width: 100,
height: 100,
anchorX: 0.5,
@@ -383,14 +510,20 @@
};
rightButton.up = function () {
moveRight = false;
};
-jumpButton.down = function () {
- if (player.onGround) {
- player.velocityY = -player.jumpPower;
- player.onGround = false;
- }
+upButton.down = function () {
+ moveUp = true;
};
+upButton.up = function () {
+ moveUp = false;
+};
+downButton.down = function () {
+ moveDown = true;
+};
+downButton.up = function () {
+ moveDown = false;
+};
shootButton.down = function () {
shooting = true;
};
shootButton.up = function () {
@@ -400,62 +533,72 @@
howToPlayScreen = game.addChild(new HowToPlay());
howToPlayScreen.visible = true;
// Game event handlers
game.down = function (x, y, obj) {
- // Handle shooting anywhere on screen
- if (x > 1024) {
- // Right side of screen
- shooting = true;
+ // Handle shooting in direction of touch
+ if (gameStarted && !gameOver && !gameWon) {
+ shootBullet(x, y);
}
};
game.up = function (x, y, obj) {
- shooting = false;
+ // Touch release events
};
// Spawn functions
function spawnZombie() {
+ var attempts = 0;
var zombie = new Zombie();
- zombie.x = Math.random() < 0.5 ? -50 : 2098; // Spawn from left or right edge
- zombie.y = groundY;
+ // Try to spawn in valid maze location
+ do {
+ zombie.x = Math.random() * 1800 + 124;
+ zombie.y = Math.random() * 2400 + 124;
+ attempts++;
+ } while (checkWallCollision(zombie.x, zombie.y) && attempts < 50);
// Scale difficulty based on wave
zombie.health += (waveNumber - 1) * 10;
- zombie.speed += (waveNumber - 1) * 0.5;
+ zombie.speed += (waveNumber - 1) * 0.2;
zombie.damage += (waveNumber - 1) * 5;
zombies.push(zombie);
game.addChild(zombie);
}
function spawnHealthPack() {
+ var attempts = 0;
var healthPack = new HealthPack();
- healthPack.x = Math.random() * 1800 + 124;
- healthPack.y = groundY - 50;
+ // Try to spawn in valid maze location
+ do {
+ healthPack.x = Math.random() * 1800 + 124;
+ healthPack.y = Math.random() * 2400 + 124;
+ attempts++;
+ } while (checkWallCollision(healthPack.x, healthPack.y) && attempts < 50);
healthPacks.push(healthPack);
game.addChild(healthPack);
}
function spawnWeaponPickup() {
+ var attempts = 0;
var weaponPickup = new WeaponPickup();
- weaponPickup.x = Math.random() * 1800 + 124;
- weaponPickup.y = groundY - 50;
+ // Try to spawn in valid maze location
+ do {
+ weaponPickup.x = Math.random() * 1800 + 124;
+ weaponPickup.y = Math.random() * 2400 + 124;
+ attempts++;
+ } while (checkWallCollision(weaponPickup.x, weaponPickup.y) && attempts < 50);
weaponPickups.push(weaponPickup);
game.addChild(weaponPickup);
}
-function shootBullet() {
+function shootBullet(targetX, targetY) {
var bullet = new Bullet();
bullet.x = player.x;
- bullet.y = player.y - 40;
+ bullet.y = player.y;
bullet.damage = 25 * player.weapon; // More damage with better weapons
- // Find nearest zombie to aim at
- var nearestZombie = null;
- var nearestDistance = Infinity;
- for (var i = 0; i < zombies.length; i++) {
- var distance = Math.abs(zombies[i].x - player.x);
- if (distance < nearestDistance) {
- nearestDistance = distance;
- nearestZombie = zombies[i];
- }
- }
- if (nearestZombie) {
- bullet.direction = nearestZombie.x > player.x ? 1 : -1;
+ // Calculate direction to target
+ var dx = targetX - player.x;
+ var dy = targetY - player.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance > 0) {
+ bullet.directionX = dx / distance;
+ bullet.directionY = dy / distance;
} else {
- bullet.direction = 1; // Default right
+ bullet.directionX = 1;
+ bullet.directionY = 0;
}
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
@@ -468,35 +611,60 @@
if (gameOver) {
LK.showGameOver();
return;
}
+ if (gameWon) {
+ LK.showYouWin();
+ return;
+ }
// Update score based on survival time
score += 1;
LK.setScore(score);
- // Handle player movement
- if (moveLeft && player.x > 50) {
- player.x -= player.speed;
+ // Handle player movement - top-down 4-directional
+ if (moveLeft) {
+ player.move(-player.speed, 0);
}
- if (moveRight && player.x < 1998) {
- player.x += player.speed;
+ if (moveRight) {
+ player.move(player.speed, 0);
}
+ if (moveUp) {
+ player.move(0, -player.speed);
+ }
+ if (moveDown) {
+ player.move(0, player.speed);
+ }
// Handle shooting
if (shooting && LK.ticks - shootTimer > 60 / player.weapon) {
- // Faster shooting with better weapons
- shootBullet();
+ // Find nearest zombie to shoot at
+ var nearestZombie = null;
+ var nearestDistance = Infinity;
+ for (var i = 0; i < zombies.length; i++) {
+ var dx = zombies[i].x - player.x;
+ var dy = zombies[i].y - player.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < nearestDistance) {
+ nearestDistance = distance;
+ nearestZombie = zombies[i];
+ }
+ }
+ if (nearestZombie) {
+ shootBullet(nearestZombie.x, nearestZombie.y);
+ } else {
+ shootBullet(player.x + 50, player.y); // Default shoot right
+ }
shootTimer = LK.ticks;
}
// Spawn zombies
zombieSpawnTimer++;
- var spawnRate = Math.max(60 - waveNumber * 5, 20); // Faster spawning each wave
+ var spawnRate = Math.max(120 - waveNumber * 10, 30); // Slower spawning for maze
if (zombieSpawnTimer >= spawnRate) {
spawnZombie();
zombieSpawnTimer = 0;
}
// Spawn pickups occasionally
pickupSpawnTimer++;
- if (pickupSpawnTimer >= 600) {
- // Every 10 seconds
+ if (pickupSpawnTimer >= 900) {
+ // Every 15 seconds
if (Math.random() < 0.7) {
spawnHealthPack();
} else {
spawnWeaponPickup();
@@ -505,10 +673,10 @@
}
// Update bullets and check collisions
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
- // Check if bullet is off screen
- if (bullet.x < -50 || bullet.x > 2098) {
+ // Check if bullet hit wall or is off screen
+ if (bullet.destroyed || bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
@@ -555,9 +723,5 @@
// Update UI
scoreText.setText('Score: ' + score);
healthText.setText('Health: ' + player.health);
waveText.setText('Wave: ' + waveNumber);
- // Check win condition (survive for a very long time)
- if (score >= 10000) {
- LK.showYouWin();
- }
};
\ No newline at end of file
Human. In-Game asset. 2d. High contrast. No shadows
Zombie. In-Game asset. 2d. High contrast. No shadows
Health. In-Game asset. 2d. High contrast. No shadows
Weapon. In-Game asset. 2d. High contrast. No shadows
Exit. In-Game asset. 2d. High contrast. No shadows
Maze exit. In-Game asset. 2d. High contrast. No shadows
Bullet. In-Game asset. 2d. High contrast. No shadows
Player Health. In-Game asset. 2d. High contrast. No shadows