User prompt
Please fix the bug: 'Script error.' in or related to this line: 'inputTextDisplay.style.fill = "#000000";' Line Number: 655
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'classIconAsset.tint = parseInt(classInfo.color.replace('#', '0x'));' Line Number: 292
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'uiRefs.inputTextDisplay.style.fill = "#000000";' Line Number: 1259
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'uiRefs.inputTextDisplay.style.fill = "#777777";' Line Number: 1161
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'uiRefs.inputTextDisplay.style.fill = "#000000";' Line Number: 1259
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'messagesContainer.addChild')' in or related to this line: 'messagesContainer.addChild(chatMessage);' Line Number: 1098
Code edit (1 edits merged)
Please save this source code
User prompt
Titanic Chat: Class & Collect
Initial prompt
A titanic chat room, a chat room all about the titanic. You get coins every time you chat. Everyone starts as a coal worker. Which gives you a tag of [coal worker] in dark gray. In the shop, you can buy usertags. Stay in the game for 300 seconds total, and have 10 coins total, you can buy one usertag called [third class] in light gray. [Second class] costs 500 seconds total and 50 coins total. It is white, and it gives you access to send photos. [First class] costs 1000 seconds total and 100 coins total. It is purple color, and you have access to send private chats to anyone in any class if they accept. [Crew member] costs 2500 seconds total and 500 coins total. It is red color, and you get access to delete your own chats. [Captain] it costs 5000 seconds total and 1000 coins. It is green color and you get access to everything mentioned plus the ability to send videos up to 5 minutes. Coal worker: +1 coin every chat. Third class: 2 per chat. Second class: 5 per chat. First class: 10 per chat. Crew members:25 per chat. Captain: 50 per chat. Coins can also be used to buy gifs and secret emojis like Titanic gifs and emojis. Every 60 seconds, a bit types in a random Titanic fact.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { coins: 0, experience: 0, socialClass: "coal", purchasedEmojis: [], purchasedGifs: [], playerName: "Anonymous", playerColor: "#000000", lastVisit: "undefined" }); /**** * Classes ****/ var ChatMessage = Container.expand(function (messageText, sender, isBot, socialClass) { var self = Container.call(this); var bubble = self.attachAsset('chatBubble', { anchorX: 0, anchorY: 0 }); var isPlayerMessage = !isBot && sender === storage.playerName; // Configure bubble based on sender if (isBot) { bubble.tint = 0xE6FFE6; // Light green for bot } else if (isPlayerMessage) { bubble.tint = 0xE6F3FF; // Light blue for player } // Icon based on sender type var iconAsset = isBot ? 'botIcon' : 'profileIcon'; var icon = self.attachAsset(iconAsset, { anchorX: 0.5, anchorY: 0.5, x: 40, y: 40 }); // Tint the profile icon based on social class if (!isBot) { switch (socialClass) { case 'coal': icon.tint = 0x333333; // Dark gray break; case 'thirdClass': icon.tint = 0x8B4513; // Brown break; case 'secondClass': icon.tint = 0xC0C0C0; // Silver break; case 'firstClass': icon.tint = 0xFFD700; // Gold break; case 'crew': icon.tint = 0x4169E1; // Royal Blue break; case 'captain': icon.tint = 0x000080; // Navy break; } } // Sender name var senderText = new Text2(sender, { size: 24, fill: isBot ? "#008000" : "#000080" }); senderText.x = 90; senderText.y = 10; self.addChild(senderText); // Social class badge if (!isBot) { var classText = new Text2(socialClass.toUpperCase(), { size: 14, fill: 0x555555 }); classText.x = 90; classText.y = 40; self.addChild(classText); } // Message text var messageTxt = new Text2(messageText, { size: 28, fill: 0x000000 }); messageTxt.x = 90; messageTxt.y = 70; // Limit text width if (messageTxt.width > 480) { messageTxt.scale.set(480 / messageTxt.width); } self.addChild(messageTxt); // For crew and captain: delete button if ((socialClass === 'crew' || socialClass === 'captain') && isPlayerMessage) { var deleteText = new Text2("×", { size: 40, fill: 0xFF0000 }); deleteText.x = 570; deleteText.y = 5; deleteText.interactive = true; self.addChild(deleteText); deleteText.down = function () { self.alpha = 0.5; tween(self, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { self.destroy(); } }); }; } // Timestamp var time = new Date(); var timeText = new Text2(time.getHours() + ":" + (time.getMinutes() < 10 ? "0" : "") + time.getMinutes(), { size: 16, fill: 0x777777 }); timeText.x = 540; timeText.y = 125; self.addChild(timeText); return self; }); var EmojiItem = Container.expand(function (emoji, price, isPurchased) { var self = Container.call(this); var background = self.attachAsset('emojiButton', { anchorX: 0.5, anchorY: 0.5 }); var emojiText = new Text2(emoji, { size: 40 }); emojiText.anchor.set(0.5); self.addChild(emojiText); if (!isPurchased) { // Price tag var priceTag = new Text2(price + " 🪙", { size: 18, fill: 0x000000 }); priceTag.anchor.set(0.5); priceTag.y = 45; self.addChild(priceTag); // Locked overlay var lock = new Text2("🔒", { size: 20 }); lock.anchor.set(0.5); lock.y = -25; self.addChild(lock); } self.interactive = true; self.emoji = emoji; self.price = price; self.isPurchased = isPurchased; return self; }); var SocialClassPanel = Container.expand(function () { var self = Container.call(this); var panel = self.attachAsset('storePanel', { anchorX: 0.5, anchorY: 0.5, width: 1600, height: 1800 }); // Title var titleText = new Text2("SOCIAL CLASSES", { size: 60, fill: 0x000080 }); titleText.anchor.set(0.5, 0); titleText.x = 0; titleText.y = -800; self.addChild(titleText); // Close button var closeBtn = self.attachAsset('closeButton', { anchorX: 0.5, anchorY: 0.5, x: 700, y: -800 }); var closeText = new Text2("X", { size: 40, fill: 0xFFFFFF }); closeText.anchor.set(0.5); closeText.x = 700; closeText.y = -800; self.addChild(closeText); closeBtn.interactive = true; closeBtn.down = function () { self.visible = false; }; // Social classes information var classes = [{ name: "Coal Worker", exp: 0, color: 0x333333, description: "You shovel coal in the boiler room. No special privileges." }, { name: "Third Class", exp: 500, color: 0x8B4513, description: "Basic passenger. Can use custom text colors." }, { name: "Second Class", exp: 1500, color: 0xC0C0C0, description: "Mid-tier passenger. Can share links to photos." }, { name: "First Class", exp: 3000, color: 0xFFD700, description: "Upper-class passenger. Can direct message others." }, { name: "Crew Member", exp: 5000, color: 0x4169E1, description: "Ship staff. Can delete your own messages." }, { name: "Captain", exp: 10000, color: 0x000080, description: "The ship's leader. Can share videos and pins." }]; var currentExp = storage.experience || 0; var yPos = -650; classes.forEach(function (classInfo, index) { var isUnlocked = currentExp >= classInfo.exp; var isCurrentClass = false; if (index === 0 && storage.socialClass === 'coal') isCurrentClass = true; if (index === 1 && storage.socialClass === 'thirdClass') isCurrentClass = true; if (index === 2 && storage.socialClass === 'secondClass') isCurrentClass = true; if (index === 3 && storage.socialClass === 'firstClass') isCurrentClass = true; if (index === 4 && storage.socialClass === 'crew') isCurrentClass = true; if (index === 5 && storage.socialClass === 'captain') isCurrentClass = true; // Class background var classBg = self.attachAsset('chatBubble', { anchorX: 0.5, anchorY: 0.5, width: 1400, height: 220, x: 0, y: yPos }); if (isCurrentClass) { classBg.tint = 0xE6F3FF; // Highlight current class } else if (!isUnlocked) { classBg.tint = 0xDDDDDD; // Gray out locked classes } // Class icon var classIconAsset = self.attachAsset('classIcon', { anchorX: 0.5, anchorY: 0.5, x: -600, y: yPos }); classIconAsset.tint = parseInt(classInfo.color.replace('#', '0x')); // Class name var classNameText = new Text2(classInfo.name.toUpperCase(), { size: 40, fill: classInfo.color }); classNameText.anchor.set(0, 0.5); classNameText.x = -500; classNameText.y = yPos - 50; self.addChild(classNameText); // Experience required var expText = new Text2("Required: " + classInfo.exp + " XP", { size: 26, fill: 0x555555 }); expText.anchor.set(0, 0.5); expText.x = -500; expText.y = yPos; self.addChild(expText); // Status var statusText = new Text2(isCurrentClass ? "CURRENT" : isUnlocked ? "UNLOCKED" : "LOCKED", { size: 30, fill: isCurrentClass ? "#008000" : isUnlocked ? "#0000FF" : "#FF0000" }); statusText.anchor.set(1, 0.5); statusText.x = 600; statusText.y = yPos - 50; self.addChild(statusText); // Description var descText = new Text2(classInfo.description, { size: 28, fill: 0x000000 }); descText.anchor.set(0, 0.5); descText.x = -500; descText.y = yPos + 50; self.addChild(descText); yPos += 280; }); // Current progress var progressText = new Text2("Your Experience: " + currentExp + " XP", { size: 36, fill: 0x000080 }); progressText.anchor.set(0.5); progressText.x = 0; progressText.y = 700; self.addChild(progressText); return self; }); var StoreItem = Container.expand(function (name, description, price, type, content, isPurchased) { var self = Container.call(this); var background = self.attachAsset('chatBubble', { anchorX: 0, anchorY: 0, width: 750, height: 180 }); // Item name var nameText = new Text2(name, { size: 30, fill: 0x000080 }); nameText.x = 20; nameText.y = 15; self.addChild(nameText); // Description var descText = new Text2(description, { size: 22, fill: 0x000000 }); descText.x = 20; descText.y = 55; // Limit text width if (descText.width > 700) { descText.scale.set(700 / descText.width); } self.addChild(descText); // Preview (emoji or text representation of gif) var previewText = new Text2(content, { size: 40 }); previewText.x = 20; previewText.y = 100; self.addChild(previewText); // Price or purchased status var statusText; if (isPurchased) { statusText = new Text2("OWNED", { size: 28, fill: 0x008000 }); } else { statusText = new Text2(price + " 🪙", { size: 28, fill: 0xFF8C00 }); // Buy button for unpurchased items var buyButton = self.attachAsset('sendButton', { anchorX: 0.5, anchorY: 0.5, width: 100, height: 50, x: 675, y: 140 }); var buyText = new Text2("BUY", { size: 24, fill: 0xFFFFFF }); buyText.anchor.set(0.5); buyText.x = 675; buyText.y = 140; self.addChild(buyText); } statusText.x = 600; statusText.y = 30; self.addChild(statusText); self.interactive = true; self.name = name; self.price = price; self.type = type; self.content = content; self.isPurchased = isPurchased; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB // Sky blue background (ocean theme) }); /**** * Game Code ****/ // Game variables var messages = []; var emojiPanel = null; var storePanel = null; var socialClassPanel = null; var inputText = ""; var lastMessageTime = 0; var botMessageInterval = 60000; // 1 minute between bot messages var expGainInterval = 30000; // 30 seconds between exp gains var lastExpGain = Date.now(); var isInputFocused = false; var titanicFacts = ["The Titanic was 882 feet (269 meters) long and 175 feet (53 meters) tall.", "The ship's top speed was 24 knots (28 mph).", "The Titanic had 3 million rivets holding it together.", "First-class passengers enjoyed a swimming pool, gym, and Turkish bath.", "The ship had its own newspaper called the 'Atlantic Daily Bulletin'.", "The Titanic's whistles could be heard from 10 miles away.", "There were 840 staterooms on the Titanic — 416 in first class.", "The ship had three propellers, with the center one measuring 17 feet in diameter.", "The Titanic carried 20,000 bottles of beer and 1,500 bottles of wine.", "The ship had 16 watertight compartments but could only stay afloat if 4 flooded.", "The fourth smokestack was fake, added for aesthetics and ventilation.", "The Titanic's radio operators used the new 'SOS' distress signal.", "The maiden voyage had 2,223 people on board, but lifeboats for only 1,178.", "The Titanic hit the iceberg at 11:40 PM on April 14, 1912.", "The ship took 2 hours and 40 minutes to sink after hitting the iceberg.", "The water temperature was about 28°F (-2°C) the night of the sinking.", "Only 705 people survived the disaster.", "The wreck wasn't discovered until 1985, 73 years after it sank.", "The ship broke into two pieces as it sank.", "Third-class passengers had access to two bathtubs—for all 700+ people."]; // Emojis and store items data var availableEmojis = [{ emoji: "🚢", price: 10 }, { emoji: "⚓", price: 10 }, { emoji: "🧊", price: 20 }, { emoji: "🌊", price: 20 }, { emoji: "🔱", price: 30 }, { emoji: "⛵", price: 30 }, { emoji: "🧭", price: 40 }, { emoji: "🌅", price: 40 }, { emoji: "💎", price: 50 }, { emoji: "👑", price: 100 }]; var storeItems = [{ name: "Titanic Model", description: "A beautiful model of the Titanic ship", price: 100, type: "gif", content: "🚢" }, { name: "Captain's Hat", description: "Show your authority with this special hat", price: 200, type: "gif", content: "👒" }, { name: "Iceberg Warning", description: "Alert others of danger ahead!", price: 150, type: "gif", content: "⚠️🧊" }, { name: "First Class Ticket", description: "VIP treatment without the experience requirement", price: 500, type: "special", content: "🎫" }, { name: "Custom Name Color", description: "Change your name color (available to all classes)", price: 50, type: "color", content: "🎨" }]; // UI Components var createUI = function createUI() { // Main chat container var chatContainer = new Container(); chatContainer.x = 0; chatContainer.y = 0; game.addChild(chatContainer); // Ocean background with gradient var oceanTop = LK.getAsset('chatBubble', { anchorX: 0, anchorY: 0, width: 2048, height: 2732 }); oceanTop.tint = 0x87CEEB; // Sky blue chatContainer.addChild(oceanTop); // Chat header var headerBar = LK.getAsset('chatBubble', { anchorX: 0, anchorY: 0, width: 2048, height: 120, x: 0, y: 0 }); headerBar.tint = 0x1A5276; // Dark blue chatContainer.addChild(headerBar); // Title var titleText = new Text2("TITANIC CHAT", { size: 60, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 60; chatContainer.addChild(titleText); // Profile button var profileBtn = LK.getAsset('profileIcon', { anchorX: 0.5, anchorY: 0.5, x: 1948, y: 60 }); profileBtn.interactive = true; chatContainer.addChild(profileBtn); profileBtn.down = function () { if (!socialClassPanel) { socialClassPanel = new SocialClassPanel(); socialClassPanel.x = 2048 / 2; socialClassPanel.y = 2732 / 2; chatContainer.addChild(socialClassPanel); } else { socialClassPanel.visible = !socialClassPanel.visible; } }; // Store button var storeBtn = LK.getAsset('storeButton', { anchorX: 0.5, anchorY: 0.5, x: 150, y: 60 }); storeBtn.interactive = true; chatContainer.addChild(storeBtn); var storeBtnText = new Text2("💰", { size: 50 }); storeBtnText.anchor.set(0.5); storeBtnText.x = 150; storeBtnText.y = 60; chatContainer.addChild(storeBtnText); storeBtn.down = function () { openStore(); }; // Coin display var coinBackground = LK.getAsset('chatBubble', { anchorX: 0, anchorY: 0, width: 200, height: 60, x: 250, y: 30 }); coinBackground.tint = 0xFFD700; // Gold chatContainer.addChild(coinBackground); var coinText = new Text2("🪙 " + (storage.coins || 0), { size: 40, fill: 0x000000 }); coinText.anchor.set(0.5); coinText.x = 350; coinText.y = 60; chatContainer.addChild(coinText); // Social class display var classBackground = LK.getAsset('chatBubble', { anchorX: 0, anchorY: 0, width: 300, height: 60, x: 480, y: 30 }); classBackground.tint = 0xF5F5F5; chatContainer.addChild(classBackground); var classText = new Text2("CLASS: " + getDisplayNameForClass(storage.socialClass), { size: 30, fill: 0x000080 }); classText.anchor.set(0.5); classText.x = 630; classText.y = 60; chatContainer.addChild(classText); // Messages container var messagesContainer = new Container(); messagesContainer.x = 0; messagesContainer.y = 130; chatContainer.addChild(messagesContainer); // Input area var inputBar = LK.getAsset('chatBubble', { anchorX: 0, anchorY: 0, width: 2048, height: 140, x: 0, y: 2592 }); inputBar.tint = 0xE5E8E8; // Light gray chatContainer.addChild(inputBar); // Text input box var inputBox = LK.getAsset('inputBox', { anchorX: 0, anchorY: 0.5, x: 120, y: 2662 }); inputBox.interactive = true; chatContainer.addChild(inputBox); var inputTextDisplay = new Text2("Tap to chat...", { size: 36, fill: 0x777777 }); inputTextDisplay.anchor.set(0, 0.5); inputTextDisplay.x = 150; inputTextDisplay.y = 2662; chatContainer.addChild(inputTextDisplay); inputBox.down = function () { isInputFocused = true; // Show a simulated keyboard focus inputBox.tint = 0xE6F3FF; // Light blue tint if (inputText === "") { inputTextDisplay.setText("Type here..."); inputTextDisplay.style.fill = "#000000"; } }; // Add emoji button var emojiBtn = LK.getAsset('emojiButton', { anchorX: 0.5, anchorY: 0.5, x: 80, y: 2662 }); emojiBtn.interactive = true; chatContainer.addChild(emojiBtn); var emojiBtnText = new Text2("😀", { size: 40 }); emojiBtnText.anchor.set(0.5); emojiBtnText.x = 80; emojiBtnText.y = 2662; chatContainer.addChild(emojiBtnText); emojiBtn.down = function () { _toggleEmojiPanel(); }; // Send button var sendBtn = LK.getAsset('sendButton', { anchorX: 0.5, anchorY: 0.5, x: 1888, y: 2662 }); sendBtn.interactive = true; chatContainer.addChild(sendBtn); var sendBtnText = new Text2("SEND", { size: 36, fill: 0xFFFFFF }); sendBtnText.anchor.set(0.5); sendBtnText.x = 1888; sendBtnText.y = 2662; chatContainer.addChild(sendBtnText); sendBtn.down = function () { sendMessage(); }; // Add welcome message addSystemMessage("Welcome to Titanic Chat! You're starting as a Coal Worker. Chat to earn coins and experience!"); addBotMessage("Hello! I'm TitanicBot. I'll share interesting facts about the Titanic with you periodically. Chat to earn coins and experience!"); // Create a virtual keyboard for simulation createVirtualKeyboard(chatContainer); // Play background music LK.playMusic('oceanWaves', { loop: true }); // Update UI references uiRefs = { chatContainer: chatContainer, messagesContainer: messagesContainer, coinText: coinText, classText: classText, inputTextDisplay: inputTextDisplay, inputBox: inputBox }; }; // Virtual keyboard for simulation var createVirtualKeyboard = function createVirtualKeyboard(parent) { var keyboard = new Container(); keyboard.x = 0; keyboard.y = 2140; keyboard.visible = false; parent.addChild(keyboard); var keyboardBg = LK.getAsset('chatBubble', { anchorX: 0, anchorY: 0, width: 2048, height: 450, x: 0, y: 0 }); keyboardBg.tint = 0xCCCCCC; keyboard.addChild(keyboardBg); // Create row of letter keys var lettersRow1 = "QWERTYUIOP"; var lettersRow2 = "ASDFGHJKL"; var lettersRow3 = "ZXCVBNM"; var createKey = function createKey(letter, x, y) { var key = LK.getAsset('chatBubble', { anchorX: 0.5, anchorY: 0.5, width: 150, height: 100, x: x, y: y }); key.tint = 0xFFFFFF; key.interactive = true; keyboard.addChild(key); var keyText = new Text2(letter, { size: 40, fill: 0x000000 }); keyText.anchor.set(0.5); keyText.x = x; keyText.y = y; keyboard.addChild(keyText); key.down = function () { if (letter === "⌫") { // Backspace if (inputText.length > 0) { inputText = inputText.slice(0, -1); } } else if (letter === "⏎") { // Enter/Return sendMessage(); } else if (letter === "␣") { // Space inputText += " "; } else if (letter === "⬆") {// Shift // Toggle uppercase/lowercase (not implemented in this demo) } else if (letter === "123") {// Switch to numbers // Switch keyboard layout (not implemented in this demo) } else if (letter === "ABC") {// Switch to letters // Switch keyboard layout (not implemented in this demo) } else if (letter === "⌧") { // Close keyboard keyboard.visible = false; isInputFocused = false; uiRefs.inputBox.tint = 0xFFFFFF; if (inputText === "") { uiRefs.inputTextDisplay.setText("Tap to chat..."); uiRefs.inputTextDisplay.style.fill = "#777777"; } } else { inputText += letter; } // Update input display updateInputDisplay(); }; return key; }; // Create keyboard rows for (var i = 0; i < lettersRow1.length; i++) { createKey(lettersRow1[i], 124 + i * 180, 50); } for (var i = 0; i < lettersRow2.length; i++) { createKey(lettersRow2[i], 214 + i * 180, 160); } // Special keys on third row createKey("⬆", 124, 270); // Shift for (var i = 0; i < lettersRow3.length; i++) { createKey(lettersRow3[i], 304 + i * 180, 270); } createKey("⌫", 1924, 270); // Backspace // Bottom row with special keys createKey("123", 124, 380); // Numbers createKey("␣", 1024, 380); // Space createKey("⏎", 1744, 380); // Enter createKey("⌧", 1924, 380); // Close // Save reference virtualKeyboard = keyboard; }; // Helper functions var getDisplayNameForClass = function getDisplayNameForClass(classId) { switch (classId) { case 'coal': return 'COAL WORKER'; case 'thirdClass': return '3RD CLASS'; case 'secondClass': return '2ND CLASS'; case 'firstClass': return '1ST CLASS'; case 'crew': return 'CREW'; case 'captain': return 'CAPTAIN'; default: return 'UNKNOWN'; } }; var updateInputDisplay = function updateInputDisplay() { if (inputText === "") { uiRefs.inputTextDisplay.setText("Type here..."); } else { uiRefs.inputTextDisplay.setText(inputText); } }; var _toggleEmojiPanel = function toggleEmojiPanel() { if (emojiPanel && emojiPanel.visible) { emojiPanel.visible = false; return; } if (!emojiPanel) { // Create emoji panel emojiPanel = new Container(); emojiPanel.x = 1024; emojiPanel.y = 2300; uiRefs.chatContainer.addChild(emojiPanel); var panelBg = LK.getAsset('emojiPanel', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); emojiPanel.addChild(panelBg); // Close button var closeBtn = LK.getAsset('closeButton', { anchorX: 0.5, anchorY: 0.5, x: 380, y: -130 }); closeBtn.interactive = true; emojiPanel.addChild(closeBtn); var closeText = new Text2("X", { size: 40, fill: 0xFFFFFF }); closeText.anchor.set(0.5); closeText.x = 380; closeText.y = -130; emojiPanel.addChild(closeText); closeBtn.down = function () { emojiPanel.visible = false; }; // Add emojis var emojiX = -350; var emojiY = -100; var count = 0; availableEmojis.forEach(function (emojiData) { var isPurchased = (storage.purchasedEmojis || []).indexOf(emojiData.emoji) !== -1; var emojiItem = new EmojiItem(emojiData.emoji, emojiData.price, isPurchased); emojiItem.x = emojiX; emojiItem.y = emojiY; emojiPanel.addChild(emojiItem); emojiItem.down = function () { if (isPurchased) { // Use emoji inputText += emojiData.emoji; updateInputDisplay(); emojiPanel.visible = false; } else { // Try to purchase if (storage.coins >= emojiData.price) { storage.coins -= emojiData.price; if (!storage.purchasedEmojis) storage.purchasedEmojis = []; storage.purchasedEmojis.push(emojiData.emoji); // Update coin display uiRefs.coinText.setText("🪙 " + storage.coins); // Play purchase sound LK.getSound('coin').play(); // Update emoji panel emojiPanel.visible = false; emojiPanel.destroy(); emojiPanel = null; _toggleEmojiPanel(); } else { // Not enough coins addSystemMessage("You don't have enough coins to purchase this emoji."); } } }; count++; emojiX += 140; if (count % 5 === 0) { emojiX = -350; emojiY += 140; } }); // Add default emojis var defaultEmojis = ["😀", "😊", "🙂", "😍", "😎", "😢", "😭", "🤔", "👍", "👎"]; var defaultX = -350; var defaultY = 100; count = 0; defaultEmojis.forEach(function (emoji) { var emojiItem = new EmojiItem(emoji, 0, true); emojiItem.x = defaultX; emojiItem.y = defaultY; emojiPanel.addChild(emojiItem); emojiItem.down = function () { inputText += emoji; updateInputDisplay(); emojiPanel.visible = false; }; count++; defaultX += 140; if (count % 5 === 0) { defaultX = -350; defaultY += 140; } }); } else { emojiPanel.visible = true; } }; var openStore = function openStore() { if (storePanel && storePanel.visible) { storePanel.visible = false; return; } if (!storePanel) { // Create store panel storePanel = new Container(); storePanel.x = 1024; storePanel.y = 1366; uiRefs.chatContainer.addChild(storePanel); var panelBg = LK.getAsset('storePanel', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); storePanel.addChild(panelBg); // Title var titleText = new Text2("TITANIC STORE", { size: 60, fill: 0x000080 }); titleText.anchor.set(0.5, 0); titleText.x = 0; titleText.y = -650; storePanel.addChild(titleText); // Close button var closeBtn = LK.getAsset('closeButton', { anchorX: 0.5, anchorY: 0.5, x: 750, y: -650 }); closeBtn.interactive = true; storePanel.addChild(closeBtn); var closeText = new Text2("X", { size: 40, fill: 0xFFFFFF }); closeText.anchor.set(0.5); closeText.x = 750; closeText.y = -650; storePanel.addChild(closeText); closeBtn.down = function () { storePanel.visible = false; }; // Coin display var storeCoinsText = new Text2("Your Coins: 🪙 " + (storage.coins || 0), { size: 40, fill: 0xFFD700 }); storeCoinsText.anchor.set(0.5, 0); storeCoinsText.x = 0; storeCoinsText.y = -550; storePanel.addChild(storeCoinsText); // Add store items var itemsY = -450; storeItems.forEach(function (itemData) { var isPurchased = false; if (itemData.type === "gif" && storage.purchasedGifs && storage.purchasedGifs.indexOf(itemData.name) !== -1) { isPurchased = true; } else if (itemData.type === "emoji" && storage.purchasedEmojis && storage.purchasedEmojis.indexOf(itemData.content) !== -1) { isPurchased = true; } else if (itemData.type === "special" && storage.specialItems && storage.specialItems.indexOf(itemData.name) !== -1) { isPurchased = true; } else if (itemData.type === "color" && storage.hasColorChange) { isPurchased = true; } var storeItem = new StoreItem(itemData.name, itemData.description, itemData.price, itemData.type, itemData.content, isPurchased); storeItem.x = 0; storeItem.y = itemsY; storePanel.addChild(storeItem); storeItem.down = function () { if (!isPurchased) { // Try to purchase if (storage.coins >= itemData.price) { storage.coins -= itemData.price; if (itemData.type === "gif") { if (!storage.purchasedGifs) storage.purchasedGifs = []; storage.purchasedGifs.push(itemData.name); } else if (itemData.type === "emoji") { if (!storage.purchasedEmojis) storage.purchasedEmojis = []; storage.purchasedEmojis.push(itemData.content); } else if (itemData.type === "special") { if (!storage.specialItems) storage.specialItems = []; storage.specialItems.push(itemData.name); // Special handling for special items if (itemData.name === "First Class Ticket") { if (["coal", "thirdClass", "secondClass"].indexOf(storage.socialClass) !== -1) { storage.socialClass = "firstClass"; uiRefs.classText.setText("CLASS: " + getDisplayNameForClass(storage.socialClass)); addSystemMessage("Congratulations! You've been upgraded to First Class!"); } else { addSystemMessage("You're already in a higher class than First Class!"); } } } else if (itemData.type === "color") { storage.hasColorChange = true; // Show color picker (simplified) var colors = ["#FF0000", "#00FF00", "#0000FF", "#FFFF00", "#FF00FF", "#00FFFF"]; var colorIndex = Math.floor(Math.random() * colors.length); storage.playerColor = colors[colorIndex]; addSystemMessage("Your name color has been changed!"); } // Update coin displays uiRefs.coinText.setText("🪙 " + storage.coins); storeCoinsText.setText("Your Coins: 🪙 " + storage.coins); // Play purchase sound LK.getSound('coin').play(); // Update store panel storePanel.visible = false; storePanel.destroy(); storePanel = null; addSystemMessage("Purchase successful: " + itemData.name); } else { // Not enough coins addSystemMessage("You don't have enough coins to purchase this item."); } } else if (itemData.type === "gif") { // Use the gif in chat sendGif(itemData.content); storePanel.visible = false; } }; itemsY += 200; }); } else { storePanel.visible = true; } }; var addMessage = function addMessage(message, fromPlayer, isBot) { // Check if UI references exist if (!uiRefs || !uiRefs.messagesContainer) { console.log("Error: Messages container not initialized yet"); return null; } var messagesContainer = uiRefs.messagesContainer; var messageY = 0; // Calculate position based on existing messages if (messages.length > 0) { var lastMessage = messages[messages.length - 1]; messageY = lastMessage.y + lastMessage.height + 20; } // Add new message var chatMessage = new ChatMessage(message, fromPlayer ? storage.playerName : isBot ? "TitanicBot" : "System", isBot, fromPlayer ? storage.socialClass : "bot"); chatMessage.x = 24; chatMessage.y = messageY; messagesContainer.addChild(chatMessage); // Keep track of messages messages.push(chatMessage); // Scroll to bottom if too many messages if (messages.length > 10) { // Shift viewable window for (var i = 0; i < messages.length; i++) { tween(messages[i], { y: messages[i].y - 170 }, { duration: 300 }); } // Remove oldest message if it's offscreen if (messages[0].y < -200) { var oldest = messages.shift(); tween(oldest, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { oldest.destroy(); } }); } } return chatMessage; }; var addSystemMessage = function addSystemMessage(message) { return addMessage(message, false, false); }; var addBotMessage = function addBotMessage(message) { var msg = addMessage(message, false, true); lastMessageTime = Date.now(); return msg; }; var sendMessage = function sendMessage() { if (inputText.trim() === "") { return; } // Add player message addMessage(inputText, true, false); // Play message sound LK.getSound('message').play(); // Award coins (1-3 per message) var coinsEarned = Math.floor(Math.random() * 3) + 1; storage.coins = (storage.coins || 0) + coinsEarned; uiRefs.coinText.setText("🪙 " + storage.coins); // Clear input inputText = ""; updateInputDisplay(); // Hide virtual keyboard if (virtualKeyboard) { virtualKeyboard.visible = false; } isInputFocused = false; uiRefs.inputBox.tint = 0xFFFFFF; uiRefs.inputTextDisplay.setText("Tap to chat..."); uiRefs.inputTextDisplay.style.fill = "#777777"; }; var sendGif = function sendGif(gifContent) { // Create a special message with just the gif emoji (representing a gif) addMessage(gifContent + " [GIF]", true, false); // Play message sound LK.getSound('message').play(); }; var checkSocialClassUpgrade = function checkSocialClassUpgrade() { var currentExp = storage.experience || 0; var currentClass = storage.socialClass; var newClass = currentClass; // Check for class upgrades if (currentClass === 'coal' && currentExp >= 500) { newClass = 'thirdClass'; } else if (currentClass === 'thirdClass' && currentExp >= 1500) { newClass = 'secondClass'; } else if (currentClass === 'secondClass' && currentExp >= 3000) { newClass = 'firstClass'; } else if (currentClass === 'firstClass' && currentExp >= 5000) { newClass = 'crew'; } else if (currentClass === 'crew' && currentExp >= 10000) { newClass = 'captain'; } // If eligible for upgrade if (newClass !== currentClass) { storage.socialClass = newClass; uiRefs.classText.setText("CLASS: " + getDisplayNameForClass(newClass)); // Play unlock sound and show message LK.getSound('unlock').play(); addSystemMessage("Congratulations! You've been promoted to " + getDisplayNameForClass(newClass) + "!"); // Flash the class text LK.effects.flashObject(uiRefs.classText, 0xFFD700, 1000); } }; // Create UI elements var uiRefs = {}; var virtualKeyboard = null; createUI(); // Game update loop game.update = function () { var currentTime = Date.now(); // Handle keyboard visibility if (isInputFocused && virtualKeyboard && !virtualKeyboard.visible) { virtualKeyboard.visible = true; } // Add experience periodically if (currentTime - lastExpGain >= expGainInterval) { storage.experience = (storage.experience || 0) + 10; lastExpGain = currentTime; // Check for class upgrades checkSocialClassUpgrade(); } // Send bot messages periodically if (currentTime - lastMessageTime >= botMessageInterval) { // Select random Titanic fact var randomFact = titanicFacts[Math.floor(Math.random() * titanicFacts.length)]; addBotMessage(randomFact); } }; // Handle game interactions game.down = function (x, y, obj) { // Handle taps outside UI elements if (y > 2140 && virtualKeyboard && virtualKeyboard.visible) { // Do nothing, let the keyboard handle it } else if (storePanel && storePanel.visible) { // Check if tap is outside store panel var localPoint = storePanel.toLocal({ x: x, y: y }); if (Math.abs(localPoint.x) > 800 || Math.abs(localPoint.y) > 700) { storePanel.visible = false; } } else if (emojiPanel && emojiPanel.visible) { // Check if tap is outside emoji panel var localPoint = emojiPanel.toLocal({ x: x, y: y }); if (Math.abs(localPoint.x) > 400 || Math.abs(localPoint.y) > 150) { emojiPanel.visible = false; } } else if (socialClassPanel && socialClassPanel.visible) { // Check if tap is outside social class panel var localPoint = socialClassPanel.toLocal({ x: x, y: y }); if (Math.abs(localPoint.x) > 800 || Math.abs(localPoint.y) > 900) { socialClassPanel.visible = false; } } else if (y > 2592 && y < 2732) { // Tapped in input area but not on a specific control isInputFocused = true; uiRefs.inputBox.tint = 0xE6F3FF; if (inputText === "") { uiRefs.inputTextDisplay.setText("Type here..."); uiRefs.inputTextDisplay.style.fill = "#000000"; } if (virtualKeyboard) { virtualKeyboard.visible = true; } } }; game.move = function (x, y, obj) { // No specific move handling needed }; game.up = function (x, y, obj) { // No specific up handling needed };
===================================================================
--- original.js
+++ change.js
@@ -9,9 +9,9 @@
purchasedEmojis: [],
purchasedGifs: [],
playerName: "Anonymous",
playerColor: "#000000",
- lastVisit: undefined
+ lastVisit: "undefined"
});
/****
* Classes
@@ -1043,8 +1043,13 @@
storePanel.visible = true;
}
};
var addMessage = function addMessage(message, fromPlayer, isBot) {
+ // Check if UI references exist
+ if (!uiRefs || !uiRefs.messagesContainer) {
+ console.log("Error: Messages container not initialized yet");
+ return null;
+ }
var messagesContainer = uiRefs.messagesContainer;
var messageY = 0;
// Calculate position based on existing messages
if (messages.length > 0) {