/**** * 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