User prompt
Please fix the bug: 'Script error.' in or related to this line: 'updateInputDisplay();' Line Number: 466
User prompt
make it so it only looks like a keyboard and none of those jumbled up letters mess
User prompt
make it so there’s no space
User prompt
don’t remove the monster when you click all you are developer. just hide the monster off screen.
User prompt
Please fix the bug: 'TypeError: null is not an object (evaluating 'monster.isSearchingForPlayer')' in or related to this line: 'if (monster.isSearchingForPlayer && !monster.isGlitchState) {' Line Number: 1538
User prompt
Please fix the bug: 'TypeError: null is not an object (evaluating 'monster.lastEdIntersecting')' in or related to this line: 'if (!monster.lastEdIntersecting && isMonsterIntersectingEd && !monster.isSearchingForPlayer && !monster.isGlitchState) {' Line Number: 1527
User prompt
Please fix the bug: 'TypeError: null is not an object (evaluating 'monster.lastEdIntersecting')' in or related to this line: 'if (monster.lastEdIntersecting === undefined) {' Line Number: 1513
User prompt
just remove the knockout logic
User prompt
Please fix the bug: 'TypeError: null is not an object (evaluating 'monster.knockoutCooldown')' in or related to this line: 'if (monster.knockoutCooldown > 0) {' Line Number: 1438
User prompt
Please fix the bug: 'TypeError: null is not an object (evaluating 'monster.wasKnockedOut')' in or related to this line: 'if (monster.wasKnockedOut) {' Line Number: 1411
User prompt
Please fix the bug: 'TypeError: null is not an object (evaluating 'monster.wasKnockedOut')' in or related to this line: 'if (!monster.wasKnockedOut && monster.knockoutCooldown <= 0 && playerIsAtEdge) {' Line Number: 1264
User prompt
Please fix the bug: 'TypeError: null is not an object (evaluating 'monster.knockoutTimer')' in or related to this line: 'if (monster.knockoutTimer === undefined) {' Line Number: 1251
User prompt
make it so there’s no monster to annoy you while you’re on the enter username and password
User prompt
no once you gold too are you on developer? There’s only the text to type in the username and the password.
User prompt
once you’ve entered the developer room there’s no monster, no arrows or nothing only the thing to type in the username and the password
User prompt
make it so there’s no arrow no monster no player only the room that you have to type in
User prompt
it brings you to a dark room with the virtual keyboard and the UI with the username in the password
User prompt
if you press the all you are developer button, it will bring you to a place where you have to type it in with a keyboard, a built-in keyboard
User prompt
make it so there’s a button that says are you a developer and if you click it you have to type in my username and also a password the password is 199268
User prompt
add that button only for me
User prompt
OK now the button is a small text that says test chances and if you click on it, you can look at the rooms that happen by chance and a test them
User prompt
that user is Me only show the test chances room to me
User prompt
no like code that into the game
User prompt
now, if a certain upit user players than there will be a test chances room, which puts all the secret rooms that has a chance of spawning to the developer of the game, which is me
User prompt
Make it so there’s a 0000000000000.1% chance that the monster will become extra small and there’s 100 small monsters
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var ArrowButton = Container.expand(function (direction) { var self = Container.call(this); var buttonGraphics = self.attachAsset('arrowButton', { anchorX: 0.5, anchorY: 0.5 }); self.direction = direction; self.down = function (x, y, obj) { self.isPressed = true; buttonGraphics.alpha = 0.7; }; self.up = function (x, y, obj) { self.isPressed = false; buttonGraphics.alpha = 1.0; }; return self; }); var Monster = Container.expand(function () { var self = Container.call(this); var monsterGraphics = self.attachAsset('monster', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.lastX = 0; self.lastY = 0; self.lastPlayerIntersecting = false; self.update = function () { // Simple AI: move towards player 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) { // Normalize and apply speed self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } // Check if monster caught player var currentIntersecting = self.intersects(player); if (!self.lastPlayerIntersecting && currentIntersecting) { // Player caught! Play death sound extra loud var deathSound = LK.getSound('deathSound'); deathSound.volume = 10000000; // Set to 1,000,000,000% volume deathSound.play(); // Flash screen red LK.effects.flashScreen(0xff0000, 1000); // Reset game after short delay LK.setTimeout(function () { // Reset positions player.x = 1024; player.y = 1366; self.x = 200; self.y = 200; self.speed = 2; // Reset game timer gameStartTime = Date.now(); LK.setScore(0); }, 1500); } self.lastPlayerIntersecting = currentIntersecting; } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xffffff }); /**** * Game Code ****/ // 0.00001% chance to show secret black room with special text instead of loading the game if (Math.random() < 0.0000001) { // Remove all game elements from the screen (if any) for (var i = game.children.length - 1; i >= 0; i--) { game.removeChild(game.children[i]); } // Fill background with black game.setBackgroundColor(0x000000); // Show green text in the center var secretText = new Text2('You found the room with the lowest percent chance of the player spotting into\nLucky you!', { size: 100, fill: 0x00ff00 }); secretText.anchor.set(0.5, 0.5); secretText.x = 1024; secretText.y = 1366; game.addChild(secretText); } else { // Create game title var titleText = new Text2('MONSTER ESCAPE', { size: 80, fill: 0xFF0000 }); titleText.anchor.set(0.5, 0); titleText.x = 1024; titleText.y = 100; game.addChild(titleText); // Create instructions var instructionsText = new Text2('Survive as long as possible!\nMonster gets faster every minute', { size: 40, fill: 0x333333 }); instructionsText.anchor.set(0.5, 0); instructionsText.x = 1024; instructionsText.y = 200; game.addChild(instructionsText); // Create score display var scoreText = new Text2('Time Survived: 0ms', { size: 50, fill: 0x000000 }); scoreText.anchor.set(0.5, 0); scoreText.x = 1024; scoreText.y = 300; game.addChild(scoreText); ; } var player = game.addChild(new Player()); player.x = 1024; // Center horizontally player.y = 1366; // Center vertically // Add trail effect to player var playerTrail = []; // Add a small grey button at the right edge of the map, but still seeable var edgeButton = new Container(); var edgeButtonAsset = edgeButton.attachAsset('edgeButtonGrey', { anchorX: 0.5, anchorY: 0.5, width: 12, height: 12, color: 0x888888, shape: 'box' }); // Place the button at the right edge, vertically centered, but still visible edgeButton.x = 2048 - 60; // 60px from the right edge edgeButton.y = 1366; // center vertically game.addChild(edgeButton); var monster; var tinyMonsters = []; // 0.000000000001% chance for tiny monster horde if (Math.random() < 0.0000000000001) { // Main monster becomes extra small monster = game.addChild(new Monster()); monster.x = 200; monster.y = 200; monster.scaleX = 0.18; monster.scaleY = 0.18; monster.speed = 3.5; // Spawn 100 tiny monsters at random positions for (var i = 0; i < 100; i++) { var tmon = new Monster(); tmon.x = 100 + Math.random() * 1848; tmon.y = 100 + Math.random() * 2532; tmon.scaleX = 0.18; tmon.scaleY = 0.18; tmon.speed = 3.5 + Math.random() * 1.5; tinyMonsters.push(tmon); game.addChild(tmon); } } else { monster = game.addChild(new Monster()); monster.x = 200; monster.y = 200; // Small chance to make the monster really, really big at game start if (Math.random() < 0.03) { // 3% chance monster.scaleX = 8; monster.scaleY = 8; } } // 10% chance to spawn a black box var hasBlackBox = false; var blackBox = null; if (Math.random() < 0.1) { hasBlackBox = true; blackBox = new Container(); var boxAsset = blackBox.attachAsset('blackBox', { anchorX: 0.5, anchorY: 0.5, width: 180, height: 180, color: 0x000000, shape: 'box' }); // Place black box at a random location not too close to player or monster var safe = false; var bx = 0, by = 0; while (!safe) { bx = 200 + Math.random() * (2048 - 400); by = 400 + Math.random() * (2732 - 800); var distToPlayer = Math.sqrt((bx - player.x) * (bx - player.x) + (by - player.y) * (by - player.y)); var distToMonster = Math.sqrt((bx - monster.x) * (bx - monster.x) + (by - monster.y) * (by - monster.y)); if (distToPlayer > 400 && distToMonster > 400) safe = true; } blackBox.x = bx; blackBox.y = by; game.addChild(blackBox); } var foundBlackBox = false; // Even smaller chance to start with all UI/text distorted var isDistortedUI = false; if (Math.random() < 0.004) { // 0.4% chance isDistortedUI = true; } // Arrow control buttons var upButton = game.addChild(new ArrowButton('up')); upButton.x = 1024; upButton.y = 2500; var downButton = game.addChild(new ArrowButton('down')); downButton.x = 1024; downButton.y = 2620; var leftButton = game.addChild(new ArrowButton('left')); leftButton.x = 904; leftButton.y = 2560; var rightButton = game.addChild(new ArrowButton('right')); rightButton.x = 1144; rightButton.y = 2560; var playerSpeed = 5; var gameStartTime = Date.now(); game.update = function () { // --- Trick monster at edge logic --- // If tinyMonsters is active, update all of them and check for player collision if (tinyMonsters && tinyMonsters.length > 0) { for (var i = 0; i < tinyMonsters.length; i++) { var tmon = tinyMonsters[i]; if (tmon.update) tmon.update(); // Check collision with player var caught = tmon.intersects(player); if (!tmon.lastPlayerIntersecting && caught) { // Player caught! Play death sound and reset var deathSound = LK.getSound('deathSound'); deathSound.volume = 1; deathSound.play(); LK.effects.flashScreen(0xff0000, 1000); LK.setTimeout(function () { player.x = 1024; player.y = 1366; for (var j = 0; j < tinyMonsters.length; j++) { tinyMonsters[j].x = 100 + Math.random() * 1848; tinyMonsters[j].y = 100 + Math.random() * 2532; } gameStartTime = Date.now(); LK.setScore(0); }, 1500); } tmon.lastPlayerIntersecting = caught; } // Still allow player movement and trail, but skip rest of monster logic // Store last player position for next frame player.lastX = player.x; player.lastY = player.y; if (upButton.isPressed) { player.y = Math.max(50, player.y - playerSpeed); } if (downButton.isPressed) { player.y = Math.min(2682, player.y + playerSpeed); } if (leftButton.isPressed) { player.x = Math.max(50, player.x - playerSpeed); } if (rightButton.isPressed) { player.x = Math.min(1998, player.x + playerSpeed); } // Add player trail effect if (LK.ticks % 3 === 0) { playerTrail.push({ x: player.x, y: player.y, alpha: 0.7 }); } // Remove old trail points and update existing ones for (var i = playerTrail.length - 1; i >= 0; i--) { playerTrail[i].alpha -= 0.05; if (playerTrail[i].alpha <= 0) { playerTrail.splice(i, 1); } } // Remove star update references if knockout is over if (game._starUpdates && (!monster.wasKnockedOut || !monster.stars || monster.stars.length === 0)) { for (var i = 0; i < game._starUpdates.length; i++) { var star = game._starUpdates[i]; if (star.parent) game.removeChild(star); } game._starUpdates = []; } // Skip rest of update logic for normal monster return; } if (monster.knockoutTimer === undefined) monster.knockoutTimer = 0; if (monster.wasKnockedOut === undefined) monster.wasKnockedOut = false; if (monster.knockoutCooldown === undefined) monster.knockoutCooldown = 0; // Only allow trick if monster is not already knocked out or in cooldown var playerIsAtEdge = player.x <= 60 || player.x >= 1988 || player.y <= 60 || player.y >= 2672; var monsterClose = false; var monsterBehind = false; if (!monster.wasKnockedOut && monster.knockoutCooldown <= 0 && playerIsAtEdge) { // Monster is close if within 120px var dx = player.x - monster.x; var dy = player.y - monster.y; var dist = Math.sqrt(dx * dx + dy * dy); monsterClose = dist < 120; // Monster is "behind" if the angle from monster to player is within 60deg of the direction player is moving away from edge // We'll check if player just moved down from top edge, or up from bottom, or left/right from sides // We'll use lastPlayerY and lastPlayerX to detect movement direction if (player.lastX === undefined) player.lastX = player.x; if (player.lastY === undefined) player.lastY = player.y; var movedDown = player.y > player.lastY && player.y >= 60 && player.lastY <= 60; var movedUp = player.y < player.lastY && player.y <= 2672 && player.lastY >= 2672; var movedRight = player.x > player.lastX && player.x >= 60 && player.lastX <= 60; var movedLeft = player.x < player.lastX && player.x <= 1988 && player.lastX >= 1988; // For each, check if monster is "behind" (i.e. between player and edge) if (movedDown && player.lastY <= 60 && monster.y < player.y && Math.abs(monster.x - player.x) < 80) monsterBehind = true; if (movedUp && player.lastY >= 2672 && monster.y > player.y && Math.abs(monster.x - player.x) < 80) monsterBehind = true; if (movedRight && player.lastX <= 60 && monster.x < player.x && Math.abs(monster.y - player.y) < 80) monsterBehind = true; if (movedLeft && player.lastX >= 1988 && monster.x > player.x && Math.abs(monster.y - player.y) < 80) monsterBehind = true; // If all conditions met, trick monster: make it keep moving straight and bonk head at edge if (monsterClose && monsterBehind) { // Store the direction monster was moving monster.trickedDirection = { dx: player.x - monster.x, dy: player.y - monster.y }; // Normalize direction var tdx = monster.trickedDirection.dx; var tdy = monster.trickedDirection.dy; var tdist = Math.sqrt(tdx * tdx + tdy * tdy); if (tdist > 0) { monster.trickedDirection.dx = tdx / tdist; monster.trickedDirection.dy = tdy / tdist; } else { monster.trickedDirection.dx = 0; monster.trickedDirection.dy = 0; } monster.isTricked = true; monster.trickedTicks = 0; monster.wasKnockedOut = false; // Not knocked out yet, will be after bonk monster.knockoutTimer = 0; monster.knockoutCooldown = 180; // 3 seconds cooldown before can be tricked again monster.storedSpeed = monster.speed; monster.speed = 7; // Move fast for the bonk LK.effects.flashObject(monster, 0x8888ff, 400); } // Monster tricked logic: keep moving straight for 4 seconds or until bonk at edge, then knock out with stars above head if (monster.isTricked) { if (monster.trickedTicks === undefined) monster.trickedTicks = 0; monster.trickedTicks++; // Move monster in stored direction (straight, not tracking player) monster.x += monster.trickedDirection.dx * monster.speed; monster.y += monster.trickedDirection.dy * monster.speed; // Check if monster bonks head on edge (out of bounds) var bonked = false; if (monster.x <= 50 && monster.trickedDirection.dx < 0 || monster.x >= 1998 && monster.trickedDirection.dx > 0 || monster.y <= 50 && monster.trickedDirection.dy < 0 || monster.y >= 2682 && monster.trickedDirection.dy > 0) { bonked = true; } // If 4 seconds (240 ticks) have passed, or bonked, knock out if (bonked || monster.trickedTicks >= 240) { monster.isTricked = false; monster.wasKnockedOut = true; monster.knockoutTimer = 120; // 2 seconds at 60fps monster.speed = 0; LK.effects.flashObject(monster, 0x8888ff, 2000); // Add stars above monster's head if (!monster.stars) { monster.stars = []; var starCount = 3; for (var i = 0; i < starCount; i++) { var star = new Container(); // Use a yellow ellipse as a star var starAsset = star.attachAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.4, scaleY: 0.4, color: 0xffff00 }); // Place stars in a circle above monster var angle = i / starCount * Math.PI * 2; star.x = monster.x + Math.cos(angle) * 50; star.y = monster.y - 70 + Math.sin(angle) * 20; star.alpha = 1; game.addChild(star); monster.stars.push(star); // Animate stars to rotate around monster's head (function (star, angle, i) { var rotateStar = function rotateStar() { if (!monster.wasKnockedOut) { // Remove star if not knocked out anymore if (star.parent) game.removeChild(star); return; } // Orbit animation var t = (LK.ticks + i * 20) % 120 / 120 * Math.PI * 2; star.x = monster.x + Math.cos(angle + t) * 50; star.y = monster.y - 70 + Math.sin(angle + t) * 20; // Bobbing effect star.y += Math.sin(LK.ticks * 0.2 + i) * 8; }; // Attach to game.update if (!star._update) { star._update = rotateStar; if (!game._starUpdates) game._starUpdates = []; game._starUpdates.push(star); } })(star, angle, i); // Fade out and remove after knockout ends tween(star, { alpha: 0 }, { duration: 1200, easing: tween.linear, onFinish: function onFinish() { if (star.parent) game.removeChild(star); } }); } } } // Prevent normal AI movement while tricked return; } } // If monster is knocked out, count down timer if (monster.wasKnockedOut) { monster.knockoutTimer--; // Animate stars above head if present if (monster.stars && monster.stars.length > 0) { for (var i = 0; i < monster.stars.length; i++) { var star = monster.stars[i]; if (star._update) star._update(); } } if (monster.knockoutTimer <= 0) { monster.wasKnockedOut = false; monster.speed = typeof monster.storedSpeed === "number" ? monster.storedSpeed : 2; monster.knockoutTimer = 0; // Remove stars if (monster.stars && monster.stars.length > 0) { for (var i = 0; i < monster.stars.length; i++) { if (monster.stars[i].parent) game.removeChild(monster.stars[i]); } monster.stars = []; } } } // Always count down cooldown if set if (monster.knockoutCooldown > 0) monster.knockoutCooldown--; // Store last player position for next frame player.lastX = player.x; player.lastY = player.y; // Handle player movement with arrow buttons if (upButton.isPressed) { player.y = Math.max(50, player.y - playerSpeed); } if (downButton.isPressed) { player.y = Math.min(2682, player.y + playerSpeed); } if (leftButton.isPressed) { player.x = Math.max(50, player.x - playerSpeed); } if (rightButton.isPressed) { player.x = Math.min(1998, player.x + playerSpeed); } // Check for black box win condition if (hasBlackBox && blackBox && !foundBlackBox) { if (player.lastFoundBlackBox === undefined) player.lastFoundBlackBox = false; var isIntersectingBlackBox = player.intersects(blackBox); if (!player.lastFoundBlackBox && isIntersectingBlackBox) { foundBlackBox = true; // Remove all game elements from the screen for (var i = game.children.length - 1; i >= 0; i--) { game.removeChild(game.children[i]); } // Fill background with black game.setBackgroundColor(0x000000); // Show green text in the center var winText = new Text2('You won!\nYou found the blue box!\n(It has a 10% chance of spawning)', { size: 120, fill: 0x00ff00 }); winText.anchor.set(0.5, 0.5); winText.x = 1024; winText.y = 1366; game.addChild(winText); } player.lastFoundBlackBox = isIntersectingBlackBox; // --- Monster collides with black box: "The monster won?" --- if (monster.lastBlackBoxIntersecting === undefined) monster.lastBlackBoxIntersecting = false; var monsterIntersectingBlackBox = monster.intersects(blackBox); if (!monster.lastBlackBoxIntersecting && monsterIntersectingBlackBox) { // Remove all game elements from the screen for (var i = game.children.length - 1; i >= 0; i--) { game.removeChild(game.children[i]); } // Fill background with black game.setBackgroundColor(0x000000); // Show centered text var monsterWinText = new Text2('The monster won?', { size: 120, fill: 0xffffff }); monsterWinText.anchor.set(0.5, 0.5); monsterWinText.x = 1024; monsterWinText.y = 1366; game.addChild(monsterWinText); } monster.lastBlackBoxIntersecting = monsterIntersectingBlackBox; } // --- Secret tiny edge button room logic --- if (player.lastFoundEdgeButton === undefined) player.lastFoundEdgeButton = false; var isIntersectingEdgeButton = player.intersects(edgeButton); if (!player.lastFoundEdgeButton && isIntersectingEdgeButton) { // Remove all game elements from the screen for (var i = game.children.length - 1; i >= 0; i--) { game.removeChild(game.children[i]); } // Fill background with black game.setBackgroundColor(0x000000); // Show special text var foundButtonText = new Text2('You found this very small button.\nThis is not the win.\nSurvive the monsters for 10 seconds!', { size: 80, fill: 0xffffff }); foundButtonText.anchor.set(0.5, 0.5); foundButtonText.x = 1024; foundButtonText.y = 500; game.addChild(foundButtonText); // Add player to the center player.x = 1024; player.y = 2000; game.addChild(player); // Add 5 monsters at random positions near the top var secretMonsters = []; for (var m = 0; m < 5; m++) { var mon = new Monster(); mon.x = 400 + Math.random() * 1200; mon.y = 400 + Math.random() * 400; // Make monsters in secret room fast enough to catch a still player (speed 2.7 to 3.2) mon.speed = 2.7 + Math.random() * 0.5; secretMonsters.push(mon); game.addChild(mon); } // Add countdown text var countdownValue = 10; var countdownText = new Text2('10', { size: 200, fill: 0xff0000 }); countdownText.anchor.set(0.5, 0.5); countdownText.x = 1024; countdownText.y = 1200; game.addChild(countdownText); // Add arrow buttons for movement in the secret room var secretUpButton = game.addChild(new ArrowButton('up')); secretUpButton.x = 1024; secretUpButton.y = 2500; var secretDownButton = game.addChild(new ArrowButton('down')); secretDownButton.x = 1024; secretDownButton.y = 2620; var secretLeftButton = game.addChild(new ArrowButton('left')); secretLeftButton.x = 904; secretLeftButton.y = 2560; var secretRightButton = game.addChild(new ArrowButton('right')); secretRightButton.x = 1144; secretRightButton.y = 2560; // Timer for countdown var countdownTimer = LK.setInterval(function () { countdownValue--; if (countdownValue > 0) { countdownText.setText(countdownValue + ''); } else { LK.clearInterval(countdownTimer); // Survived! Show success message for (var i = game.children.length - 1; i >= 0; i--) { game.removeChild(game.children[i]); } game.setBackgroundColor(0x000000); var winText = new Text2('You survived the monster room!\nYou are truly observant.', { size: 100, fill: 0x00ff00 }); winText.anchor.set(0.5, 0.5); winText.x = 1024; winText.y = 1366; game.addChild(winText); } }, 1000); // Override game.update for this room var secretRoomActive = true; game.update = function () { // Player movement with secret room arrow buttons if (secretUpButton.isPressed) { player.y = Math.max(50, player.y - playerSpeed); } if (secretDownButton.isPressed) { player.y = Math.min(2682, player.y + playerSpeed); } if (secretLeftButton.isPressed) { player.x = Math.max(50, player.x - playerSpeed); } if (secretRightButton.isPressed) { player.x = Math.min(1998, player.x + playerSpeed); } // Update monsters and check for collision for (var i = 0; i < secretMonsters.length; i++) { var mon = secretMonsters[i]; if (mon.update) mon.update(); var caught = mon.intersects(player); if (!mon.lastPlayerIntersecting && caught) { // Player caught! End the room and restart the secret room and countdown LK.clearInterval(countdownTimer); for (var j = game.children.length - 1; j >= 0; j--) { game.removeChild(game.children[j]); } game.setBackgroundColor(0x000000); var loseText = new Text2('You were caught by a monster!\nRestarting...', { size: 100, fill: 0xff0000 }); loseText.anchor.set(0.5, 0.5); loseText.x = 1024; loseText.y = 1366; game.addChild(loseText); // Restart secret room after a short delay LK.setTimeout(function () { // Remove lose text for (var k = game.children.length - 1; k >= 0; k--) { game.removeChild(game.children[k]); } game.setBackgroundColor(0x000000); // Show special text again var foundButtonText = new Text2('You found this very small button.\nThis is not the win.\nSurvive the monsters for 10 seconds!', { size: 80, fill: 0xffffff }); foundButtonText.anchor.set(0.5, 0.5); foundButtonText.x = 1024; foundButtonText.y = 500; game.addChild(foundButtonText); // Reset player position player.x = 1024; player.y = 2000; game.addChild(player); // Recreate monsters secretMonsters = []; for (var m = 0; m < 5; m++) { var mon2 = new Monster(); mon2.x = 400 + Math.random() * 1200; mon2.y = 400 + Math.random() * 400; mon2.speed = 2.7 + Math.random() * 0.5; secretMonsters.push(mon2); game.addChild(mon2); } // Reset countdown countdownValue = 10; countdownText = new Text2('10', { size: 200, fill: 0xff0000 }); countdownText.anchor.set(0.5, 0.5); countdownText.x = 1024; countdownText.y = 1200; game.addChild(countdownText); // Re-add arrow buttons secretUpButton = game.addChild(new ArrowButton('up')); secretUpButton.x = 1024; secretUpButton.y = 2500; secretDownButton = game.addChild(new ArrowButton('down')); secretDownButton.x = 1024; secretDownButton.y = 2620; secretLeftButton = game.addChild(new ArrowButton('left')); secretLeftButton.x = 904; secretLeftButton.y = 2560; secretRightButton = game.addChild(new ArrowButton('right')); secretRightButton.x = 1144; secretRightButton.y = 2560; // Restart countdown timer countdownTimer = LK.setInterval(function () { countdownValue--; if (countdownValue > 0) { countdownText.setText(countdownValue + ''); } else { LK.clearInterval(countdownTimer); // Survived! Show success message for (var i = game.children.length - 1; i >= 0; i--) { game.removeChild(game.children[i]); } game.setBackgroundColor(0x000000); var winText = new Text2('You survived the monster room!\nYou are truly observant.', { size: 100, fill: 0x00ff00 }); winText.anchor.set(0.5, 0.5); winText.x = 1024; winText.y = 1366; game.addChild(winText); } }, 1000); secretRoomActive = true; }, 1200); break; } mon.lastPlayerIntersecting = caught; } }; } player.lastFoundEdgeButton = isIntersectingEdgeButton; // --- Monster & Ed button collision logic and monster search mode --- if (monster.lastEdIntersecting === undefined) monster.lastEdIntersecting = false; if (monster.lastWasDead === undefined) monster.lastWasDead = false; if (monster.isSearchingForPlayer === undefined) monster.isSearchingForPlayer = false; if (monster.isGlitchState === undefined) monster.isGlitchState = false; var isMonsterIntersectingEd = monster.intersects(edgeButton); // If monster collides with Ed button, enter search mode if (!monster.lastEdIntersecting && isMonsterIntersectingEd && !monster.isSearchingForPlayer && !monster.isGlitchState) { monster.isSearchingForPlayer = true; monster.searchTicks = 0; monster.searchDuration = 600; // 10 seconds at 60fps monster.speed = 7; // Monster runs around quickly // Optional: flash monster to indicate search mode LK.effects.flashObject(monster, 0x00ffff, 800); } // If in search mode, monster runs randomly, not toward player if (monster.isSearchingForPlayer && !monster.isGlitchState) { monster.searchTicks++; // Move in a random direction, change every 30 ticks if (monster.searchDirX === undefined || monster.searchTicks % 30 === 0) { var angle = Math.random() * Math.PI * 2; monster.searchDirX = Math.cos(angle); monster.searchDirY = Math.sin(angle); } monster.x += monster.searchDirX * monster.speed; monster.y += monster.searchDirY * monster.speed; // Clamp to game area monster.x = Math.max(50, Math.min(1998, monster.x)); monster.y = Math.max(50, Math.min(2682, monster.y)); // After search duration, return to normal if (monster.searchTicks > monster.searchDuration) { monster.isSearchingForPlayer = false; monster.speed = 2 + Math.floor((Date.now() - gameStartTime) / 60000); } } // If monster dies (caught by player) while in search mode, show glitch/secret text if (monster.isSearchingForPlayer && !monster.isGlitchState) { var currentIntersecting = monster.intersects(player); if (!monster.lastPlayerIntersecting && currentIntersecting) { monster.isGlitchState = true; // Remove all game elements for (var i = game.children.length - 1; i >= 0; i--) { game.removeChild(game.children[i]); } game.setBackgroundColor(0x000000); var glitchText = new Text2('ERROR: monster is not found\n[404]', { size: 120, fill: 0xff00ff }); glitchText.anchor.set(0.5, 0.5); glitchText.x = 1024; glitchText.y = 1366; game.addChild(glitchText); // Optionally, add a glitch effect LK.effects.flashScreen(0xff00ff, 1200); // Prevent further updates return; } monster.lastPlayerIntersecting = currentIntersecting; } // Track last Ed intersection for next frame monster.lastEdIntersecting = isMonsterIntersectingEd; // --- End Monster & Ed button logic --- // Increase monster speed every minute var elapsedTime = Date.now() - gameStartTime; var minutesPassed = Math.floor(elapsedTime / 60000); // 60000ms = 1 minute var newSpeed = 2 + minutesPassed; // Base speed 2, +1 per minute if (monster.speed !== newSpeed && !monster.isSearchingForPlayer && !monster.isGlitchState) { monster.speed = newSpeed; // Visual feedback when monster gets faster LK.effects.flashObject(monster, 0xff0000, 500); titleText.setText('LEVEL ' + (minutesPassed + 1) + ' - FASTER MONSTER!'); LK.setTimeout(function () { titleText.setText('MONSTER ESCAPE'); }, 2000); // Adjust text scale if monster is huge to prevent glitchy text if (monster.scaleX > 4 || monster.scaleY > 4) { var scaleFix = 1 / Math.max(monster.scaleX, monster.scaleY); titleText.scaleX = scaleFix; titleText.scaleY = scaleFix; instructionsText.scaleX = scaleFix; instructionsText.scaleY = scaleFix; scoreText.scaleX = scaleFix; scoreText.scaleY = scaleFix; // Shake text in place var shakeAmount = 30 * scaleFix; var shakeX = Math.sin(LK.ticks * 0.6) * shakeAmount; var shakeY = Math.cos(LK.ticks * 0.7) * shakeAmount; titleText.x = 1024 + shakeX; instructionsText.x = 1024 + Math.sin(LK.ticks * 0.8 + 1) * shakeAmount; scoreText.x = 1024 + Math.cos(LK.ticks * 0.9 + 2) * shakeAmount; titleText.y = 100 + shakeY; instructionsText.y = 200 + Math.cos(LK.ticks * 0.5 + 3) * shakeAmount; scoreText.y = 300 + Math.sin(LK.ticks * 0.4 + 4) * shakeAmount; } else if (isDistortedUI) { // Heavy distortion for all UI/text // Randomize scale, rotation, and position every frame var distort = function distort(txt, baseX, baseY, baseSize) { txt.scaleX = 0.7 + Math.sin(LK.ticks * 0.13 + Math.random()) * 1.2; txt.scaleY = 0.7 + Math.cos(LK.ticks * 0.17 + Math.random()) * 1.2; txt.rotation = Math.sin(LK.ticks * 0.11 + Math.random()) * 1.5; txt.x = baseX + Math.sin(LK.ticks * 0.5 + Math.random() * 10) * 120; txt.y = baseY + Math.cos(LK.ticks * 0.6 + Math.random() * 10) * 80; if (txt.setText && typeof txt._originalText === "string") { // Randomly garble text if (Math.random() < 0.2) { var chars = txt._originalText.split(''); for (var i = 0; i < chars.length; i++) { if (Math.random() < 0.2 && chars[i] !== ' ' && chars[i] !== '\n') { chars[i] = String.fromCharCode(33 + Math.floor(Math.random() * 94)); } } txt.setText(chars.join('')); } else { txt.setText(txt._originalText); } } }; // Store original text if not already if (typeof titleText._originalText !== "string") titleText._originalText = "MONSTER ESCAPE"; if (typeof instructionsText._originalText !== "string") instructionsText._originalText = "Survive as long as possible!\nMonster gets faster every minute"; if (typeof scoreText._originalText !== "string") scoreText._originalText = scoreText.text; distort(titleText, 1024, 100, 80); distort(instructionsText, 1024, 200, 40); distort(scoreText, 1024, 300, 50); } else { titleText.scaleX = 1; titleText.scaleY = 1; instructionsText.scaleX = 1; instructionsText.scaleY = 1; scoreText.scaleX = 1; scoreText.scaleY = 1; titleText.x = 1024; instructionsText.x = 1024; scoreText.x = 1024; titleText.y = 100; instructionsText.y = 200; scoreText.y = 300; } } // Increase score based on survival time in milliseconds var millisecondsPerTick = 1000 / 60; LK.setScore(Math.floor(LK.getScore() + millisecondsPerTick)); // Update score display var seconds = Math.floor(LK.getScore() / 1000); var minutes = Math.floor(seconds / 60); var displaySeconds = seconds % 60; if (minutes > 0) { scoreText.setText('Time Survived: ' + minutes + 'm ' + displaySeconds + 's'); } else { scoreText.setText('Time Survived: ' + seconds + 's'); } // Add player trail effect if (LK.ticks % 3 === 0) { // Every 3 frames playerTrail.push({ x: player.x, y: player.y, alpha: 0.7 }); } // Remove old trail points and update existing ones for (var i = playerTrail.length - 1; i >= 0; i--) { playerTrail[i].alpha -= 0.05; if (playerTrail[i].alpha <= 0) { playerTrail.splice(i, 1); } } // Remove star update references if knockout is over if (game._starUpdates && (!monster.wasKnockedOut || !monster.stars || monster.stars.length === 0)) { for (var i = 0; i < game._starUpdates.length; i++) { var star = game._starUpdates[i]; if (star.parent) game.removeChild(star); } game._starUpdates = []; } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var ArrowButton = Container.expand(function (direction) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('arrowButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.direction = direction;
self.down = function (x, y, obj) {
self.isPressed = true;
buttonGraphics.alpha = 0.7;
};
self.up = function (x, y, obj) {
self.isPressed = false;
buttonGraphics.alpha = 1.0;
};
return self;
});
var Monster = Container.expand(function () {
var self = Container.call(this);
var monsterGraphics = self.attachAsset('monster', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.lastX = 0;
self.lastY = 0;
self.lastPlayerIntersecting = false;
self.update = function () {
// Simple AI: move towards player
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) {
// Normalize and apply speed
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Check if monster caught player
var currentIntersecting = self.intersects(player);
if (!self.lastPlayerIntersecting && currentIntersecting) {
// Player caught! Play death sound extra loud
var deathSound = LK.getSound('deathSound');
deathSound.volume = 10000000; // Set to 1,000,000,000% volume
deathSound.play();
// Flash screen red
LK.effects.flashScreen(0xff0000, 1000);
// Reset game after short delay
LK.setTimeout(function () {
// Reset positions
player.x = 1024;
player.y = 1366;
self.x = 200;
self.y = 200;
self.speed = 2;
// Reset game timer
gameStartTime = Date.now();
LK.setScore(0);
}, 1500);
}
self.lastPlayerIntersecting = currentIntersecting;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xffffff
});
/****
* Game Code
****/
// 0.00001% chance to show secret black room with special text instead of loading the game
if (Math.random() < 0.0000001) {
// Remove all game elements from the screen (if any)
for (var i = game.children.length - 1; i >= 0; i--) {
game.removeChild(game.children[i]);
}
// Fill background with black
game.setBackgroundColor(0x000000);
// Show green text in the center
var secretText = new Text2('You found the room with the lowest percent chance of the player spotting into\nLucky you!', {
size: 100,
fill: 0x00ff00
});
secretText.anchor.set(0.5, 0.5);
secretText.x = 1024;
secretText.y = 1366;
game.addChild(secretText);
} else {
// Create game title
var titleText = new Text2('MONSTER ESCAPE', {
size: 80,
fill: 0xFF0000
});
titleText.anchor.set(0.5, 0);
titleText.x = 1024;
titleText.y = 100;
game.addChild(titleText);
// Create instructions
var instructionsText = new Text2('Survive as long as possible!\nMonster gets faster every minute', {
size: 40,
fill: 0x333333
});
instructionsText.anchor.set(0.5, 0);
instructionsText.x = 1024;
instructionsText.y = 200;
game.addChild(instructionsText);
// Create score display
var scoreText = new Text2('Time Survived: 0ms', {
size: 50,
fill: 0x000000
});
scoreText.anchor.set(0.5, 0);
scoreText.x = 1024;
scoreText.y = 300;
game.addChild(scoreText);
;
}
var player = game.addChild(new Player());
player.x = 1024; // Center horizontally
player.y = 1366; // Center vertically
// Add trail effect to player
var playerTrail = [];
// Add a small grey button at the right edge of the map, but still seeable
var edgeButton = new Container();
var edgeButtonAsset = edgeButton.attachAsset('edgeButtonGrey', {
anchorX: 0.5,
anchorY: 0.5,
width: 12,
height: 12,
color: 0x888888,
shape: 'box'
});
// Place the button at the right edge, vertically centered, but still visible
edgeButton.x = 2048 - 60; // 60px from the right edge
edgeButton.y = 1366; // center vertically
game.addChild(edgeButton);
var monster;
var tinyMonsters = [];
// 0.000000000001% chance for tiny monster horde
if (Math.random() < 0.0000000000001) {
// Main monster becomes extra small
monster = game.addChild(new Monster());
monster.x = 200;
monster.y = 200;
monster.scaleX = 0.18;
monster.scaleY = 0.18;
monster.speed = 3.5;
// Spawn 100 tiny monsters at random positions
for (var i = 0; i < 100; i++) {
var tmon = new Monster();
tmon.x = 100 + Math.random() * 1848;
tmon.y = 100 + Math.random() * 2532;
tmon.scaleX = 0.18;
tmon.scaleY = 0.18;
tmon.speed = 3.5 + Math.random() * 1.5;
tinyMonsters.push(tmon);
game.addChild(tmon);
}
} else {
monster = game.addChild(new Monster());
monster.x = 200;
monster.y = 200;
// Small chance to make the monster really, really big at game start
if (Math.random() < 0.03) {
// 3% chance
monster.scaleX = 8;
monster.scaleY = 8;
}
}
// 10% chance to spawn a black box
var hasBlackBox = false;
var blackBox = null;
if (Math.random() < 0.1) {
hasBlackBox = true;
blackBox = new Container();
var boxAsset = blackBox.attachAsset('blackBox', {
anchorX: 0.5,
anchorY: 0.5,
width: 180,
height: 180,
color: 0x000000,
shape: 'box'
});
// Place black box at a random location not too close to player or monster
var safe = false;
var bx = 0,
by = 0;
while (!safe) {
bx = 200 + Math.random() * (2048 - 400);
by = 400 + Math.random() * (2732 - 800);
var distToPlayer = Math.sqrt((bx - player.x) * (bx - player.x) + (by - player.y) * (by - player.y));
var distToMonster = Math.sqrt((bx - monster.x) * (bx - monster.x) + (by - monster.y) * (by - monster.y));
if (distToPlayer > 400 && distToMonster > 400) safe = true;
}
blackBox.x = bx;
blackBox.y = by;
game.addChild(blackBox);
}
var foundBlackBox = false;
// Even smaller chance to start with all UI/text distorted
var isDistortedUI = false;
if (Math.random() < 0.004) {
// 0.4% chance
isDistortedUI = true;
}
// Arrow control buttons
var upButton = game.addChild(new ArrowButton('up'));
upButton.x = 1024;
upButton.y = 2500;
var downButton = game.addChild(new ArrowButton('down'));
downButton.x = 1024;
downButton.y = 2620;
var leftButton = game.addChild(new ArrowButton('left'));
leftButton.x = 904;
leftButton.y = 2560;
var rightButton = game.addChild(new ArrowButton('right'));
rightButton.x = 1144;
rightButton.y = 2560;
var playerSpeed = 5;
var gameStartTime = Date.now();
game.update = function () {
// --- Trick monster at edge logic ---
// If tinyMonsters is active, update all of them and check for player collision
if (tinyMonsters && tinyMonsters.length > 0) {
for (var i = 0; i < tinyMonsters.length; i++) {
var tmon = tinyMonsters[i];
if (tmon.update) tmon.update();
// Check collision with player
var caught = tmon.intersects(player);
if (!tmon.lastPlayerIntersecting && caught) {
// Player caught! Play death sound and reset
var deathSound = LK.getSound('deathSound');
deathSound.volume = 1;
deathSound.play();
LK.effects.flashScreen(0xff0000, 1000);
LK.setTimeout(function () {
player.x = 1024;
player.y = 1366;
for (var j = 0; j < tinyMonsters.length; j++) {
tinyMonsters[j].x = 100 + Math.random() * 1848;
tinyMonsters[j].y = 100 + Math.random() * 2532;
}
gameStartTime = Date.now();
LK.setScore(0);
}, 1500);
}
tmon.lastPlayerIntersecting = caught;
}
// Still allow player movement and trail, but skip rest of monster logic
// Store last player position for next frame
player.lastX = player.x;
player.lastY = player.y;
if (upButton.isPressed) {
player.y = Math.max(50, player.y - playerSpeed);
}
if (downButton.isPressed) {
player.y = Math.min(2682, player.y + playerSpeed);
}
if (leftButton.isPressed) {
player.x = Math.max(50, player.x - playerSpeed);
}
if (rightButton.isPressed) {
player.x = Math.min(1998, player.x + playerSpeed);
}
// Add player trail effect
if (LK.ticks % 3 === 0) {
playerTrail.push({
x: player.x,
y: player.y,
alpha: 0.7
});
}
// Remove old trail points and update existing ones
for (var i = playerTrail.length - 1; i >= 0; i--) {
playerTrail[i].alpha -= 0.05;
if (playerTrail[i].alpha <= 0) {
playerTrail.splice(i, 1);
}
}
// Remove star update references if knockout is over
if (game._starUpdates && (!monster.wasKnockedOut || !monster.stars || monster.stars.length === 0)) {
for (var i = 0; i < game._starUpdates.length; i++) {
var star = game._starUpdates[i];
if (star.parent) game.removeChild(star);
}
game._starUpdates = [];
}
// Skip rest of update logic for normal monster
return;
}
if (monster.knockoutTimer === undefined) monster.knockoutTimer = 0;
if (monster.wasKnockedOut === undefined) monster.wasKnockedOut = false;
if (monster.knockoutCooldown === undefined) monster.knockoutCooldown = 0;
// Only allow trick if monster is not already knocked out or in cooldown
var playerIsAtEdge = player.x <= 60 || player.x >= 1988 || player.y <= 60 || player.y >= 2672;
var monsterClose = false;
var monsterBehind = false;
if (!monster.wasKnockedOut && monster.knockoutCooldown <= 0 && playerIsAtEdge) {
// Monster is close if within 120px
var dx = player.x - monster.x;
var dy = player.y - monster.y;
var dist = Math.sqrt(dx * dx + dy * dy);
monsterClose = dist < 120;
// Monster is "behind" if the angle from monster to player is within 60deg of the direction player is moving away from edge
// We'll check if player just moved down from top edge, or up from bottom, or left/right from sides
// We'll use lastPlayerY and lastPlayerX to detect movement direction
if (player.lastX === undefined) player.lastX = player.x;
if (player.lastY === undefined) player.lastY = player.y;
var movedDown = player.y > player.lastY && player.y >= 60 && player.lastY <= 60;
var movedUp = player.y < player.lastY && player.y <= 2672 && player.lastY >= 2672;
var movedRight = player.x > player.lastX && player.x >= 60 && player.lastX <= 60;
var movedLeft = player.x < player.lastX && player.x <= 1988 && player.lastX >= 1988;
// For each, check if monster is "behind" (i.e. between player and edge)
if (movedDown && player.lastY <= 60 && monster.y < player.y && Math.abs(monster.x - player.x) < 80) monsterBehind = true;
if (movedUp && player.lastY >= 2672 && monster.y > player.y && Math.abs(monster.x - player.x) < 80) monsterBehind = true;
if (movedRight && player.lastX <= 60 && monster.x < player.x && Math.abs(monster.y - player.y) < 80) monsterBehind = true;
if (movedLeft && player.lastX >= 1988 && monster.x > player.x && Math.abs(monster.y - player.y) < 80) monsterBehind = true;
// If all conditions met, trick monster: make it keep moving straight and bonk head at edge
if (monsterClose && monsterBehind) {
// Store the direction monster was moving
monster.trickedDirection = {
dx: player.x - monster.x,
dy: player.y - monster.y
};
// Normalize direction
var tdx = monster.trickedDirection.dx;
var tdy = monster.trickedDirection.dy;
var tdist = Math.sqrt(tdx * tdx + tdy * tdy);
if (tdist > 0) {
monster.trickedDirection.dx = tdx / tdist;
monster.trickedDirection.dy = tdy / tdist;
} else {
monster.trickedDirection.dx = 0;
monster.trickedDirection.dy = 0;
}
monster.isTricked = true;
monster.trickedTicks = 0;
monster.wasKnockedOut = false; // Not knocked out yet, will be after bonk
monster.knockoutTimer = 0;
monster.knockoutCooldown = 180; // 3 seconds cooldown before can be tricked again
monster.storedSpeed = monster.speed;
monster.speed = 7; // Move fast for the bonk
LK.effects.flashObject(monster, 0x8888ff, 400);
}
// Monster tricked logic: keep moving straight for 4 seconds or until bonk at edge, then knock out with stars above head
if (monster.isTricked) {
if (monster.trickedTicks === undefined) monster.trickedTicks = 0;
monster.trickedTicks++;
// Move monster in stored direction (straight, not tracking player)
monster.x += monster.trickedDirection.dx * monster.speed;
monster.y += monster.trickedDirection.dy * monster.speed;
// Check if monster bonks head on edge (out of bounds)
var bonked = false;
if (monster.x <= 50 && monster.trickedDirection.dx < 0 || monster.x >= 1998 && monster.trickedDirection.dx > 0 || monster.y <= 50 && monster.trickedDirection.dy < 0 || monster.y >= 2682 && monster.trickedDirection.dy > 0) {
bonked = true;
}
// If 4 seconds (240 ticks) have passed, or bonked, knock out
if (bonked || monster.trickedTicks >= 240) {
monster.isTricked = false;
monster.wasKnockedOut = true;
monster.knockoutTimer = 120; // 2 seconds at 60fps
monster.speed = 0;
LK.effects.flashObject(monster, 0x8888ff, 2000);
// Add stars above monster's head
if (!monster.stars) {
monster.stars = [];
var starCount = 3;
for (var i = 0; i < starCount; i++) {
var star = new Container();
// Use a yellow ellipse as a star
var starAsset = star.attachAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.4,
color: 0xffff00
});
// Place stars in a circle above monster
var angle = i / starCount * Math.PI * 2;
star.x = monster.x + Math.cos(angle) * 50;
star.y = monster.y - 70 + Math.sin(angle) * 20;
star.alpha = 1;
game.addChild(star);
monster.stars.push(star);
// Animate stars to rotate around monster's head
(function (star, angle, i) {
var rotateStar = function rotateStar() {
if (!monster.wasKnockedOut) {
// Remove star if not knocked out anymore
if (star.parent) game.removeChild(star);
return;
}
// Orbit animation
var t = (LK.ticks + i * 20) % 120 / 120 * Math.PI * 2;
star.x = monster.x + Math.cos(angle + t) * 50;
star.y = monster.y - 70 + Math.sin(angle + t) * 20;
// Bobbing effect
star.y += Math.sin(LK.ticks * 0.2 + i) * 8;
};
// Attach to game.update
if (!star._update) {
star._update = rotateStar;
if (!game._starUpdates) game._starUpdates = [];
game._starUpdates.push(star);
}
})(star, angle, i);
// Fade out and remove after knockout ends
tween(star, {
alpha: 0
}, {
duration: 1200,
easing: tween.linear,
onFinish: function onFinish() {
if (star.parent) game.removeChild(star);
}
});
}
}
}
// Prevent normal AI movement while tricked
return;
}
}
// If monster is knocked out, count down timer
if (monster.wasKnockedOut) {
monster.knockoutTimer--;
// Animate stars above head if present
if (monster.stars && monster.stars.length > 0) {
for (var i = 0; i < monster.stars.length; i++) {
var star = monster.stars[i];
if (star._update) star._update();
}
}
if (monster.knockoutTimer <= 0) {
monster.wasKnockedOut = false;
monster.speed = typeof monster.storedSpeed === "number" ? monster.storedSpeed : 2;
monster.knockoutTimer = 0;
// Remove stars
if (monster.stars && monster.stars.length > 0) {
for (var i = 0; i < monster.stars.length; i++) {
if (monster.stars[i].parent) game.removeChild(monster.stars[i]);
}
monster.stars = [];
}
}
}
// Always count down cooldown if set
if (monster.knockoutCooldown > 0) monster.knockoutCooldown--;
// Store last player position for next frame
player.lastX = player.x;
player.lastY = player.y;
// Handle player movement with arrow buttons
if (upButton.isPressed) {
player.y = Math.max(50, player.y - playerSpeed);
}
if (downButton.isPressed) {
player.y = Math.min(2682, player.y + playerSpeed);
}
if (leftButton.isPressed) {
player.x = Math.max(50, player.x - playerSpeed);
}
if (rightButton.isPressed) {
player.x = Math.min(1998, player.x + playerSpeed);
}
// Check for black box win condition
if (hasBlackBox && blackBox && !foundBlackBox) {
if (player.lastFoundBlackBox === undefined) player.lastFoundBlackBox = false;
var isIntersectingBlackBox = player.intersects(blackBox);
if (!player.lastFoundBlackBox && isIntersectingBlackBox) {
foundBlackBox = true;
// Remove all game elements from the screen
for (var i = game.children.length - 1; i >= 0; i--) {
game.removeChild(game.children[i]);
}
// Fill background with black
game.setBackgroundColor(0x000000);
// Show green text in the center
var winText = new Text2('You won!\nYou found the blue box!\n(It has a 10% chance of spawning)', {
size: 120,
fill: 0x00ff00
});
winText.anchor.set(0.5, 0.5);
winText.x = 1024;
winText.y = 1366;
game.addChild(winText);
}
player.lastFoundBlackBox = isIntersectingBlackBox;
// --- Monster collides with black box: "The monster won?" ---
if (monster.lastBlackBoxIntersecting === undefined) monster.lastBlackBoxIntersecting = false;
var monsterIntersectingBlackBox = monster.intersects(blackBox);
if (!monster.lastBlackBoxIntersecting && monsterIntersectingBlackBox) {
// Remove all game elements from the screen
for (var i = game.children.length - 1; i >= 0; i--) {
game.removeChild(game.children[i]);
}
// Fill background with black
game.setBackgroundColor(0x000000);
// Show centered text
var monsterWinText = new Text2('The monster won?', {
size: 120,
fill: 0xffffff
});
monsterWinText.anchor.set(0.5, 0.5);
monsterWinText.x = 1024;
monsterWinText.y = 1366;
game.addChild(monsterWinText);
}
monster.lastBlackBoxIntersecting = monsterIntersectingBlackBox;
}
// --- Secret tiny edge button room logic ---
if (player.lastFoundEdgeButton === undefined) player.lastFoundEdgeButton = false;
var isIntersectingEdgeButton = player.intersects(edgeButton);
if (!player.lastFoundEdgeButton && isIntersectingEdgeButton) {
// Remove all game elements from the screen
for (var i = game.children.length - 1; i >= 0; i--) {
game.removeChild(game.children[i]);
}
// Fill background with black
game.setBackgroundColor(0x000000);
// Show special text
var foundButtonText = new Text2('You found this very small button.\nThis is not the win.\nSurvive the monsters for 10 seconds!', {
size: 80,
fill: 0xffffff
});
foundButtonText.anchor.set(0.5, 0.5);
foundButtonText.x = 1024;
foundButtonText.y = 500;
game.addChild(foundButtonText);
// Add player to the center
player.x = 1024;
player.y = 2000;
game.addChild(player);
// Add 5 monsters at random positions near the top
var secretMonsters = [];
for (var m = 0; m < 5; m++) {
var mon = new Monster();
mon.x = 400 + Math.random() * 1200;
mon.y = 400 + Math.random() * 400;
// Make monsters in secret room fast enough to catch a still player (speed 2.7 to 3.2)
mon.speed = 2.7 + Math.random() * 0.5;
secretMonsters.push(mon);
game.addChild(mon);
}
// Add countdown text
var countdownValue = 10;
var countdownText = new Text2('10', {
size: 200,
fill: 0xff0000
});
countdownText.anchor.set(0.5, 0.5);
countdownText.x = 1024;
countdownText.y = 1200;
game.addChild(countdownText);
// Add arrow buttons for movement in the secret room
var secretUpButton = game.addChild(new ArrowButton('up'));
secretUpButton.x = 1024;
secretUpButton.y = 2500;
var secretDownButton = game.addChild(new ArrowButton('down'));
secretDownButton.x = 1024;
secretDownButton.y = 2620;
var secretLeftButton = game.addChild(new ArrowButton('left'));
secretLeftButton.x = 904;
secretLeftButton.y = 2560;
var secretRightButton = game.addChild(new ArrowButton('right'));
secretRightButton.x = 1144;
secretRightButton.y = 2560;
// Timer for countdown
var countdownTimer = LK.setInterval(function () {
countdownValue--;
if (countdownValue > 0) {
countdownText.setText(countdownValue + '');
} else {
LK.clearInterval(countdownTimer);
// Survived! Show success message
for (var i = game.children.length - 1; i >= 0; i--) {
game.removeChild(game.children[i]);
}
game.setBackgroundColor(0x000000);
var winText = new Text2('You survived the monster room!\nYou are truly observant.', {
size: 100,
fill: 0x00ff00
});
winText.anchor.set(0.5, 0.5);
winText.x = 1024;
winText.y = 1366;
game.addChild(winText);
}
}, 1000);
// Override game.update for this room
var secretRoomActive = true;
game.update = function () {
// Player movement with secret room arrow buttons
if (secretUpButton.isPressed) {
player.y = Math.max(50, player.y - playerSpeed);
}
if (secretDownButton.isPressed) {
player.y = Math.min(2682, player.y + playerSpeed);
}
if (secretLeftButton.isPressed) {
player.x = Math.max(50, player.x - playerSpeed);
}
if (secretRightButton.isPressed) {
player.x = Math.min(1998, player.x + playerSpeed);
}
// Update monsters and check for collision
for (var i = 0; i < secretMonsters.length; i++) {
var mon = secretMonsters[i];
if (mon.update) mon.update();
var caught = mon.intersects(player);
if (!mon.lastPlayerIntersecting && caught) {
// Player caught! End the room and restart the secret room and countdown
LK.clearInterval(countdownTimer);
for (var j = game.children.length - 1; j >= 0; j--) {
game.removeChild(game.children[j]);
}
game.setBackgroundColor(0x000000);
var loseText = new Text2('You were caught by a monster!\nRestarting...', {
size: 100,
fill: 0xff0000
});
loseText.anchor.set(0.5, 0.5);
loseText.x = 1024;
loseText.y = 1366;
game.addChild(loseText);
// Restart secret room after a short delay
LK.setTimeout(function () {
// Remove lose text
for (var k = game.children.length - 1; k >= 0; k--) {
game.removeChild(game.children[k]);
}
game.setBackgroundColor(0x000000);
// Show special text again
var foundButtonText = new Text2('You found this very small button.\nThis is not the win.\nSurvive the monsters for 10 seconds!', {
size: 80,
fill: 0xffffff
});
foundButtonText.anchor.set(0.5, 0.5);
foundButtonText.x = 1024;
foundButtonText.y = 500;
game.addChild(foundButtonText);
// Reset player position
player.x = 1024;
player.y = 2000;
game.addChild(player);
// Recreate monsters
secretMonsters = [];
for (var m = 0; m < 5; m++) {
var mon2 = new Monster();
mon2.x = 400 + Math.random() * 1200;
mon2.y = 400 + Math.random() * 400;
mon2.speed = 2.7 + Math.random() * 0.5;
secretMonsters.push(mon2);
game.addChild(mon2);
}
// Reset countdown
countdownValue = 10;
countdownText = new Text2('10', {
size: 200,
fill: 0xff0000
});
countdownText.anchor.set(0.5, 0.5);
countdownText.x = 1024;
countdownText.y = 1200;
game.addChild(countdownText);
// Re-add arrow buttons
secretUpButton = game.addChild(new ArrowButton('up'));
secretUpButton.x = 1024;
secretUpButton.y = 2500;
secretDownButton = game.addChild(new ArrowButton('down'));
secretDownButton.x = 1024;
secretDownButton.y = 2620;
secretLeftButton = game.addChild(new ArrowButton('left'));
secretLeftButton.x = 904;
secretLeftButton.y = 2560;
secretRightButton = game.addChild(new ArrowButton('right'));
secretRightButton.x = 1144;
secretRightButton.y = 2560;
// Restart countdown timer
countdownTimer = LK.setInterval(function () {
countdownValue--;
if (countdownValue > 0) {
countdownText.setText(countdownValue + '');
} else {
LK.clearInterval(countdownTimer);
// Survived! Show success message
for (var i = game.children.length - 1; i >= 0; i--) {
game.removeChild(game.children[i]);
}
game.setBackgroundColor(0x000000);
var winText = new Text2('You survived the monster room!\nYou are truly observant.', {
size: 100,
fill: 0x00ff00
});
winText.anchor.set(0.5, 0.5);
winText.x = 1024;
winText.y = 1366;
game.addChild(winText);
}
}, 1000);
secretRoomActive = true;
}, 1200);
break;
}
mon.lastPlayerIntersecting = caught;
}
};
}
player.lastFoundEdgeButton = isIntersectingEdgeButton;
// --- Monster & Ed button collision logic and monster search mode ---
if (monster.lastEdIntersecting === undefined) monster.lastEdIntersecting = false;
if (monster.lastWasDead === undefined) monster.lastWasDead = false;
if (monster.isSearchingForPlayer === undefined) monster.isSearchingForPlayer = false;
if (monster.isGlitchState === undefined) monster.isGlitchState = false;
var isMonsterIntersectingEd = monster.intersects(edgeButton);
// If monster collides with Ed button, enter search mode
if (!monster.lastEdIntersecting && isMonsterIntersectingEd && !monster.isSearchingForPlayer && !monster.isGlitchState) {
monster.isSearchingForPlayer = true;
monster.searchTicks = 0;
monster.searchDuration = 600; // 10 seconds at 60fps
monster.speed = 7; // Monster runs around quickly
// Optional: flash monster to indicate search mode
LK.effects.flashObject(monster, 0x00ffff, 800);
}
// If in search mode, monster runs randomly, not toward player
if (monster.isSearchingForPlayer && !monster.isGlitchState) {
monster.searchTicks++;
// Move in a random direction, change every 30 ticks
if (monster.searchDirX === undefined || monster.searchTicks % 30 === 0) {
var angle = Math.random() * Math.PI * 2;
monster.searchDirX = Math.cos(angle);
monster.searchDirY = Math.sin(angle);
}
monster.x += monster.searchDirX * monster.speed;
monster.y += monster.searchDirY * monster.speed;
// Clamp to game area
monster.x = Math.max(50, Math.min(1998, monster.x));
monster.y = Math.max(50, Math.min(2682, monster.y));
// After search duration, return to normal
if (monster.searchTicks > monster.searchDuration) {
monster.isSearchingForPlayer = false;
monster.speed = 2 + Math.floor((Date.now() - gameStartTime) / 60000);
}
}
// If monster dies (caught by player) while in search mode, show glitch/secret text
if (monster.isSearchingForPlayer && !monster.isGlitchState) {
var currentIntersecting = monster.intersects(player);
if (!monster.lastPlayerIntersecting && currentIntersecting) {
monster.isGlitchState = true;
// Remove all game elements
for (var i = game.children.length - 1; i >= 0; i--) {
game.removeChild(game.children[i]);
}
game.setBackgroundColor(0x000000);
var glitchText = new Text2('ERROR: monster is not found\n[404]', {
size: 120,
fill: 0xff00ff
});
glitchText.anchor.set(0.5, 0.5);
glitchText.x = 1024;
glitchText.y = 1366;
game.addChild(glitchText);
// Optionally, add a glitch effect
LK.effects.flashScreen(0xff00ff, 1200);
// Prevent further updates
return;
}
monster.lastPlayerIntersecting = currentIntersecting;
}
// Track last Ed intersection for next frame
monster.lastEdIntersecting = isMonsterIntersectingEd;
// --- End Monster & Ed button logic ---
// Increase monster speed every minute
var elapsedTime = Date.now() - gameStartTime;
var minutesPassed = Math.floor(elapsedTime / 60000); // 60000ms = 1 minute
var newSpeed = 2 + minutesPassed; // Base speed 2, +1 per minute
if (monster.speed !== newSpeed && !monster.isSearchingForPlayer && !monster.isGlitchState) {
monster.speed = newSpeed;
// Visual feedback when monster gets faster
LK.effects.flashObject(monster, 0xff0000, 500);
titleText.setText('LEVEL ' + (minutesPassed + 1) + ' - FASTER MONSTER!');
LK.setTimeout(function () {
titleText.setText('MONSTER ESCAPE');
}, 2000);
// Adjust text scale if monster is huge to prevent glitchy text
if (monster.scaleX > 4 || monster.scaleY > 4) {
var scaleFix = 1 / Math.max(monster.scaleX, monster.scaleY);
titleText.scaleX = scaleFix;
titleText.scaleY = scaleFix;
instructionsText.scaleX = scaleFix;
instructionsText.scaleY = scaleFix;
scoreText.scaleX = scaleFix;
scoreText.scaleY = scaleFix;
// Shake text in place
var shakeAmount = 30 * scaleFix;
var shakeX = Math.sin(LK.ticks * 0.6) * shakeAmount;
var shakeY = Math.cos(LK.ticks * 0.7) * shakeAmount;
titleText.x = 1024 + shakeX;
instructionsText.x = 1024 + Math.sin(LK.ticks * 0.8 + 1) * shakeAmount;
scoreText.x = 1024 + Math.cos(LK.ticks * 0.9 + 2) * shakeAmount;
titleText.y = 100 + shakeY;
instructionsText.y = 200 + Math.cos(LK.ticks * 0.5 + 3) * shakeAmount;
scoreText.y = 300 + Math.sin(LK.ticks * 0.4 + 4) * shakeAmount;
} else if (isDistortedUI) {
// Heavy distortion for all UI/text
// Randomize scale, rotation, and position every frame
var distort = function distort(txt, baseX, baseY, baseSize) {
txt.scaleX = 0.7 + Math.sin(LK.ticks * 0.13 + Math.random()) * 1.2;
txt.scaleY = 0.7 + Math.cos(LK.ticks * 0.17 + Math.random()) * 1.2;
txt.rotation = Math.sin(LK.ticks * 0.11 + Math.random()) * 1.5;
txt.x = baseX + Math.sin(LK.ticks * 0.5 + Math.random() * 10) * 120;
txt.y = baseY + Math.cos(LK.ticks * 0.6 + Math.random() * 10) * 80;
if (txt.setText && typeof txt._originalText === "string") {
// Randomly garble text
if (Math.random() < 0.2) {
var chars = txt._originalText.split('');
for (var i = 0; i < chars.length; i++) {
if (Math.random() < 0.2 && chars[i] !== ' ' && chars[i] !== '\n') {
chars[i] = String.fromCharCode(33 + Math.floor(Math.random() * 94));
}
}
txt.setText(chars.join(''));
} else {
txt.setText(txt._originalText);
}
}
};
// Store original text if not already
if (typeof titleText._originalText !== "string") titleText._originalText = "MONSTER ESCAPE";
if (typeof instructionsText._originalText !== "string") instructionsText._originalText = "Survive as long as possible!\nMonster gets faster every minute";
if (typeof scoreText._originalText !== "string") scoreText._originalText = scoreText.text;
distort(titleText, 1024, 100, 80);
distort(instructionsText, 1024, 200, 40);
distort(scoreText, 1024, 300, 50);
} else {
titleText.scaleX = 1;
titleText.scaleY = 1;
instructionsText.scaleX = 1;
instructionsText.scaleY = 1;
scoreText.scaleX = 1;
scoreText.scaleY = 1;
titleText.x = 1024;
instructionsText.x = 1024;
scoreText.x = 1024;
titleText.y = 100;
instructionsText.y = 200;
scoreText.y = 300;
}
}
// Increase score based on survival time in milliseconds
var millisecondsPerTick = 1000 / 60;
LK.setScore(Math.floor(LK.getScore() + millisecondsPerTick));
// Update score display
var seconds = Math.floor(LK.getScore() / 1000);
var minutes = Math.floor(seconds / 60);
var displaySeconds = seconds % 60;
if (minutes > 0) {
scoreText.setText('Time Survived: ' + minutes + 'm ' + displaySeconds + 's');
} else {
scoreText.setText('Time Survived: ' + seconds + 's');
}
// Add player trail effect
if (LK.ticks % 3 === 0) {
// Every 3 frames
playerTrail.push({
x: player.x,
y: player.y,
alpha: 0.7
});
}
// Remove old trail points and update existing ones
for (var i = playerTrail.length - 1; i >= 0; i--) {
playerTrail[i].alpha -= 0.05;
if (playerTrail[i].alpha <= 0) {
playerTrail.splice(i, 1);
}
}
// Remove star update references if knockout is over
if (game._starUpdates && (!monster.wasKnockedOut || !monster.stars || monster.stars.length === 0)) {
for (var i = 0; i < game._starUpdates.length; i++) {
var star = game._starUpdates[i];
if (star.parent) game.removeChild(star);
}
game._starUpdates = [];
}
};
Modern App Store icon, high definition, square with rounded corners, for a game titled "Monster Chase" and with the description "Control a character with your finger while an AI monster hunts you down. Survive as long as possible in this intense chase game with intuitive touch controls.". No text on icon!
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "Monster Chase" and with the description "Control a character with your finger while an AI monster hunts you down. Survive as long as possible in this intense chase game with intuitive touch controls.". No text on banner!