User prompt
spawn puzzle
User prompt
make four rooms with each different shape and size but combined together
User prompt
set floor5 as level
User prompt
rooms are horizontal
User prompt
add rooms to this level
User prompt
when I get out of the door move me to one floor down
User prompt
show floor in the upper middle
User prompt
name this level as floor 6
User prompt
open door when unlocked
User prompt
unlock door when puzzle solved
User prompt
remove the key asset
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'destroy')' in or related to this line: 'keyObj.destroy();' Line Number: 440
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'destroy')' in or related to this line: 'keyObj.destroy();' Line Number: 438
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'destroy')' in or related to this line: 'keyObj.destroy();' Line Number: 436
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'destroy')' in or related to this line: 'keyObj.destroy();' Line Number: 436
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'destroy')' in or related to this line: 'keyObj.destroy();' Line Number: 434
Code edit (1 edits merged)
Please save this source code
User prompt
Haunted Floors: Escape the House
Initial prompt
ı want to build a horror game that takes place in a house with multiple stories (floors) and we see the rooms from the top
/**** * 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); // 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(); };
===================================================================
--- original.js
+++ change.js