User prompt
There are some bugs in the game, like the player suddenly dying, also make the menu and buttons customizable with images
User prompt
Add a menu for the play button and options, add a small text saying "This game may contain bugs, if so, please restart."
User prompt
make the trees not so crowded
User prompt
Add a forest background with collision trees
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'batteryText.style.fill = "#44ff44";' Line Number: 344
Code edit (1 edits merged)
Please save this source code
User prompt
Shadow Hunt
Initial prompt
Quieto hacer un juego de terror
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Collectible = Container.expand(function () { var self = Container.call(this); var collectibleGraphics = self.attachAsset('collectible', { anchorX: 0.5, anchorY: 0.5 }); self.collected = false; return self; }); var Flashlight = Container.expand(function () { var self = Container.call(this); var flashlightGraphics = self.attachAsset('flashlightBeam', { anchorX: 0.5, anchorY: 0.5 }); flashlightGraphics.alpha = 0.6; self.battery = 100; self.maxBattery = 100; self.update = function () { self.battery -= 0.1; if (self.battery <= 0) { self.battery = 0; flashlightGraphics.alpha = 0; } else { var batteryRatio = self.battery / self.maxBattery; flashlightGraphics.alpha = 0.3 + 0.3 * batteryRatio; // Flickering effect when battery is low if (batteryRatio < 0.3) { if (Math.random() < 0.1) { flashlightGraphics.alpha *= 0.3; } } } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3; self.health = 3; return self; }); var ShadowCreature = Container.expand(function () { var self = Container.call(this); var shadowGraphics = self.attachAsset('shadowCreature', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.patrolDirection = Math.random() * Math.PI * 2; self.isInLight = false; self.isChasing = false; self.patrolTimer = 0; self.update = function () { // Store original position for collision detection var originalX = self.x; var originalY = self.y; if (self.isInLight) { // Shadow retreats when in light var dx = self.x - flashlight.x; var dy = self.y - flashlight.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed * 2; self.y += dy / distance * self.speed * 2; } self.isChasing = false; } else if (self.isChasing) { // Chase player var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed * 1.5; self.y += dy / distance * self.speed * 1.5; } } else { // Patrol behavior self.patrolTimer++; if (self.patrolTimer > 120) { self.patrolDirection = Math.random() * Math.PI * 2; self.patrolTimer = 0; } self.x += Math.cos(self.patrolDirection) * self.speed * 0.5; self.y += Math.sin(self.patrolDirection) * self.speed * 0.5; } // Check collision with trees var collisionDetected = false; for (var i = 0; i < trees.length; i++) { if (self.intersects(trees[i])) { collisionDetected = true; break; } } // If collision detected, revert movement and change patrol direction if (collisionDetected) { self.x = originalX; self.y = originalY; self.patrolDirection = Math.random() * Math.PI * 2; } // Keep within bounds if (self.x < 50) self.x = 50; if (self.x > 1998) self.x = 1998; if (self.y < 50) self.y = 50; if (self.y > 2682) self.y = 2682; }; return self; }); var Tree = Container.expand(function () { var self = Container.call(this); var treeGraphics = self.attachAsset('tree', { anchorX: 0.5, anchorY: 1.0 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x0a0a0a }); /**** * Game Code ****/ // Add forest background var forestBg = game.addChild(LK.getAsset('forestBackground', { anchorX: 0, anchorY: 0 })); forestBg.x = 0; forestBg.y = 0; var player = game.addChild(new Player()); var flashlight = game.addChild(new Flashlight()); var shadowCreatures = []; var collectibles = []; var trees = []; var exitPoint = null; // Game state variables var gameStarted = false; var gameOver = false; var itemsCollected = 0; var totalItems = 6; var flashlightX = 1024; var flashlightY = 1366; // Create collision trees scattered around the forest for (var i = 0; i < 20; i++) { var tree = game.addChild(new Tree()); tree.x = Math.random() * 1800 + 100; tree.y = Math.random() * 2400 + 200; trees.push(tree); } // Initialize player position player.x = 1024; player.y = 2400; // Create shadow creatures for (var i = 0; i < 4; i++) { var shadow = game.addChild(new ShadowCreature()); shadow.x = Math.random() * 1800 + 100; shadow.y = Math.random() * 2000 + 100; shadowCreatures.push(shadow); } // Create collectibles for (var i = 0; i < totalItems; i++) { var collectible = game.addChild(new Collectible()); collectible.x = Math.random() * 1800 + 100; collectible.y = Math.random() * 2000 + 100; collectibles.push(collectible); } // Create exit point (initially hidden) exitPoint = game.addChild(LK.getAsset('exitPoint', { anchorX: 0.5, anchorY: 0.5 })); exitPoint.x = 1024; exitPoint.y = 100; exitPoint.alpha = 0; // UI Elements var healthText = new Text2('Health: 3', { size: 80, fill: 0xFF4444 }); healthText.anchor.set(0, 0); LK.gui.topRight.addChild(healthText); var itemsText = new Text2('Items: 0/' + totalItems, { size: 80, fill: 0xFFFF44 }); itemsText.anchor.set(0, 0); LK.gui.top.addChild(itemsText); var batteryText = new Text2('Battery: 100%', { size: 60, fill: 0x44FF44 }); batteryText.anchor.set(1, 0); LK.gui.bottomRight.addChild(batteryText); // Game controls game.move = function (x, y, obj) { if (gameOver) return; flashlightX = x; flashlightY = y; flashlight.x = x; flashlight.y = y; }; game.down = function (x, y, obj) { if (gameOver) return; if (!gameStarted) { gameStarted = true; LK.playMusic('ambientHorror'); } flashlightX = x; flashlightY = y; flashlight.x = x; flashlight.y = y; }; function checkFlashlightCollision(target) { var dx = target.x - flashlight.x; var dy = target.y - flashlight.y; var distance = Math.sqrt(dx * dx + dy * dy); return distance < 150; } function movePlayerTowardsFlashlight() { var dx = flashlightX - player.x; var dy = flashlightY - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 5) { var moveX = dx / distance * player.speed; var moveY = dy / distance * player.speed; // Store original position var originalX = player.x; var originalY = player.y; // Try to move player.x += moveX; player.y += moveY; // Check collision with trees var collisionDetected = false; for (var i = 0; i < trees.length; i++) { if (player.intersects(trees[i])) { collisionDetected = true; break; } } // If collision detected, revert movement if (collisionDetected) { player.x = originalX; player.y = originalY; } // Keep player within bounds if (player.x < 30) player.x = 30; if (player.x > 2018) player.x = 2018; if (player.y < 30) player.y = 30; if (player.y > 2702) player.y = 2702; } } function checkShadowDetection() { for (var i = 0; i < shadowCreatures.length; i++) { var shadow = shadowCreatures[i]; // Check if shadow is in light shadow.isInLight = checkFlashlightCollision(shadow); // Check if shadow can see player (not in light and close enough) if (!shadow.isInLight) { var dx = player.x - shadow.x; var dy = player.y - shadow.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { shadow.isChasing = true; LK.getSound('shadowMove').play(); } else if (distance > 400) { shadow.isChasing = false; } } } } function checkPlayerCaught() { for (var i = 0; i < shadowCreatures.length; i++) { var shadow = shadowCreatures[i]; if (player.intersects(shadow) && !shadow.isInLight) { player.health--; healthText.setText('Health: ' + player.health); LK.getSound('caught').play(); LK.effects.flashScreen(0xff0000, 500); // Push player away from shadow var dx = player.x - shadow.x; var dy = player.y - shadow.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { player.x += dx / distance * 100; player.y += dy / distance * 100; } if (player.health <= 0) { gameOver = true; LK.showGameOver(); return; } break; } } } function checkCollectibles() { for (var i = collectibles.length - 1; i >= 0; i--) { var collectible = collectibles[i]; if (!collectible.collected && player.intersects(collectible)) { collectible.collected = true; collectible.alpha = 0; itemsCollected++; LK.getSound('collect').play(); itemsText.setText('Items: ' + itemsCollected + '/' + totalItems); if (itemsCollected >= totalItems) { exitPoint.alpha = 1; tween(exitPoint, { scaleX: 1.2, scaleY: 1.2 }, { duration: 500, easing: tween.easeInOut }); } } } } function checkWinCondition() { if (itemsCollected >= totalItems && player.intersects(exitPoint)) { gameOver = true; LK.getSound('victory').play(); LK.showYouWin(); } } function checkBatteryDeath() { if (flashlight.battery <= 0) { gameOver = true; LK.showGameOver(); } } game.update = function () { if (gameOver || !gameStarted) return; movePlayerTowardsFlashlight(); checkShadowDetection(); checkPlayerCaught(); checkCollectibles(); checkWinCondition(); checkBatteryDeath(); // Update battery display var batteryPercent = Math.floor(flashlight.battery); batteryText.setText('Battery: ' + batteryPercent + '%'); // Change battery text color based on level if (flashlight.battery < 30) { batteryText.fill = "#ff4444"; } else if (flashlight.battery < 60) { batteryText.fill = "#ffaa44"; } else { batteryText.fill = "#44ff44"; } };
===================================================================
--- original.js
+++ change.js
@@ -63,8 +63,11 @@
self.isInLight = false;
self.isChasing = false;
self.patrolTimer = 0;
self.update = function () {
+ // Store original position for collision detection
+ var originalX = self.x;
+ var originalY = self.y;
if (self.isInLight) {
// Shadow retreats when in light
var dx = self.x - flashlight.x;
var dy = self.y - flashlight.y;
@@ -92,16 +95,38 @@
}
self.x += Math.cos(self.patrolDirection) * self.speed * 0.5;
self.y += Math.sin(self.patrolDirection) * self.speed * 0.5;
}
+ // Check collision with trees
+ var collisionDetected = false;
+ for (var i = 0; i < trees.length; i++) {
+ if (self.intersects(trees[i])) {
+ collisionDetected = true;
+ break;
+ }
+ }
+ // If collision detected, revert movement and change patrol direction
+ if (collisionDetected) {
+ self.x = originalX;
+ self.y = originalY;
+ self.patrolDirection = Math.random() * Math.PI * 2;
+ }
// Keep within bounds
if (self.x < 50) self.x = 50;
if (self.x > 1998) self.x = 1998;
if (self.y < 50) self.y = 50;
if (self.y > 2682) self.y = 2682;
};
return self;
});
+var Tree = Container.expand(function () {
+ var self = Container.call(this);
+ var treeGraphics = self.attachAsset('tree', {
+ anchorX: 0.5,
+ anchorY: 1.0
+ });
+ return self;
+});
/****
* Initialize Game
****/
@@ -111,20 +136,35 @@
/****
* Game Code
****/
+// Add forest background
+var forestBg = game.addChild(LK.getAsset('forestBackground', {
+ anchorX: 0,
+ anchorY: 0
+}));
+forestBg.x = 0;
+forestBg.y = 0;
var player = game.addChild(new Player());
var flashlight = game.addChild(new Flashlight());
var shadowCreatures = [];
var collectibles = [];
+var trees = [];
var exitPoint = null;
// Game state variables
var gameStarted = false;
var gameOver = false;
var itemsCollected = 0;
var totalItems = 6;
var flashlightX = 1024;
var flashlightY = 1366;
+// Create collision trees scattered around the forest
+for (var i = 0; i < 20; i++) {
+ var tree = game.addChild(new Tree());
+ tree.x = Math.random() * 1800 + 100;
+ tree.y = Math.random() * 2400 + 200;
+ trees.push(tree);
+}
// Initialize player position
player.x = 1024;
player.y = 2400;
// Create shadow creatures
@@ -199,10 +239,27 @@
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
var moveX = dx / distance * player.speed;
var moveY = dy / distance * player.speed;
+ // Store original position
+ var originalX = player.x;
+ var originalY = player.y;
+ // Try to move
player.x += moveX;
player.y += moveY;
+ // Check collision with trees
+ var collisionDetected = false;
+ for (var i = 0; i < trees.length; i++) {
+ if (player.intersects(trees[i])) {
+ collisionDetected = true;
+ break;
+ }
+ }
+ // If collision detected, revert movement
+ if (collisionDetected) {
+ player.x = originalX;
+ player.y = originalY;
+ }
// Keep player within bounds
if (player.x < 30) player.x = 30;
if (player.x > 2018) player.x = 2018;
if (player.y < 30) player.y = 30;
a scared pixel art kid with a flashlight. In-Game asset. High contrast. No shadows
a large black beast with fangs sharpened with blood pixel art style. In-Game asset. High contrast. No shadows
an open book with blood, terrifying pixel art. In-Game asset. 2d. High contrast. No shadows
a terrifying but illuminating exit. In-Game asset. 2d. High contrast. No shadows
Tree pixel art. In-Game asset. 2d. High contrast. No shadows
a dark forest with bloodthirsty black wolves. In-Game asset. 2d. High contrast. No shadows
Button terror. In-Game asset. 2d. High contrast. No shadows