User prompt
show floor number only in the list
User prompt
highlight correct floor number
User prompt
remove floor number on the top
User prompt
put floor1 on all floors
User prompt
ghost chases you
User prompt
spawn floor1 on floor 1
User prompt
when you reach floor 6 you win the game
User prompt
keep only one puzzle on each level
User prompt
spawn puzzle on each floor
User prompt
spawn puzzle on floor 5
User prompt
spawn puzzle on floor3
User prompt
remove other doors from other levels
User prompt
remove all walls
User prompt
move door out of the wall
User prompt
move door in floor1 reachable
User prompt
move door out of the wall
User prompt
add four more floors
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'addChild')' in or related to this line: 'floorListContainer.addChild(txt);' Line Number: 610
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'children')' in or related to this line: 'while (floorListContainer.children.length) {' Line Number: 594
User prompt
show floor list on the right
User prompt
make doors reachable
User prompt
ghost moves 10% faster
User prompt
ghost moves in random directions
User prompt
each puzzle opens a door
User prompt
add one puzzle to each level
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Door class var Door = Container.expand(function () { var self = Container.call(this); self.locked = true; self.doorAsset = self.attachAsset('door_locked', { anchorX: 0.5, anchorY: 0.5 }); self.unlock = function () { self.locked = false; self.doorAsset.destroy(); self.doorAsset = self.attachAsset('door_unlocked', { anchorX: 0.5, anchorY: 0.5 }); }; return self; }); // Enemy (ghost) class var Ghost = Container.expand(function () { var self = Container.call(this); self.attachAsset('ghost', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 4; self.direction = 1; // 1: right, -1: left self.update = function () { self.x += self.speed * self.direction; // Bounce off walls (simple horizontal patrol) if (self.x < 300) self.direction = 1; if (self.x > 2048 - 300) self.direction = -1; }; return self; }); // Player class var Player = Container.expand(function () { var self = Container.call(this); self.asset = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.canMove = true; self.moveTo = function (x, y) { if (!self.canMove) return; // Clamp to game area var px = Math.max(60, Math.min(2048 - 60, x)); var py = Math.max(60, Math.min(2732 - 60, y)); self.x = px; self.y = py; }; return self; }); // Puzzle class var Puzzle = Container.expand(function () { var self = Container.call(this); self.solved = false; self.attachAsset('puzzle', { anchorX: 0.5, anchorY: 0.5 }); return self; }); // Wall class var Wall = Container.expand(function () { var self = Container.call(this); var wallAsset = self.attachAsset('wall', { anchorX: 0.5, anchorY: 0.5 }); self.isSolid = true; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // Enemy (ghost) // Puzzle object // Key // Door (unlocked) // Door (locked) // Wall // Player // --- Game State --- var currentFloor = 0; // 0: ground, 1: upstairs var floors = []; var player; var dragPlayer = false; var lastPlayerPos = { x: 0, y: 0 }; var keyObj = null; var doorObj = null; var puzzleObj = null; var ghostObj = null; var messageTxt = null; var floorTxt = null; var puzzleSolved = false; var gameOver = false; // --- Room/Floor Layouts --- function createFloor0() { // Floor 5: Four rooms, each with different shape and size, combined together var floor = { walls: [], doors: [], keys: [], puzzles: [], enemies: [] }; // --- Room 1: Large Rectangle (Top Left) --- // Top wall var wallR1Top = new Wall(); wallR1Top.x = 350; wallR1Top.y = 200; wallR1Top.width = 600; wallR1Top.height = 60; floor.walls.push(wallR1Top); // Left wall var wallR1Left = new Wall(); wallR1Left.x = 70; wallR1Left.y = 500; wallR1Left.width = 60; wallR1Left.height = 600; floor.walls.push(wallR1Left); // Bottom wall var wallR1Bottom = new Wall(); wallR1Bottom.x = 350; wallR1Bottom.y = 800; wallR1Bottom.width = 600; wallR1Bottom.height = 60; floor.walls.push(wallR1Bottom); // Right wall (shared with Room 2, has a door) var wallR1RightA = new Wall(); wallR1RightA.x = 650; wallR1RightA.y = 470; wallR1RightA.width = 60; wallR1RightA.height = 200; floor.walls.push(wallR1RightA); var wallR1RightB = new Wall(); wallR1RightB.x = 650; wallR1RightB.y = 730; wallR1RightB.width = 60; wallR1RightB.height = 200; floor.walls.push(wallR1RightB); // --- Room 2: Tall Rectangle (Top Right) --- // Top wall var wallR2Top = new Wall(); wallR2Top.x = 1200; wallR2Top.y = 200; wallR2Top.width = 600; wallR2Top.height = 60; floor.walls.push(wallR2Top); // Right wall var wallR2Right = new Wall(); wallR2Right.x = 1550; wallR2Right.y = 600; wallR2Right.width = 60; wallR2Right.height = 800; floor.walls.push(wallR2Right); // Bottom wall (shared with Room 3, has a door) var wallR2BottomA = new Wall(); wallR2BottomA.x = 1200; wallR2BottomA.y = 1000; wallR2BottomA.width = 250; wallR2BottomA.height = 60; floor.walls.push(wallR2BottomA); var wallR2BottomB = new Wall(); wallR2BottomB.x = 1450; wallR2BottomB.y = 1000; wallR2BottomB.width = 250; wallR2BottomB.height = 60; floor.walls.push(wallR2BottomB); // Left wall (shared with Room 1, has a door) var wallR2LeftA = new Wall(); wallR2LeftA.x = 850; wallR2LeftA.y = 470; wallR2LeftA.width = 60; wallR2LeftA.height = 200; floor.walls.push(wallR2LeftA); var wallR2LeftB = new Wall(); wallR2LeftB.x = 850; wallR2LeftB.y = 730; wallR2LeftB.width = 60; wallR2LeftB.height = 200; floor.walls.push(wallR2LeftB); // --- Room 3: Square (Bottom Right) --- // Top wall (shared with Room 2, has a door) var wallR3TopA = new Wall(); wallR3TopA.x = 1200; wallR3TopA.y = 1200; wallR3TopA.width = 250; wallR3TopA.height = 60; floor.walls.push(wallR3TopA); var wallR3TopB = new Wall(); wallR3TopB.x = 1450; wallR3TopB.y = 1200; wallR3TopB.width = 250; wallR3TopB.height = 60; floor.walls.push(wallR3TopB); // Right wall var wallR3Right = new Wall(); wallR3Right.x = 1550; wallR3Right.y = 1500; wallR3Right.width = 60; wallR3Right.height = 600; floor.walls.push(wallR3Right); // Bottom wall var wallR3Bottom = new Wall(); wallR3Bottom.x = 1200; wallR3Bottom.y = 1800; wallR3Bottom.width = 600; wallR3Bottom.height = 60; floor.walls.push(wallR3Bottom); // Left wall (shared with Room 4, has a door) var wallR3LeftA = new Wall(); wallR3LeftA.x = 850; wallR3LeftA.y = 1400; wallR3LeftA.width = 60; wallR3LeftA.height = 200; floor.walls.push(wallR3LeftA); var wallR3LeftB = new Wall(); wallR3LeftB.x = 850; wallR3LeftB.y = 1700; wallR3LeftB.width = 60; wallR3LeftB.height = 200; floor.walls.push(wallR3LeftB); // --- Room 4: L-Shape (Bottom Left) --- // Top wall var wallR4Top = new Wall(); wallR4Top.x = 350; wallR4Top.y = 1200; wallR4Top.width = 600; wallR4Top.height = 60; floor.walls.push(wallR4Top); // Left wall var wallR4Left = new Wall(); wallR4Left.x = 70; wallR4Left.y = 1500; wallR4Left.width = 60; wallR4Left.height = 600; floor.walls.push(wallR4Left); // Bottom wall var wallR4Bottom = new Wall(); wallR4Bottom.x = 350; wallR4Bottom.y = 1800; wallR4Bottom.width = 600; wallR4Bottom.height = 60; floor.walls.push(wallR4Bottom); // Right wall (shared with Room 3, has a door) var wallR4RightA = new Wall(); wallR4RightA.x = 650; wallR4RightA.y = 1400; wallR4RightA.width = 60; wallR4RightA.height = 200; floor.walls.push(wallR4RightA); var wallR4RightB = new Wall(); wallR4RightB.x = 650; wallR4RightB.y = 1700; wallR4RightB.width = 60; wallR4RightB.height = 200; floor.walls.push(wallR4RightB); // --- Doors between rooms --- // Door between Room 1 and Room 2 (top horizontal) var door1 = new Door(); door1.x = 750; door1.y = 470; floor.doors.push(door1); // Door between Room 2 and Room 3 (vertical) var door2 = new Door(); door2.x = 1200; door2.y = 1100; floor.doors.push(door2); // Door between Room 3 and Room 4 (bottom horizontal) var door3 = new Door(); door3.x = 750; door3.y = 1700; floor.doors.push(door3); // Door between Room 4 and Room 1 (vertical) var door4 = new Door(); door4.x = 350; door4.y = 1000; floor.doors.push(door4); // --- Puzzle in Room 3 (bottom right) --- var puzzle = new Puzzle(); puzzle.x = 1400; puzzle.y = 1600; floor.puzzles.push(puzzle); // --- Ghost in Room 2 (top right) --- var ghost = new Ghost(); ghost.x = 1300; ghost.y = 600; floor.enemies.push(ghost); return floor; } function createFloor1() { // Upstairs: 1 room, exit door (unlocked if puzzle solved), 1 ghost var floor = { walls: [], doors: [], keys: [], puzzles: [], enemies: [] }; // Walls (rectangle room) var wallTop = new Wall(); wallTop.x = 2048 / 2; wallTop.y = 400; wallTop.width = 1600; wallTop.height = 60; floor.walls.push(wallTop); var wallBottom = new Wall(); wallBottom.x = 2048 / 2; wallBottom.y = 2732 - 400; wallBottom.width = 1600; wallBottom.height = 60; floor.walls.push(wallBottom); var wallLeft = new Wall(); wallLeft.x = 300; wallLeft.y = 2732 / 2; wallLeft.width = 60; wallLeft.height = 1800; floor.walls.push(wallLeft); var wallRight = new Wall(); wallRight.x = 2048 - 300; wallRight.y = 2732 / 2; wallRight.width = 60; wallRight.height = 1800; floor.walls.push(wallRight); // Exit Door (top center, unlocked if puzzle solved) var door = new Door(); door.x = 2048 / 2; door.y = 400; door.locked = false; door.doorAsset.destroy(); door.doorAsset = door.attachAsset('door_unlocked', { anchorX: 0.5, anchorY: 0.5 }); floor.doors.push(door); // Puzzle in the center of the room var puzzle = new Puzzle(); puzzle.x = 2048 / 2; puzzle.y = 2732 / 2; floor.puzzles.push(puzzle); // Ghost (patrols horizontally) var ghost = new Ghost(); ghost.x = 2048 / 2; ghost.y = 1200; floor.enemies.push(ghost); return floor; } // --- Helper Functions --- function clearFloor() { // Remove all objects from game if (floors[currentFloor]) { var f = floors[currentFloor]; for (var i = 0; i < f.walls.length; ++i) f.walls[i].destroy(); for (var i = 0; i < f.doors.length; ++i) f.doors[i].destroy(); for (var i = 0; i < f.keys.length; ++i) f.keys[i].destroy(); for (var i = 0; i < f.puzzles.length; ++i) f.puzzles[i].destroy(); for (var i = 0; i < f.enemies.length; ++i) f.enemies[i].destroy(); } if (doorObj) { if (typeof doorObj.destroy === "function") { doorObj.destroy(); } doorObj = null; } if (puzzleObj) { if (typeof puzzleObj.destroy === "function") { puzzleObj.destroy(); } puzzleObj = null; } if (ghostObj) { ghostObj.destroy(); ghostObj = null; } } function setupFloor(floorNum) { clearFloor(); var f = floors[floorNum]; // Add walls for (var i = 0; i < f.walls.length; ++i) game.addChild(f.walls[i]); // Add doors for (var i = 0; i < f.doors.length; ++i) game.addChild(f.doors[i]); // Add puzzles for (var i = 0; i < f.puzzles.length; ++i) game.addChild(f.puzzles[i]); // Add enemies for (var i = 0; i < f.enemies.length; ++i) game.addChild(f.enemies[i]); // For easy reference doorObj = f.doors.length ? f.doors[0] : null; keyObj = null; puzzleObj = f.puzzles.length ? f.puzzles[0] : null; ghostObj = f.enemies.length ? f.enemies[0] : null; } // --- GUI --- messageTxt = new Text2('', { size: 90, fill: 0xFFCCCC }); messageTxt.anchor.set(0.5, 0); LK.gui.top.addChild(messageTxt); floorTxt = new Text2('Floor 1', { size: 70, fill: 0xCCCCFF }); floorTxt.anchor.set(0.5, 0); LK.gui.top.addChild(floorTxt); // --- Game Setup --- floors[0] = createFloor0(); floors[1] = createFloor1(); player = new Player(); player.x = 2048 / 2; player.y = 2732 - 700; game.addChild(player); setupFloor(0); updateFloorText(); function updateFloorText() { floorTxt.setText('Floor 5'); } // --- Movement & Controls --- function canMoveTo(x, y) { // Check collision with walls var f = floors[currentFloor]; for (var i = 0; i < f.walls.length; ++i) { var wall = f.walls[i]; // Simple AABB collision var dx = Math.abs(x - wall.x); var dy = Math.abs(y - wall.y); if (dx < wall.width / 2 + 60 && dy < wall.height / 2 + 60) { return false; } } return true; } function handleMove(x, y, obj) { if (gameOver) return; if (!dragPlayer) return; // Clamp to game area var px = Math.max(60, Math.min(2048 - 60, x)); var py = Math.max(60, Math.min(2732 - 60, y)); // Only move if not colliding with wall if (canMoveTo(px, py)) { player.moveTo(px, py); } } game.down = function (x, y, obj) { if (gameOver) return; // Only start drag if touch/click is on player var dx = x - player.x; var dy = y - player.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 100) { dragPlayer = true; lastPlayerPos.x = player.x; lastPlayerPos.y = player.y; handleMove(x, y, obj); } }; game.move = function (x, y, obj) { handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragPlayer = false; }; // --- Puzzle Interaction --- function trySolvePuzzle() { if (!puzzleObj || puzzleObj.solved) return; // Simple puzzle: tap puzzle to solve puzzleObj.solved = true; puzzleSolved = true; messageTxt.setText("Puzzle solved!\nThe door unlocked."); // Unlock door if (doorObj && doorObj.locked) { doorObj.unlock(); } // Animate puzzle fade out tween(puzzleObj, { alpha: 0 }, { duration: 800, onFinish: function onFinish() { puzzleObj.destroy(); } }); LK.setTimeout(function () { messageTxt.setText(''); }, 1500); } // --- Door Interaction --- function tryOpenDoor() { if (!doorObj) return; if (doorObj.locked) { messageTxt.setText("The door is locked."); LK.setTimeout(function () { messageTxt.setText(''); }, 1200); } else { // Go to next floor or win if (currentFloor === 0) { // Go upstairs currentFloor = 1; setupFloor(1); player.x = 2048 / 2; player.y = 2732 - 700; updateFloorText(); messageTxt.setText("You ascend to the next floor..."); LK.setTimeout(function () { messageTxt.setText(''); }, 1200); } else { // Win! LK.showYouWin(); } } } // --- Enemy (Ghost) Collision --- function checkGhostCollision() { if (!ghostObj) return; var dx = player.x - ghostObj.x; var dy = player.y - ghostObj.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 90) { // Game over gameOver = true; player.canMove = false; messageTxt.setText("A ghost caught you!"); LK.effects.flashScreen(0x990000, 1200); LK.setTimeout(function () { LK.showGameOver(); }, 1200); } } // --- Main Game Update --- game.update = function () { if (gameOver) return; // Ghost patrol if (ghostObj && ghostObj.update) ghostObj.update(); // Check for puzzle interaction if (puzzleObj && !puzzleObj.solved) { var dx = player.x - puzzleObj.x; var dy = player.y - puzzleObj.y; if (Math.sqrt(dx * dx + dy * dy) < 100 && dragPlayer) { trySolvePuzzle(); } } // Check for door interaction if (doorObj) { var dx = player.x - doorObj.x; var dy = player.y - doorObj.y; if (Math.abs(dx) < 80 && Math.abs(dy) < 80 && dragPlayer) { if (doorObj.locked) { tryOpenDoor(); } else { // Move player through the door (to the other side of the door) if (currentFloor === 0) { // Go upstairs currentFloor = 1; setupFloor(1); player.x = 2048 / 2; player.y = 2732 - 700; updateFloorText(); messageTxt.setText("You ascend to the next floor..."); LK.setTimeout(function () { messageTxt.setText(''); }, 1200); } else { // Move player to one floor down (go back to floor 0) currentFloor = 0; setupFloor(0); player.x = 2048 / 2; player.y = 2732 - 700; updateFloorText(); messageTxt.setText("You descend to the previous floor..."); LK.setTimeout(function () { messageTxt.setText(''); }, 1200); } } } } // Check for ghost collision checkGhostCollision(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Door class
var Door = Container.expand(function () {
var self = Container.call(this);
self.locked = true;
self.doorAsset = self.attachAsset('door_locked', {
anchorX: 0.5,
anchorY: 0.5
});
self.unlock = function () {
self.locked = false;
self.doorAsset.destroy();
self.doorAsset = self.attachAsset('door_unlocked', {
anchorX: 0.5,
anchorY: 0.5
});
};
return self;
});
// Enemy (ghost) class
var Ghost = Container.expand(function () {
var self = Container.call(this);
self.attachAsset('ghost', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.direction = 1; // 1: right, -1: left
self.update = function () {
self.x += self.speed * self.direction;
// Bounce off walls (simple horizontal patrol)
if (self.x < 300) self.direction = 1;
if (self.x > 2048 - 300) self.direction = -1;
};
return self;
});
// Player class
var Player = Container.expand(function () {
var self = Container.call(this);
self.asset = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.canMove = true;
self.moveTo = function (x, y) {
if (!self.canMove) return;
// Clamp to game area
var px = Math.max(60, Math.min(2048 - 60, x));
var py = Math.max(60, Math.min(2732 - 60, y));
self.x = px;
self.y = py;
};
return self;
});
// Puzzle class
var Puzzle = Container.expand(function () {
var self = Container.call(this);
self.solved = false;
self.attachAsset('puzzle', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
// Wall class
var Wall = Container.expand(function () {
var self = Container.call(this);
var wallAsset = self.attachAsset('wall', {
anchorX: 0.5,
anchorY: 0.5
});
self.isSolid = true;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181818
});
/****
* Game Code
****/
// Enemy (ghost)
// Puzzle object
// Key
// Door (unlocked)
// Door (locked)
// Wall
// Player
// --- Game State ---
var currentFloor = 0; // 0: ground, 1: upstairs
var floors = [];
var player;
var dragPlayer = false;
var lastPlayerPos = {
x: 0,
y: 0
};
var keyObj = null;
var doorObj = null;
var puzzleObj = null;
var ghostObj = null;
var messageTxt = null;
var floorTxt = null;
var puzzleSolved = false;
var gameOver = false;
// --- Room/Floor Layouts ---
function createFloor0() {
// Floor 5: Four rooms, each with different shape and size, combined together
var floor = {
walls: [],
doors: [],
keys: [],
puzzles: [],
enemies: []
};
// --- Room 1: Large Rectangle (Top Left) ---
// Top wall
var wallR1Top = new Wall();
wallR1Top.x = 350;
wallR1Top.y = 200;
wallR1Top.width = 600;
wallR1Top.height = 60;
floor.walls.push(wallR1Top);
// Left wall
var wallR1Left = new Wall();
wallR1Left.x = 70;
wallR1Left.y = 500;
wallR1Left.width = 60;
wallR1Left.height = 600;
floor.walls.push(wallR1Left);
// Bottom wall
var wallR1Bottom = new Wall();
wallR1Bottom.x = 350;
wallR1Bottom.y = 800;
wallR1Bottom.width = 600;
wallR1Bottom.height = 60;
floor.walls.push(wallR1Bottom);
// Right wall (shared with Room 2, has a door)
var wallR1RightA = new Wall();
wallR1RightA.x = 650;
wallR1RightA.y = 470;
wallR1RightA.width = 60;
wallR1RightA.height = 200;
floor.walls.push(wallR1RightA);
var wallR1RightB = new Wall();
wallR1RightB.x = 650;
wallR1RightB.y = 730;
wallR1RightB.width = 60;
wallR1RightB.height = 200;
floor.walls.push(wallR1RightB);
// --- Room 2: Tall Rectangle (Top Right) ---
// Top wall
var wallR2Top = new Wall();
wallR2Top.x = 1200;
wallR2Top.y = 200;
wallR2Top.width = 600;
wallR2Top.height = 60;
floor.walls.push(wallR2Top);
// Right wall
var wallR2Right = new Wall();
wallR2Right.x = 1550;
wallR2Right.y = 600;
wallR2Right.width = 60;
wallR2Right.height = 800;
floor.walls.push(wallR2Right);
// Bottom wall (shared with Room 3, has a door)
var wallR2BottomA = new Wall();
wallR2BottomA.x = 1200;
wallR2BottomA.y = 1000;
wallR2BottomA.width = 250;
wallR2BottomA.height = 60;
floor.walls.push(wallR2BottomA);
var wallR2BottomB = new Wall();
wallR2BottomB.x = 1450;
wallR2BottomB.y = 1000;
wallR2BottomB.width = 250;
wallR2BottomB.height = 60;
floor.walls.push(wallR2BottomB);
// Left wall (shared with Room 1, has a door)
var wallR2LeftA = new Wall();
wallR2LeftA.x = 850;
wallR2LeftA.y = 470;
wallR2LeftA.width = 60;
wallR2LeftA.height = 200;
floor.walls.push(wallR2LeftA);
var wallR2LeftB = new Wall();
wallR2LeftB.x = 850;
wallR2LeftB.y = 730;
wallR2LeftB.width = 60;
wallR2LeftB.height = 200;
floor.walls.push(wallR2LeftB);
// --- Room 3: Square (Bottom Right) ---
// Top wall (shared with Room 2, has a door)
var wallR3TopA = new Wall();
wallR3TopA.x = 1200;
wallR3TopA.y = 1200;
wallR3TopA.width = 250;
wallR3TopA.height = 60;
floor.walls.push(wallR3TopA);
var wallR3TopB = new Wall();
wallR3TopB.x = 1450;
wallR3TopB.y = 1200;
wallR3TopB.width = 250;
wallR3TopB.height = 60;
floor.walls.push(wallR3TopB);
// Right wall
var wallR3Right = new Wall();
wallR3Right.x = 1550;
wallR3Right.y = 1500;
wallR3Right.width = 60;
wallR3Right.height = 600;
floor.walls.push(wallR3Right);
// Bottom wall
var wallR3Bottom = new Wall();
wallR3Bottom.x = 1200;
wallR3Bottom.y = 1800;
wallR3Bottom.width = 600;
wallR3Bottom.height = 60;
floor.walls.push(wallR3Bottom);
// Left wall (shared with Room 4, has a door)
var wallR3LeftA = new Wall();
wallR3LeftA.x = 850;
wallR3LeftA.y = 1400;
wallR3LeftA.width = 60;
wallR3LeftA.height = 200;
floor.walls.push(wallR3LeftA);
var wallR3LeftB = new Wall();
wallR3LeftB.x = 850;
wallR3LeftB.y = 1700;
wallR3LeftB.width = 60;
wallR3LeftB.height = 200;
floor.walls.push(wallR3LeftB);
// --- Room 4: L-Shape (Bottom Left) ---
// Top wall
var wallR4Top = new Wall();
wallR4Top.x = 350;
wallR4Top.y = 1200;
wallR4Top.width = 600;
wallR4Top.height = 60;
floor.walls.push(wallR4Top);
// Left wall
var wallR4Left = new Wall();
wallR4Left.x = 70;
wallR4Left.y = 1500;
wallR4Left.width = 60;
wallR4Left.height = 600;
floor.walls.push(wallR4Left);
// Bottom wall
var wallR4Bottom = new Wall();
wallR4Bottom.x = 350;
wallR4Bottom.y = 1800;
wallR4Bottom.width = 600;
wallR4Bottom.height = 60;
floor.walls.push(wallR4Bottom);
// Right wall (shared with Room 3, has a door)
var wallR4RightA = new Wall();
wallR4RightA.x = 650;
wallR4RightA.y = 1400;
wallR4RightA.width = 60;
wallR4RightA.height = 200;
floor.walls.push(wallR4RightA);
var wallR4RightB = new Wall();
wallR4RightB.x = 650;
wallR4RightB.y = 1700;
wallR4RightB.width = 60;
wallR4RightB.height = 200;
floor.walls.push(wallR4RightB);
// --- Doors between rooms ---
// Door between Room 1 and Room 2 (top horizontal)
var door1 = new Door();
door1.x = 750;
door1.y = 470;
floor.doors.push(door1);
// Door between Room 2 and Room 3 (vertical)
var door2 = new Door();
door2.x = 1200;
door2.y = 1100;
floor.doors.push(door2);
// Door between Room 3 and Room 4 (bottom horizontal)
var door3 = new Door();
door3.x = 750;
door3.y = 1700;
floor.doors.push(door3);
// Door between Room 4 and Room 1 (vertical)
var door4 = new Door();
door4.x = 350;
door4.y = 1000;
floor.doors.push(door4);
// --- Puzzle in Room 3 (bottom right) ---
var puzzle = new Puzzle();
puzzle.x = 1400;
puzzle.y = 1600;
floor.puzzles.push(puzzle);
// --- Ghost in Room 2 (top right) ---
var ghost = new Ghost();
ghost.x = 1300;
ghost.y = 600;
floor.enemies.push(ghost);
return floor;
}
function createFloor1() {
// Upstairs: 1 room, exit door (unlocked if puzzle solved), 1 ghost
var floor = {
walls: [],
doors: [],
keys: [],
puzzles: [],
enemies: []
};
// Walls (rectangle room)
var wallTop = new Wall();
wallTop.x = 2048 / 2;
wallTop.y = 400;
wallTop.width = 1600;
wallTop.height = 60;
floor.walls.push(wallTop);
var wallBottom = new Wall();
wallBottom.x = 2048 / 2;
wallBottom.y = 2732 - 400;
wallBottom.width = 1600;
wallBottom.height = 60;
floor.walls.push(wallBottom);
var wallLeft = new Wall();
wallLeft.x = 300;
wallLeft.y = 2732 / 2;
wallLeft.width = 60;
wallLeft.height = 1800;
floor.walls.push(wallLeft);
var wallRight = new Wall();
wallRight.x = 2048 - 300;
wallRight.y = 2732 / 2;
wallRight.width = 60;
wallRight.height = 1800;
floor.walls.push(wallRight);
// Exit Door (top center, unlocked if puzzle solved)
var door = new Door();
door.x = 2048 / 2;
door.y = 400;
door.locked = false;
door.doorAsset.destroy();
door.doorAsset = door.attachAsset('door_unlocked', {
anchorX: 0.5,
anchorY: 0.5
});
floor.doors.push(door);
// Puzzle in the center of the room
var puzzle = new Puzzle();
puzzle.x = 2048 / 2;
puzzle.y = 2732 / 2;
floor.puzzles.push(puzzle);
// Ghost (patrols horizontally)
var ghost = new Ghost();
ghost.x = 2048 / 2;
ghost.y = 1200;
floor.enemies.push(ghost);
return floor;
}
// --- Helper Functions ---
function clearFloor() {
// Remove all objects from game
if (floors[currentFloor]) {
var f = floors[currentFloor];
for (var i = 0; i < f.walls.length; ++i) f.walls[i].destroy();
for (var i = 0; i < f.doors.length; ++i) f.doors[i].destroy();
for (var i = 0; i < f.keys.length; ++i) f.keys[i].destroy();
for (var i = 0; i < f.puzzles.length; ++i) f.puzzles[i].destroy();
for (var i = 0; i < f.enemies.length; ++i) f.enemies[i].destroy();
}
if (doorObj) {
if (typeof doorObj.destroy === "function") {
doorObj.destroy();
}
doorObj = null;
}
if (puzzleObj) {
if (typeof puzzleObj.destroy === "function") {
puzzleObj.destroy();
}
puzzleObj = null;
}
if (ghostObj) {
ghostObj.destroy();
ghostObj = null;
}
}
function setupFloor(floorNum) {
clearFloor();
var f = floors[floorNum];
// Add walls
for (var i = 0; i < f.walls.length; ++i) game.addChild(f.walls[i]);
// Add doors
for (var i = 0; i < f.doors.length; ++i) game.addChild(f.doors[i]);
// Add puzzles
for (var i = 0; i < f.puzzles.length; ++i) game.addChild(f.puzzles[i]);
// Add enemies
for (var i = 0; i < f.enemies.length; ++i) game.addChild(f.enemies[i]);
// For easy reference
doorObj = f.doors.length ? f.doors[0] : null;
keyObj = null;
puzzleObj = f.puzzles.length ? f.puzzles[0] : null;
ghostObj = f.enemies.length ? f.enemies[0] : null;
}
// --- GUI ---
messageTxt = new Text2('', {
size: 90,
fill: 0xFFCCCC
});
messageTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(messageTxt);
floorTxt = new Text2('Floor 1', {
size: 70,
fill: 0xCCCCFF
});
floorTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(floorTxt);
// --- Game Setup ---
floors[0] = createFloor0();
floors[1] = createFloor1();
player = new Player();
player.x = 2048 / 2;
player.y = 2732 - 700;
game.addChild(player);
setupFloor(0);
updateFloorText();
function updateFloorText() {
floorTxt.setText('Floor 5');
}
// --- Movement & Controls ---
function canMoveTo(x, y) {
// Check collision with walls
var f = floors[currentFloor];
for (var i = 0; i < f.walls.length; ++i) {
var wall = f.walls[i];
// Simple AABB collision
var dx = Math.abs(x - wall.x);
var dy = Math.abs(y - wall.y);
if (dx < wall.width / 2 + 60 && dy < wall.height / 2 + 60) {
return false;
}
}
return true;
}
function handleMove(x, y, obj) {
if (gameOver) return;
if (!dragPlayer) return;
// Clamp to game area
var px = Math.max(60, Math.min(2048 - 60, x));
var py = Math.max(60, Math.min(2732 - 60, y));
// Only move if not colliding with wall
if (canMoveTo(px, py)) {
player.moveTo(px, py);
}
}
game.down = function (x, y, obj) {
if (gameOver) return;
// Only start drag if touch/click is on player
var dx = x - player.x;
var dy = y - player.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 100) {
dragPlayer = true;
lastPlayerPos.x = player.x;
lastPlayerPos.y = player.y;
handleMove(x, y, obj);
}
};
game.move = function (x, y, obj) {
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragPlayer = false;
};
// --- Puzzle Interaction ---
function trySolvePuzzle() {
if (!puzzleObj || puzzleObj.solved) return;
// Simple puzzle: tap puzzle to solve
puzzleObj.solved = true;
puzzleSolved = true;
messageTxt.setText("Puzzle solved!\nThe door unlocked.");
// Unlock door
if (doorObj && doorObj.locked) {
doorObj.unlock();
}
// Animate puzzle fade out
tween(puzzleObj, {
alpha: 0
}, {
duration: 800,
onFinish: function onFinish() {
puzzleObj.destroy();
}
});
LK.setTimeout(function () {
messageTxt.setText('');
}, 1500);
}
// --- Door Interaction ---
function tryOpenDoor() {
if (!doorObj) return;
if (doorObj.locked) {
messageTxt.setText("The door is locked.");
LK.setTimeout(function () {
messageTxt.setText('');
}, 1200);
} else {
// Go to next floor or win
if (currentFloor === 0) {
// Go upstairs
currentFloor = 1;
setupFloor(1);
player.x = 2048 / 2;
player.y = 2732 - 700;
updateFloorText();
messageTxt.setText("You ascend to the next floor...");
LK.setTimeout(function () {
messageTxt.setText('');
}, 1200);
} else {
// Win!
LK.showYouWin();
}
}
}
// --- Enemy (Ghost) Collision ---
function checkGhostCollision() {
if (!ghostObj) return;
var dx = player.x - ghostObj.x;
var dy = player.y - ghostObj.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 90) {
// Game over
gameOver = true;
player.canMove = false;
messageTxt.setText("A ghost caught you!");
LK.effects.flashScreen(0x990000, 1200);
LK.setTimeout(function () {
LK.showGameOver();
}, 1200);
}
}
// --- Main Game Update ---
game.update = function () {
if (gameOver) return;
// Ghost patrol
if (ghostObj && ghostObj.update) ghostObj.update();
// Check for puzzle interaction
if (puzzleObj && !puzzleObj.solved) {
var dx = player.x - puzzleObj.x;
var dy = player.y - puzzleObj.y;
if (Math.sqrt(dx * dx + dy * dy) < 100 && dragPlayer) {
trySolvePuzzle();
}
}
// Check for door interaction
if (doorObj) {
var dx = player.x - doorObj.x;
var dy = player.y - doorObj.y;
if (Math.abs(dx) < 80 && Math.abs(dy) < 80 && dragPlayer) {
if (doorObj.locked) {
tryOpenDoor();
} else {
// Move player through the door (to the other side of the door)
if (currentFloor === 0) {
// Go upstairs
currentFloor = 1;
setupFloor(1);
player.x = 2048 / 2;
player.y = 2732 - 700;
updateFloorText();
messageTxt.setText("You ascend to the next floor...");
LK.setTimeout(function () {
messageTxt.setText('');
}, 1200);
} else {
// Move player to one floor down (go back to floor 0)
currentFloor = 0;
setupFloor(0);
player.x = 2048 / 2;
player.y = 2732 - 700;
updateFloorText();
messageTxt.setText("You descend to the previous floor...");
LK.setTimeout(function () {
messageTxt.setText('');
}, 1200);
}
}
}
}
// Check for ghost collision
checkGhostCollision();
};