User prompt
Now make the players stay in like the maze and like they can't move out of the maze otherwise that would just be bad
User prompt
it can the joystick be like pretty big and then when you move it around when you like touch it or move around and it moves in that direction and also make it stay in like the box like the maze so yeah
Code edit (1 edits merged)
Please save this source code
User prompt
Mine Shaft Escape
Initial prompt
the game the game will be about a guy who is stuck in a mine shaft and monsters one one monster the skeleton tries to change
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Exit = Container.expand(function () { var self = Container.call(this); var exitGraphics = self.attachAsset('exit', { anchorX: 0.5, anchorY: 0.5 }); // Pulsing effect self.pulseDirection = 1; self.update = function () { exitGraphics.alpha += self.pulseDirection * 0.02; if (exitGraphics.alpha >= 1) { self.pulseDirection = -1; } else if (exitGraphics.alpha <= 0.3) { self.pulseDirection = 1; } }; return self; }); var Floor = Container.expand(function () { var self = Container.call(this); var floorGraphics = self.attachAsset('floor', { anchorX: 0, anchorY: 0 }); return self; }); var Player = Container.expand(function () { var self = Container.call(this); self.speed = 5; self.targetX = 0; self.targetY = 0; self.isMoving = false; self.setTarget = function (x, y) { self.targetX = x; self.targetY = y; self.isMoving = true; }; self.update = function () { if (self.isMoving) { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > self.speed) { var moveX = dx / distance * self.speed; var moveY = dy / distance * self.speed; var newX = self.x + moveX; var newY = self.y + moveY; // Calculate maze boundaries with padding for player size var mazeLeft = offsetX + 20; var mazeRight = offsetX + mazeLayout[0].length * cellSize - 20; var mazeTop = offsetY + 20; var mazeBottom = offsetY + mazeLayout.length * cellSize - 20; // Check boundaries and wall collisions for X movement if (newX >= mazeLeft && newX <= mazeRight && !checkWallCollision(newX, self.y)) { self.x = newX; } // Check boundaries and wall collisions for Y movement if (newY >= mazeTop && newY <= mazeBottom && !checkWallCollision(self.x, newY)) { self.y = newY; } // Play footstep sound occasionally while moving if (Math.random() < 0.05) { LK.getSound('footstep').play(); } } else { self.isMoving = false; } } }; var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var Skeleton = Container.expand(function () { var self = Container.call(this); self.update = function () { if (player) { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { var speed = 0.8; var moveX = dx / distance * speed; var moveY = dy / distance * speed; self.x += moveX; self.y += moveY; } // Random roar sound if (Math.random() < 0.002) { LK.getSound('skeleton_roar').play(); } } }; var skeletonGraphics = self.attachAsset('skeleton', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var VictoryScreen = Container.expand(function () { var self = Container.call(this); // Create victory background var victoryGraphics = self.attachAsset('victory_screen', { anchorX: 0.5, anchorY: 0.5 }); // Center the victory screen self.x = 2048 / 2; self.y = 2732 / 2; // Start hidden and fade in victoryGraphics.alpha = 0; self.show = function () { // Fade in the victory screen tween(victoryGraphics, { alpha: 1 }, { duration: 1000, easing: tween.easeInOut }); // After showing victory screen, trigger actual win after delay LK.setTimeout(function () { LK.showYouWin(); }, 3000); }; return self; }); var Wall = Container.expand(function () { var self = Container.call(this); var wallGraphics = self.attachAsset('wall', { anchorX: 0, anchorY: 0 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a1a }); /**** * Game Code ****/ // Game variables var player; var skeleton; var walls = []; var floors = []; var exit; var gameStarted = false; var lastPlayerX = 0; var lastPlayerY = 0; var lastSkeletonDistance = Infinity; var mazeLayout; var possibleExitPositions = []; var victoryScreen; // Generate random maze layout function generateRandomMaze() { var width = 20; var height = 15; var maze = []; // Initialize maze with all walls for (var row = 0; row < height; row++) { maze[row] = []; for (var col = 0; col < width; col++) { maze[row][col] = 1; } } // Create paths using recursive backtracking var stack = []; var startX = 1; var startY = 1; maze[startY][startX] = 0; stack.push({ x: startX, y: startY }); possibleExitPositions = []; while (stack.length > 0) { var current = stack[stack.length - 1]; var neighbors = []; // Check all four directions var directions = [{ x: 0, y: -2 }, // Up { x: 2, y: 0 }, // Right { x: 0, y: 2 }, // Down { x: -2, y: 0 } // Left ]; for (var i = 0; i < directions.length; i++) { var newX = current.x + directions[i].x; var newY = current.y + directions[i].y; if (newX > 0 && newX < width - 1 && newY > 0 && newY < height - 1 && maze[newY][newX] === 1) { neighbors.push({ x: newX, y: newY, wallX: current.x + directions[i].x / 2, wallY: current.y + directions[i].y / 2 }); } } if (neighbors.length > 0) { var randomNeighbor = neighbors[Math.floor(Math.random() * neighbors.length)]; maze[randomNeighbor.y][randomNeighbor.x] = 0; maze[randomNeighbor.wallY][randomNeighbor.wallX] = 0; // Create wider paths by clearing additional adjacent cells var wideningDirections = [{ x: 1, y: 0 }, { x: -1, y: 0 }, { x: 0, y: 1 }, { x: 0, y: -1 }]; for (var w = 0; w < wideningDirections.length; w++) { var wideX = randomNeighbor.x + wideningDirections[w].x; var wideY = randomNeighbor.y + wideningDirections[w].y; if (wideX > 0 && wideX < width - 1 && wideY > 0 && wideY < height - 1) { maze[wideY][wideX] = 0; } } // Add to possible exit positions if it's near the edge if (randomNeighbor.x >= width - 3 || randomNeighbor.y <= 2) { possibleExitPositions.push({ x: randomNeighbor.x, y: randomNeighbor.y }); } stack.push({ x: randomNeighbor.x, y: randomNeighbor.y }); } else { stack.pop(); } } // Ensure borders are walls for (var row = 0; row < height; row++) { maze[row][0] = 1; maze[row][width - 1] = 1; } for (var col = 0; col < width; col++) { maze[0][col] = 1; maze[height - 1][col] = 1; } return maze; } // Generate initial maze layout mazeLayout = generateRandomMaze(); var cellSize = 60; var offsetX = (2048 - mazeLayout[0].length * cellSize) / 2; var offsetY = 200; // Function to create maze from layout function createMaze() { // Clear existing maze elements for (var i = 0; i < walls.length; i++) { walls[i].destroy(); } for (var i = 0; i < floors.length; i++) { floors[i].destroy(); } walls = []; floors = []; // Create maze - ensure all cells are processed for (var row = 0; row < mazeLayout.length; row++) { for (var col = 0; col < mazeLayout[row].length; col++) { var x = offsetX + col * cellSize; var y = offsetY + row * cellSize; if (mazeLayout[row][col] === 1) { // Create wall var wall = new Wall(); wall.x = x; wall.y = y; walls.push(wall); game.addChild(wall); } else { // Create floor for open spaces var floor = new Floor(); floor.x = x; floor.y = y; floors.push(floor); game.addChild(floor); } } } // LK engine handles rendering automatically } // Create initial maze createMaze(); // Create player at starting position player = new Player(); player.x = offsetX + 1.5 * cellSize; player.y = offsetY + 1.5 * cellSize; lastPlayerX = player.x; lastPlayerY = player.y; game.addChild(player); console.log("Player created at position:", player.x, player.y); console.log("Player dimensions:", player.width, player.height); // Create skeleton at bottom of maze skeleton = new Skeleton(); skeleton.x = offsetX + (mazeLayout[0].length - 2.5) * cellSize; skeleton.y = offsetY + (mazeLayout.length - 2.5) * cellSize; game.addChild(skeleton); // Function to position exit randomly function positionExit() { if (exit) { exit.destroy(); } exit = new Exit(); // Choose random exit position from possible locations if (possibleExitPositions.length > 0) { var randomExitIndex = Math.floor(Math.random() * possibleExitPositions.length); var exitPos = possibleExitPositions[randomExitIndex]; exit.x = offsetX + (exitPos.x + 0.5) * cellSize; exit.y = offsetY + (exitPos.y + 0.5) * cellSize; } else { // Fallback to top right if no positions found exit.x = offsetX + 18.5 * cellSize; exit.y = offsetY + 1.5 * cellSize; } game.addChild(exit); } // Create initial exit positionExit(); // Create victory screen (hidden initially) victoryScreen = new VictoryScreen(); game.addChild(victoryScreen); // UI elements var instructionText = new Text2('Click to move. Escape the mine!', { size: 60, fill: 0xFFFFFF }); instructionText.anchor.set(0.5, 0); LK.gui.top.addChild(instructionText); instructionText.y = 100; var distanceText = new Text2('', { size: 50, fill: 0xFF4444 }); distanceText.anchor.set(0.5, 0); LK.gui.top.addChild(distanceText); distanceText.y = 180; function checkWallCollision(x, y) { var col = Math.floor((x - offsetX) / cellSize); var row = Math.floor((y - offsetY) / cellSize); if (row < 0 || row >= mazeLayout.length || col < 0 || col >= mazeLayout[0].length) { return true; } return mazeLayout[row][col] === 1; } // Function to reset game with new maze function resetGameWithNewMaze() { // Generate new maze layout mazeLayout = generateRandomMaze(); // Recalculate positioning offsets for new maze offsetX = (2048 - mazeLayout[0].length * cellSize) / 2; offsetY = 200; // Recreate maze createMaze(); // Destroy and recreate player to ensure clean state if (player) { player.destroy(); } player = new Player(); player.x = offsetX + 1.5 * cellSize; player.y = offsetY + 1.5 * cellSize; player.isMoving = false; lastPlayerX = player.x; lastPlayerY = player.y; game.addChild(player); // Destroy and recreate skeleton to ensure clean state if (skeleton) { skeleton.destroy(); } skeleton = new Skeleton(); skeleton.x = offsetX + (mazeLayout[0].length - 2.5) * cellSize; skeleton.y = offsetY + (mazeLayout.length - 2.5) * cellSize; game.addChild(skeleton); // Position new exit positionExit(); // Reset distance tracking lastSkeletonDistance = Infinity; // Recreate victory screen if (victoryScreen) { victoryScreen.destroy(); } victoryScreen = new VictoryScreen(); game.addChild(victoryScreen); } game.update = function () { // Ensure player is always visible and in the game if (!player || !game.children.includes(player)) { console.log("Player missing, recreating..."); // Ensure we have current positioning offsets offsetX = (2048 - mazeLayout[0].length * cellSize) / 2; offsetY = 200; // Destroy existing player if it exists but is not in children if (player && !game.children.includes(player)) { player.destroy(); } player = new Player(); player.x = offsetX + 1.5 * cellSize; player.y = offsetY + 1.5 * cellSize; lastPlayerX = player.x; lastPlayerY = player.y; game.addChild(player); console.log("Player recreated at position:", player.x, player.y); } // Ensure maze is always visible - recreate if walls/floors are missing if (walls.length === 0 || floors.length === 0) { // Recalculate positioning offsets offsetX = (2048 - mazeLayout[0].length * cellSize) / 2; offsetY = 200; createMaze(); } // Check if player reached exit if (player.intersects(exit)) { LK.getSound('escape').play(); // Show custom victory screen if (victoryScreen) { victoryScreen.show(); } else { LK.showYouWin(); } return; } // Check if skeleton caught player var skeletonDistance = Math.sqrt(Math.pow(player.x - skeleton.x, 2) + Math.pow(player.y - skeleton.y, 2)); if (!lastSkeletonDistance) lastSkeletonDistance = skeletonDistance; // Play gregor sound when skeleton gets close (transition from far to close) if (lastSkeletonDistance > 100 && skeletonDistance <= 100) { LK.getSound('gregor').play(); } // Continue playing gregor sound while skeleton is close with increasing intensity if (skeletonDistance <= 100) { // Calculate intensity based on distance (closer = more intense) var intensity = (100 - skeletonDistance) / 100; // Play gregor sound more frequently as skeleton gets closer var playChance = intensity * 0.15; // Up to 15% chance per frame when very close if (Math.random() < playChance) { LK.getSound('gregor').play(); } } if (lastSkeletonDistance > 50 && skeletonDistance <= 50) { // Play creepy jump-scare sound LK.getSound('skeleton_roar').play(); LK.getSound('gregor').play(); // Monster comes up to face - move skeleton to center of screen and scale dramatically var centerX = 2048 / 2; var centerY = 2732 / 2; // First: Move skeleton to player's face (center of screen) tween(skeleton, { x: centerX, y: centerY, scaleX: 8, scaleY: 8 }, { duration: 300, easing: tween.easeOut }); // Make skeleton shake violently tween(skeleton, { x: centerX + 30 }, { duration: 80, easing: tween.easeInOut, onFinish: function onFinish() { tween(skeleton, { x: centerX - 60 }, { duration: 80, easing: tween.easeInOut, onFinish: function onFinish() { tween(skeleton, { x: centerX + 60 }, { duration: 80, easing: tween.easeInOut, onFinish: function onFinish() { tween(skeleton, { x: centerX - 30 }, { duration: 80, easing: tween.easeInOut, onFinish: function onFinish() { tween(skeleton, { x: centerX }, { duration: 80, easing: tween.easeInOut }); } }); } }); } }); } }); // Flash screen red multiple times for intense jump-scare LK.effects.flashScreen(0xff0000, 400); LK.setTimeout(function () { LK.effects.flashScreen(0xff0000, 300); }, 200); LK.setTimeout(function () { LK.effects.flashScreen(0xff0000, 200); }, 400); // After jump-scare animation, restart the game completely LK.setTimeout(function () { // Reset skeleton scale and position back to normal tween(skeleton, { scaleX: 1, scaleY: 1, x: offsetX + 18.5 * cellSize, y: offsetY + 13.5 * cellSize }, { duration: 100 }); // Reset with new maze layout and restart game resetGameWithNewMaze(); // Force maze recreation to ensure full visibility createMaze(); }, 1200); return; } lastSkeletonDistance = skeletonDistance; // Update distance display var distanceToExit = Math.sqrt(Math.pow(player.x - exit.x, 2) + Math.pow(player.y - exit.y, 2)); distanceText.setText('Skeleton Distance: ' + Math.floor(skeletonDistance)); // Create tension effect when skeleton is close if (skeletonDistance < 120) { var intensity = (120 - skeletonDistance) / 120; game.setBackgroundColor(Math.floor(0x1a * (1 + intensity)) << 16 | Math.floor(0x1a * (1 - intensity * 0.5)) << 8 | Math.floor(0x1a * (1 - intensity * 0.5))); } else { game.setBackgroundColor(0x1a1a1a); } }; // Click to move handler game.down = function (x, y, obj) { if (player) { player.setTarget(x, y); } }; // Start ambient music LK.playMusic('horror_ambient'); ;
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Exit = Container.expand(function () {
var self = Container.call(this);
var exitGraphics = self.attachAsset('exit', {
anchorX: 0.5,
anchorY: 0.5
});
// Pulsing effect
self.pulseDirection = 1;
self.update = function () {
exitGraphics.alpha += self.pulseDirection * 0.02;
if (exitGraphics.alpha >= 1) {
self.pulseDirection = -1;
} else if (exitGraphics.alpha <= 0.3) {
self.pulseDirection = 1;
}
};
return self;
});
var Floor = Container.expand(function () {
var self = Container.call(this);
var floorGraphics = self.attachAsset('floor', {
anchorX: 0,
anchorY: 0
});
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
self.speed = 5;
self.targetX = 0;
self.targetY = 0;
self.isMoving = false;
self.setTarget = function (x, y) {
self.targetX = x;
self.targetY = y;
self.isMoving = true;
};
self.update = function () {
if (self.isMoving) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.speed) {
var moveX = dx / distance * self.speed;
var moveY = dy / distance * self.speed;
var newX = self.x + moveX;
var newY = self.y + moveY;
// Calculate maze boundaries with padding for player size
var mazeLeft = offsetX + 20;
var mazeRight = offsetX + mazeLayout[0].length * cellSize - 20;
var mazeTop = offsetY + 20;
var mazeBottom = offsetY + mazeLayout.length * cellSize - 20;
// Check boundaries and wall collisions for X movement
if (newX >= mazeLeft && newX <= mazeRight && !checkWallCollision(newX, self.y)) {
self.x = newX;
}
// Check boundaries and wall collisions for Y movement
if (newY >= mazeTop && newY <= mazeBottom && !checkWallCollision(self.x, newY)) {
self.y = newY;
}
// Play footstep sound occasionally while moving
if (Math.random() < 0.05) {
LK.getSound('footstep').play();
}
} else {
self.isMoving = false;
}
}
};
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Skeleton = Container.expand(function () {
var self = Container.call(this);
self.update = function () {
if (player) {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var speed = 0.8;
var moveX = dx / distance * speed;
var moveY = dy / distance * speed;
self.x += moveX;
self.y += moveY;
}
// Random roar sound
if (Math.random() < 0.002) {
LK.getSound('skeleton_roar').play();
}
}
};
var skeletonGraphics = self.attachAsset('skeleton', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var VictoryScreen = Container.expand(function () {
var self = Container.call(this);
// Create victory background
var victoryGraphics = self.attachAsset('victory_screen', {
anchorX: 0.5,
anchorY: 0.5
});
// Center the victory screen
self.x = 2048 / 2;
self.y = 2732 / 2;
// Start hidden and fade in
victoryGraphics.alpha = 0;
self.show = function () {
// Fade in the victory screen
tween(victoryGraphics, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeInOut
});
// After showing victory screen, trigger actual win after delay
LK.setTimeout(function () {
LK.showYouWin();
}, 3000);
};
return self;
});
var Wall = Container.expand(function () {
var self = Container.call(this);
var wallGraphics = self.attachAsset('wall', {
anchorX: 0,
anchorY: 0
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// Game variables
var player;
var skeleton;
var walls = [];
var floors = [];
var exit;
var gameStarted = false;
var lastPlayerX = 0;
var lastPlayerY = 0;
var lastSkeletonDistance = Infinity;
var mazeLayout;
var possibleExitPositions = [];
var victoryScreen;
// Generate random maze layout
function generateRandomMaze() {
var width = 20;
var height = 15;
var maze = [];
// Initialize maze with all walls
for (var row = 0; row < height; row++) {
maze[row] = [];
for (var col = 0; col < width; col++) {
maze[row][col] = 1;
}
}
// Create paths using recursive backtracking
var stack = [];
var startX = 1;
var startY = 1;
maze[startY][startX] = 0;
stack.push({
x: startX,
y: startY
});
possibleExitPositions = [];
while (stack.length > 0) {
var current = stack[stack.length - 1];
var neighbors = [];
// Check all four directions
var directions = [{
x: 0,
y: -2
},
// Up
{
x: 2,
y: 0
},
// Right
{
x: 0,
y: 2
},
// Down
{
x: -2,
y: 0
} // Left
];
for (var i = 0; i < directions.length; i++) {
var newX = current.x + directions[i].x;
var newY = current.y + directions[i].y;
if (newX > 0 && newX < width - 1 && newY > 0 && newY < height - 1 && maze[newY][newX] === 1) {
neighbors.push({
x: newX,
y: newY,
wallX: current.x + directions[i].x / 2,
wallY: current.y + directions[i].y / 2
});
}
}
if (neighbors.length > 0) {
var randomNeighbor = neighbors[Math.floor(Math.random() * neighbors.length)];
maze[randomNeighbor.y][randomNeighbor.x] = 0;
maze[randomNeighbor.wallY][randomNeighbor.wallX] = 0;
// Create wider paths by clearing additional adjacent cells
var wideningDirections = [{
x: 1,
y: 0
}, {
x: -1,
y: 0
}, {
x: 0,
y: 1
}, {
x: 0,
y: -1
}];
for (var w = 0; w < wideningDirections.length; w++) {
var wideX = randomNeighbor.x + wideningDirections[w].x;
var wideY = randomNeighbor.y + wideningDirections[w].y;
if (wideX > 0 && wideX < width - 1 && wideY > 0 && wideY < height - 1) {
maze[wideY][wideX] = 0;
}
}
// Add to possible exit positions if it's near the edge
if (randomNeighbor.x >= width - 3 || randomNeighbor.y <= 2) {
possibleExitPositions.push({
x: randomNeighbor.x,
y: randomNeighbor.y
});
}
stack.push({
x: randomNeighbor.x,
y: randomNeighbor.y
});
} else {
stack.pop();
}
}
// Ensure borders are walls
for (var row = 0; row < height; row++) {
maze[row][0] = 1;
maze[row][width - 1] = 1;
}
for (var col = 0; col < width; col++) {
maze[0][col] = 1;
maze[height - 1][col] = 1;
}
return maze;
}
// Generate initial maze layout
mazeLayout = generateRandomMaze();
var cellSize = 60;
var offsetX = (2048 - mazeLayout[0].length * cellSize) / 2;
var offsetY = 200;
// Function to create maze from layout
function createMaze() {
// Clear existing maze elements
for (var i = 0; i < walls.length; i++) {
walls[i].destroy();
}
for (var i = 0; i < floors.length; i++) {
floors[i].destroy();
}
walls = [];
floors = [];
// Create maze - ensure all cells are processed
for (var row = 0; row < mazeLayout.length; row++) {
for (var col = 0; col < mazeLayout[row].length; col++) {
var x = offsetX + col * cellSize;
var y = offsetY + row * cellSize;
if (mazeLayout[row][col] === 1) {
// Create wall
var wall = new Wall();
wall.x = x;
wall.y = y;
walls.push(wall);
game.addChild(wall);
} else {
// Create floor for open spaces
var floor = new Floor();
floor.x = x;
floor.y = y;
floors.push(floor);
game.addChild(floor);
}
}
}
// LK engine handles rendering automatically
}
// Create initial maze
createMaze();
// Create player at starting position
player = new Player();
player.x = offsetX + 1.5 * cellSize;
player.y = offsetY + 1.5 * cellSize;
lastPlayerX = player.x;
lastPlayerY = player.y;
game.addChild(player);
console.log("Player created at position:", player.x, player.y);
console.log("Player dimensions:", player.width, player.height);
// Create skeleton at bottom of maze
skeleton = new Skeleton();
skeleton.x = offsetX + (mazeLayout[0].length - 2.5) * cellSize;
skeleton.y = offsetY + (mazeLayout.length - 2.5) * cellSize;
game.addChild(skeleton);
// Function to position exit randomly
function positionExit() {
if (exit) {
exit.destroy();
}
exit = new Exit();
// Choose random exit position from possible locations
if (possibleExitPositions.length > 0) {
var randomExitIndex = Math.floor(Math.random() * possibleExitPositions.length);
var exitPos = possibleExitPositions[randomExitIndex];
exit.x = offsetX + (exitPos.x + 0.5) * cellSize;
exit.y = offsetY + (exitPos.y + 0.5) * cellSize;
} else {
// Fallback to top right if no positions found
exit.x = offsetX + 18.5 * cellSize;
exit.y = offsetY + 1.5 * cellSize;
}
game.addChild(exit);
}
// Create initial exit
positionExit();
// Create victory screen (hidden initially)
victoryScreen = new VictoryScreen();
game.addChild(victoryScreen);
// UI elements
var instructionText = new Text2('Click to move. Escape the mine!', {
size: 60,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0);
LK.gui.top.addChild(instructionText);
instructionText.y = 100;
var distanceText = new Text2('', {
size: 50,
fill: 0xFF4444
});
distanceText.anchor.set(0.5, 0);
LK.gui.top.addChild(distanceText);
distanceText.y = 180;
function checkWallCollision(x, y) {
var col = Math.floor((x - offsetX) / cellSize);
var row = Math.floor((y - offsetY) / cellSize);
if (row < 0 || row >= mazeLayout.length || col < 0 || col >= mazeLayout[0].length) {
return true;
}
return mazeLayout[row][col] === 1;
}
// Function to reset game with new maze
function resetGameWithNewMaze() {
// Generate new maze layout
mazeLayout = generateRandomMaze();
// Recalculate positioning offsets for new maze
offsetX = (2048 - mazeLayout[0].length * cellSize) / 2;
offsetY = 200;
// Recreate maze
createMaze();
// Destroy and recreate player to ensure clean state
if (player) {
player.destroy();
}
player = new Player();
player.x = offsetX + 1.5 * cellSize;
player.y = offsetY + 1.5 * cellSize;
player.isMoving = false;
lastPlayerX = player.x;
lastPlayerY = player.y;
game.addChild(player);
// Destroy and recreate skeleton to ensure clean state
if (skeleton) {
skeleton.destroy();
}
skeleton = new Skeleton();
skeleton.x = offsetX + (mazeLayout[0].length - 2.5) * cellSize;
skeleton.y = offsetY + (mazeLayout.length - 2.5) * cellSize;
game.addChild(skeleton);
// Position new exit
positionExit();
// Reset distance tracking
lastSkeletonDistance = Infinity;
// Recreate victory screen
if (victoryScreen) {
victoryScreen.destroy();
}
victoryScreen = new VictoryScreen();
game.addChild(victoryScreen);
}
game.update = function () {
// Ensure player is always visible and in the game
if (!player || !game.children.includes(player)) {
console.log("Player missing, recreating...");
// Ensure we have current positioning offsets
offsetX = (2048 - mazeLayout[0].length * cellSize) / 2;
offsetY = 200;
// Destroy existing player if it exists but is not in children
if (player && !game.children.includes(player)) {
player.destroy();
}
player = new Player();
player.x = offsetX + 1.5 * cellSize;
player.y = offsetY + 1.5 * cellSize;
lastPlayerX = player.x;
lastPlayerY = player.y;
game.addChild(player);
console.log("Player recreated at position:", player.x, player.y);
}
// Ensure maze is always visible - recreate if walls/floors are missing
if (walls.length === 0 || floors.length === 0) {
// Recalculate positioning offsets
offsetX = (2048 - mazeLayout[0].length * cellSize) / 2;
offsetY = 200;
createMaze();
}
// Check if player reached exit
if (player.intersects(exit)) {
LK.getSound('escape').play();
// Show custom victory screen
if (victoryScreen) {
victoryScreen.show();
} else {
LK.showYouWin();
}
return;
}
// Check if skeleton caught player
var skeletonDistance = Math.sqrt(Math.pow(player.x - skeleton.x, 2) + Math.pow(player.y - skeleton.y, 2));
if (!lastSkeletonDistance) lastSkeletonDistance = skeletonDistance;
// Play gregor sound when skeleton gets close (transition from far to close)
if (lastSkeletonDistance > 100 && skeletonDistance <= 100) {
LK.getSound('gregor').play();
}
// Continue playing gregor sound while skeleton is close with increasing intensity
if (skeletonDistance <= 100) {
// Calculate intensity based on distance (closer = more intense)
var intensity = (100 - skeletonDistance) / 100;
// Play gregor sound more frequently as skeleton gets closer
var playChance = intensity * 0.15; // Up to 15% chance per frame when very close
if (Math.random() < playChance) {
LK.getSound('gregor').play();
}
}
if (lastSkeletonDistance > 50 && skeletonDistance <= 50) {
// Play creepy jump-scare sound
LK.getSound('skeleton_roar').play();
LK.getSound('gregor').play();
// Monster comes up to face - move skeleton to center of screen and scale dramatically
var centerX = 2048 / 2;
var centerY = 2732 / 2;
// First: Move skeleton to player's face (center of screen)
tween(skeleton, {
x: centerX,
y: centerY,
scaleX: 8,
scaleY: 8
}, {
duration: 300,
easing: tween.easeOut
});
// Make skeleton shake violently
tween(skeleton, {
x: centerX + 30
}, {
duration: 80,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(skeleton, {
x: centerX - 60
}, {
duration: 80,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(skeleton, {
x: centerX + 60
}, {
duration: 80,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(skeleton, {
x: centerX - 30
}, {
duration: 80,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(skeleton, {
x: centerX
}, {
duration: 80,
easing: tween.easeInOut
});
}
});
}
});
}
});
}
});
// Flash screen red multiple times for intense jump-scare
LK.effects.flashScreen(0xff0000, 400);
LK.setTimeout(function () {
LK.effects.flashScreen(0xff0000, 300);
}, 200);
LK.setTimeout(function () {
LK.effects.flashScreen(0xff0000, 200);
}, 400);
// After jump-scare animation, restart the game completely
LK.setTimeout(function () {
// Reset skeleton scale and position back to normal
tween(skeleton, {
scaleX: 1,
scaleY: 1,
x: offsetX + 18.5 * cellSize,
y: offsetY + 13.5 * cellSize
}, {
duration: 100
});
// Reset with new maze layout and restart game
resetGameWithNewMaze();
// Force maze recreation to ensure full visibility
createMaze();
}, 1200);
return;
}
lastSkeletonDistance = skeletonDistance;
// Update distance display
var distanceToExit = Math.sqrt(Math.pow(player.x - exit.x, 2) + Math.pow(player.y - exit.y, 2));
distanceText.setText('Skeleton Distance: ' + Math.floor(skeletonDistance));
// Create tension effect when skeleton is close
if (skeletonDistance < 120) {
var intensity = (120 - skeletonDistance) / 120;
game.setBackgroundColor(Math.floor(0x1a * (1 + intensity)) << 16 | Math.floor(0x1a * (1 - intensity * 0.5)) << 8 | Math.floor(0x1a * (1 - intensity * 0.5)));
} else {
game.setBackgroundColor(0x1a1a1a);
}
};
// Click to move handler
game.down = function (x, y, obj) {
if (player) {
player.setTarget(x, y);
}
};
// Start ambient music
LK.playMusic('horror_ambient');
;
A guy with a bag over his head with a cross on it. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
The player with a torch in his hand and the monster skeleton dead on the floor with a knife in his head and blood everywhere. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat