User prompt
make 20 levels
User prompt
there is a bug that makes the items unpickable make them pickable on EVERY LEVEL
User prompt
there is a bug that makes the items unpickable on every level fix it
User prompt
there is a bug when picking up objects fix it
User prompt
make the game 10 levels
Code edit (1 edits merged)
Please save this source code
User prompt
Mindlock: Memory Chambers
Initial prompt
Mindlock Tür: Hikaye tabanlı odadan kaçış/puzzle – 2D side-scroller veya point & click Görsel Stil: Hafif bulanık, rüya gibi arka planlar; pastel ve soluk renkler. Mekanik: Her “anı odası” tek ekranlı bir bulmaca. Oyuncu odadaki ipuçlarını toplayarak geçmişe dair bir olayı doğru sıralamayla tekrar yaşatıyor. Eşyaları farklı kombinasyonlarda kullanmak gerekiyor. Zorluk ilerledikçe eşyalar arasında metaforik bağlantılar kuruluyor (örn. bir saat = zamanı boşa harcamak).
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
currentLevel: 1,
unlockedLevels: 1
});
/****
* Classes
****/
var DialogBox = Container.expand(function () {
var self = Container.call(this);
// Background for dialog
self.bg = self.attachAsset('dialogBox', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.9
});
// Dialog text
self.text = new Text2("", {
size: 60,
fill: 0xFFFFFF
});
self.text.anchor.set(0.5, 0.5);
self.addChild(self.text);
// Prompt to continue
self.prompt = new Text2("Tap to continue...", {
size: 36,
fill: 0xAAAAAA
});
self.prompt.anchor.set(0.5, 0);
self.prompt.y = 100;
self.addChild(self.prompt);
// Set up interaction
self.down = function (x, y, obj) {
self.hide();
};
self.show = function (message) {
self.text.setText(message);
self.alpha = 0;
game.dialogShowing = true;
tween(self, {
alpha: 1
}, {
duration: 200
});
};
self.hide = function () {
tween(self, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
game.dialogShowing = false;
}
});
};
return self;
});
var InventorySlot = Container.expand(function (index) {
var self = Container.call(this);
self.index = index;
self.item = null;
// Visual representation of the slot
self.visual = self.attachAsset('inventorySlot', {
anchorX: 0.5,
anchorY: 0.5
});
// Make slot interactive
self.down = function (x, y, obj) {
if (self.item && !game.dialogShowing) {
tween(self.visual, {
alpha: 0.7
}, {
duration: 100
});
}
};
self.up = function (x, y, obj) {
tween(self.visual, {
alpha: 1
}, {
duration: 100
});
if (game.dialogShowing) {
return;
}
if (self.item) {
game.selectInventoryItem(self.index);
}
};
self.setItem = function (item) {
self.item = item;
if (item) {
item.position.set(0, 0);
item.scale.set(0.7);
self.addChild(item);
}
};
self.removeItem = function () {
if (self.item) {
self.removeChild(self.item);
var item = self.item;
self.item = null;
return item;
}
return null;
};
return self;
});
var MemoryItem = Container.expand(function (id, name, description) {
var self = Container.call(this);
self.id = id;
self.name = name;
self.description = description;
self.isPickedUp = false;
self.combinableWith = [];
// Visual representation of the item
self.visual = self.attachAsset('memoryBox', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xffffff - id * 12345 % 0xffffff // Generate unique color based on id
});
// Item name display
self.label = new Text2(name, {
size: 32,
fill: 0x000000
});
self.label.anchor.set(0.5, 0.5);
self.label.y = self.visual.height * 0.7;
self.addChild(self.label);
// Highlight effect when hovering
self.highlight = LK.getAsset('itemHighlight', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.addChild(self.highlight);
// Set up interaction methods
self.down = function (x, y, obj) {
if (!self.isPickedUp && !game.dialogShowing) {
tween(self.highlight, {
alpha: 0.3
}, {
duration: 100
});
}
};
self.up = function (x, y, obj) {
tween(self.highlight, {
alpha: 0
}, {
duration: 100
});
if (game.dialogShowing) {
return;
}
if (!self.isPickedUp) {
LK.getSound('pickup').play();
game.pickupItem(self);
}
};
self.setCombinableWith = function (ids) {
self.combinableWith = ids;
};
return self;
});
var MemoryLock = Container.expand(function (id, requiredItems, hint) {
var self = Container.call(this);
self.id = id;
self.requiredItems = requiredItems;
self.hint = hint || "This lock seems to require specific items...";
self.isUnlocked = false;
// Visual representation of the lock
self.visual = self.attachAsset('lockShape', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xaaaaaa
});
// Lock status icon
self.icon = new Text2("🔒", {
size: 80,
fill: 0xFFFFFF
});
self.icon.anchor.set(0.5, 0.5);
self.addChild(self.icon);
// Set up interaction methods
self.down = function (x, y, obj) {
if (!self.isUnlocked && !game.dialogShowing) {
tween(self.visual, {
alpha: 0.7
}, {
duration: 100
});
}
};
self.up = function (x, y, obj) {
tween(self.visual, {
alpha: 1
}, {
duration: 100
});
if (game.dialogShowing) {
return;
}
if (!self.isUnlocked) {
game.tryUnlock(self);
}
};
self.unlock = function () {
self.isUnlocked = true;
self.icon.setText("✓");
tween(self.visual, {
tint: 0x44aa44
}, {
duration: 500
});
LK.getSound('unlock').play();
};
return self;
});
var Room = Container.expand(function (level) {
var self = Container.call(this);
self.level = level;
self.items = [];
self.locks = [];
self.isComplete = false;
// Room background
self.bg = self.attachAsset('roomBg', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xffffff - level * 12345 % 0x555555 + 0xaaaaaa
});
// Room title
self.title = new Text2("Memory Chamber " + level, {
size: 70,
fill: 0x333333
});
self.title.anchor.set(0.5, 0);
self.title.y = -self.bg.height / 2 + 50;
self.addChild(self.title);
// Set up items and locks based on level
self.setupLevel = function () {
self.clearItems();
switch (level) {
case 1:
// First level - simple matching puzzle
var keyItem = new MemoryItem(1, "Key", "A brass key");
keyItem.position.set(-300, -200);
self.addItem(keyItem);
var lockItem = new MemoryLock(1, [1], "This lock needs a key...");
lockItem.position.set(300, -200);
self.addLock(lockItem);
var noteItem = new MemoryItem(2, "Note", "A handwritten note");
noteItem.position.set(-300, 200);
self.addItem(noteItem);
var boxItem = new MemoryLock(2, [2], "There's a slot for a paper...");
boxItem.position.set(300, 200);
self.addLock(boxItem);
break;
case 2:
// Second level - combination puzzle
var waterItem = new MemoryItem(3, "Water", "A small vial of water");
waterItem.position.set(-400, -300);
self.addItem(waterItem);
var seedItem = new MemoryItem(4, "Seed", "A dormant plant seed");
seedItem.position.set(0, -300);
self.addItem(seedItem);
var sunlightItem = new MemoryItem(5, "Light", "A ray of sunlight");
sunlightItem.position.set(400, -300);
self.addItem(sunlightItem);
var plantLock = new MemoryLock(3, [3, 4, 5], "Something needs to grow here...");
plantLock.position.set(0, 200);
self.addLock(plantLock);
break;
case 3:
// Third level - more abstract connections
var tearsItem = new MemoryItem(6, "Tears", "Droplets of sadness");
tearsItem.position.set(-500, -200);
self.addItem(tearsItem);
var laughterItem = new MemoryItem(7, "Laughter", "Sounds of joy");
laughterItem.position.set(-200, -300);
self.addItem(laughterItem);
var angerItem = new MemoryItem(8, "Anger", "Burning emotion");
angerItem.position.set(200, -300);
self.addItem(angerItem);
var peaceItem = new MemoryItem(9, "Peace", "Calm understanding");
peaceItem.position.set(500, -200);
self.addItem(peaceItem);
var memoryLock = new MemoryLock(4, [6, 7, 8, 9], "The essence of a complete memory...");
memoryLock.position.set(0, 250);
self.addLock(memoryLock);
break;
case 4:
// Fourth level - time based puzzle
var clockItem = new MemoryItem(10, "Clock", "A timepiece showing 3 o'clock");
clockItem.position.set(-400, -250);
self.addItem(clockItem);
var hourglassItem = new MemoryItem(11, "Hourglass", "Sand slowly trickling down");
hourglassItem.position.set(0, -300);
self.addItem(hourglassItem);
var calendarItem = new MemoryItem(12, "Calendar", "Marked with important dates");
calendarItem.position.set(400, -250);
self.addItem(calendarItem);
var timeLock = new MemoryLock(5, [10, 11, 12], "Time seems to be frozen here...");
timeLock.position.set(0, 200);
self.addLock(timeLock);
break;
case 5:
// Fifth level - musical elements
var drumItem = new MemoryItem(13, "Drum", "A percussion instrument");
drumItem.position.set(-500, -200);
self.addItem(drumItem);
var melodyItem = new MemoryItem(14, "Melody", "A series of sweet notes");
melodyItem.position.set(-200, -300);
self.addItem(melodyItem);
var rhythmItem = new MemoryItem(15, "Rhythm", "A pattern of beats");
rhythmItem.position.set(200, -300);
self.addItem(rhythmItem);
var harmonyItem = new MemoryItem(16, "Harmony", "Complementary sounds");
harmonyItem.position.set(500, -200);
self.addItem(harmonyItem);
var musicLock = new MemoryLock(6, [13, 14, 15, 16], "This lock seems to respond to music...");
musicLock.position.set(0, 250);
self.addLock(musicLock);
break;
case 6:
// Sixth level - elements of nature
var earthItem = new MemoryItem(17, "Earth", "Rich soil full of minerals");
earthItem.position.set(-400, -300);
self.addItem(earthItem);
var waterItem = new MemoryItem(18, "Water", "Clear flowing liquid");
waterItem.position.set(-150, -200);
self.addItem(waterItem);
var fireItem = new MemoryItem(19, "Fire", "Warm flickering flames");
fireItem.position.set(150, -200);
self.addItem(fireItem);
var airItem = new MemoryItem(20, "Air", "Gentle swirling breeze");
airItem.position.set(400, -300);
self.addItem(airItem);
var natureLock = new MemoryLock(7, [17, 18, 19, 20], "The forces of nature must be balanced...");
natureLock.position.set(0, 250);
self.addLock(natureLock);
break;
case 7:
// Seventh level - color puzzle
var redItem = new MemoryItem(21, "Red", "A vibrant crimson hue");
redItem.position.set(-500, -200);
redItem.visual.tint = 0xff0000;
self.addItem(redItem);
var blueItem = new MemoryItem(22, "Blue", "A deep azure shade");
blueItem.position.set(-200, -300);
blueItem.visual.tint = 0x0000ff;
self.addItem(blueItem);
var yellowItem = new MemoryItem(23, "Yellow", "A bright sunny color");
yellowItem.position.set(200, -300);
yellowItem.visual.tint = 0xffff00;
self.addItem(yellowItem);
var prismLock = new MemoryLock(8, [21, 22, 23], "The lock shows a rainbow pattern...");
prismLock.position.set(0, 250);
self.addLock(prismLock);
break;
case 8:
// Eighth level - knowledge puzzle
var bookItem = new MemoryItem(24, "Book", "Ancient tome of knowledge");
bookItem.position.set(-400, -250);
self.addItem(bookItem);
var quillItem = new MemoryItem(25, "Quill", "A writing instrument");
quillItem.position.set(-100, -300);
self.addItem(quillItem);
var inkItem = new MemoryItem(26, "Ink", "Midnight black liquid");
inkItem.position.set(100, -300);
self.addItem(inkItem);
var scrollItem = new MemoryItem(27, "Scroll", "Blank parchment");
scrollItem.position.set(400, -250);
self.addItem(scrollItem);
var wisdomLock = new MemoryLock(9, [24, 25, 26, 27], "Knowledge must be preserved and shared...");
wisdomLock.position.set(0, 200);
self.addLock(wisdomLock);
break;
case 9:
// Ninth level - celestial puzzle
var sunItem = new MemoryItem(28, "Sun", "The radiant day star");
sunItem.position.set(-400, -200);
sunItem.visual.tint = 0xffcc00;
self.addItem(sunItem);
var moonItem = new MemoryItem(29, "Moon", "The glowing night guardian");
moonItem.position.set(0, -300);
moonItem.visual.tint = 0xcccccc;
self.addItem(moonItem);
var starsItem = new MemoryItem(30, "Stars", "Distant twinkling lights");
starsItem.position.set(400, -200);
starsItem.visual.tint = 0xffffff;
self.addItem(starsItem);
var celestialLock = new MemoryLock(10, [28, 29, 30], "As above, so below...");
celestialLock.position.set(0, 200);
self.addLock(celestialLock);
break;
case 10:
// Final level - complex combination puzzle
var pastItem = new MemoryItem(31, "Past", "Faded memories");
pastItem.position.set(-500, -300);
pastItem.visual.tint = 0xaaaaaa;
self.addItem(pastItem);
var presentItem = new MemoryItem(32, "Present", "The moment now");
presentItem.position.set(-250, -200);
presentItem.visual.tint = 0xffffff;
self.addItem(presentItem);
var futureItem = new MemoryItem(33, "Future", "Potential possibilities");
futureItem.position.set(0, -300);
futureItem.visual.tint = 0xaaddff;
self.addItem(futureItem);
var dreamItem = new MemoryItem(34, "Dream", "Subconscious visions");
dreamItem.position.set(250, -200);
self.addItem(dreamItem);
var realityItem = new MemoryItem(35, "Reality", "Tangible existence");
realityItem.position.set(500, -300);
self.addItem(realityItem);
var finalLock = new MemoryLock(11, [31, 32, 33, 34, 35], "The complete mind requires all aspects of consciousness...");
finalLock.position.set(0, 250);
self.addLock(finalLock);
break;
}
};
self.addItem = function (item) {
self.items.push(item);
self.addChild(item);
};
self.addLock = function (lock) {
self.locks.push(lock);
self.addChild(lock);
};
self.clearItems = function () {
for (var i = 0; i < self.items.length; i++) {
self.removeChild(self.items[i]);
}
self.items = [];
for (var j = 0; j < self.locks.length; j++) {
self.removeChild(self.locks[j]);
}
self.locks = [];
};
self.checkCompletion = function () {
for (var i = 0; i < self.locks.length; i++) {
if (!self.locks[i].isUnlocked) {
return false;
}
}
self.isComplete = true;
return true;
};
// Initialize the level
self.setupLevel();
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xf0f6ff
});
/****
* Game Code
****/
// Game variables
var currentLevel = storage.currentLevel || 1;
var maxLevels = 10;
var unlockedLevels = storage.unlockedLevels || 1;
var currentRoom = null;
var inventory = [];
var inventorySlots = [];
var selectedInventoryIndex = -1;
var dialogShowing = false;
var dialogBox = null;
// Create and position the room
function createRoom(level) {
if (currentRoom) {
game.removeChild(currentRoom);
}
currentRoom = new Room(level);
currentRoom.position.set(2048 / 2, 2732 / 2);
game.addChild(currentRoom);
return currentRoom;
}
// Initialize inventory
function createInventory() {
var inventoryContainer = new Container();
game.addChild(inventoryContainer);
// Create inventory slots
for (var i = 0; i < 4; i++) {
var slot = new InventorySlot(i);
slot.position.set(300 + i * 500, 2732 - 150);
inventorySlots.push(slot);
inventoryContainer.addChild(slot);
}
// Create inventory title
var inventoryTitle = new Text2("Inventory", {
size: 50,
fill: 0x333333
});
inventoryTitle.anchor.set(0, 0.5);
inventoryTitle.position.set(300, 2732 - 250);
inventoryContainer.addChild(inventoryTitle);
}
// Initialize dialog box
function createDialogBox() {
dialogBox = new DialogBox();
dialogBox.position.set(2048 / 2, 2732 / 2);
dialogBox.alpha = 0;
game.addChild(dialogBox);
}
// Add item to inventory
game.pickupItem = function (item) {
// Find first empty inventory slot
var slotIndex = -1;
for (var i = 0; i < inventorySlots.length; i++) {
if (!inventorySlots[i].item) {
slotIndex = i;
break;
}
}
if (slotIndex !== -1) {
// Add to inventory
item.isPickedUp = true;
// Store a reference to the item before removing from parent
var itemToAdd = item;
// Remove from room
var parentIndex = currentRoom.items.indexOf(item);
if (parentIndex !== -1) {
currentRoom.items.splice(parentIndex, 1);
currentRoom.removeChild(item);
}
// Add to inventory slot - need to store the reference first, then add to slot after removing from parent
inventorySlots[slotIndex].setItem(itemToAdd);
inventory[slotIndex] = itemToAdd;
// Show description
showDialog(itemToAdd.name + ": " + itemToAdd.description);
} else {
showDialog("Your inventory is full!");
}
};
// Select inventory item
game.selectInventoryItem = function (index) {
// If we have an item in this slot
if (inventorySlots[index].item) {
// If we already had a selection, deselect it
if (selectedInventoryIndex !== -1) {
tween(inventorySlots[selectedInventoryIndex].visual, {
tint: 0xe0e0e0
}, {
duration: 200
});
}
// If we're selecting the same item, deselect it
if (selectedInventoryIndex === index) {
selectedInventoryIndex = -1;
showDialog(inventorySlots[index].item.name + ": " + inventorySlots[index].item.description);
} else {
// Select the new item
selectedInventoryIndex = index;
tween(inventorySlots[index].visual, {
tint: 0xaaffaa
}, {
duration: 200
});
showDialog("Selected: " + inventorySlots[index].item.name);
}
}
};
// Try to unlock a lock with selected inventory items
game.tryUnlock = function (lock) {
if (selectedInventoryIndex === -1) {
// No item selected
showDialog(lock.hint);
return;
}
var selectedItem = inventory[selectedInventoryIndex];
if (lock.requiredItems.indexOf(selectedItem.id) !== -1) {
// Correct item for this lock
// Check if this is a single-item lock or multi-item lock
if (lock.requiredItems.length === 1) {
// Single item lock - unlock immediately
lock.unlock();
// Remove item from inventory
inventorySlots[selectedInventoryIndex].removeItem();
inventory[selectedInventoryIndex] = null;
selectedInventoryIndex = -1;
// Check if room is complete
if (currentRoom.checkCompletion()) {
LK.setTimeout(function () {
completeLevel();
}, 1000);
}
} else {
// Multi-item lock - check if we have all required items
var hasAllItems = true;
var itemIds = [];
// Collect all inventory item IDs
for (var i = 0; i < inventory.length; i++) {
if (inventory[i]) {
itemIds.push(inventory[i].id);
}
}
// Check if we have all required items
for (var j = 0; j < lock.requiredItems.length; j++) {
if (itemIds.indexOf(lock.requiredItems[j]) === -1) {
hasAllItems = false;
break;
}
}
if (hasAllItems) {
// We have all required items
lock.unlock();
// Remove all required items from inventory
for (var k = 0; k < lock.requiredItems.length; k++) {
var requiredId = lock.requiredItems[k];
for (var l = 0; l < inventory.length; l++) {
if (inventory[l] && inventory[l].id === requiredId) {
inventorySlots[l].removeItem();
inventory[l] = null;
}
}
}
selectedInventoryIndex = -1;
// Check if room is complete
if (currentRoom.checkCompletion()) {
LK.setTimeout(function () {
completeLevel();
}, 1000);
}
} else {
// Missing some required items
LK.getSound('error').play();
showDialog("This lock requires more items than just this one...");
}
}
} else {
// Wrong item
LK.getSound('error').play();
showDialog("This doesn't seem to work here...");
}
};
// Complete the current level and advance
function completeLevel() {
LK.getSound('success').play();
if (currentLevel < maxLevels) {
// Advance to next level
currentLevel++;
if (currentLevel > unlockedLevels) {
unlockedLevels = currentLevel;
storage.unlockedLevels = unlockedLevels;
}
storage.currentLevel = currentLevel;
// Show level complete message
showDialog("Memory unlocked! Advancing to chamber " + currentLevel + "...", function () {
// Clear inventory
for (var i = 0; i < inventorySlots.length; i++) {
if (inventorySlots[i].item) {
inventorySlots[i].removeItem();
inventory[i] = null;
}
}
selectedInventoryIndex = -1;
// Create new room
createRoom(currentLevel);
});
} else {
// Game complete
showDialog("All 10 memory chambers have been unlocked! You have completely restored your mind. Congratulations!", function () {
// Restart the game
LK.showYouWin();
});
}
}
// Show dialog message
function showDialog(message, callback) {
dialogBox.show(message);
if (callback) {
LK.setTimeout(callback, 2000);
}
}
// Initialize the game
function initGame() {
// Create room based on current level
createRoom(currentLevel);
// Create inventory
createInventory();
// Create dialog box
createDialogBox();
// Play background music
LK.playMusic('bgAmbience');
// Show welcome message
LK.setTimeout(function () {
showDialog("Welcome to Mindlock: Memory Chambers. Find items and use them to unlock forgotten memories.");
}, 500);
}
// Initialize game
initGame();
// Game update function
game.update = function () {
// Pulse effect on locked objects
if (currentRoom) {
for (var i = 0; i < currentRoom.locks.length; i++) {
var lock = currentRoom.locks[i];
if (!lock.isUnlocked) {
lock.visual.alpha = 0.8 + Math.sin(LK.ticks / 20) * 0.2;
}
}
}
};
// Event handlers for touch/mouse interaction
game.down = function (x, y, obj) {
// If there's no direct object hit, deselect inventory item
if (!obj || obj === game) {
if (selectedInventoryIndex !== -1 && !dialogShowing) {
tween(inventorySlots[selectedInventoryIndex].visual, {
tint: 0xe0e0e0
}, {
duration: 200
});
selectedInventoryIndex = -1;
}
}
};
game.move = function (x, y, obj) {
// No dragging functionality needed for this game
}; ===================================================================
--- original.js
+++ change.js
@@ -533,9 +533,9 @@
if (parentIndex !== -1) {
currentRoom.items.splice(parentIndex, 1);
currentRoom.removeChild(item);
}
- // Add to inventory slot
+ // Add to inventory slot - need to store the reference first, then add to slot after removing from parent
inventorySlots[slotIndex].setItem(itemToAdd);
inventory[slotIndex] = itemToAdd;
// Show description
showDialog(itemToAdd.name + ": " + itemToAdd.description);