User prompt
hasar yediğimiz zaman ekrandaki kırmızı rengi kaldır hasar efekti olmasın
User prompt
erzakları topladığımız zaman canımız %25 artsın
User prompt
karakter zombilere yaklaştığı zaman katana otomatik vursun
User prompt
Katananın vuruş alani %20 artsın
User prompt
karakterin 100 canı olsun
User prompt
katana zombilere hasar versin ve karakterin 10 canı olsun
User prompt
zombiler evlerin etrafında dursun biz zombilere yaklaştığımız zaman onlar bizim üzerimize koşsun
Code edit (1 edits merged)
Please save this source code
User prompt
Katana Survivor: Zombi Kıyameti
Initial prompt
dünyada tek başına kalmış savaşçı bir kadınız elimizde çok keskin bir katana var ve düşmanlarımız zombiler. amacımız evlere girip evlerden erzak toplayıp zombileri öldürüp hayatta kalmak.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // House class var House = Container.expand(function () { var self = Container.call(this); var houseSprite = self.attachAsset('house', { anchorX: 0.5, anchorY: 0.5 }); // Loot inside self.hasLoot = true; self.loot = null; // Place loot inside house self.spawnLoot = function () { if (!self.hasLoot) return; var loot = LK.getAsset('loot', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); self.addChild(loot); self.loot = loot; }; // Remove loot self.takeLoot = function () { if (self.loot) { self.loot.destroy(); self.loot = null; self.hasLoot = false; } }; return self; }); // Player class var Player = Container.expand(function () { var self = Container.call(this); var playerSprite = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); // Katana asset (rotates for slash) var katana = self.attachAsset('katana', { anchorX: 0.1, anchorY: 0.5, x: 60, // right hand y: 0 }); self.katana = katana; katana.rotation = 0; // Katana slash cooldown self.canSlash = true; // Katana slash animation self.slash = function (dir) { if (!self.canSlash) return; self.canSlash = false; // Animate katana swing var startRot = dir === 'left' ? -Math.PI / 3 : Math.PI / 3; katana.rotation = 0; tween(katana, { rotation: startRot }, { duration: 60, easing: tween.cubicOut, onFinish: function onFinish() { tween(katana, { rotation: 0 }, { duration: 120, easing: tween.cubicIn, onFinish: function onFinish() { self.canSlash = true; } }); } }); // Slash effect var slashFx = LK.getAsset('slash', { anchorX: 0.1, anchorY: 0.5, x: katana.x, y: katana.y, rotation: startRot, alpha: 0.7 }); self.addChild(slashFx); tween(slashFx, { alpha: 0 }, { duration: 180, onFinish: function onFinish() { slashFx.destroy(); } }); }; // Move to (x, y) with bounds self.moveTo = function (x, y) { // Clamp to game area (leave 100px margin) var hw = self.width / 2, hh = self.height / 2; var minX = 100 + hw, maxX = 2048 - hw - 100; var minY = 100 + hh, maxY = 2732 - hh - 100; self.x = Math.max(minX, Math.min(maxX, x)); self.y = Math.max(minY, Math.min(maxY, y)); }; return self; }); // Zombie class var Zombie = Container.expand(function () { var self = Container.call(this); var zombieSprite = self.attachAsset('zombie', { anchorX: 0.5, anchorY: 0.5 }); // Target to follow (player) self.target = null; self.speed = 2.2 + Math.random() * 1.2; // randomize speed a bit // For hit flash self.isHit = false; // For AI: wander around house if not chasing self.homeX = 0; self.homeY = 0; self.wanderAngle = Math.random() * Math.PI * 2; self.wanderTimer = 0; self.chaseRadius = 420; // distance to start chasing player // --- Health for zombie --- // Set zombie health to 100% (was 1.5, now 3) self.maxHealth = 3; self.health = self.maxHealth; self.update = function () { if (!self.target) return; // Calculate distance to player var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < self.chaseRadius) { // Chase player if (dist > 10) { self.x += dx / dist * self.speed * 1.25; // run a bit faster when chasing self.y += dy / dist * self.speed * 1.25; } } else { // Wander around home position self.wanderTimer--; if (self.wanderTimer <= 0) { self.wanderAngle = Math.random() * Math.PI * 2; self.wanderTimer = 60 + Math.floor(Math.random() * 60); } var wanderDist = 60 + Math.random() * 40; var targetX = self.homeX + Math.cos(self.wanderAngle) * wanderDist; var targetY = self.homeY + Math.sin(self.wanderAngle) * wanderDist; var wx = targetX - self.x; var wy = targetY - self.y; var wdist = Math.sqrt(wx * wx + wy * wy); if (wdist > 4) { self.x += wx / wdist * self.speed * 0.5; self.y += wy / wdist * self.speed * 0.5; } } }; // Flash red when hit self.flashHit = function () { if (self.isHit) return; self.isHit = true; tween(zombieSprite, { tint: 0xff0000 }, { duration: 80, onFinish: function onFinish() { tween(zombieSprite, { tint: 0x4e9a06 }, { duration: 120, onFinish: function onFinish() { self.isHit = false; } }); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x23272e }); /**** * Game Code ****/ // --- Game variables --- // Kadın savaşçı (player) // Katana (kılıç) // Zombi // Ev // Erzak (loot) // Zombi öldürme efekti // Katana sallama efekti var player; var zombies = []; var houses = []; var score = 0; var scoreTxt; var playerHealth = 100; var healthTxt; var dragNode = null; var lastPlayerX = 0, lastPlayerY = 0; var lastIntersectingZombie = false; var lastIntersectingLoot = false; var gameOver = false; // --- UI --- scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Health UI healthTxt = new Text2('Can: 100', { size: 90, fill: 0xFF6666 }); healthTxt.anchor.set(0.5, 0); healthTxt.y = 120; LK.gui.top.addChild(healthTxt); // --- Level system --- var currentLevel = 1; var lootHealAmount = 0.4; // default, can be changed per level // --- Spawn houses --- function spawnHouses() { houses = []; var housePositions = []; if (currentLevel === 1) { housePositions = [{ x: 400, y: 700 }, { x: 1648, y: 700 }, { x: 400, y: 2000 }, { x: 1648, y: 2000 }, { x: 1024, y: 1400 }]; lootHealAmount = 0.4; // Level 1: 40% heal (for consistency, can be 0.15 if you want to keep old) } else if (currentLevel === 2) { housePositions = [{ x: 600, y: 800 }, { x: 1024, y: 1800 }, { x: 1600, y: 800 }]; lootHealAmount = 0.3; // Level 2: 30% heal } for (var i = 0; i < housePositions.length; i++) { var h = new House(); h.x = housePositions[i].x; h.y = housePositions[i].y; h.spawnLoot(); houses.push(h); game.addChild(h); } } // --- Spawn zombies around houses --- function spawnZombies() { zombies = []; var zombiesPerHouse = currentLevel === 2 ? 2 : 3; for (var i = 0; i < houses.length; i++) { for (var j = 0; j < zombiesPerHouse; j++) { var z = new Zombie(); // Place randomly around house var angle = Math.random() * Math.PI * 2; var dist = 180 + Math.random() * 60; z.x = houses[i].x + Math.cos(angle) * dist; z.y = houses[i].y + Math.sin(angle) * dist; z.homeX = z.x; z.homeY = z.y; z.target = null; // will be set to player later zombies.push(z); game.addChild(z); } } } // --- Spawn player --- function spawnPlayer() { player = new Player(); player.x = 1024; player.y = 2400; game.addChild(player); } // --- Reset game state --- function resetGame() { // Remove all children except GUI for (var i = game.children.length - 1; i >= 0; i--) { game.children[i].destroy(); } score = 0; scoreTxt.setText(score); gameOver = false; spawnHouses(); spawnZombies(); spawnPlayer(); // Set all zombies to follow player for (var i = 0; i < zombies.length; i++) { zombies[i].target = player; } } // --- Start Screen --- var startScreen = new Container(); // Add zombie-themed background image to start screen var zombieBg = LK.getAsset('zombie', { anchorX: 0.5, anchorY: 0.5, scaleX: 14, scaleY: 14, x: 1024, y: 1366, alpha: 0.13 }); startScreen.addChild(zombieBg); // Button var startBtnBg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 1.2, x: 1024, y: 1500 }); startScreen.addChild(startBtnBg); // Add button text var startBtnTxt = new Text2('zombi kıyametinde hayatta kalmaya hazır mısın ?', { size: 70, fill: "#fff", align: "center", wordWrap: true, wordWrapWidth: 1800 }); startBtnTxt.anchor.set(0.5, 0); // anchor at top center startBtnTxt.x = 1024; startBtnTxt.y = 120; // top center of the screen, below the top margin startScreen.addChild(startBtnTxt); game.addChild(startScreen); // Hide game UI until started scoreTxt.visible = false; healthTxt.visible = false; // Start button handler startScreen.down = function (x, y, obj) { // Check if tap is inside button var dx = x - 1024; var dy = y - 1500; if (Math.abs(dx) < startBtnBg.width / 2 && Math.abs(dy) < startBtnBg.height / 2) { // Hide start screen, show game UI, start game startScreen.visible = false; scoreTxt.visible = true; healthTxt.visible = true; resetGame(); } }; startScreen.interactive = true; // Only allow game input after start var gameStarted = false; var origGameDown = function origGameDown(x, y, obj) { // Only allow drag if not game over if (gameOver) return; // Only drag if touch is on player if (player && game) { var local = player.toLocal(game.toGlobal({ x: x, y: y })); if (local.x > -player.width / 2 && local.x < player.width / 2 && local.y > -player.height / 2 && local.y < player.height / 2) { dragNode = player; } } }; game.down = function (x, y, obj) { if (!startScreen.visible) { origGameDown(x, y, obj); } }; game.up = function (x, y, obj) { dragNode = null; }; function handleMove(x, y, obj) { if (gameOver) return; if (dragNode) { player.moveTo(x, y); } } game.move = handleMove; // --- Katana slash on tap (anywhere) --- game.tap = function (x, y, obj) { if (gameOver) return; // Determine direction: tap left or right of player if (player) { var dir = x < player.x ? 'left' : 'right'; player.slash(dir); } }; // Since LK does not have tap, simulate with down+up var tapTimeout = null; game.down = function (x, y, obj) { if (gameOver) return; // If touch is on player, drag if (player && game) { var local = player.toLocal(game.toGlobal({ x: x, y: y })); if (local.x > -player.width / 2 && local.x < player.width / 2 && local.y > -player.height / 2 && local.y < player.height / 2) { dragNode = player; } else { // Else, treat as katana slash if (player) { var dir = x < player.x ? 'left' : 'right'; player.slash(dir); } } } // For tap simulation if (tapTimeout) LK.clearTimeout(tapTimeout); tapTimeout = LK.setTimeout(function () { tapTimeout = null; }, 200); }; game.up = function (x, y, obj) { dragNode = null; }; // --- Main update loop --- game.update = function () { if (gameOver) return; // --- Zombies update --- var autoSlashTriggered = false; for (var i = zombies.length - 1; i >= 0; i--) { var z = zombies[i]; z.update(); // Check collision with player (damage) if (z.intersects(player)) { // Only damage if not already game over if (!gameOver) { playerHealth -= 1; if (playerHealth < 0) playerHealth = 0; healthTxt.setText('Can: ' + playerHealth); if (playerHealth <= 0) { gameOver = true; LK.showGameOver(); return; } } } // --- Auto katana slash if close to zombie --- if (!autoSlashTriggered && player.canSlash) { // Use same katana hitbox as in katana hit detection, but allow a bit more generous range var katana = player.katana; var katanaTipX = player.x + Math.cos(katana.rotation) * katana.x; var katanaTipY = player.y + Math.sin(katana.rotation) * katana.x; // 20% larger area var katanaRect = { x: katanaTipX - 36, y: katanaTipY - 36, width: 72, height: 72 }; // Zombie rectangle var zRect = { x: z.x - z.width / 2, y: z.y - z.height / 2, width: z.width, height: z.height }; // Simple AABB collision var close = !(katanaRect.x + katanaRect.width < zRect.x || katanaRect.x > zRect.x + zRect.width || katanaRect.y + katanaRect.height < zRect.y || katanaRect.y > zRect.y + zRect.height); // If not already swinging, and close, trigger slash if (close) { var dir = z.x < player.x ? 'left' : 'right'; player.slash(dir); autoSlashTriggered = true; } } } // Katana hit detection --- // If katana is swinging, check for zombie hits for (var i = zombies.length - 1; i >= 0; i--) { var z = zombies[i]; // Katana tip position var katana = player.katana; var katanaTipX = player.x + Math.cos(katana.rotation) * katana.x; var katanaTipY = player.y + Math.sin(katana.rotation) * katana.x; // Create a larger rectangle at katana tip (20% bigger) var katanaRect = { x: katanaTipX - 36, y: katanaTipY - 36, width: 72, height: 72 }; // Zombie rectangle var zRect = { x: z.x - z.width / 2, y: z.y - z.height / 2, width: z.width, height: z.height }; // Simple AABB collision var hit = !(katanaRect.x + katanaRect.width < zRect.x || katanaRect.x > zRect.x + zRect.width || katanaRect.y + katanaRect.height < zRect.y || katanaRect.y > zRect.y + zRect.height); if (hit && player.katana.rotation !== 0) { // Katana deals 20% of zombie max health per hit z.health -= z.maxHealth * 0.20; z.flashHit(); // Blood effect var blood = LK.getAsset('zombieBlood', { anchorX: 0.5, anchorY: 0.5, x: z.x, y: z.y, alpha: 0.8 }); game.addChild(blood); tween(blood, { alpha: 0 }, { duration: 400, onFinish: function onFinish() { blood.destroy(); } }); if (z.health <= 0) { z.destroy(); zombies.splice(i, 1); // Score score += 10; scoreTxt.setText(score); // Win if all zombies dead and all loot collected if (zombies.length === 0 && allLootCollected()) { if (currentLevel === 1) { // Show custom level complete screen with continue button gameOver = true; scoreTxt.visible = false; healthTxt.visible = false; var levelCompleteScreen = new Container(); // Zombie themed background (dimmed) var bg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 10, scaleY: 6, x: 1024, y: 1366, alpha: 0.92, tint: 0x23272e }); levelCompleteScreen.addChild(bg); // Large zombie image in the center var zombieImg = LK.getAsset('zombie', { anchorX: 0.5, anchorY: 0.5, scaleX: 4.5, scaleY: 4.5, x: 1024, y: 1100, alpha: 0.22 }); levelCompleteScreen.addChild(zombieImg); // Text var txt = new Text2('1. Bölüm Bitti', { size: 120, fill: "#fff" }); txt.anchor.set(0.5, 0.5); txt.x = 1024; txt.y = 1200; levelCompleteScreen.addChild(txt); // No "start game" text in the background // Continue button var btnBg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 1.2, x: 1024, y: 1500 }); levelCompleteScreen.addChild(btnBg); var btnTxt = new Text2('2. Bölüme Devam Et', { size: 80, fill: "#fff" }); btnTxt.anchor.set(0.5, 0); // anchor at top center btnTxt.x = 1024; btnTxt.y = 200; // top center, below the top margin levelCompleteScreen.addChild(btnTxt); // Button handler levelCompleteScreen.down = function (x, y, obj) { var dx = x - 1024; var dy = y - 1500; if (Math.abs(dx) < btnBg.width / 2 && Math.abs(dy) < btnBg.height / 2) { // Advance to level 2 currentLevel = 2; // Set player health to 100% at start of level 2 playerHealth = 100; levelCompleteScreen.visible = false; scoreTxt.visible = true; healthTxt.visible = true; resetGame(); gameOver = false; } }; levelCompleteScreen.interactive = true; game.addChild(levelCompleteScreen); return; } else { // Level 2 win: show win and reset to level 1 for replay LK.showYouWin(); currentLevel = 1; gameOver = true; return; } } } } } // --- Loot collection --- for (var i = 0; i < houses.length; i++) { var h = houses[i]; if (h.hasLoot && h.loot && player.intersects(h.loot)) { h.takeLoot(); // Score score += 20; scoreTxt.setText(score); // Increase player health by lootHealAmount (max 100) playerHealth = Math.min(100, Math.round(playerHealth + 100 * lootHealAmount)); healthTxt.setText('Can: ' + playerHealth); // Win if all loot collected and all zombies dead if (zombies.length === 0 && allLootCollected()) { LK.showYouWin(); gameOver = true; return; } } } }; // --- Helper: all loot collected? --- function allLootCollected() { for (var i = 0; i < houses.length; i++) { if (houses[i].hasLoot) return false; } return true; }
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// House class
var House = Container.expand(function () {
var self = Container.call(this);
var houseSprite = self.attachAsset('house', {
anchorX: 0.5,
anchorY: 0.5
});
// Loot inside
self.hasLoot = true;
self.loot = null;
// Place loot inside house
self.spawnLoot = function () {
if (!self.hasLoot) return;
var loot = LK.getAsset('loot', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
self.addChild(loot);
self.loot = loot;
};
// Remove loot
self.takeLoot = function () {
if (self.loot) {
self.loot.destroy();
self.loot = null;
self.hasLoot = false;
}
};
return self;
});
// Player class
var Player = Container.expand(function () {
var self = Container.call(this);
var playerSprite = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Katana asset (rotates for slash)
var katana = self.attachAsset('katana', {
anchorX: 0.1,
anchorY: 0.5,
x: 60,
// right hand
y: 0
});
self.katana = katana;
katana.rotation = 0;
// Katana slash cooldown
self.canSlash = true;
// Katana slash animation
self.slash = function (dir) {
if (!self.canSlash) return;
self.canSlash = false;
// Animate katana swing
var startRot = dir === 'left' ? -Math.PI / 3 : Math.PI / 3;
katana.rotation = 0;
tween(katana, {
rotation: startRot
}, {
duration: 60,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(katana, {
rotation: 0
}, {
duration: 120,
easing: tween.cubicIn,
onFinish: function onFinish() {
self.canSlash = true;
}
});
}
});
// Slash effect
var slashFx = LK.getAsset('slash', {
anchorX: 0.1,
anchorY: 0.5,
x: katana.x,
y: katana.y,
rotation: startRot,
alpha: 0.7
});
self.addChild(slashFx);
tween(slashFx, {
alpha: 0
}, {
duration: 180,
onFinish: function onFinish() {
slashFx.destroy();
}
});
};
// Move to (x, y) with bounds
self.moveTo = function (x, y) {
// Clamp to game area (leave 100px margin)
var hw = self.width / 2,
hh = self.height / 2;
var minX = 100 + hw,
maxX = 2048 - hw - 100;
var minY = 100 + hh,
maxY = 2732 - hh - 100;
self.x = Math.max(minX, Math.min(maxX, x));
self.y = Math.max(minY, Math.min(maxY, y));
};
return self;
});
// Zombie class
var Zombie = Container.expand(function () {
var self = Container.call(this);
var zombieSprite = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
// Target to follow (player)
self.target = null;
self.speed = 2.2 + Math.random() * 1.2; // randomize speed a bit
// For hit flash
self.isHit = false;
// For AI: wander around house if not chasing
self.homeX = 0;
self.homeY = 0;
self.wanderAngle = Math.random() * Math.PI * 2;
self.wanderTimer = 0;
self.chaseRadius = 420; // distance to start chasing player
// --- Health for zombie ---
// Set zombie health to 100% (was 1.5, now 3)
self.maxHealth = 3;
self.health = self.maxHealth;
self.update = function () {
if (!self.target) return;
// Calculate distance to player
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < self.chaseRadius) {
// Chase player
if (dist > 10) {
self.x += dx / dist * self.speed * 1.25; // run a bit faster when chasing
self.y += dy / dist * self.speed * 1.25;
}
} else {
// Wander around home position
self.wanderTimer--;
if (self.wanderTimer <= 0) {
self.wanderAngle = Math.random() * Math.PI * 2;
self.wanderTimer = 60 + Math.floor(Math.random() * 60);
}
var wanderDist = 60 + Math.random() * 40;
var targetX = self.homeX + Math.cos(self.wanderAngle) * wanderDist;
var targetY = self.homeY + Math.sin(self.wanderAngle) * wanderDist;
var wx = targetX - self.x;
var wy = targetY - self.y;
var wdist = Math.sqrt(wx * wx + wy * wy);
if (wdist > 4) {
self.x += wx / wdist * self.speed * 0.5;
self.y += wy / wdist * self.speed * 0.5;
}
}
};
// Flash red when hit
self.flashHit = function () {
if (self.isHit) return;
self.isHit = true;
tween(zombieSprite, {
tint: 0xff0000
}, {
duration: 80,
onFinish: function onFinish() {
tween(zombieSprite, {
tint: 0x4e9a06
}, {
duration: 120,
onFinish: function onFinish() {
self.isHit = false;
}
});
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x23272e
});
/****
* Game Code
****/
// --- Game variables ---
// Kadın savaşçı (player)
// Katana (kılıç)
// Zombi
// Ev
// Erzak (loot)
// Zombi öldürme efekti
// Katana sallama efekti
var player;
var zombies = [];
var houses = [];
var score = 0;
var scoreTxt;
var playerHealth = 100;
var healthTxt;
var dragNode = null;
var lastPlayerX = 0,
lastPlayerY = 0;
var lastIntersectingZombie = false;
var lastIntersectingLoot = false;
var gameOver = false;
// --- UI ---
scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Health UI
healthTxt = new Text2('Can: 100', {
size: 90,
fill: 0xFF6666
});
healthTxt.anchor.set(0.5, 0);
healthTxt.y = 120;
LK.gui.top.addChild(healthTxt);
// --- Level system ---
var currentLevel = 1;
var lootHealAmount = 0.4; // default, can be changed per level
// --- Spawn houses ---
function spawnHouses() {
houses = [];
var housePositions = [];
if (currentLevel === 1) {
housePositions = [{
x: 400,
y: 700
}, {
x: 1648,
y: 700
}, {
x: 400,
y: 2000
}, {
x: 1648,
y: 2000
}, {
x: 1024,
y: 1400
}];
lootHealAmount = 0.4; // Level 1: 40% heal (for consistency, can be 0.15 if you want to keep old)
} else if (currentLevel === 2) {
housePositions = [{
x: 600,
y: 800
}, {
x: 1024,
y: 1800
}, {
x: 1600,
y: 800
}];
lootHealAmount = 0.3; // Level 2: 30% heal
}
for (var i = 0; i < housePositions.length; i++) {
var h = new House();
h.x = housePositions[i].x;
h.y = housePositions[i].y;
h.spawnLoot();
houses.push(h);
game.addChild(h);
}
}
// --- Spawn zombies around houses ---
function spawnZombies() {
zombies = [];
var zombiesPerHouse = currentLevel === 2 ? 2 : 3;
for (var i = 0; i < houses.length; i++) {
for (var j = 0; j < zombiesPerHouse; j++) {
var z = new Zombie();
// Place randomly around house
var angle = Math.random() * Math.PI * 2;
var dist = 180 + Math.random() * 60;
z.x = houses[i].x + Math.cos(angle) * dist;
z.y = houses[i].y + Math.sin(angle) * dist;
z.homeX = z.x;
z.homeY = z.y;
z.target = null; // will be set to player later
zombies.push(z);
game.addChild(z);
}
}
}
// --- Spawn player ---
function spawnPlayer() {
player = new Player();
player.x = 1024;
player.y = 2400;
game.addChild(player);
}
// --- Reset game state ---
function resetGame() {
// Remove all children except GUI
for (var i = game.children.length - 1; i >= 0; i--) {
game.children[i].destroy();
}
score = 0;
scoreTxt.setText(score);
gameOver = false;
spawnHouses();
spawnZombies();
spawnPlayer();
// Set all zombies to follow player
for (var i = 0; i < zombies.length; i++) {
zombies[i].target = player;
}
}
// --- Start Screen ---
var startScreen = new Container();
// Add zombie-themed background image to start screen
var zombieBg = LK.getAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 14,
scaleY: 14,
x: 1024,
y: 1366,
alpha: 0.13
});
startScreen.addChild(zombieBg);
// Button
var startBtnBg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 1.2,
x: 1024,
y: 1500
});
startScreen.addChild(startBtnBg);
// Add button text
var startBtnTxt = new Text2('zombi kıyametinde hayatta kalmaya hazır mısın ?', {
size: 70,
fill: "#fff",
align: "center",
wordWrap: true,
wordWrapWidth: 1800
});
startBtnTxt.anchor.set(0.5, 0); // anchor at top center
startBtnTxt.x = 1024;
startBtnTxt.y = 120; // top center of the screen, below the top margin
startScreen.addChild(startBtnTxt);
game.addChild(startScreen);
// Hide game UI until started
scoreTxt.visible = false;
healthTxt.visible = false;
// Start button handler
startScreen.down = function (x, y, obj) {
// Check if tap is inside button
var dx = x - 1024;
var dy = y - 1500;
if (Math.abs(dx) < startBtnBg.width / 2 && Math.abs(dy) < startBtnBg.height / 2) {
// Hide start screen, show game UI, start game
startScreen.visible = false;
scoreTxt.visible = true;
healthTxt.visible = true;
resetGame();
}
};
startScreen.interactive = true;
// Only allow game input after start
var gameStarted = false;
var origGameDown = function origGameDown(x, y, obj) {
// Only allow drag if not game over
if (gameOver) return;
// Only drag if touch is on player
if (player && game) {
var local = player.toLocal(game.toGlobal({
x: x,
y: y
}));
if (local.x > -player.width / 2 && local.x < player.width / 2 && local.y > -player.height / 2 && local.y < player.height / 2) {
dragNode = player;
}
}
};
game.down = function (x, y, obj) {
if (!startScreen.visible) {
origGameDown(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
function handleMove(x, y, obj) {
if (gameOver) return;
if (dragNode) {
player.moveTo(x, y);
}
}
game.move = handleMove;
// --- Katana slash on tap (anywhere) ---
game.tap = function (x, y, obj) {
if (gameOver) return;
// Determine direction: tap left or right of player
if (player) {
var dir = x < player.x ? 'left' : 'right';
player.slash(dir);
}
};
// Since LK does not have tap, simulate with down+up
var tapTimeout = null;
game.down = function (x, y, obj) {
if (gameOver) return;
// If touch is on player, drag
if (player && game) {
var local = player.toLocal(game.toGlobal({
x: x,
y: y
}));
if (local.x > -player.width / 2 && local.x < player.width / 2 && local.y > -player.height / 2 && local.y < player.height / 2) {
dragNode = player;
} else {
// Else, treat as katana slash
if (player) {
var dir = x < player.x ? 'left' : 'right';
player.slash(dir);
}
}
}
// For tap simulation
if (tapTimeout) LK.clearTimeout(tapTimeout);
tapTimeout = LK.setTimeout(function () {
tapTimeout = null;
}, 200);
};
game.up = function (x, y, obj) {
dragNode = null;
};
// --- Main update loop ---
game.update = function () {
if (gameOver) return;
// --- Zombies update ---
var autoSlashTriggered = false;
for (var i = zombies.length - 1; i >= 0; i--) {
var z = zombies[i];
z.update();
// Check collision with player (damage)
if (z.intersects(player)) {
// Only damage if not already game over
if (!gameOver) {
playerHealth -= 1;
if (playerHealth < 0) playerHealth = 0;
healthTxt.setText('Can: ' + playerHealth);
if (playerHealth <= 0) {
gameOver = true;
LK.showGameOver();
return;
}
}
}
// --- Auto katana slash if close to zombie ---
if (!autoSlashTriggered && player.canSlash) {
// Use same katana hitbox as in katana hit detection, but allow a bit more generous range
var katana = player.katana;
var katanaTipX = player.x + Math.cos(katana.rotation) * katana.x;
var katanaTipY = player.y + Math.sin(katana.rotation) * katana.x;
// 20% larger area
var katanaRect = {
x: katanaTipX - 36,
y: katanaTipY - 36,
width: 72,
height: 72
};
// Zombie rectangle
var zRect = {
x: z.x - z.width / 2,
y: z.y - z.height / 2,
width: z.width,
height: z.height
};
// Simple AABB collision
var close = !(katanaRect.x + katanaRect.width < zRect.x || katanaRect.x > zRect.x + zRect.width || katanaRect.y + katanaRect.height < zRect.y || katanaRect.y > zRect.y + zRect.height);
// If not already swinging, and close, trigger slash
if (close) {
var dir = z.x < player.x ? 'left' : 'right';
player.slash(dir);
autoSlashTriggered = true;
}
}
}
// Katana hit detection ---
// If katana is swinging, check for zombie hits
for (var i = zombies.length - 1; i >= 0; i--) {
var z = zombies[i];
// Katana tip position
var katana = player.katana;
var katanaTipX = player.x + Math.cos(katana.rotation) * katana.x;
var katanaTipY = player.y + Math.sin(katana.rotation) * katana.x;
// Create a larger rectangle at katana tip (20% bigger)
var katanaRect = {
x: katanaTipX - 36,
y: katanaTipY - 36,
width: 72,
height: 72
};
// Zombie rectangle
var zRect = {
x: z.x - z.width / 2,
y: z.y - z.height / 2,
width: z.width,
height: z.height
};
// Simple AABB collision
var hit = !(katanaRect.x + katanaRect.width < zRect.x || katanaRect.x > zRect.x + zRect.width || katanaRect.y + katanaRect.height < zRect.y || katanaRect.y > zRect.y + zRect.height);
if (hit && player.katana.rotation !== 0) {
// Katana deals 20% of zombie max health per hit
z.health -= z.maxHealth * 0.20;
z.flashHit();
// Blood effect
var blood = LK.getAsset('zombieBlood', {
anchorX: 0.5,
anchorY: 0.5,
x: z.x,
y: z.y,
alpha: 0.8
});
game.addChild(blood);
tween(blood, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
blood.destroy();
}
});
if (z.health <= 0) {
z.destroy();
zombies.splice(i, 1);
// Score
score += 10;
scoreTxt.setText(score);
// Win if all zombies dead and all loot collected
if (zombies.length === 0 && allLootCollected()) {
if (currentLevel === 1) {
// Show custom level complete screen with continue button
gameOver = true;
scoreTxt.visible = false;
healthTxt.visible = false;
var levelCompleteScreen = new Container();
// Zombie themed background (dimmed)
var bg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 10,
scaleY: 6,
x: 1024,
y: 1366,
alpha: 0.92,
tint: 0x23272e
});
levelCompleteScreen.addChild(bg);
// Large zombie image in the center
var zombieImg = LK.getAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.5,
scaleY: 4.5,
x: 1024,
y: 1100,
alpha: 0.22
});
levelCompleteScreen.addChild(zombieImg);
// Text
var txt = new Text2('1. Bölüm Bitti', {
size: 120,
fill: "#fff"
});
txt.anchor.set(0.5, 0.5);
txt.x = 1024;
txt.y = 1200;
levelCompleteScreen.addChild(txt);
// No "start game" text in the background
// Continue button
var btnBg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 1.2,
x: 1024,
y: 1500
});
levelCompleteScreen.addChild(btnBg);
var btnTxt = new Text2('2. Bölüme Devam Et', {
size: 80,
fill: "#fff"
});
btnTxt.anchor.set(0.5, 0); // anchor at top center
btnTxt.x = 1024;
btnTxt.y = 200; // top center, below the top margin
levelCompleteScreen.addChild(btnTxt);
// Button handler
levelCompleteScreen.down = function (x, y, obj) {
var dx = x - 1024;
var dy = y - 1500;
if (Math.abs(dx) < btnBg.width / 2 && Math.abs(dy) < btnBg.height / 2) {
// Advance to level 2
currentLevel = 2;
// Set player health to 100% at start of level 2
playerHealth = 100;
levelCompleteScreen.visible = false;
scoreTxt.visible = true;
healthTxt.visible = true;
resetGame();
gameOver = false;
}
};
levelCompleteScreen.interactive = true;
game.addChild(levelCompleteScreen);
return;
} else {
// Level 2 win: show win and reset to level 1 for replay
LK.showYouWin();
currentLevel = 1;
gameOver = true;
return;
}
}
}
}
}
// --- Loot collection ---
for (var i = 0; i < houses.length; i++) {
var h = houses[i];
if (h.hasLoot && h.loot && player.intersects(h.loot)) {
h.takeLoot();
// Score
score += 20;
scoreTxt.setText(score);
// Increase player health by lootHealAmount (max 100)
playerHealth = Math.min(100, Math.round(playerHealth + 100 * lootHealAmount));
healthTxt.setText('Can: ' + playerHealth);
// Win if all loot collected and all zombies dead
if (zombies.length === 0 && allLootCollected()) {
LK.showYouWin();
gameOver = true;
return;
}
}
}
};
// --- Helper: all loot collected? ---
function allLootCollected() {
for (var i = 0; i < houses.length; i++) {
if (houses[i].hasLoot) return false;
}
return true;
}
katana. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
zombie. In-Game asset. High contrast. No shadows. 2d
Terk edilmiş ev. In-Game asset. 2d. High contrast. No shadows
Women. In-Game asset. 2d. High contrast. No shadows
erzak. In-Game asset. 2d. High contrast. No shadows
kan efekti. In-Game asset. 2d. High contrast. No shadows
start game button. In-Game asset. 2d. High contrast. No shadows