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; }); // Key class var Key = Container.expand(function () { var self = Container.call(this); self.attachAsset('key', { anchorX: 0.5, anchorY: 0.5 }); 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.hasKey = false; 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() { // Ground floor: 1 room, 1 locked door, 1 key, 1 puzzle, 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); // Door (top center) var door = new Door(); door.x = 2048 / 2; door.y = 400; floor.doors.push(door); // Key (bottom left) var key = new Key(); key.x = 500; key.y = 2732 - 600; floor.keys.push(key); // Puzzle (bottom right) var puzzle = new Puzzle(); puzzle.x = 2048 - 500; puzzle.y = 2732 - 600; floor.puzzles.push(puzzle); // Ghost (patrols horizontally) var ghost = new Ghost(); ghost.x = 2048 / 2; ghost.y = 1200; 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 (keyObj) { if (keyObj && typeof keyObj.destroy === "function") { keyObj.destroy(); } keyObj = null; } 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 keys for (var i = 0; i < f.keys.length; ++i) game.addChild(f.keys[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 = f.keys.length ? f.keys[0] : 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.topRight.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 ' + (currentFloor + 1)); } // --- 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); } // --- Key Pickup --- function tryPickupKey() { if (!keyObj) return; player.hasKey = true; messageTxt.setText("You found a key!"); tween(keyObj, { alpha: 0 }, { duration: 600, onFinish: function onFinish() { keyObj.destroy(); keyObj = null; } }); LK.setTimeout(function () { messageTxt.setText(''); }, 1200); } // --- Door Interaction --- function tryOpenDoor() { if (!doorObj) return; if (doorObj.locked) { if (player.hasKey) { doorObj.unlock(); messageTxt.setText("You unlocked the door!"); LK.setTimeout(function () { messageTxt.setText(''); }, 1200); } else { 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 key pickup if (keyObj) { var dx = player.x - keyObj.x; var dy = player.y - keyObj.y; if (Math.sqrt(dx * dx + dy * dy) < 90) { tryPickupKey(); } } // 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) { tryOpenDoor(); } } // Check for ghost collision checkGhostCollision(); };
===================================================================
--- original.js
+++ change.js
@@ -244,9 +244,9 @@
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 (keyObj) {
- if (typeof keyObj.destroy === "function") {
+ if (keyObj && typeof keyObj.destroy === "function") {
keyObj.destroy();
}
keyObj = null;
}