User prompt
hareket etme sistemi çalışmıyo birde oyunun girişine katil olmayı seçme veya masum olmayı seçme modu ekle
User prompt
grafikleri daha gerçekçi pixel yap fnaf into the pit teki gibi katili zorlaştır yeni oyuncular ekle katil olabilme modu ekle oyuncu mouse ile hareket etmesin sadece w a s d ile hareket etsin
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'addEventListener')' in or related to this line: 'document.addEventListener('keydown', function (e) {' Line Number: 426
User prompt
grafikleri daha güzel yap jeneratörlerin üzeinde bir işaret belirsin w a s d ile hareket edilebilsin jeneratörün yanında 5 sn f tuşuna basınca aktif olsun
Code edit (1 edits merged)
Please save this source code
User prompt
Pixel Dread: Killer Hunt
Initial prompt
bana dead by daylight oyunu 2D ve pixel tarzında oluştur
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var ExitGate = Container.expand(function () {
var self = Container.call(this);
var exitGraphics = self.attachAsset('exitGate', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Generator = Container.expand(function () {
var self = Container.call(this);
var generatorGraphics = self.attachAsset('generator', {
anchorX: 0.5,
anchorY: 0.5
});
var indicatorGraphics = self.attachAsset('generatorIndicator', {
anchorX: 0.5,
anchorY: 0.5
});
indicatorGraphics.y = -50;
var repairText = new Text2('0%', {
size: 30,
fill: '#ffffff'
});
repairText.anchor.set(0.5, 0.5);
repairText.y = 0;
self.addChild(repairText);
self.isRepaired = false;
self.repairProgress = 0;
self.maxRepairProgress = 100;
self.update = function () {
repairText.setText(Math.floor(self.repairProgress / 100 * 100) + '%');
if (self.isRepaired) {
generatorGraphics.tint = 0x00ff00;
}
};
return self;
});
var HidingSpot = Container.expand(function () {
var self = Container.call(this);
var hidingGraphics = self.attachAsset('hidingSpot', {
anchorX: 0.5,
anchorY: 0.5
});
self.isOccupied = false;
return self;
});
var Killer = Container.expand(function () {
var self = Container.call(this);
var killerGraphics = self.attachAsset('killer', {
anchorX: 0.5,
anchorY: 0.5
});
var killerEyeLeft = self.attachAsset('killerEyes', {
anchorX: 0.5,
anchorY: 0.5
});
killerEyeLeft.x = -12;
killerEyeLeft.y = -8;
var killerEyeRight = self.attachAsset('killerEyes', {
anchorX: 0.5,
anchorY: 0.5
});
killerEyeRight.x = 12;
killerEyeRight.y = -8;
self.speed = 3.2;
self.detectionRadius = 400;
self.aggressiveRadius = 180;
self.targetSurvivor = null;
self.isChasing = false;
self.chaseTimer = 0;
self.chaseDuration = 0;
self.lastX = self.x;
self.lastY = self.y;
self.huntingMode = false;
self.predictionX = 0;
self.predictionY = 0;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
var Survivor = Container.expand(function () {
var self = Container.call(this);
var survivorGraphics = self.attachAsset('survivor', {
anchorX: 0.5,
anchorY: 0.5
});
var survivorHead = self.attachAsset('survivorHead', {
anchorX: 0.5,
anchorY: 0.5
});
survivorHead.y = -15;
self.speed = 3;
self.isRunning = false;
self.isHiding = false;
self.isRepairing = false;
self.repairProgress = 0;
self.maxRepairTime = 300;
self.trailCounter = 0;
self.lastX = self.x;
self.lastY = self.y;
self.id = 0;
self.escaped = false;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
var Wall = Container.expand(function () {
var self = Container.call(this);
var wallGraphics = self.attachAsset('wall', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// Game state variables
var survivors = [];
var activeSurvivor = 0;
var killer;
var generators = [];
var walls = [];
var hidingSpots = [];
var exitGates = [];
var generatorsRepaired = 0;
var gameState = 'playing'; // playing, chasing, won, lost, killerMode
var dragNode = null;
var survivorTrail = [];
var killerDetected = false;
var detectionFlashTimer = 0;
var gameMode = 'survivor'; // survivor or killer
var survivorsEscaped = 0;
// Initialize UI
var statusText = new Text2('Generators: 0/3', {
size: 80,
fill: '#ffffff'
});
statusText.anchor.set(0.5, 0);
LK.gui.top.addChild(statusText);
var objectiveText = new Text2('Repair all generators to escape', {
size: 60,
fill: '#ffffff'
});
objectiveText.anchor.set(0.5, 0.5);
objectiveText.y = 80;
LK.gui.center.addChild(objectiveText);
var gameModeText = new Text2('Mode: SURVIVOR', {
size: 50,
fill: '#00ff00'
});
gameModeText.anchor.set(0.5, 0);
gameModeText.x = 1024;
gameModeText.y = 150;
game.addChild(gameModeText);
// Create arena layout
function initializeArena() {
// Create perimeter walls
var wallPositions = [{
x: 100,
y: 100
}, {
x: 300,
y: 100
}, {
x: 500,
y: 100
}, {
x: 700,
y: 100
}, {
x: 900,
y: 100
}, {
x: 1100,
y: 100
}, {
x: 1300,
y: 100
}, {
x: 1500,
y: 100
}, {
x: 1700,
y: 100
}, {
x: 1900,
y: 100
}, {
x: 100,
y: 2600
}, {
x: 300,
y: 2600
}, {
x: 500,
y: 2600
}, {
x: 700,
y: 2600
}, {
x: 900,
y: 2600
}, {
x: 1100,
y: 2600
}, {
x: 1300,
y: 2600
}, {
x: 1500,
y: 2600
}, {
x: 1700,
y: 2600
}, {
x: 1900,
y: 2600
}, {
x: 100,
y: 300
}, {
x: 100,
y: 600
}, {
x: 100,
y: 900
}, {
x: 100,
y: 1200
}, {
x: 100,
y: 1500
}, {
x: 100,
y: 1800
}, {
x: 100,
y: 2100
}, {
x: 100,
y: 2400
}, {
x: 1900,
y: 300
}, {
x: 1900,
y: 600
}, {
x: 1900,
y: 900
}, {
x: 1900,
y: 1200
}, {
x: 1900,
y: 1500
}, {
x: 1900,
y: 1800
}, {
x: 1900,
y: 2100
}, {
x: 1900,
y: 2400
}];
for (var i = 0; i < wallPositions.length; i++) {
var wall = game.addChild(new Wall());
wall.x = wallPositions[i].x;
wall.y = wallPositions[i].y;
walls.push(wall);
}
// Internal obstacles
var obstaclePositions = [{
x: 400,
y: 400
}, {
x: 1600,
y: 400
}, {
x: 400,
y: 2300
}, {
x: 1600,
y: 2300
}, {
x: 1024,
y: 800
}, {
x: 1024,
y: 1900
}, {
x: 600,
y: 1350
}, {
x: 1450,
y: 1350
}];
for (var i = 0; i < obstaclePositions.length; i++) {
var wall = game.addChild(new Wall());
wall.x = obstaclePositions[i].x;
wall.y = obstaclePositions[i].y;
walls.push(wall);
}
// Create hiding spots
var hidingPositions = [{
x: 300,
y: 600
}, {
x: 1700,
y: 600
}, {
x: 300,
y: 2100
}, {
x: 1700,
y: 2100
}, {
x: 800,
y: 1350
}, {
x: 1250,
y: 1350
}];
for (var i = 0; i < hidingPositions.length; i++) {
var hiding = game.addChild(new HidingSpot());
hiding.x = hidingPositions[i].x;
hiding.y = hidingPositions[i].y;
hidingSpots.push(hiding);
}
// Create generators
var generatorPositions = [{
x: 350,
y: 1350
}, {
x: 1700,
y: 800
}, {
x: 1300,
y: 2200
}];
for (var i = 0; i < generatorPositions.length; i++) {
var gen = game.addChild(new Generator());
gen.x = generatorPositions[i].x;
gen.y = generatorPositions[i].y;
generators.push(gen);
}
// Create exit gates (spawn but locked)
var exitPositions = [{
x: 200,
y: 1350
}, {
x: 1850,
y: 1350
}];
for (var i = 0; i < exitPositions.length; i++) {
var exit = game.addChild(new ExitGate());
exit.x = exitPositions[i].x;
exit.y = exitPositions[i].y;
exitGates.push(exit);
}
}
// Create multiple survivors
var survivorSpawns = [{
x: 300,
y: 500
}, {
x: 1750,
y: 500
}, {
x: 300,
y: 2200
}, {
x: 1750,
y: 2200
}];
for (var s = 0; s < survivorSpawns.length; s++) {
var survivor = game.addChild(new Survivor());
survivor.x = survivorSpawns[s].x;
survivor.y = survivorSpawns[s].y;
survivor.id = s;
survivor.escaped = false;
survivors.push(survivor);
}
// Create killer
killer = game.addChild(new Killer());
killer.x = 1024;
killer.y = 300;
killer.mode = gameMode;
// Initialize arena
initializeArena();
// Play ambient music
LK.playMusic('ambience');
// Collision detection helper
function checkCollision(obj1, obj2) {
var dx = obj1.x - obj2.x;
var dy = obj1.y - obj2.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var minDist = obj1.width / 2 + obj2.width / 2;
return distance < minDist;
}
// Distance calculation
function getDistance(obj1, obj2) {
var dx = obj1.x - obj2.x;
var dy = obj1.y - obj2.y;
return Math.sqrt(dx * dx + dy * dy);
}
// Obstacle collision check
function isPathBlocked(fromX, fromY, toX, toY) {
for (var i = 0; i < walls.length; i++) {
var wall = walls[i];
var dx = toX - fromX;
var dy = toY - fromY;
var len = Math.sqrt(dx * dx + dy * dy);
if (len === 0) return false;
var stepX = dx / len * 5;
var stepY = dy / len * 5;
var steps = Math.floor(len / 5);
var checkX = fromX;
var checkY = fromY;
for (var s = 0; s < steps; s++) {
checkX += stepX;
checkY += stepY;
var wallDx = checkX - wall.x;
var wallDy = checkY - wall.y;
var wallDist = Math.sqrt(wallDx * wallDx + wallDy * wallDy);
if (wallDist < 50) return true;
}
}
return false;
}
// Movement zones for touch controls (replaces WASD)
var gameWidth = 2048;
var gameHeight = 2732;
var movementZoneSize = 400;
var touchActive = {
up: false,
down: false,
left: false,
right: false
};
game.down = function (x, y, obj) {
if (gameState !== 'playing' && gameState !== 'killerMode') return;
// Determine which movement zone was touched
if (y < movementZoneSize) touchActive.up = true;
if (y > gameHeight - movementZoneSize) touchActive.down = true;
if (x < movementZoneSize) touchActive.left = true;
if (x > gameWidth - movementZoneSize) touchActive.right = true;
dragNode = gameMode === 'survivor' ? survivors[activeSurvivor] : killer;
};
game.move = function (x, y, obj) {
if (gameState !== 'playing' && gameState !== 'killerMode') return;
// Update touch zones based on current position
touchActive.up = y < movementZoneSize;
touchActive.down = y > gameHeight - movementZoneSize;
touchActive.left = x < movementZoneSize;
touchActive.right = x > gameWidth - movementZoneSize;
};
game.up = function (x, y, obj) {
touchActive.up = false;
touchActive.down = false;
touchActive.left = false;
touchActive.right = false;
dragNode = null;
};
// Main game update loop
game.update = function () {
if (gameState !== 'playing' && gameState !== 'killerMode') return;
// Update all survivors
for (var s = 0; s < survivors.length; s++) {
survivors[s].update();
}
killer.update();
if (gameMode === 'survivor') {
// Survivor mode gameplay
var survivor = survivors[activeSurvivor];
// Apply touch-based movement
var moveX = 0;
var moveY = 0;
if (touchActive.up) moveY -= survivor.speed;
if (touchActive.down) moveY += survivor.speed;
if (touchActive.left) moveX -= survivor.speed;
if (touchActive.right) moveX += survivor.speed;
survivor.x += moveX;
survivor.y += moveY;
survivor.isRunning = moveX !== 0 || moveY !== 0;
var canMove = true;
for (var i = 0; i < walls.length; i++) {
if (getDistance({
x: survivor.x,
y: survivor.y
}, walls[i]) < 50) {
canMove = false;
survivor.x -= moveX;
survivor.y -= moveY;
break;
}
}
// Clamp survivor to arena
if (survivor.x < 150) survivor.x = 150;
if (survivor.x > 1900) survivor.x = 1900;
if (survivor.y < 150) survivor.y = 150;
if (survivor.y > 2600) survivor.y = 2600;
// Update killer AI with enhanced difficulty
var closestDist = 999999;
var closestSurvivor = null;
for (var s = 0; s < survivors.length; s++) {
if (!survivors[s].escaped) {
var dist = getDistance(killer, survivors[s]);
if (dist < closestDist) {
closestDist = dist;
closestSurvivor = survivors[s];
}
}
}
if (closestSurvivor) {
if (closestDist < killer.detectionRadius) {
killerDetected = true;
detectionFlashTimer = 30;
killer.targetSurvivor = closestSurvivor;
// Predictive movement for harder AI
var predictX = closestSurvivor.x;
var predictY = closestSurvivor.y;
if (closestSurvivor.isRunning) {
var distX = closestSurvivor.x - closestSurvivor.lastX;
var distY = closestSurvivor.y - closestSurvivor.lastY;
predictX += distX * 8;
predictY += distY * 8;
}
killer.predictionX = predictX;
killer.predictionY = predictY;
// Killer moves toward prediction point
if (closestDist > 30) {
var angle = Math.atan2(predictY - killer.y, predictX - killer.x);
var killerSpeed = closestDist < killer.aggressiveRadius ? killer.speed * 2 : killer.speed;
var killerNewX = killer.x + Math.cos(angle) * killerSpeed;
var killerNewY = killer.y + Math.sin(angle) * killerSpeed;
var canKillerMove = true;
for (var i = 0; i < walls.length; i++) {
if (getDistance({
x: killerNewX,
y: killerNewY
}, walls[i]) < 50) {
canKillerMove = false;
break;
}
}
if (canKillerMove) {
killer.x = killerNewX;
killer.y = killerNewY;
}
}
if (closestDist < 50) {
gameState = 'chasing';
LK.getSound('chase').play();
}
} else {
killerDetected = false;
}
}
// Update hiding
survivor.isHiding = false;
for (var i = 0; i < hidingSpots.length; i++) {
if (getDistance(survivor, hidingSpots[i]) < 45) {
survivor.isHiding = true;
break;
}
}
// Check generator repair
var currentRepairingGen = null;
for (var i = 0; i < generators.length; i++) {
var gen = generators[i];
if (!gen.isRepaired && getDistance(survivor, gen) < 60 && !survivor.isHiding && !survivor.isRunning) {
currentRepairingGen = gen;
break;
}
}
if (currentRepairingGen && !survivor.isRunning) {
survivor.isRepairing = true;
survivor.repairProgress += 1;
currentRepairingGen.repairProgress = survivor.repairProgress;
if (survivor.repairProgress >= 300) {
currentRepairingGen.isRepaired = true;
generatorsRepaired++;
survivor.isRepairing = false;
survivor.repairProgress = 0;
LK.getSound('repair').play();
}
} else if (survivor.isRunning || !currentRepairingGen) {
survivor.isRepairing = false;
}
// Check exit gate collision
if (generatorsRepaired >= 3) {
for (var i = 0; i < exitGates.length; i++) {
if (getDistance(survivor, exitGates[i]) < 50) {
survivor.escaped = true;
survivorsEscaped++;
if (survivorsEscaped >= survivors.length) {
gameState = 'won';
LK.showYouWin();
return;
}
}
}
}
statusText.setText('Generators: ' + generatorsRepaired + '/3 | Escaped: ' + survivorsEscaped + '/' + survivors.length);
// Flash effect when detected
if (killerDetected && detectionFlashTimer > 0) {
detectionFlashTimer--;
if (detectionFlashTimer % 6 < 3) {
survivor.alpha = 0.5;
} else {
survivor.alpha = 1;
}
} else {
survivor.alpha = 1;
}
} else if (gameMode === 'killer') {
// Killer mode gameplay
var moveX = 0;
var moveY = 0;
if (touchActive.up) moveY -= killer.speed;
if (touchActive.down) moveY += killer.speed;
if (touchActive.left) moveX -= killer.speed;
if (touchActive.right) moveX += killer.speed;
killer.x += moveX;
killer.y += moveY;
// Clamp killer to arena
if (killer.x < 150) killer.x = 150;
if (killer.x > 1900) killer.x = 1900;
if (killer.y < 150) killer.y = 150;
if (killer.y > 2600) killer.y = 2600;
// Collision with walls
for (var i = 0; i < walls.length; i++) {
if (getDistance(killer, walls[i]) < 50) {
killer.x -= moveX;
killer.y -= moveY;
break;
}
}
// Check if killer caught survivors
for (var s = 0; s < survivors.length; s++) {
if (!survivors[s].escaped && getDistance(killer, survivors[s]) < 50) {
gameState = 'won';
LK.showYouWin();
return;
}
}
statusText.setText('Catch the survivors! Generators: ' + generatorsRepaired + '/3');
}
// Update generator UI
for (var i = 0; i < generators.length; i++) {
generators[i].update();
}
// Game over condition
if (gameState === 'chasing') {
gameState = 'lost';
LK.showGameOver();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -58,16 +58,32 @@
var killerGraphics = self.attachAsset('killer', {
anchorX: 0.5,
anchorY: 0.5
});
- self.speed = 2.5;
- self.detectionRadius = 300;
- self.aggressiveRadius = 150;
+ var killerEyeLeft = self.attachAsset('killerEyes', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ killerEyeLeft.x = -12;
+ killerEyeLeft.y = -8;
+ var killerEyeRight = self.attachAsset('killerEyes', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ killerEyeRight.x = 12;
+ killerEyeRight.y = -8;
+ self.speed = 3.2;
+ self.detectionRadius = 400;
+ self.aggressiveRadius = 180;
self.targetSurvivor = null;
self.isChasing = false;
self.chaseTimer = 0;
+ self.chaseDuration = 0;
self.lastX = self.x;
self.lastY = self.y;
+ self.huntingMode = false;
+ self.predictionX = 0;
+ self.predictionY = 0;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
};
@@ -78,8 +94,13 @@
var survivorGraphics = self.attachAsset('survivor', {
anchorX: 0.5,
anchorY: 0.5
});
+ var survivorHead = self.attachAsset('survivorHead', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ survivorHead.y = -15;
self.speed = 3;
self.isRunning = false;
self.isHiding = false;
self.isRepairing = false;
@@ -87,8 +108,10 @@
self.maxRepairTime = 300;
self.trailCounter = 0;
self.lastX = self.x;
self.lastY = self.y;
+ self.id = 0;
+ self.escaped = false;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
};
@@ -113,20 +136,23 @@
/****
* Game Code
****/
// Game state variables
-var survivor;
+var survivors = [];
+var activeSurvivor = 0;
var killer;
var generators = [];
var walls = [];
var hidingSpots = [];
var exitGates = [];
var generatorsRepaired = 0;
-var gameState = 'playing'; // playing, chasing, won, lost
+var gameState = 'playing'; // playing, chasing, won, lost, killerMode
var dragNode = null;
var survivorTrail = [];
var killerDetected = false;
var detectionFlashTimer = 0;
+var gameMode = 'survivor'; // survivor or killer
+var survivorsEscaped = 0;
// Initialize UI
var statusText = new Text2('Generators: 0/3', {
size: 80,
fill: '#ffffff'
@@ -139,8 +165,16 @@
});
objectiveText.anchor.set(0.5, 0.5);
objectiveText.y = 80;
LK.gui.center.addChild(objectiveText);
+var gameModeText = new Text2('Mode: SURVIVOR', {
+ size: 50,
+ fill: '#00ff00'
+});
+gameModeText.anchor.set(0.5, 0);
+gameModeText.x = 1024;
+gameModeText.y = 150;
+game.addChild(gameModeText);
// Create arena layout
function initializeArena() {
// Create perimeter walls
var wallPositions = [{
@@ -347,16 +381,35 @@
exit.y = exitPositions[i].y;
exitGates.push(exit);
}
}
-// Create survivor
-survivor = game.addChild(new Survivor());
-survivor.x = 1024;
-survivor.y = 1366;
+// Create multiple survivors
+var survivorSpawns = [{
+ x: 300,
+ y: 500
+}, {
+ x: 1750,
+ y: 500
+}, {
+ x: 300,
+ y: 2200
+}, {
+ x: 1750,
+ y: 2200
+}];
+for (var s = 0; s < survivorSpawns.length; s++) {
+ var survivor = game.addChild(new Survivor());
+ survivor.x = survivorSpawns[s].x;
+ survivor.y = survivorSpawns[s].y;
+ survivor.id = s;
+ survivor.escaped = false;
+ survivors.push(survivor);
+}
// Create killer
killer = game.addChild(new Killer());
killer.x = 1024;
killer.y = 300;
+killer.mode = gameMode;
// Initialize arena
initializeArena();
// Play ambient music
LK.playMusic('ambience');
@@ -397,140 +450,227 @@
}
}
return false;
}
-// Handle survivor controls with touch/drag
-var movementVector = {
- x: 0,
- y: 0
+// Movement zones for touch controls (replaces WASD)
+var gameWidth = 2048;
+var gameHeight = 2732;
+var movementZoneSize = 400;
+var touchActive = {
+ up: false,
+ down: false,
+ left: false,
+ right: false
};
-var keysPressed = {};
game.down = function (x, y, obj) {
- if (gameState !== 'playing') return;
- dragNode = survivor;
+ if (gameState !== 'playing' && gameState !== 'killerMode') return;
+ // Determine which movement zone was touched
+ if (y < movementZoneSize) touchActive.up = true;
+ if (y > gameHeight - movementZoneSize) touchActive.down = true;
+ if (x < movementZoneSize) touchActive.left = true;
+ if (x > gameWidth - movementZoneSize) touchActive.right = true;
+ dragNode = gameMode === 'survivor' ? survivors[activeSurvivor] : killer;
};
game.move = function (x, y, obj) {
- if (gameState !== 'playing') return;
- if (dragNode) {
- dragNode.x = x;
- dragNode.y = y;
- }
+ if (gameState !== 'playing' && gameState !== 'killerMode') return;
+ // Update touch zones based on current position
+ touchActive.up = y < movementZoneSize;
+ touchActive.down = y > gameHeight - movementZoneSize;
+ touchActive.left = x < movementZoneSize;
+ touchActive.right = x > gameWidth - movementZoneSize;
};
game.up = function (x, y, obj) {
+ touchActive.up = false;
+ touchActive.down = false;
+ touchActive.left = false;
+ touchActive.right = false;
dragNode = null;
};
// Main game update loop
game.update = function () {
- if (gameState !== 'playing') return;
- survivor.update();
+ if (gameState !== 'playing' && gameState !== 'killerMode') return;
+ // Update all survivors
+ for (var s = 0; s < survivors.length; s++) {
+ survivors[s].update();
+ }
killer.update();
- // Survivor is moved via drag (game.move handles position updates)
- survivor.isRunning = dragNode === survivor;
- var canMove = true;
- for (var i = 0; i < walls.length; i++) {
- if (getDistance({
- x: survivor.x,
- y: survivor.y
- }, walls[i]) < 50) {
- canMove = false;
- survivor.x = survivor.lastX;
- survivor.y = survivor.lastY;
- break;
+ if (gameMode === 'survivor') {
+ // Survivor mode gameplay
+ var survivor = survivors[activeSurvivor];
+ // Apply touch-based movement
+ var moveX = 0;
+ var moveY = 0;
+ if (touchActive.up) moveY -= survivor.speed;
+ if (touchActive.down) moveY += survivor.speed;
+ if (touchActive.left) moveX -= survivor.speed;
+ if (touchActive.right) moveX += survivor.speed;
+ survivor.x += moveX;
+ survivor.y += moveY;
+ survivor.isRunning = moveX !== 0 || moveY !== 0;
+ var canMove = true;
+ for (var i = 0; i < walls.length; i++) {
+ if (getDistance({
+ x: survivor.x,
+ y: survivor.y
+ }, walls[i]) < 50) {
+ canMove = false;
+ survivor.x -= moveX;
+ survivor.y -= moveY;
+ break;
+ }
}
- }
- // Clamp survivor to arena
- if (survivor.x < 150) survivor.x = 150;
- if (survivor.x > 1900) survivor.x = 1900;
- if (survivor.y < 150) survivor.y = 150;
- if (survivor.y > 2600) survivor.y = 2600;
- // Update killer AI
- var distToSurvivor = getDistance(killer, survivor);
- if (distToSurvivor < killer.detectionRadius) {
- killerDetected = true;
- detectionFlashTimer = 30;
- LK.getSound('detected').play();
- // Killer moves toward survivor
- if (distToSurvivor > 30) {
- var angle = Math.atan2(survivor.y - killer.y, survivor.x - killer.x);
- var killerSpeed = distToSurvivor < killer.aggressiveRadius ? killer.speed * 1.5 : killer.speed;
- var killerNewX = killer.x + Math.cos(angle) * killerSpeed;
- var killerNewY = killer.y + Math.sin(angle) * killerSpeed;
- var canKillerMove = true;
- for (var i = 0; i < walls.length; i++) {
- if (getDistance({
- x: killerNewX,
- y: killerNewY
- }, walls[i]) < 50) {
- canKillerMove = false;
- break;
+ // Clamp survivor to arena
+ if (survivor.x < 150) survivor.x = 150;
+ if (survivor.x > 1900) survivor.x = 1900;
+ if (survivor.y < 150) survivor.y = 150;
+ if (survivor.y > 2600) survivor.y = 2600;
+ // Update killer AI with enhanced difficulty
+ var closestDist = 999999;
+ var closestSurvivor = null;
+ for (var s = 0; s < survivors.length; s++) {
+ if (!survivors[s].escaped) {
+ var dist = getDistance(killer, survivors[s]);
+ if (dist < closestDist) {
+ closestDist = dist;
+ closestSurvivor = survivors[s];
}
}
- if (canKillerMove) {
- killer.x = killerNewX;
- killer.y = killerNewY;
+ }
+ if (closestSurvivor) {
+ if (closestDist < killer.detectionRadius) {
+ killerDetected = true;
+ detectionFlashTimer = 30;
+ killer.targetSurvivor = closestSurvivor;
+ // Predictive movement for harder AI
+ var predictX = closestSurvivor.x;
+ var predictY = closestSurvivor.y;
+ if (closestSurvivor.isRunning) {
+ var distX = closestSurvivor.x - closestSurvivor.lastX;
+ var distY = closestSurvivor.y - closestSurvivor.lastY;
+ predictX += distX * 8;
+ predictY += distY * 8;
+ }
+ killer.predictionX = predictX;
+ killer.predictionY = predictY;
+ // Killer moves toward prediction point
+ if (closestDist > 30) {
+ var angle = Math.atan2(predictY - killer.y, predictX - killer.x);
+ var killerSpeed = closestDist < killer.aggressiveRadius ? killer.speed * 2 : killer.speed;
+ var killerNewX = killer.x + Math.cos(angle) * killerSpeed;
+ var killerNewY = killer.y + Math.sin(angle) * killerSpeed;
+ var canKillerMove = true;
+ for (var i = 0; i < walls.length; i++) {
+ if (getDistance({
+ x: killerNewX,
+ y: killerNewY
+ }, walls[i]) < 50) {
+ canKillerMove = false;
+ break;
+ }
+ }
+ if (canKillerMove) {
+ killer.x = killerNewX;
+ killer.y = killerNewY;
+ }
+ }
+ if (closestDist < 50) {
+ gameState = 'chasing';
+ LK.getSound('chase').play();
+ }
+ } else {
+ killerDetected = false;
}
}
- if (distToSurvivor < 50) {
- gameState = 'chasing';
- LK.getSound('chase').play();
+ // Update hiding
+ survivor.isHiding = false;
+ for (var i = 0; i < hidingSpots.length; i++) {
+ if (getDistance(survivor, hidingSpots[i]) < 45) {
+ survivor.isHiding = true;
+ break;
+ }
}
- } else {
- killerDetected = false;
- }
- // Update hiding
- survivor.isHiding = false;
- for (var i = 0; i < hidingSpots.length; i++) {
- if (getDistance(survivor, hidingSpots[i]) < 45) {
- survivor.isHiding = true;
- break;
+ // Check generator repair
+ var currentRepairingGen = null;
+ for (var i = 0; i < generators.length; i++) {
+ var gen = generators[i];
+ if (!gen.isRepaired && getDistance(survivor, gen) < 60 && !survivor.isHiding && !survivor.isRunning) {
+ currentRepairingGen = gen;
+ break;
+ }
}
- }
- // Check generator repair - player must be near and standing still
- var currentRepairingGen = null;
- for (var i = 0; i < generators.length; i++) {
- var gen = generators[i];
- if (!gen.isRepaired && getDistance(survivor, gen) < 60 && !survivor.isHiding && !survivor.isRunning) {
- currentRepairingGen = gen;
- break;
- }
- }
- if (currentRepairingGen && !survivor.isRunning) {
- survivor.isRepairing = true;
- survivor.repairProgress += 1;
- currentRepairingGen.repairProgress = survivor.repairProgress;
- if (survivor.repairProgress >= 300) {
- currentRepairingGen.isRepaired = true;
- generatorsRepaired++;
+ if (currentRepairingGen && !survivor.isRunning) {
+ survivor.isRepairing = true;
+ survivor.repairProgress += 1;
+ currentRepairingGen.repairProgress = survivor.repairProgress;
+ if (survivor.repairProgress >= 300) {
+ currentRepairingGen.isRepaired = true;
+ generatorsRepaired++;
+ survivor.isRepairing = false;
+ survivor.repairProgress = 0;
+ LK.getSound('repair').play();
+ }
+ } else if (survivor.isRunning || !currentRepairingGen) {
survivor.isRepairing = false;
- survivor.repairProgress = 0;
- LK.getSound('repair').play();
}
- } else if (survivor.isRunning || !currentRepairingGen) {
- survivor.isRepairing = false;
- }
- // Check exit gate collision
- if (generatorsRepaired >= 3) {
- for (var i = 0; i < exitGates.length; i++) {
- if (getDistance(survivor, exitGates[i]) < 50) {
+ // Check exit gate collision
+ if (generatorsRepaired >= 3) {
+ for (var i = 0; i < exitGates.length; i++) {
+ if (getDistance(survivor, exitGates[i]) < 50) {
+ survivor.escaped = true;
+ survivorsEscaped++;
+ if (survivorsEscaped >= survivors.length) {
+ gameState = 'won';
+ LK.showYouWin();
+ return;
+ }
+ }
+ }
+ }
+ statusText.setText('Generators: ' + generatorsRepaired + '/3 | Escaped: ' + survivorsEscaped + '/' + survivors.length);
+ // Flash effect when detected
+ if (killerDetected && detectionFlashTimer > 0) {
+ detectionFlashTimer--;
+ if (detectionFlashTimer % 6 < 3) {
+ survivor.alpha = 0.5;
+ } else {
+ survivor.alpha = 1;
+ }
+ } else {
+ survivor.alpha = 1;
+ }
+ } else if (gameMode === 'killer') {
+ // Killer mode gameplay
+ var moveX = 0;
+ var moveY = 0;
+ if (touchActive.up) moveY -= killer.speed;
+ if (touchActive.down) moveY += killer.speed;
+ if (touchActive.left) moveX -= killer.speed;
+ if (touchActive.right) moveX += killer.speed;
+ killer.x += moveX;
+ killer.y += moveY;
+ // Clamp killer to arena
+ if (killer.x < 150) killer.x = 150;
+ if (killer.x > 1900) killer.x = 1900;
+ if (killer.y < 150) killer.y = 150;
+ if (killer.y > 2600) killer.y = 2600;
+ // Collision with walls
+ for (var i = 0; i < walls.length; i++) {
+ if (getDistance(killer, walls[i]) < 50) {
+ killer.x -= moveX;
+ killer.y -= moveY;
+ break;
+ }
+ }
+ // Check if killer caught survivors
+ for (var s = 0; s < survivors.length; s++) {
+ if (!survivors[s].escaped && getDistance(killer, survivors[s]) < 50) {
gameState = 'won';
LK.showYouWin();
return;
}
}
+ statusText.setText('Catch the survivors! Generators: ' + generatorsRepaired + '/3');
}
- // Update status text
- statusText.setText('Generators: ' + generatorsRepaired + '/3');
- // Flash effect when detected
- if (killerDetected && detectionFlashTimer > 0) {
- detectionFlashTimer--;
- if (detectionFlashTimer % 6 < 3) {
- survivor.alpha = 0.5;
- } else {
- survivor.alpha = 1;
- }
- } else {
- survivor.alpha = 1;
- }
// Update generator UI
for (var i = 0; i < generators.length; i++) {
generators[i].update();
}