User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'updateLanguage')' in or related to this line: 'self.updateLanguage = function (lang) {' Line Number: 3418
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'updateLanguage')' in or related to this line: 'self.updateLanguage = function (lang) {' Line Number: 3411
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'updateLanguage')' in or related to this line: 'self.updateLanguage = function (lang) {' Line Number: 3412
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'updateLanguage')' in or related to this line: 'self.updateLanguage = function (lang) {' Line Number: 3417
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'updateLanguage')' in or related to this line: 'self.updateLanguage = function (lang) {' Line Number: 3412
User prompt
Adjust Simplified Chinese words display for Cultural Information Panel so that they are inside the panel without affecting other languages
User prompt
Make the cultural information panel bigger in size
User prompt
Try again
User prompt
Please fix the bug: 'Graphics is not a constructor' in or related to this line: 'var mask = new Graphics();' Line Number: 595
User prompt
// 1. Update CulturalInfoPanel styling var CulturalInfoPanel = Container.expand(function () { var self = Container.call(this); // Panel background with scrollable area var bg = self.attachAsset('uiPanel', { width: 1800, // Increased width height: 1300, // Increased height tint: 0xFFFAF0 }); // Add scroll container var scrollContainer = new Container(); scrollContainer.height = 1000; // Visible area height self.addChild(scrollContainer); // Title with padding self.titleText = new Text2("", { size: 60, fill: 0x4682B4, wordWrap: true, wordWrapWidth: 1600 // Match panel width }); scrollContainer.addChild(self.titleText); // Info text with proper constraints self.infoText = new Text2("", { size: 40, fill: 0x333333, wordWrap: true, wordWrapWidth: 1600, // 1600px width lineHeight: 56 // 40px font + 16px spacing }); // Add text to scroll container scrollContainer.addChild(self.infoText); // Position elements self.titleText.position.set(-800, 40); // Left align with padding self.infoText.position.set(-800, 140); // Below title // Add mask for scroll area var mask = new Graphics() .beginFill(0xFFFFFF) .drawRect(-800, 40, 1600, 1000) .endFill(); scrollContainer.mask = mask; // Add scroll interaction self.scrollY = 0; self.maxScroll = 0; self.interactive = true; self.on('wheel', (e) => { self.scrollY = Math.min(Math.max(self.scrollY + e.deltaY, -self.maxScroll), 0); scrollContainer.y = self.scrollY; }); return self; }); // 2. Update show method with language-specific formatting CulturalInfoPanel.prototype.show = function(itemKey) { const content = culturalInfoScripts[itemKey][storage.currentLanguage]; // Set language-specific styles this.infoText.style.fontFamily = this.getFontFamily(); this.infoText.style.lineHeight = this.getLineHeight(); // Calculate required space this.infoText.setText(content); const textHeight = this.infoText.height; // Update scroll limits this.maxScroll = Math.max(0, textHeight - 1000); this.scrollY = 0; scrollContainer.y = 0; // Other existing show logic... }; // 3. Add font and line height helpers CulturalInfoPanel.prototype.getFontFamily = function() { return { en: "'Arial', sans-serif", ms: "'Arial', sans-serif", zh: "'Noto Sans SC', sans-serif", ta: "'Noto Sans Tamil', sans-serif" }[storage.currentLanguage]; }; CulturalInfoPanel.prototype.getLineHeight = function() { // Taller line heights for CJK and Tamil return { en: 56, ms: 56, zh: 64, ta: 64 }[storage.currentLanguage]; };
User prompt
Show Serani's Attire for Serani female
User prompt
Still occuring error for Serani female which is accidentally show up salwar kameez panel, it should show Serani's Attire
User prompt
Fix the error of cultural information panel between Singh female and Serani female
User prompt
Add itemClick asset for selecting the items, and add categoryChange asset for appearing new attire
User prompt
Add Opensymbol when the speaker is opened, the Mutesymbol can be automatically change to Opensymbol after the speaker is opened
User prompt
Malaysian Mix music didn't play at the opening screen
User prompt
Malaysian Mix only for opening's background music, while Fashionshow only for game play background music
User prompt
Malaysian Mix background music didn't muted even though mute button is selected!!
User prompt
All the background music is muted after the mute button is selected
User prompt
Move the Mutesymbol to the bottom of the frontpage so that it doesn't overlapp with the play button at the frontpage!!
User prompt
Fix the integration failed!!
User prompt
Fix the integration failed!
User prompt
Fix the integration error!!
User prompt
Add asset Mutesymbol to replace the current mute button
User prompt
Add mute option for the background musics
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { savedCharacters: [], currentLanguage: "en", currentWardrobePage: 0 }); /**** * Classes ****/ var CategorySelector = Container.expand(function () { var self = Container.call(this); self.categories = [{ id: 'siamese', label: { en: 'Siamese', ms: 'Siam', zh: '暹罗', ta: 'சியாமீஸ்' } }, { id: 'malay', label: { en: 'Malay', ms: 'Melayu', zh: '马来', ta: 'மலாய்' } }, { id: 'chinese', label: { en: 'Chinese', ms: 'Cina', zh: '华人', ta: 'சீன' } }, { id: 'indian', label: { en: 'Indian', ms: 'India', zh: '印度', ta: 'இந்திய' } }, { id: 'singh', label: { en: 'Singh', ms: 'Singh', zh: '辛格', ta: 'சிங்' } }, { id: 'indigenous', label: { en: 'Indigenous', ms: 'Orang Asli', zh: '原住民', ta: 'பழங்குடி' } }, { id: 'iban', label: { en: 'Iban', ms: 'Iban', zh: '伊班族', ta: 'இபான்' } }, { id: 'kadazan', label: { en: 'Kadazan', ms: 'Kadazan', zh: '卡达山族', ta: 'கடசான்' } }, { id: 'babanyonya', label: { en: 'Baba Nyonya', ms: 'Baba Nyonya', zh: '峇峇娘惹', ta: 'பாபா நியோனியா' } }, { id: 'chetti', label: { en: 'Chetti', ms: 'Chetti', zh: '切蒂', ta: 'செட்டி' } }, { id: 'modern', label: { en: 'Serani', ms: 'Serani', zh: 'Serani', ta: 'Serani' } }]; self.selectedCategory = 'malay'; self.buttons = []; self.updateLanguage = function (lang) { for (var i = 0; i < self.categories.length; i++) { var cat = self.categories[i]; self.buttons[i].setText(cat.label[lang]); } }; self.setup = function () { var spacing = 220; var startX = -((self.categories.length - 1) * spacing) / 2; // Adjust Y position to separate from other UI elements self.y = -50; // Move category selector a bit higher for (var i = 0; i < self.categories.length; i++) { var cat = self.categories[i]; var lang = storage.currentLanguage; // Create panel background first var btnPanel = LK.getAsset('uiPanel', { anchorX: 0.5, anchorY: 0.5, width: 200, height: 80, tint: 0x87CEFA }); btnPanel.x = startX + i * spacing; btnPanel.y = -80; // Positioned higher to improve layout self.addChild(btnPanel); // Create button on top of panel var btn = new UIButton(cat.label[lang], 180, 60, 0x87CEFA); btn.x = startX + i * spacing; btn.y = -80; // Positioned higher to improve layout btn.categoryId = cat.id; btn.setCallback(function () { var catId = this.categoryId; LK.getSound('categoryChange').play(); self.selectedCategory = catId; self.updateButtonStates(); if (self.onCategoryChange) { self.onCategoryChange(catId); } }.bind(btn)); self.addChild(btn); self.buttons.push(btn); } self.updateButtonStates(); return self; }; self.updateButtonStates = function () { for (var i = 0; i < self.buttons.length; i++) { var btn = self.buttons[i]; if (btn.categoryId === self.selectedCategory) { btn.buttonText.style.fill = "#FFFFFF"; tween(btn.children[0], { tint: 0x4682B4 }, { duration: 200 }); } else { btn.buttonText.style.fill = "#000000"; tween(btn.children[0], { tint: 0x87CEFA }, { duration: 200 }); } } }; self.setChangeCallback = function (callback) { self.onCategoryChange = callback; return self; }; return self; }); var Character = Container.expand(function () { var self = Container.call(this); // Create character base - default to female self.gender = 'female'; var base = self.attachAsset('characterBaseFemale', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); // Layers for different clothing types self.layers = { base: base, bottom: null, top: null, headdress: null, accessory: null }; // Method to change the character gender self.setGender = function (gender) { self.gender = gender; // Remove current base if (self.layers.base) { self.removeChild(self.layers.base); } // Create new base based on gender var baseAssetId = gender === 'male' ? 'Malecharacterbase' : 'characterBaseFemale'; var newBase = self.attachAsset(baseAssetId, { anchorX: 0.5, anchorY: 0.5, scaleX: gender === 'male' ? 0.6 : 1, // Scale male character width to 60% to avoid looking too fat scaleY: gender === 'male' ? 0.5127 : 1 // Scale male character to fit 1528px height }); // Update reference self.layers.base = newBase; // Ensure proper layering self.sortLayers(); return self; }; self.equip = function (item) { if (!item) { return; } // Check if trying to equip kurta for Indian male if (item.itemName === 'kurta' && self.gender === 'male') { return self; // Don't equip kurta for Indian male } // Check if trying to equip headdress for indigenous female if (item.type === 'headdress' && self.gender === 'female' && item.category === 'indigenous') { return self; // Don't equip headdress for indigenous female } // Remove previous item in this layer if exists if (self.layers[item.type]) { self.removeChild(self.layers[item.type]); } // Add new item and store reference self.layers[item.type] = item; self.addChild(item); // Position according to type switch (item.type) { case 'top': item.y = 50; break; case 'bottom': item.y = 300; break; case 'headdress': item.y = -300; break; case 'accessory': item.y = -100; break; } // Ensure proper layering self.sortLayers(); return self; }; self.sortLayers = function () { // Manual sorting to ensure correct layering var layerOrder = ['base', 'bottom', 'top', 'accessory', 'headdress']; var zIndex = 0; layerOrder.forEach(function (layerName) { var layer = self.layers[layerName]; if (layer) { // Remove and re-add to ensure proper order if (layer.parent === self) { self.removeChild(layer); } self.addChild(layer); } }); }; self.getData = function () { var data = { gender: self.gender, items: {} }; // Store item data for each layer for (var layerName in self.layers) { if (layerName !== 'base' && self.layers[layerName]) { data.items[layerName] = { name: self.layers[layerName].itemName, category: self.layers[layerName].category }; } } return data || {}; // Return empty object if data is undefined }; self.loadData = function (data) { // Clear current items for (var layerName in self.layers) { if (layerName !== 'base' && self.layers[layerName]) { self.removeChild(self.layers[layerName]); self.layers[layerName] = null; } } // Set gender if provided in data if (data && data.gender) { self.setGender(data.gender); } // Load saved items if (data && data.items) { for (var layerName in data.items) { var itemData = data.items[layerName]; var item = new ClothingItem(layerName, itemData.category, itemData.name); self.equip(item); } } return self; }; return self; }); var ClothingItem = Container.expand(function (type, category, itemName) { var self = Container.call(this); self.type = type; self.category = category; self.itemName = itemName; // Use the appropriate asset based on item name var itemGraphics; // For all items, use the appropriate asset itemGraphics = self.attachAsset(itemName, { anchorX: 0.5, anchorY: 0.5 }); // Add specific styling for Changsan to fit button size with minimal padding if (itemName === 'Changsan') { itemGraphics.width = itemGraphics.width * 0.98; // 98% width (1% padding on each side) itemGraphics.height = itemGraphics.height * 0.98; // 98% height (1% padding on each side) } // Center the item graphics in its container if (itemGraphics) { // Store original dimensions for reference self.originalWidth = itemGraphics.width; self.originalHeight = itemGraphics.height; // Properly center the item within the container itemGraphics.x = 0; itemGraphics.y = 0; // Allow items to be displayed at their original size in buttons // Only scale down if they're extremely large if (self.originalHeight > 1500 || self.originalWidth > 900) { var scaleFactor = Math.min(900 / self.originalWidth, 1500 / self.originalHeight); // Special case for Ibanman and Ibanwoman - maintain exact 768x1528 ratio even in buttons if (itemName === 'Ibanman' || itemName === 'Ibanwoman') { scaleFactor = Math.min(768 / self.originalWidth, 1528 / self.originalHeight); // Ensure Ibanwoman is displayed properly with 768x1528 aspect ratio if (itemName === 'Ibanwoman') { // Preserve aspect ratio while ensuring proper dimensions scaleFactor = Math.min(768 / self.originalWidth, 1528 / self.originalHeight); } } itemGraphics.scale.set(scaleFactor, scaleFactor); } // For certain types, adjust position to prevent overlap if (self.type === 'headdress') { itemGraphics.y = -itemGraphics.height * 0.25; } else if (self.type === 'accessory') { itemGraphics.y = -itemGraphics.height * 0.1; } } self.select = function () { LK.getSound('itemSelect').play(); // If we're in a character and there's a base layer, hide it if (self.parent && self.parent.layers && self.parent.layers.base) { self.parent.layers.base.visible = false; } // If this is a saree, remove any bottom layer if (self.itemName === 'saree' && self.parent && self.parent.layers && self.parent.layers.bottom) { self.parent.removeChild(self.parent.layers.bottom); self.parent.layers.bottom = null; } // Scale up the attire when selected to fit 768x1528 dimensions if (self.children[0]) { // Store original scale if not already stored if (!self.originalScale) { self.originalScale = { x: self.children[0].scale.x, y: self.children[0].scale.y }; } // Calculate scale factor to fit within 768x1528 area while maximizing size var maxWidth = 768; var maxHeight = 1528; var currentWidth = self.originalWidth * self.originalScale.x; var currentHeight = self.originalHeight * self.originalScale.y; var scaleFactor = Math.min(maxWidth / currentWidth, maxHeight / currentHeight); // Special handling for Ibanman, Ibanwoman, Nyonya, and Kadazanman to ensure exact 768x1528 dimensions if (self.itemName === 'Ibanman' || self.itemName === 'Ibanwoman') { // Force exact dimensions for Ibanman and Ibanwoman var exactScaleFactor = Math.min(768 / self.originalWidth, 1528 / self.originalHeight); scaleFactor = exactScaleFactor; } else if (self.itemName === 'Nyonya' || self.itemName === 'Kadazanman') { // Make Nyonya and Kadazanman showcase exactly 768x1528 px to match other items scaleFactor = Math.min(768 / self.originalWidth, 1528 / self.originalHeight); // Special handling for Kadazanman to ensure proper visibility after selection if (self.itemName === 'Kadazanman') { // Force exact dimensions for Kadazanman showcase var exactScaleFactor = Math.min(768 / self.originalWidth, 1528 / self.originalHeight); scaleFactor = exactScaleFactor; } } // Apply larger scale with animation tween(self.children[0], { scaleX: self.originalScale.x * scaleFactor, scaleY: self.originalScale.y * scaleFactor }, { duration: 500, easing: tween.easeOut }); } // Force visibility for Nyonya specifically to prevent it from disappearing if (self.itemName === 'Nyonya') { // Make sure Nyonya is visible self.visible = true; self.alpha = 1; // Also ensure the child element is visible if (self.children[0]) { self.children[0].visible = true; self.children[0].alpha = 1; } } // Explicitly ensure the item is visible after selection self.visible = true; return self; }; self.down = function (x, y, obj) { // Handle item selection self.select(); // Show cultural info if this is a Baju Kurung if (self.itemName === 'bajuKurung' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('bajuKurung'); } // Show cultural info if this is Baju Melayu if (self.itemName === 'bajumelayu' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('bajuMelayu'); } // Show cultural info if this is Cheongsam if (self.itemName === 'cheongsam' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('cheongsam'); } // Show cultural info if this is Changsan if (self.itemName === 'Changsan' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('changsan'); } // Show cultural info if this is saree if (self.itemName === 'saree' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('indianFemale'); } // Show cultural info if this is Dhotti if (self.itemName === 'Dhotti' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('indianMale'); } // Show cultural info if this is Singhman if (self.itemName === 'Singhman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('singhMale'); } // Show cultural info if this is Singhwoman if (self.itemName === 'Singhwoman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('seraniFemale'); } // Show cultural info if this is siameseDress (Pha Sin) if (self.itemName === 'siameseDress' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('siameseFemale'); } // Show cultural info if this is siameseTop (Suea Phra Ratchathan) if (self.itemName === 'siameseTop' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('siameseMale'); } // Show cultural info if this is Seraniwoman if (self.itemName === 'Seraniwoman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('singhFemale'); } // Show cultural info if this is Seraniman if (self.itemName === 'Seraniman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('seraniMale'); } // Show cultural info if this is Indigenous if (self.itemName === 'Indigenous' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('indigenousFemale'); } // Show cultural info if this is indigenousVest with Kadazan category if (self.itemName === 'indigenousVest' && self.category === 'kadazan' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('kadazanFemale'); } // Show cultural info if this is Kadazanman if (self.itemName === 'Kadazanman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('kadazanMale'); } // Show cultural info if this is Ibanman if (self.itemName === 'Ibanman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('ibanMale'); } // Show cultural info if this is Ibanwoman if (self.itemName === 'Ibanwoman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('ibanFemale'); } // Show cultural info if this is babaNyonyaTop with male category if (self.itemName === 'babaNyonyaTop' && self.category === 'babanyonya' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('babanyonyaMale'); } // Show cultural info if this is Nyonya if (self.itemName === 'Nyonya' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('babanyonyaFemale'); } // Show cultural info if this is Chettiman if (self.itemName === 'Chettiman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('chettiMale'); } // Show cultural info if this is Chettiwoman if (self.itemName === 'Chettiwoman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('chettiFemale'); } }; return self; }); var CulturalInfoPanel = Container.expand(function () { var self = Container.call(this); // Create background panel with improved size and positioning var bg = self.attachAsset('uiPanel', { anchorX: 0.5, anchorY: 0.5, width: 1600, height: 800, // Adjusted width and height for better display without overlapping tint: 0xFAFAFA // Lighter background for better contrast }); // Title text self.titleText = new Text2("Cultural Information", { size: 60, fill: 0x4682B4 }); self.titleText.anchor.set(0.5, 0); self.titleText.y = -bg.height / 2 + 60; self.addChild(self.titleText); // Info text with word wrapping self.infoText = new Text2("", { size: 36, fill: 0x333333, wordWrap: true, wordWrapWidth: 1650 // Increased width for better text wrapping }); self.infoText.anchor.set(0.5, 0); self.infoText.y = -bg.height / 2 + 140; self.addChild(self.infoText); // Close button var closeButton = new UIButton("X", 80, 80, 0xF44336); closeButton.x = bg.width / 2 - 80; closeButton.y = -bg.height / 2 + 60; // Better positioned close button closeButton.setCallback(function () { self.hide(); }); self.addChild(closeButton); // Show panel with specific item info self.show = function (itemName) { // Hide panel initially for animation self.visible = true; self.alpha = 0; // Center the panel on screen vertically self.y = 2732 / 2 - 350; // Position even higher on screen to ensure full visibility // Get current language var lang = storage.currentLanguage; // Update title based on language and item var titleTranslations = _defineProperty(_defineProperty({ bajuKurung: { en: "Baju Kurung", ms: "Baju Kurung", zh: "马来传统服装", ta: "பாஜு குருங்" }, bajuMelayu: { en: "Baju Melayu", ms: "Baju Melayu", zh: "马来男装", ta: "பாஜு மேலாயு" }, cheongsam: { en: "Cheongsam", ms: "Cheongsam", zh: "旗袍", ta: "சியோங்க்சாம்" }, changsan: { en: "Changshan", ms: "Changshan", zh: "长衫", ta: "சாங்ஷான்" }, indianFemale: { en: "Saree", ms: "Sari", zh: "纱丽", ta: "சேலை" }, indianMale: { en: "Dhoti", ms: "Dhoti", zh: "多蒂", ta: "தோட்டி" }, singhMale: { en: "Punjabi Kurta", ms: "Kurta Punjabi", zh: "旁遮普库尔塔", ta: "பஞ்சாபி குர்தா" }, singhFemale: { en: "Salwar Kameez", ms: "Salwar Kameez", zh: "沙尔瓦尔·卡米兹", ta: "சல்வார் கமீஸ்" }, siameseFemale: { en: "Pha Sin", ms: "Pha Sin", zh: "帕辛", ta: "பா சின்" }, siameseMale: { en: "Suea Phra Ratchathan", ms: "Suea Phra Ratchathan", zh: "御赐外套", ta: "சுவியா ப்ரா ராட்சாதன்" }, seraniFemale: { en: "Serani Attire", ms: "Pakaian Serani", zh: "Serani 服装", ta: "செரானி ஆடை" }, indigenousFemale: { en: "Indigenous Attire", ms: "Pakaian Orang Asli", zh: "原住民服装", ta: "பழங்குடி ஆடை" } }, "indigenousFemale", { en: "Indigenous Attire", ms: "Pakaian Orang Asli", zh: "原住民服装", ta: "பழங்குடி ஆடை" }), "default", { en: "Cultural Information", ms: "Maklumat Budaya", zh: "文化信息", ta: "கலாச்சார தகவல்" }); // Set title based on item type or use default var titleTranslations = _defineProperty(_defineProperty({ chettiFemale: { en: "Chetti Female Attire", ms: "Pakaian Wanita Chetti", zh: "切蒂女性服饰", ta: "செட்டி பெண் ஆடை" }, chettiMale: { en: "Chetti's Traditional Attire", ms: "Pakaian Tradisional Chetti", zh: "切蒂传统服饰", ta: "செட்டி பாரம்பரிய ஆடை" }, bajuKurung: { en: "Baju Kurung", ms: "Baju Kurung", zh: "马来传统服装", ta: "பாஜு குருங்" }, bajuMelayu: { en: "Baju Melayu", ms: "Baju Melayu", zh: "马来男装", ta: "பாஜு மேலாயு" }, cheongsam: { en: "Cheongsam", ms: "Cheongsam", zh: "旗袍", ta: "சியோங்க்சாம்" }, changsan: { en: "Changshan", ms: "Changshan", zh: "长衫", ta: "சாங்ஷான்" }, indianFemale: { en: "Saree", ms: "Sari", zh: "纱丽", ta: "சேலை" }, indianMale: { en: "Dhoti", ms: "Dhoti", zh: "多蒂", ta: "தோட்டி" }, singhMale: { en: "Punjabi Kurta", ms: "Kurta Punjabi", zh: "旁遮普库尔塔", ta: "பஞ்சாபி குர்தா" }, singhFemale: { en: "Salwar Kameez", ms: "Salwar Kameez", zh: "沙尔瓦尔·卡米兹", ta: "சல்வார் கமீஸ்" }, siameseFemale: { en: "Pha Sin", ms: "Pha Sin", zh: "帕辛", ta: "பா சின்" }, siameseMale: { en: "Suea Phra Ratchathan", ms: "Suea Phra Ratchathan", zh: "御赐外套", ta: "சுவியா ப்ரா ராட்சாதன்" }, seraniFemale: { en: "Serani Attire", ms: "Pakaian Serani", zh: "Serani 服装", ta: "செரானி ஆடை" }, seraniMale: { en: "Serani Attire", ms: "Pakaian Serani", zh: "Serani 服装", ta: "செரானி ஆடை" }, indigenousFemale: { en: "Indigenous Attire", ms: "Pakaian Orang Asli", zh: "原住民服装", ta: "பழங்குடி ஆடை" }, kadazanFemale: { en: "Sinuangga", ms: "Sinuangga", zh: "Sinuangga", ta: "சினுவாங்கா" }, kadazanMale: { en: "Gaung", ms: "Gaung", zh: "Gaung", ta: "கவுங்" }, ibanMale: { en: "Baju Burung", ms: "Baju Burung", zh: "Baju Burung", ta: "பாஜு புருங்" }, ibanFemale: { en: "Iban Female Attire", ms: "Pakaian Wanita Iban", zh: "伊班族女性服装", ta: "இபான் பெண் ஆடை" }, babanyonyaFemale: { en: "Baju Kebaya", ms: "Baju Kebaya", zh: "娘惹长衫", ta: "பாஜு கெபாயா" }, babanyonyaMale: { en: "Baju Lokchuan", ms: "Baju Lokchuan", zh: "峇峇长衫", ta: "பாஜு லோக்சுவான்" } }, "indigenousFemale", { en: "Indigenous Attire", ms: "Pakaian Orang Asli", zh: "原住民服装", ta: "பழங்குடி ஆடை" }), "default", { en: "Cultural Information", ms: "Maklumat Budaya", zh: "文化信息", ta: "கலாச்சார தகவல்" }); var titleText = titleTranslations[itemName] && titleTranslations[itemName][lang] || titleTranslations["default"][lang] || "Cultural Information"; self.titleText.setText(titleText); // Set content if available for this item if (culturalInfoScripts[itemName] && culturalInfoScripts[itemName][lang]) { self.infoText.setText(culturalInfoScripts[itemName][lang]); } else { // Default text if no info available var defaultText = { en: "No information available for this item.", ms: "Tiada maklumat tersedia untuk item ini.", zh: "没有关于此物品的信息。", ta: "இந்த பொருளுக்கு தகவல் இல்லை." }; self.infoText.setText(defaultText[lang]); } // Fade in animation tween(self, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); return self; }; // Hide panel self.hide = function () { self.visible = false; return self; }; // Initial state self.visible = false; return self; }); var GenderSelector = Container.expand(function () { var self = Container.call(this); self.genders = [{ id: 'female', label: { en: 'Female', ms: 'Perempuan', zh: '女', ta: 'பெண்' } }, { id: 'male', label: { en: 'Male', ms: 'Lelaki', zh: '男', ta: 'ஆண்' } }]; self.selectedGender = 'female'; self.buttons = []; self.updateLanguage = function (lang) { for (var i = 0; i < self.genders.length; i++) { var gender = self.genders[i]; self.buttons[i].setText(gender.label[lang]); } }; self.setup = function () { // Create buttons vertically stacked var spacing = -100; // Vertical spacing between buttons var lang = storage.currentLanguage; // Create panel and button for female (top position) var femalePanel = LK.getAsset('uiPanel', { anchorX: 0.5, anchorY: 0.5, width: 200, height: 80, tint: 0x87CEFA }); femalePanel.y = spacing; // Position above center self.addChild(femalePanel); var femaleBtn = new UIButton(self.genders[0].label[lang], 180, 60, 0x87CEFA); femaleBtn.y = spacing; // Position above center femaleBtn.genderId = 'female'; femaleBtn.setCallback(function () { LK.getSound('categoryChange').play(); self.selectedGender = 'female'; self.updateButtonStates(); if (self.onGenderChange) { self.onGenderChange('female'); } }.bind(femaleBtn)); self.addChild(femaleBtn); self.buttons.push(femaleBtn); // Create panel and button for male (bottom position) var malePanel = LK.getAsset('uiPanel', { anchorX: 0.5, anchorY: 0.5, width: 200, height: 80, tint: 0x87CEFA }); malePanel.y = -spacing; // Position below center self.addChild(malePanel); var maleBtn = new UIButton(self.genders[1].label[lang], 180, 60, 0x87CEFA); maleBtn.y = -spacing; // Position below center maleBtn.genderId = 'male'; maleBtn.setCallback(function () { LK.getSound('categoryChange').play(); self.selectedGender = 'male'; self.updateButtonStates(); if (self.onGenderChange) { self.onGenderChange('male'); } }.bind(maleBtn)); self.addChild(maleBtn); self.buttons.push(maleBtn); self.updateButtonStates(); return self; }; self.updateButtonStates = function () { for (var i = 0; i < self.buttons.length; i++) { var btn = self.buttons[i]; if (btn.genderId === self.selectedGender) { btn.buttonText.style.fill = "#FFFFFF"; tween(btn.children[0], { tint: 0x4682B4 }, { duration: 200 }); } else { btn.buttonText.style.fill = "#000000"; tween(btn.children[0], { tint: 0x87CEFA }, { duration: 200 }); } } }; self.setChangeCallback = function (callback) { self.onGenderChange = callback; return self; }; return self; }); var ItemSelector = Container.expand(function () { var self = Container.call(this); self.items = { siamese: { female: { top: [{ name: 'siameseDress', label: { en: 'Siamese Dress', ms: 'Pakaian Siam', zh: '暹罗服装', ta: 'சியாமீஸ் ஆடை' } }], headdress: [] }, male: { top: [{ name: 'siameseTop', label: { en: 'Siamese Attire', ms: 'Pakaian Siam', zh: '暹罗男装', ta: 'சியாமீஸ் ஆடை' } }], headdress: [] } }, singh: { female: { top: [{ name: 'Singhwoman', label: { en: 'Salwar Kameez', ms: 'Salwar Kameez', zh: '沙尔瓦尔·卡米兹', ta: 'சல்வார் கமீஸ்' } }], headdress: [] }, male: { top: [{ name: 'Singhman', label: { en: 'Punjabi Kurta', ms: 'Kurta Punjabi', zh: '旁遮普库尔塔', ta: 'பஞ்சாபி குர்தா' } }] } }, malay: { female: { top: [{ name: 'bajuKurung', label: { en: 'Baju Kurung', ms: 'Baju Kurung', zh: '马来传统服装', ta: 'பாஜு குருங்' } }], headdress: [] }, male: { top: [{ name: 'bajuMelayu', label: { en: 'Baju Melayu', ms: 'Baju Melayu', zh: '马来男装', ta: 'பாஜு மேலாயு' } }], headdress: [] } }, chinese: { female: { top: [{ name: 'cheongsam', label: { en: 'Cheongsam', ms: 'Cheongsam', zh: '旗袍', ta: 'சியோங்சாம்' } }], accessory: [] }, male: { top: [{ name: 'Changsan', label: { en: 'Changshan', ms: 'Changshan', zh: '长衫', ta: 'சாங்ஷான்' } }], accessory: [] } }, indian: { female: { top: [{ name: 'saree', label: { en: 'Saree', ms: 'Sari', zh: '纱丽', ta: 'சேலை' } }], accessory: [] }, male: { top: [{ name: 'kurta', label: { en: 'Kurta', ms: 'Kurta', zh: '库尔塔', ta: 'குர்தா' } }], bottom: [{ name: 'Dhotti', label: { en: 'Dhoti', ms: 'Dhoti', zh: '多蒂', ta: 'தோட்டி' } }] } }, indigenous: { female: { top: [{ name: 'indigenousVest', label: { en: 'Traditional Vest', ms: 'Rompi Tradisional', zh: '传统背心', ta: 'பாரம்பரிய மேலாடை' } }], headdress: [{ name: 'headDress', label: { en: 'Headdress', ms: 'Hiasan Kepala', zh: '头饰', ta: 'தலை அணி' } }] }, male: {} }, iban: { female: { top: [{ name: 'indigenousVest', label: { en: 'Ngepan Vest', ms: 'Rompi Ngepan', zh: '伊班族背心', ta: 'நெகபன் மேலாடை' } }], headdress: [] }, male: { top: [{ name: 'ibanVest', label: { en: 'Iban Vest', ms: 'Rompi Iban', zh: '伊班族背心', ta: 'இபான் மேலாடை' } }], headdress: [] } }, kadazan: { female: { top: [{ name: 'indigenousVest', label: { en: 'Sinuangga Vest', ms: 'Rompi Sinuangga', zh: '卡达山族背心', ta: 'சினுவாங்க மேலாடை' } }], headdress: [] }, male: { top: [{ name: 'kadazanVest', label: { en: 'Kadazan Vest', ms: 'Rompi Kadazan', zh: '卡达山族背心', ta: 'கடசான் மேலாடை' } }], headdress: [] } }, babanyonya: { female: { top: [{ name: 'babaNyonyaTop', label: { en: 'Kebaya Nyonya', ms: 'Kebaya Nyonya', zh: '娘惹峇峇服', ta: 'கெபாயா நியோனியா' } }], bottom: [], accessory: [] }, male: { top: [{ name: 'babaNyonyaTop', label: { en: 'Baba Tunic', ms: 'Tunik Baba', zh: '峇峇上衣', ta: 'பாபா மேலாடை' } }], bottom: [], accessory: [] } }, chetti: { female: { top: [{ name: 'Chettiwoman', label: { en: 'Chetti Saree', ms: 'Sari Chetti', zh: '切蒂纱丽', ta: 'செட்டி சேலை' } }], accessory: [] }, male: { top: [{ name: 'Chettiman', label: { en: 'Chetti Veshti', ms: 'Veshti Chetti', zh: '切蒂传统服装', ta: 'செட்டி வேஷ்டி' } }], bottom: [], accessory: [] } }, modern: { female: { top: [{ name: 'modernTop', label: { en: 'Modern Top', ms: 'Atasan Moden', zh: '现代上衣', ta: 'நவீன மேல்' } }], bottom: [] }, male: { top: [{ name: 'modernMaleTop', label: { en: 'Modern Top', ms: 'Atasan Moden', zh: '现代上衣', ta: 'நவீன மேல்' } }], bottom: [] } } }; self.currentCategory = 'malay'; self.currentType = 'top'; self.itemButtons = []; self.typeButtons = []; // Group by type instead of category, considering gender self.getItemsByType = function () { var types = {}; var currentGender = typeof genderSelector !== 'undefined' && genderSelector ? genderSelector.selectedGender : 'female'; // Get all available types for current category and gender if (self.items[self.currentCategory] && self.items[self.currentCategory][currentGender]) { for (var type in self.items[self.currentCategory][currentGender]) { types[type] = true; } } return Object.keys(types); }; self.setCategory = function (category) { self.currentCategory = category; // Determine available types for this category based on gender var types = self.getItemsByType(); // Default to first type if current not available if (!types.includes(self.currentType)) { self.currentType = types.length > 0 ? types[0] : null; } // If no valid types for the current category/gender combination, don't proceed if (!self.currentType) { self.refreshTypeButtons(); return self; } self.refreshTypeButtons(); self.refreshItems(); return self; }; self.setType = function (type) { self.currentType = type; self.refreshItems(); return self; }; self.refreshTypeButtons = function () { // Clear existing buttons for (var i = 0; i < self.typeButtons.length; i++) { self.removeChild(self.typeButtons[i]); } self.typeButtons = []; var types = self.getItemsByType(); var spacing = 180; var startX = -((types.length - 1) * spacing) / 2; // Type translation mapping var typeLabels = { top: { en: 'Top', ms: 'Atas', zh: '上身', ta: 'மேல்' }, bottom: { en: 'Bottom', ms: 'Bawah', zh: '下身', ta: 'கீழ்' }, headdress: { en: 'Headdress', ms: 'Hiasan Kepala', zh: '头饰', ta: 'தலை அணி' }, accessory: { en: 'Accessory', ms: 'Aksesori', zh: '饰品', ta: 'அணிகலன்' } }; // Create buttons for each available type for (var i = 0; i < types.length; i++) { var type = types[i]; var label = typeLabels[type][storage.currentLanguage] || type; var btn = new UIButton(label, 150, 50, 0xBBBBBB); btn.x = startX + i * spacing; btn.y = -450; // Positioned even higher to prevent overlap with other UI elements btn.typeName = type; btn.setCallback(function () { self.setType(this.typeName); self.updateTypeButtonStates(); }.bind(btn)); self.addChild(btn); self.typeButtons.push(btn); } self.updateTypeButtonStates(); }; self.updateTypeButtonStates = function () { for (var i = 0; i < self.typeButtons.length; i++) { var btn = self.typeButtons[i]; if (btn.typeName === self.currentType) { btn.buttonText.style.fill = "#FFFFFF"; tween(btn.children[0], { tint: 0x555555 }, { duration: 200 }); } else { btn.buttonText.style.fill = "#000000"; tween(btn.children[0], { tint: 0xBBBBBB }, { duration: 200 }); } } }; self.refreshItems = function () { // Clear existing item buttons for (var i = 0; i < self.itemButtons.length; i++) { self.removeChild(self.itemButtons[i]); } self.itemButtons = []; var currentGender = typeof genderSelector !== 'undefined' && genderSelector ? genderSelector.selectedGender : 'female'; var currentItems = []; // Only display items when explicitly selecting from wardrobe, not on initial load var showItems = storage.initialSetupDone === true && self.currentType !== null; // Get items for the current category, gender and type only if we should show items if (showItems && self.items[self.currentCategory] && self.items[self.currentCategory][currentGender] && self.items[self.currentCategory][currentGender][self.currentType]) { currentItems = self.items[self.currentCategory][currentGender][self.currentType] || []; } // Only handle Chinese male top type properly - don't empty Changsan when it should appear if (self.currentCategory === 'chinese' && currentGender === 'male' && self.currentType === 'top') { // Check if Changsan is not already in items var hasChangsan = currentItems.some(function (item) { return item.name === 'Changsan'; }); if (!hasChangsan) { // Add Changsan if it's not already present currentItems.push({ name: 'Changsan', label: { en: 'Changshan', ms: 'Changshan', zh: '长衫', ta: 'சாங்ஷான்' } }); } } // Handle Baba Nyonya category if (self.currentCategory === 'babanyonya') { if (currentGender === 'female' && self.currentType === 'top') { // Check if babaNyonyaTop is not already in items var hasBabaNyonyaTop = currentItems.some(function (item) { return item.name === 'babaNyonyaTop'; }); if (!hasBabaNyonyaTop) { currentItems.push({ name: 'babaNyonyaTop', label: { en: 'Kebaya Nyonya', ms: 'Kebaya Nyonya', zh: '娘惹峇峇服', ta: 'கெபாயா நியோனியா' } }); } } else if (currentGender === 'male' && self.currentType === 'top') { // Check if babaNyonyaTop is not already in items for male var hasBabaNyonyaTop = currentItems.some(function (item) { return item.name === 'babaNyonyaTop'; }); if (!hasBabaNyonyaTop) { currentItems.push({ name: 'babaNyonyaTop', label: { en: 'Baba Tunic', ms: 'Tunik Baba', zh: '峇峇上衣', ta: 'பாபா மேலாடை' } }); } } // Baba Nyonya bottom items are explicitly removed } // Add Chettiman to Chetti male attire if (self.currentCategory === 'chetti') { if (self.currentType === 'top') { // Check if Chettiwoman is not already in items for female gender if (currentGender === 'female') { var hasChettiwoman = currentItems.some(function (item) { return item.name === 'Chettiwoman'; }); if (!hasChettiwoman) { currentItems.push({ name: 'Chettiwoman', label: { en: 'Chetti Saree', ms: 'Sari Chetti', zh: '切蒂纱丽', ta: 'செட்டி சேலை' } }); } } else { // For male, use Chettiman instead of chettiTop var hasChettiman = currentItems.some(function (item) { return item.name === 'Chettiman'; }); if (!hasChettiman) { currentItems.push({ name: 'Chettiman', label: { en: 'Chetti Veshti', ms: 'Veshti Chetti', zh: '切蒂传统服装', ta: 'செட்டி வேஷ்டி' } }); } } } // Removed the male bottom section for Chetti } // Filter items to ensure gender-specific clothing and prevent Changsan from appearing in non-Chinese categories var filteredItems = currentItems.filter(function (item) { // Immediately remove Changsan from all non-Chinese categories if (item.name === 'Changsan' && self.currentCategory !== 'chinese') { return false; } // Double-check to explicitly prevent Changsan from appearing in Orang Asli, Iban, and Kadazan categories if (item.name === 'Changsan' && (self.currentCategory === 'indigenous' || self.currentCategory === 'iban' || self.currentCategory === 'kadazan')) { return false; } // Double-check to explicitly prevent Changsan from appearing in Orang Asli, Iban, and Kadazan categories if (item.name === 'Changsan' && (self.currentCategory === 'indigenous' || self.currentCategory === 'iban' || self.currentCategory === 'kadazan')) { return false; } // Always ensure we're only showing items appropriate for the current gender return self.items[self.currentCategory] && self.items[self.currentCategory][currentGender] && self.items[self.currentCategory][currentGender][self.currentType] && self.items[self.currentCategory][currentGender][self.currentType].some(function (validItem) { return validItem.name === item.name; }); }); // Use larger buttons to match attire's image size for better display var buttonWidth = 900; // Width for the button var buttonHeight = 1200; // Height for the button to maintain aspect ratio var itemsPerRow = 2; // Two items per row for better utilization of space var horizontalSpacing = 950; // Spacing between items horizontally var verticalSpacing = 1300; // Spacing between rows // Create a scroll container for wardrobe items if (!self.scrollContainer) { self.scrollContainer = new Container(); self.addChild(self.scrollContainer); // Implement scroll functionality self.lastY = 0; self.isDragging = false; self.scrollY = 0; self.maxScrollY = 0; self.down = function (x, y, obj) { self.isDragging = true; self.lastY = y; }; self.move = function (x, y, obj) { if (self.isDragging) { var deltaY = y - self.lastY; self.scrollY += deltaY; // Limit scrolling if (self.scrollY > 0) { self.scrollY = 0; } else if (self.scrollY < -self.maxScrollY) { self.scrollY = -self.maxScrollY; } self.scrollContainer.y = self.scrollY; self.lastY = y; } }; self.up = function (x, y, obj) { self.isDragging = false; }; } // Create buttons for each item for (var i = 0; i < filteredItems.length; i++) { var row = Math.floor(i / itemsPerRow); var col = i % itemsPerRow; var item = filteredItems[i]; var label = item.label[storage.currentLanguage] || item.name; var itemContainer = new Container(); // Use standard button for all items { // For all items, use a larger button background var bg = LK.getAsset('itemButton', { anchorX: 0.5, anchorY: 0.5, width: 300, // Fixed to 300px width height: 300 // Fixed to 300px height }); itemContainer.addChild(bg); // Create item preview with large display var itemPreview = new ClothingItem(self.currentType, self.currentCategory, item.name); // Make all attires fit 100% of the item button size var itemAsset = itemPreview.children[0]; if (itemAsset) { // Reset scale first to ensure proper sizing itemAsset.scale.set(1, 1); // Force all attires to fit exactly 100% of the button size itemAsset.width = bg.width; itemAsset.height = bg.height; // Special case for Nyonya - scale to fill button completely if (item.name === 'Nyonya') { // Ensure Nyonya fills the entire button area (scale to 100% of button) var scaleX = bg.width / itemAsset.width; var scaleY = bg.height / itemAsset.height; itemAsset.scale.set(scaleX, scaleY); } // Special case for Ibanman and Ibanwoman - ensure it displays at 100% while maintaining aspect ratio else if (item.name === 'Ibanman' || item.name === 'Ibanwoman') { var aspectRatio = 768 / 1528; // Correct aspect ratio var scaleFactor = Math.min(bg.width / (itemAsset.width * aspectRatio), bg.height / itemAsset.height); // Use exact scaling for Ibanwoman to ensure 768x1528 ratio if (item.name === 'Ibanwoman') { // Calculate the exact scale needed to fit in button while preserving aspect ratio var exactRatio = 768 / 1528; var exactScaleFactor = Math.min(bg.width / (itemAsset.width * exactRatio), bg.height / itemAsset.height); itemAsset.scale.set(exactScaleFactor * exactRatio, exactScaleFactor); } else { itemAsset.scale.set(scaleFactor * aspectRatio, scaleFactor); } } // Center perfectly in the button itemAsset.position.set(0, 0); } itemPreview.position.set(0, 0); itemContainer.addChild(itemPreview); } // Item label for all items var itemLabel = new Text2(label, { size: 50, fill: 0x000000 }); itemLabel.anchor.set(0.5, 0); itemLabel.y = buttonHeight / 2 + 30; itemContainer.addChild(itemLabel); // Calculate grid position var gridStartX = -((itemsPerRow - 1) * horizontalSpacing) / 2; var posX = gridStartX + col * horizontalSpacing; var posY = row * verticalSpacing - 700; // Moved buttons significantly higher in the scroll container itemContainer.x = posX; itemContainer.y = posY; itemContainer.itemName = item.name; // Handle selection itemContainer.interactive = true; itemContainer.down = function (x, y, obj) { // Create and return a new ClothingItem when selected var itemInstance = new ClothingItem(self.currentType, self.currentCategory, this.itemName); if (self.onItemSelected) { LK.getSound('itemSelect').play(); self.onItemSelected(itemInstance); } // Visual feedback tween(this, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function () { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.easeOut }); }.bind(this) }); }.bind(itemContainer); self.scrollContainer.addChild(itemContainer); self.itemButtons.push(itemContainer); } // Calculate maximum scroll based on content height var totalRows = Math.ceil(filteredItems.length / itemsPerRow); var contentHeight = totalRows * verticalSpacing; var visibleHeight = 1300; // Adjusted visible area height for larger buttons self.maxScrollY = Math.max(0, contentHeight - visibleHeight); // Position scroll container for better visibility of large items self.scrollContainer.y = self.scrollY; return self; }; self.setSelectionCallback = function (callback) { self.onItemSelected = function (item) { // First call the original callback callback(item); // Show cultural info directly if this is baju kurung if (item.itemName === 'bajuKurung') { if (typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('bajuKurung'); } } // Show cultural info directly if this is siameseDress (Pha Sin) if (item.itemName === 'siameseDress') { if (typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('siameseFemale'); } } // Show cultural info directly if this is Seraniwoman if (item.itemName === 'Seraniwoman') { if (typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('singhFemale'); } } // Show cultural info directly if this is Singhman if (item.itemName === 'Singhman') { if (typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('singhMale'); } } // Show cultural info directly if this is Singhwoman if (item.itemName === 'Singhwoman') { if (typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('seraniFemale'); } } }; return self; }; return self; }); var LanguageSelector = Container.expand(function () { var self = Container.call(this); self.languages = [{ code: 'en', name: 'English' }, { code: 'ms', name: 'Bahasa Melayu' }, { code: 'zh', name: '中文' }, { code: 'ta', name: 'தமிழ்' }]; self.buttons = []; self.setup = function () { var spacing = 250; var startX = -((self.languages.length - 1) * spacing) / 2; for (var i = 0; i < self.languages.length; i++) { var lang = self.languages[i]; // Create panel background first var btnPanel = LK.getAsset('uiPanel', { anchorX: 0.5, anchorY: 0.5, width: lang.code === 'ms' ? 220 : 160, // Wider panel for Bahasa Melayu height: 70, tint: 0xDDDDDD }); btnPanel.x = startX + i * spacing; self.addChild(btnPanel); // Create button on top of panel var btn = new UIButton(lang.name, lang.code === 'ms' ? 200 : 140, 50, 0xDDDDDD); btn.x = startX + i * spacing; btn.languageCode = lang.code; btn.setCallback(function () { var langCode = this.languageCode; storage.currentLanguage = langCode; // Update button states self.updateButtonStates(); // Notify about language change if (self.onLanguageChange) { self.onLanguageChange(langCode); } }.bind(btn)); self.addChild(btn); self.buttons.push(btn); } self.updateButtonStates(); return self; }; self.updateButtonStates = function () { for (var i = 0; i < self.buttons.length; i++) { var btn = self.buttons[i]; if (btn.languageCode === storage.currentLanguage) { btn.buttonText.style.fill = "#FFFFFF"; tween(btn.children[0], { tint: 0x4682B4 }, { duration: 200 }); } else { btn.buttonText.style.fill = "#000000"; tween(btn.children[0], { tint: 0xDDDDDD }, { duration: 200 }); } } }; self.setChangeCallback = function (callback) { self.onLanguageChange = callback; return self; }; return self; }); var OpeningScreen = Container.expand(function () { var self = Container.call(this); // Create background var bg = self.attachAsset('backgroundBox', { anchorX: 0.5, anchorY: 0.5 }); // Create title self.titleText = new Text2("**Malaysian Mosaic**", { size: 100, fill: 0xFFFFFF, fontWeight: 'bold', wordWrap: true, wordWrapWidth: 1600 }); self.titleText.anchor.set(0.5, 0.5); self.titleText.y = -400; self.addChild(self.titleText); // Create language selector label self.langLabel = new Text2("Select your language", { size: 50, fill: 0xFFFFFF }); self.langLabel.anchor.set(0.5, 0.5); self.langLabel.y = -200; self.addChild(self.langLabel); // Create language buttons self.languageButtons = []; var languages = [{ code: 'en', name: 'English' }, { code: 'ms', name: 'Bahasa Melayu' }, { code: 'zh', name: '中文' }, { code: 'ta', name: 'தமிழ்' }]; var spacing = 250; var startX = -((languages.length - 1) * spacing) / 2; for (var i = 0; i < languages.length; i++) { var lang = languages[i]; // Create panel background first var btnPanel = LK.getAsset('uiPanel', { anchorX: 0.5, anchorY: 0.5, width: lang.code === 'ms' ? 300 : 240, height: 100, tint: 0xDDDDDD }); btnPanel.x = startX + i * spacing; btnPanel.y = -50; self.addChild(btnPanel); // Create button on top of panel var btn = new UIButton(lang.name, lang.code === 'ms' ? 280 : 220, 80, 0xDDDDDD); btn.x = startX + i * spacing; btn.y = -50; btn.languageCode = lang.code; btn.buttonText.style.size = 40; btn.setCallback(function () { var langCode = this.languageCode; storage.currentLanguage = langCode; // Show play button after language selection self.playButton.visible = true; self.playButtonPanel.visible = true; // Animate the play button appearing with a bounce effect tween(self.playButton, { scaleX: 1.2, scaleY: 1.2, alpha: 1 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(self.playButton, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeOut }); } }); // Also animate panel tween(self.playButtonPanel, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); // Notify about language selection if (self.onLanguageSelect) { self.onLanguageSelect(langCode); } }.bind(btn)); self.addChild(btn); self.languageButtons.push(btn); } // Create play button panel first (similar to language button panels) self.playButtonPanel = LK.getAsset('uiPanel', { anchorX: 0.5, anchorY: 0.5, width: 450, height: 170, tint: 0x4682B4 }); self.playButtonPanel.x = 0; self.playButtonPanel.y = 200; self.playButtonPanel.visible = false; self.playButtonPanel.alpha = 0; self.addChild(self.playButtonPanel); // Create a play button (larger and more prominent than the previous start button) self.playButton = new UIButton("**Play**", 400, 150, 0x4682B4); self.playButton.x = 0; self.playButton.y = 200; self.playButton.buttonText.style.size = 70; self.playButton.buttonText.style.fill = "#FFFFFF"; self.playButton.buttonText.style.fontWeight = "bold"; self.playButton.visible = false; self.playButton.alpha = 0; // Add a pulsing animation to draw attention to the play button function pulseAnimation() { tween(self.playButton.children[0], { scaleX: 1.05, scaleY: 1.05 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.playButton.children[0], { scaleX: 1, scaleY: 1 }, { duration: 800, easing: tween.easeInOut, onFinish: pulseAnimation }); } }); } // Start the pulsing animation when the play button becomes visible self.playButton.setCallback(function () { // Visual feedback on button press tween(self.playButton, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(self.playButton, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { // Call the start callback after the animation if (self.onStart) { self.onStart(); } } }); } }); }); self.addChild(self.playButton); // Method to set language select callback self.setLanguageSelectCallback = function (callback) { self.onLanguageSelect = callback; return self; }; // Method to set start callback self.setStartCallback = function (callback) { self.onStart = callback; return self; }; // Method to update language labels based on selected language self.updateLanguage = function (lang) { var translations = { title: { en: '**Malaysian Mosaic**', ms: '**Mozek Malaysia**', zh: '**马来西亚镶嵌**', ta: '**மலேசிய மொசைக்**' }, selectLanguage: { en: 'Select your language', ms: 'Pilih bahasa anda', zh: '选择你的语言', ta: 'உங்கள் மொழியைத் தேர்ந்தெடுக்கவும்' }, play: { en: 'Play', ms: 'Main', zh: '玩', ta: 'விளையாடு' } }; self.titleText.setText(translations.title[lang]); self.langLabel.setText(translations.selectLanguage[lang]); self.playButton.setText(translations.play[lang]); // Start the pulsing animation for the play button if it's visible if (self.playButton.visible) { pulseAnimation(); } return self; }; return self; }); var UIButton = Container.expand(function (text, width, height, bgColor) { var self = Container.call(this); self.width = width || 200; self.height = height || 80; self.bgColor = bgColor || 0x6495ED; var buttonBg = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, width: self.width, height: self.height, tint: self.bgColor }); self.buttonText = new Text2(text, { size: 30, fill: 0x000000 }); self.buttonText.anchor.set(0.5, 0.5); // Make sure style property exists before accessing it if (!self.buttonText.style) { self.buttonText.style = {}; } self.buttonText.style.fill = "#000000"; self.addChild(self.buttonText); self.setText = function (newText) { self.buttonText.setText(newText); if (!self.buttonText.style) { self.buttonText.style = {}; } // At this point we've ensured style exists, so we can safely access it self.buttonText.style.fill = self.buttonText.style.fill || "#000000"; return self; }; self.down = function (x, y, obj) { // Button pressed effect tween(buttonBg, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut }); }; self.up = function (x, y, obj) { // Button release effect tween(buttonBg, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.easeOut }); // Trigger callback if set if (self.callback) { self.callback(); } }; self.setCallback = function (callback) { self.callback = callback; return self; }; return self; }); var Wardrobe = Container.expand(function () { var self = Container.call(this); var background = self.attachAsset('uiPanel', { anchorX: 0.5, anchorY: 0.5, width: 1800, height: 2000, tint: 0xF5F5F5 }); var title = new Text2("Ethnic Wardrobe", { size: 60, fill: 0x4682B4 }); title.anchor.set(0.5, 0); title.y = -background.height / 2 + 40; self.addChild(title); var closeButton = new UIButton("X", 80, 80, 0xF44336); closeButton.x = background.width / 2 - 60; closeButton.y = -background.height / 2 + 60; closeButton.setCallback(function () { self.hide(); }); self.addChild(closeButton); // Create outfit container var outfitContainer = new Container(); self.addChild(outfitContainer); // Add pagination controls var leftArrow = self.attachAsset('arrowLeft', { anchorX: 0.5, anchorY: 0.5 }); leftArrow.x = -background.width / 2 + 100; leftArrow.y = background.height / 2 - 100; // Add text marker inside left arrow to indicate back var leftText = new Text2("<", { size: 50, fill: 0xFFFFFF }); leftText.anchor.set(0.5, 0.5); leftArrow.addChild(leftText); self.addChild(leftArrow); var rightArrow = self.attachAsset('arrowRight', { anchorX: 0.5, anchorY: 0.5 }); rightArrow.x = background.width / 2 - 100; rightArrow.y = background.height / 2 - 100; // Add text marker inside right arrow to indicate forward var rightText = new Text2(">", { size: 50, fill: 0xFFFFFF }); rightText.anchor.set(0.5, 0.5); rightArrow.addChild(rightText); self.addChild(rightArrow); // Add page indicator self.pageIndicator = new Text2("Page 1/2", { size: 30, fill: 0x000000 }); self.pageIndicator.anchor.set(0.5, 0.5); self.pageIndicator.y = background.height / 2 - 100; self.addChild(self.pageIndicator); // Set up arrow interactivity leftArrow.interactive = true; rightArrow.interactive = true; leftArrow.down = function (x, y, obj) { if (storage.currentWardrobePage > 0) { storage.currentWardrobePage--; self.loadOutfits(); // Provide visual feedback tween(this, { scaleX: 0.8, scaleY: 0.8 }, { duration: 100, easing: tween.easeOut, onFinish: function () { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.easeOut }); }.bind(this) }); } }.bind(leftArrow); rightArrow.down = function (x, y, obj) { if (storage.currentWardrobePage < 1) { // Only two pages (0 and 1) storage.currentWardrobePage++; self.loadOutfits(); // Provide visual feedback tween(this, { scaleX: 0.8, scaleY: 0.8 }, { duration: 100, easing: tween.easeOut, onFinish: function () { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.easeOut }); }.bind(this) }); } }.bind(rightArrow); self.updateLanguage = function (language) { var titleTranslations = { en: "Ethnic Wardrobe", ms: "Almari Pakaian Etnik", zh: "民族服装衣柜", ta: "இன ஆடை அலமாரி" }; title.setText(titleTranslations[language] || "Ethnic Wardrobe"); return self; }; self.loadOutfits = function () { var savedCharacters = storage.savedCharacters || []; // Clear existing outfits outfitContainer.removeChildren(); // Set to true to display all ethnic outfits var displayAllEthnics = true; // Only display ethnic outfits, not saved characters var outfitsToDisplay = []; // Add ethnic outfit presets if (displayAllEthnics) { var ethnicCategories = ['siamese', 'malay', 'chinese', 'indian', 'singh', 'indigenous', 'iban', 'kadazan', 'babanyonya', 'chetti', 'modern']; var currentGender = typeof genderSelector !== 'undefined' && genderSelector ? genderSelector.selectedGender : 'female'; for (var c = 0; c < ethnicCategories.length; c++) { var category = ethnicCategories[c]; var outfitData = { items: {} }; // Get available items for this ethnic category based on gender if (itemSelector.items[category] && itemSelector.items[category][currentGender]) { for (var type in itemSelector.items[category][currentGender]) { if (itemSelector.items[category][currentGender][type] && itemSelector.items[category][currentGender][type].length > 0) { // Get the first item of this type for the current gender var item = itemSelector.items[category][currentGender][type][0]; // Special case for Malay male outfit - use bajumelayu for top if (category === 'malay' && currentGender === 'male' && type === 'top') { outfitData.items[type] = { name: 'bajumelayu', category: category }; // Special case for Indian male outfit - use Dhotti for bottom } else if (category === 'indian' && currentGender === 'male' && type === 'bottom') { outfitData.items[type] = { name: 'Dhotti', category: category }; } else { outfitData.items[type] = { name: item.name, category: category }; } } } } // Only add outfit if it has items if (Object.keys(outfitData.items).length > 0) { outfitsToDisplay.push(outfitData); } } } if (outfitsToDisplay.length === 0) { var noOutfitsText = new Text2("No saved outfits", { size: 40, fill: 0x888888 }); noOutfitsText.anchor.set(0.5, 0.5); outfitContainer.addChild(noOutfitsText); return self; } // Update page indicator var totalPages = Math.ceil(outfitsToDisplay.length / 6); self.pageIndicator.setText("Page " + (storage.currentWardrobePage + 1) + "/" + totalPages); // Calculate grid layout for pagination var itemsPerRow = 3; // 3 items per row var itemsPerPage = 6; // 6 items per page var itemSize = 350; // Size for each item var padding = 60; // Padding between items var startX = -(itemsPerRow - 1) / 2 * (itemSize + padding); var startY = -300; // Position items higher in the panel // Translations for ethnic categories var categoryLabels = { siamese: { en: 'Siamese', ms: 'Siam', zh: '暹罗', ta: 'சியாமீஸ்' }, malay: { en: 'Malay', ms: 'Melayu', zh: '马来', ta: 'மலாய்' }, chinese: { en: 'Chinese', ms: 'Cina', zh: '华人', ta: 'சீன' }, indian: { en: 'Indian', ms: 'India', zh: '印度', ta: 'இந்திய' }, singh: { en: 'Singh', ms: 'Singh', zh: '辛格', ta: 'சிங்' }, indigenous: { en: 'Indigenous', ms: 'Orang Asli', zh: '原住民', ta: 'பழங்குடி' }, iban: { en: 'Iban', ms: 'Iban', zh: '伊班族', ta: 'இபான்' }, kadazan: { en: 'Kadazan', ms: 'Kadazan', zh: '卡达山族', ta: 'கடசான்' }, babanyonya: { en: 'Baba Nyonya', ms: 'Baba Nyonya', zh: '峇峇娘惹', ta: 'பாபா நியோனியா' }, chetti: { en: 'Chetti', ms: 'Chetti', zh: '切蒂', ta: 'செட்டி' }, modern: { en: 'Serani', ms: 'Serani', zh: 'Serani', ta: 'Serani' } }; // Calculate start and end indices for pagination var startIndex = storage.currentWardrobePage * itemsPerPage; var endIndex = Math.min(startIndex + itemsPerPage, outfitsToDisplay.length); // Display items for current page only for (var i = startIndex; i < endIndex; i++) { var pageIndex = i - startIndex; // Index relative to current page var row = Math.floor(pageIndex / itemsPerRow); var col = pageIndex % itemsPerRow; var outfitPreview = new Character(); // Remove base from character preview in wardrobe outfitPreview.removeChild(outfitPreview.layers.base); outfitPreview.layers.base = null; outfitPreview.scale.set(0.25, 0.25); outfitPreview.loadData(outfitsToDisplay[i]); var outfitFrame = LK.getAsset('itemButton', { anchorX: 0.5, anchorY: 0.5, width: itemSize, height: itemSize, tint: 0xEEEEEE }); var outfitItem = new Container(); outfitItem.addChild(outfitFrame); // Adjust scale of outfit preview to ensure it fits within the frame // Better calculation for scaling to ensure attire is fully visible var baseScale = 0.15; // Base scale for outfit preview outfitPreview.scale.set(baseScale, baseScale); // Ensure the preview fits while keeping attire visible var maxHeight = itemSize * 0.75; if (outfitPreview.height > maxHeight) { var heightScaleFactor = maxHeight / outfitPreview.height; outfitPreview.scale.set(baseScale * heightScaleFactor, baseScale * heightScaleFactor); } // Center the preview in the frame and adjust Y position to prevent overlap outfitPreview.position.set(0, -20); // Move up slightly to avoid overlap with label outfitItem.addChild(outfitPreview); // Calculate position based on grid layout outfitItem.x = startX + col * (itemSize + padding); outfitItem.y = startY + row * (itemSize + padding + 40); // Try to determine ethnic category var categoryName = "Outfit"; var categoryId = null; if (outfitsToDisplay[i].items && Object.keys(outfitsToDisplay[i].items).length > 0) { var firstItem = Object.values(outfitsToDisplay[i].items)[0]; if (firstItem && firstItem.category && categoryLabels[firstItem.category]) { categoryId = firstItem.category; categoryName = categoryLabels[categoryId][storage.currentLanguage] || categoryId; } } var labelText = categoryId ? categoryName : "Outfit " + (i - ethnicCategories.length + 1); var outfitLabel = new Text2(labelText, { size: 30, fill: 0x000000 }); outfitLabel.anchor.set(0.5, 0); outfitLabel.y = itemSize / 2 + 15; outfitItem.addChild(outfitLabel); // Load button functionality outfitItem.outfitData = outfitsToDisplay[i]; outfitItem.interactive = true; outfitItem.down = function (x, y, obj) { if (self.onOutfitSelected) { self.onOutfitSelected(this.outfitData); } // Visual feedback tween(this, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function () { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.easeOut }); }.bind(this) }); }.bind(outfitItem); outfitContainer.addChild(outfitItem); } return self; }; self.show = function () { // Reset to first page when opening wardrobe storage.currentWardrobePage = 0; self.visible = true; self.loadOutfits(); return self; }; self.hide = function () { self.visible = false; // Show title text when wardrobe is closed if (typeof titleText !== 'undefined' && titleText) { titleText.visible = true; } return self; }; self.setOutfitSelectedCallback = function (callback) { self.onOutfitSelected = callback; return self; }; // Initial state self.visible = false; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // MusicManager to handle music playback and muting var MusicManager = { currentMusic: null, isTransitioning: false, isMuted: false, // Play music with proper transition handling playMusic: function playMusic(musicId, options) { options = options || {}; // If same music is already playing, do nothing if (this.currentMusic === musicId && !this.isTransitioning) { return; } this.isTransitioning = true; // First stop current music completely if (this.currentMusic) { LK.stopMusic(); } // Store the music we're about to play this.currentMusic = musicId; // Wait for a short delay to ensure previous music is fully stopped LK.setTimeout(function () { // Only play music if not muted if (!this.isMuted) { // Play the new music LK.playMusic(musicId, options); } this.isTransitioning = false; }.bind(this), 300); }, // Stop music with a clean approach stopMusic: function stopMusic() { LK.stopMusic(); this.currentMusic = null; this.isTransitioning = false; }, // Toggle mute status toggleMute: function toggleMute() { this.isMuted = !this.isMuted; if (this.isMuted) { // If muting, stop current music LK.stopMusic(); } else { // If unmuting, resume current music if there is one if (this.currentMusic) { LK.playMusic(this.currentMusic); } } return this.isMuted; } }; // Initialize ItemSelector // Game constants function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } // Create opening screen var openingScreen = new OpeningScreen(); openingScreen.x = 2048 / 2; openingScreen.y = 2732 / 2; game.addChild(openingScreen); // Play Malaysian Mix as the opening music using the music manager MusicManager.playMusic('malaysiaMix'); // Create main content container that will be initially hidden var mainContent = new Container(); mainContent.visible = false; game.addChild(mainContent); var itemSelector = new ItemSelector(); itemSelector.x = 2048 / 2; itemSelector.y = 200; // Better positioned to avoid overlap with gender selector itemSelector.currentCategory = 'malay'; // Initialize current category mainContent.addChild(itemSelector); // Setup opening screen callbacks openingScreen.setLanguageSelectCallback(function (lang) { openingScreen.updateLanguage(lang); }); openingScreen.setStartCallback(function () { // Play a sound effect if available if (LK.getSound('itemSelect')) { LK.getSound('itemSelect').play(); } // First stop the Malaysian Mix music completely before any other operations MusicManager.stopMusic(); // Fade out opening screen with a more dramatic transition tween(openingScreen, { alpha: 0, scaleX: 1.1, scaleY: 1.1 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { // Remove opening screen and show main content game.removeChild(openingScreen); mainContent.visible = true; // Add a fade-in effect for main content mainContent.alpha = 0; tween(mainContent, { alpha: 1 }, { duration: 500, easing: tween.easeOut }); // Set background for main content game.setBackgroundColor(0xE6E6FA); // Mark that initial setup is done storage.initialSetupDone = true; // Play Fashionshow music using music manager MusicManager.playMusic('Fashionshow'); } }); }); // Initialize with category selection after adding to the game but don't show any items initially itemSelector.currentCategory = 'malay'; // Add Indigenous female attire itemSelector.items.indigenous.female.top = [{ name: 'Indigenous', label: { en: 'Indigenous Attire', ms: 'Pakaian Orang Asli', zh: '原住民服装', ta: 'பழங்குடி ஆடை' } }]; // Add Ibanman to Iban male attire itemSelector.items.iban.male.top = [{ name: 'Ibanman', label: { en: 'Iban Attire', ms: 'Pakaian Iban', zh: '伊班族服装', ta: 'இபான் ஆடை' } }]; // Add Ibanwoman to Iban female attire itemSelector.items.iban.female.top = [{ name: 'Ibanwoman', label: { en: 'Iban Female Attire', ms: 'Pakaian Wanita Iban', zh: '伊班族女性服装', ta: 'இபான் பெண் ஆடை' } }]; // Add Kadazanman to Kadazan male attire itemSelector.items.kadazan.male.top = [{ name: 'Kadazanman', label: { en: 'Kadazan Male Attire', ms: 'Pakaian Lelaki Kadazan', zh: '卡达山族男性服装', ta: 'கடசான் ஆண் ஆடை' } }]; // Indian traditional // Indigenous traditional // Modern fusion // Add Seraniwoman to modern female attire itemSelector.items.modern.female.top = [{ name: 'Seraniwoman', label: { en: 'Serani Attire', ms: 'Pakaian Serani', zh: 'Serani 服装', ta: 'செரானி ஆடை' } }]; // Add Seraniman to modern male attire itemSelector.items.modern.male.top = [{ name: 'Seraniman', label: { en: 'Serani Attire', ms: 'Pakaian Serani', zh: 'Serani 服装', ta: 'செரானி ஆடை' } }]; // Sounds // Music // Initialize storage defaults if they don't exist if (storage.savedCharacters === undefined) { storage.savedCharacters = []; } if (storage.currentLanguage === undefined) { storage.currentLanguage = "en"; } // Ensure no items are initially equipped if (storage.initialSetupDone === undefined) { storage.initialSetupDone = false; // Set to false to prevent automatic display of items } var translations = { title: { en: '**Malaysian Mosaic**', ms: '**Mozek Malaysia**', zh: '**马来西亚镶嵌**', ta: '**மலேசிய மொசைக்**' }, reset: { en: 'Reset', ms: 'Tetapkan Semula', zh: '重置', ta: 'மீட்டமை' } }; // Create background var background = LK.getAsset('backgroundBox', { anchorX: 0.5, anchorY: 0.5 }); background.x = 2048 / 2; background.y = 2732 / 2; mainContent.addChild(background); // Add cultural information scripts var culturalInfoScripts = { chettiFemale: { en: "Chetti women's traditional attire is similar to traditional Malay clothing, consisting of a kebaya (long blouse and batik sarong) and kerongsang. Beaded shoes are handmade footwear requiring great skill and patience to create from fine glass beads sewn onto canvas fabric.", ms: "Pakaian tradisional wanita Chetti serupa dengan pakaian tradisi Melayu, iaitu terdiri daripada baju kebaya (baju panjang dan batik sarung) dan kerongsang. Kasut manek ialah alas kaki buatan tangan yang memerlukan kemahiran dan kesabaran tinggi untuk menghasilkannya dari jalinan manik kaca bersegi-segi halus yang dijahit pada kain terpal.", zh: "切蒂女性的传统服装类似马来传统服饰,由kebaya上衣(长衫和蜡染纱笼)以及kerongsang胸针组成。珠绣鞋是一种手工制作的鞋,需要高超的技艺和耐心,由精细的玻璃珠缝制在帆布上制成。", ta: "செட்டி பெண்களின் பாரம்பரிய உடை மலாய் பாரம்பரிய ஆடையை ஒத்துள்ளது, கெபாயா சட்டை (நீண்ட மேலாடை மற்றும் பாட்டிக் சாரோங்) மற்றும் கெரோங்சாங் ஆகியவற்றைக் கொண்டுள்ளது. கசுத் மனேக் என்பது கையால் செய்யப்பட்ட காலணிகள், நுண்ணிய கண்ணாடி மணிகளை கேன்வாஸ் துணியில் தைத்து உருவாக்க அதிக திறன் மற்றும் பொறுமை தேவைப்படுகிறது." }, chettiMale: { en: "Chetti men's traditional attire consists of checkered sarong like pulicat or batik sarong, tunic, and a headcover made of batik cloth which is tied, known as talapa (headcover). Chetti Melaka men originally wore wooden clogs with silver studs, although these clogs have now been replaced with leather sandals.", ms: "Pakaian tradisional lelaki Chetti terdiri daripada sarung berkotak seperti kain pulicat atau sarung batik, tunik, dan penutup kepala daripada kain batik yang diikat, dikenali sebagai talapa (penutup kepala). Lelaki Chetti Melaka pada asalnya memakai terompah kayu dengan paku perak, walaupun terompah ini kini telah digantikan dengan selipar kulit.", zh: "切蒂男性的传统服装包括格子纹的普利卡特或蜡染纱笼、束腰外衣以及用蜡染布料绑成的头饰,称为talapa(头巾)。 切蒂马六甲男性最初穿戴带有银钉的木屐,虽然现在这些木屐已被皮凉鞋所取代。", ta: "செட்டி ஆண்களின் பாரம்பரிய உடை புலிகட் போன்ற சதுர சாரங் அல்லது பாட்டிக் சாரங், டியூனிக், மற்றும் தலாபா (தலைப்பாகை) என்று அழைக்கப்படும் பாட்டிக் துணியால் செய்யப்பட்ட தலைப்பாகை ஆகியவற்றை உள்ளடக்கியது. மெலாக்கா செட்டி ஆண்கள் அசல் வெள்ளி ஆணிகளுடன் மரச்செருப்புகளை அணிந்தனர், இருப்பினும் இந்த செருப்புகள் தற்போது தோல் செருப்புகளாக மாற்றப்பட்டுள்ளன." }, babanyonyaFemale: { en: "Pakaian Nyonya serupa dengan pakaian tradisi Melayu, iaitu terdiri daripada baju kebaya (baju panjang dan batik sarung) dan kerongsang. Kasut manek ialah alas kaki buatan tangan yang memerlukan kemahiran dan kesabaran tinggi untuk menghasilkannya dari jalinan manik kaca bersegi-segi halus yang dijahit pada kain terpal.", ms: "Pakaian Nyonya serupa dengan pakaian tradisi Melayu, iaitu terdiri daripada baju kebaya (baju panjang dan batik sarung) dan kerongsang. Kasut manek ialah alas kaki buatan tangan yang memerlukan kemahiran dan kesabaran tinggi untuk menghasilkannya dari jalinan manik kaca bersegi-segi halus yang dijahit pada kain terpal.", zh: "娘惹服装类似马来传统服饰,由kebaya上衣(长衫和蜡染纱笼)以及kerongsang胸针组成。珠绣鞋是一种手工制作的鞋,需要高超的技艺和耐心,由精细的玻璃珠缝制在帆布上制成。", ta: "நியோனியா ஆடை மலாய் பாரம்பரிய ஆடையை ஒத்துள்ளது, கெபாயா சட்டை (நீண்ட மேலாடை மற்றும் பாட்டிக் சாரோங்) மற்றும் கெரோங்சாங் ஆகியவற்றைக் கொண்டுள்ளது. கசுத் மனேக் என்பது கையால் செய்யப்பட்ட காலணிகள், நுண்ணிய கண்ணாடி மணிகளை கேன்வாஸ் துணியில் தைத்து உருவாக்க அதிக திறன் மற்றும் பொறுமை தேவைப்படுகிறது." }, babanyonyaMale: { en: "Baba men wear the 'baju lokchuan' (long tunic) over Western-style trousers, combining Chinese embroidery with European tailoring. The outfit reflects Peranakan cultural fusion, often worn with beaded slippers.", ms: "Lelaki Baba memakai 'baju lokchuan' (jubah panjang) dengan seluar gaya Barat, menggabungkan sulaman Cina dan jahitan Eropah. Mencerminkan gabungan budaya Peranakan, selalunya dipadankan dengan kasut manik.", zh: "峇峇男性穿着长衫(baju lokchuan)配西式长裤,结合中式刺绣与欧式剪裁,搭配珠绣拖鞋,体现土生华人文化融合。", ta: "பாபா ஆண்கள் மேற்கத்திய ஸ்டைல் கால்சட்டையுடன் 'பாஜு லோக்சுவான்' (நீண்ட சட்டை) அணிகின்றனர். சீன எம்ப்ராய்டரி மற்றும் ஐரோப்பிய தையல் தொழில்நுட்பத்தை இணைக்கும் இந்த உடை பேரணாகன் கலாச்சாரத்தை பிரதிபலிக்கிறது." }, seraniMale: { en: "Serani Attire:\n- White embroidered barong tagalog shirt\n- Black trousers with suspenders\n- Black hat with Portuguese-inspired decoration\nThis fusion attire combines local and Portuguese elements, traditionally worn during Christmas and San Pedro festivals in Malacca.", ms: "Pakaian Serani:\n- Kemeja barong tagalog putih bersulam\n- Seluar hitam dengan tali suspender\n- Topi hitam berhiasan gaya Portugis\nGabungan unsur tempatan dan Portugis, dipakai semasa Krismas dan festival San Pedro di Melaka.", zh: "Serani服装:\n- 白色刺绣巴龙衬衫\n- 黑色长裤配背带\n- 葡萄牙风格装饰的黑礼帽\n融合当地和葡萄牙元素,传统上在马六甲圣诞节和圣佩德罗节期间穿着。", ta: "செரானி ஆடை:\n- வெள்ளை எம்ப்ராய்டரி பரோங் டகாலொக் சட்டை\n- கருப்பு கால்சட்டை முட்டுக்கட்டைகளுடன்\n- போர்த்துகீசிய பாணி அலங்காரத்துடன் கூடிய கருப்பு தொப்பி\nஉள்ளூர் மற்றும் போர்த்துகீசிய கூறுகளின் கலவை, மலாக்காவில் கிறிஸ்துமஸ் மற்றும் சான் பெட்ரோ திருவிழாக்களில் பாரம்பரியமாக அணியப்படுகிறது." }, ibanMale: { en: "Baju burung is traditional attire for Iban men, usually in bright red. This shirt is woven using the 'sungkit' technique resulting in fine detailing. The motifs on baju burung are similar to 'pua kumbu'. Gold thread is used for the sungkit weaving to create the baju burung.", ms: "Baju burung merupakan baju tradisional lelaki Iban dan selalunya bercorak merah terang. Baju ini ditenun menggunakancara 'sungkit' dan hasilnya halus. Motif baju burung ini sama seperti 'pua kumbu'. Benang emas digunakan untuk menyungkit kain tersebut untuk membuat baju burung.", zh: "Baju burung是伊班族男性的传统服装,通常呈鲜红色。这种衬衫采用'sungkit'技术编织,呈现精细的细节。Baju burung上的图案与'pua kumbu'相似。金线用于sungkit编织以制作baju burung。", ta: "பாஜு புருங் இபான் ஆண்களின் பாரம்பரிய ஆடையாகும், பொதுவாக பிரகாசமான சிவப்பு நிறத்தில் இருக்கும். இந்த சட்டை 'சுங்கிட்' நுட்பத்தைப் பயன்படுத்தி நெய்யப்பட்டு, நேர்த்தியான விவரங்களை கொண்டிருக்கும். பாஜு புருங்கின் மோட்டிஃப்கள் 'புவா கும்பு' போன்றவை. பாஜு புருங்கை உருவாக்க சுங்கிட் நெசவுக்கு தங்க நூல் பயன்படுத்தப்படுகிறது." }, ibanFemale: { en: "Iban women's traditional attire consists of three types: Bidang, Kalambi and Bedong. Bidang is a narrow sarong that falls to knee length. Kalambi, the Iban top, comes in two varieties - with sleeves and without sleeves. Iban women also wear a long narrow scarf called bedong, decorated with intricate woven patterns.", ms: "Pakaian tradisonal wanita Iban pula, terbahagi kepada tiga jenis iaitu Bidang, Kalambi dan Bedong. Bidangmerupakan sejenis kain sarung yang sempit dan panjangnya cuma separas lutut. Baju Kaum Iban yang dipanggil kalambi pula ada dua jenis iaitu kalambi berlengan dan kalambi tanpa lengan. Wanita Iban juga memakai kain selendang yang panjang dan sempit. Kain selempang ini dikenali sebagai bedong, iaitu ia dihiasi oleh reka corak tenunan yang sangat halus.", zh: "伊班族女性的传统服装分为三种类型:Bidang、Kalambi和Bedong。Bidang是一种窄小的纱笼,长度只到膝盖。被称为kalambi的伊班族上衣有两种类型 - 有袖和无袖。伊班族女性还佩戴一种又长又窄的围巾,称为bedong,装饰有精细的编织图案。", ta: "இபான் பெண்களின் பாரம்பரிய ஆடை மூன்று வகைகளாக பிரிக்கப்பட்டுள்ளது: பிதாங், கலம்பி மற்றும் பெடோங். பிதாங் என்பது முழங்கால் நீளத்திற்கு இருக்கும் குறுகலான சாரோங் ஆகும். இபான் மேல் ஆடையான கலம்பி, கைகளுடன் மற்றும் கைகளில்லாமல் என இரண்டு வகைகளில் வருகிறது. இபான் பெண்கள் பெடோங் என்ற நீளமான குறுகிய துண்டையும் அணிகிறார்கள், இது மிகவும் நுட்பமான நெசவு வடிவங்களுடன் அலங்கரிக்கப்பட்டுள்ளது." }, kadazanMale: { en: "'Gaung' (decorated with golden lace & betawi buttons) with a hat called 'Siga' (tanjak made from woven dastar cloth), it also includes 'Sandangon' (decoration made from palm leaves only worn when performing the Sumazau dance) that is worn crossing the body.", ms: "'Gaung'(dihiasi dengan renda keemasan&butang betawi) dengan topi yang dinamakan 'Siga'(tanjak dari kain dastar yang ditenun),ia juga disertakan dengan 'Sandangon'(hiasan dripda daun palma hanya dipakai ketika mempersembahkan tarian Sumazau) yang dipakaikan secara menyilang pada tubuh badan.", zh: "'Gaung'(装饰有金色蕾丝和betawi纽扣)配有一种名为'Siga'(由编织的头巾布制成的头饰)的帽子,还包括'Sandangon'(由棕榈叶制成的装饰,仅在表演Sumazau舞蹈时佩戴),它是交叉穿戴在身体上的。", ta: "'கவுங்' (தங்க லேஸ் மற்றும் பெதாவி பொத்தான்களால் அலங்கரிக்கப்பட்ட) 'சிகா' (நெய்யப்பட்ட தஸ்தார் துணியிலிருந்து உருவாக்கப்பட்ட தஞ்சக்) என்ற தொப்பியுடன், 'சாண்டங்கோன்' (சுமசௌ நடனத்தை நிகழ்த்தும்போது மட்டுமே அணியப்படும் பனை இலைகளிலிருந்து உருவாக்கப்பட்ட அலங்காரம்) என்பதையும் உள்ளடக்கியது, இது உடலை குறுக்காக சுற்றி அணியப்படுகிறது." }, kadazanFemale: { en: "'Sinuangga' is the traditional female Kadazan attire adorned with waist decorations called 'Himpogot' (silver metal/2 coils on the upper and lower parts of the waist decoration) and 'Tangkong' (copper metal/3 coils).", ms: "'Sinuangga' merupakan pakaian tradisional wanita Kadazan dilengkapi dengan perhiasan ikatan pinggang yang dipanggil 'Himpogot'(logam perak/2 lilitan pada bahagian atas dan bawah perhiasan di pinggang) dan 'Tangkong'(logam tembaga/3 lilitan).", zh: "'Sinuangga'是卡达山族女性的传统服装,腰间装饰着被称为'Himpogot'(银制金属/腰饰上下部分的2个线圈)和'Tangkong'(铜制金属/3个线圈)的腰饰。", ta: "'சினுவாங்கா' என்பது கடாசான் பெண்களின் பாரம்பரிய ஆடையாகும், இது 'ஹிம்போகட்' (வெள்ளி உலோகம்/இடுப்பு அலங்காரத்தின் மேல் மற்றும் கீழ் பகுதிகளில் 2 சுருள்கள்) மற்றும் 'தங்கோங்' (செம்பு உலோகம்/3 சுருள்கள்) என்ற இடுப்பு அலங்காரங்களுடன் அலங்கரிக்கப்பட்டுள்ளது." }, indigenousFemale: { en: "Orang Asli women wear handwoven bark cloth dresses decorated with natural dyes and seed beads. Patterns often represent tribal cosmology and connection to the rainforest ecosystem.", ms: "Wanita Orang Asli memakai pakaian kulit kayu tenunan tangan dihiasi pewarna semula jadi dan manik biji. Corak sering mewakili kosmologi suku dan hubungan dengan ekosistem hutan hujan.", zh: "原住民女性穿着天然染料和种子珠装饰的手织树皮布衣裙,图案常体现部落宇宙观与雨林生态的联系。", ta: "ஒராங் ஆஸ்லி பெண்கள் இயற்கை சாயங்கள் மற்றும் விதை மணிகளால் அலங்கரிக்கப்பட்ட கைநெசவு மரப்பட்டை ஆடைகளை அணிகின்றனர். வடிவங்கள் பழங்குடி பிரபஞ்சவியல் மற்றும் மழைக்காடு சூழலியல் உறவை குறிக்கின்றன." }, singhMale: { en: "The Punjabi Kurta with turban represents the Sikh community's traditional attire. The turban (dastar) symbolizes honor, self-respect, courage, and spirituality. Malaysian Sikhs preserve these cultural elements while embracing local influences in fabric choices and styling.", ms: "Kurta Punjabi dengan turban mewakili pakaian tradisional masyarakat Sikh. Turban (dastar) melambangkan kehormatan, maruah diri, keberanian, dan kerohanian. Masyarakat Sikh di Malaysia mengekalkan elemen-elemen budaya ini sambil menerima pengaruh tempatan dari segi pilihan fabrik dan gaya.", zh: "旁遮普库尔塔配头巾代表锡克社区的传统服饰。头巾(dastar)象征荣誉、自尊、勇气和灵性。马来西亚的锡克教徒在保留这些文化元素的同时,在面料选择和造型上融入了当地影响。", ta: "பஞ்சாபி குர்தா மற்றும் தலைப்பாகை சீக்கிய சமூகத்தின் பாரம்பரிய உடையை குறிக்கிறது. தலைப்பாகை (தஸ்தார்) மரியாதை, சுய மரியாதை, தைரியம் மற்றும் ஆன்மீகத்தை குறிக்கிறது. மலேசிய சீக்கியர்கள் துணி தேர்வு மற்றும் பாணியில் உள்ளூர் தாக்கங்களை ஏற்றுக்கொள்ளும் அதே வேளையில் இந்த கலாச்சார கூறுகளை பாதுகாக்கின்றனர்." }, singhFemale: { en: "The Salwar Kameez worn by Sikh women in Malaysia combines Punjabi tradition with local adaptations. The outfit consists of a long tunic (kameez), loose-fitting trousers (salwar), and a scarf (dupatta). Malaysian Sikh women often incorporate local batik patterns and tropical fabrics while maintaining traditional designs.", ms: "Salwar Kameez yang dipakai oleh wanita Sikh di Malaysia menggabungkan tradisi Punjab dengan adaptasi tempatan. Pakaian ini terdiri daripada tunik panjang (kameez), seluar longgar (salwar), dan selendang (dupatta). Wanita Sikh Malaysia sering menggabungkan corak batik tempatan dan fabrik tropika sambil mengekalkan reka bentuk tradisional.", zh: "马来西亚锡克女性穿着的沙尔瓦尔·卡米兹将旁遮普传统与当地适应相结合。这套服装由长袍(卡米兹)、宽松裤子(沙尔瓦尔)和围巾(杜帕塔)组成。马来西亚锡克女性经常在保持传统设计的同时,融入当地蜡染图案和热带面料。", ta: "மலேசியாவில் சீக்கிய பெண்கள் அணியும் சல்வார் கமீஸ் பஞ்சாப் பாரம்பரியத்தை உள்ளூர் தழுவல்களுடன் இணைக்கிறது. இந்த உடையில் நீண்ட மேலாடை (கமீஸ்), தளர்வான கால்சட்டை (சல்வார்) மற்றும் துப்பட்டா ஆகியவை அடங்கும். மலேசிய சீக்கிய பெண்கள் பாரம்பரிய வடிவமைப்புகளை பராமரித்து, உள்ளூர் பாட்டிக் முறைகள் மற்றும் வெப்பமண்டல துணிகளை இணைக்கிறார்கள்." }, seraniFemale: { en: "Serani (Eurasian) women's traditional attire combines Portuguese-inspired lace blouses with Malay-style batik skirts. This cultural fusion reflects Malaysia's colonial history and creole heritage.", ms: "Pakaian tradisional wanita Serani (Eurasia) menggabungkan blaus renda stail Portugis dengan batik sarung gaya Melayu. Gabungan budaya ini mencerminkan sejarah penjajahan dan warisan kreol Malaysia.", zh: "Serani(欧亚混血)女性传统服饰融合葡萄牙风格蕾丝上衣与马来蜡染纱笼,体现马来西亚殖民历史与克里奥尔遗产。", ta: "செரானி (யூரேசியன்) பெண்களின் பாரம்பரிய உடையில் போர்த்துகீசிய ஸ்டைல் லேஸ் ப்ளவுஸ்கள் மலாய் ஸ்டைல் பாட்டிக் பாவாடைகளுடன் இணைக்கப்படுகிறது. மலேசியாவின் காலனித்துவ வரலாறு மற்றும் கிரியோல் மரபை இது பிரதிபலிக்கிறது." }, bajuKurung: { en: "Before the 20th century, Malay women only wore kemban cloth. After the arrival of Islam, they began wearing the modest baju kurung. Baju kurung is typically known as a type of loose-fitting, long dress, sometimes reaching the knees, paired with a long folded skirt. It covers the entire body, revealing only the face and hands, seen as complying with Islamic dress rules. Baju kurung can be paired with traditional fabrics like songket or batik, and complemented with a selendang or head covering. Baju kurung is suitable for formal occasions or daily affairs.", ms: "Sebelum kurun ke-20, wanita Melayu hanya memakai kain kemban sahaja. Setelah kedatangan Islam, mereka mula memakai baju kurung yang sopan. Baju kurung lazimnya diketahui sebagai jenis baju longgar yang labuh, kadang kala hingga ke lutut dan dipadankan dengan kain panjang yang berlipat tepi. Baju tersebut meliputi seluruh tubuh, memperlihatkan wajah dan tangan sahaja, dilihat sebagai mematuhi peraturan pakaian Islam. Baju kurung boleh dipadankan dengan kain tradisional seperti songket atau batik. Digandingkan dengan kain selendang atau tudung kepala. Baju kurung sesuai dipakai dalam majlis-majlis formal atau urusan seharian.", zh: "在20世纪之前,马来女性只穿kemban布。伊斯兰教到来后,她们开始穿着保守的baju kurung。Baju kurung通常被称为一种宽松、长款的衣服,有时候长及膝盖,搭配长折边裙子。它覆盖全身,只露出脸部和双手,被视为符合伊斯兰着装规则。Baju kurung可以与传统织物如songket或batik搭配,并配以selendang或头巾。Baju kurung适合正式场合或日常事务穿着。", ta: "20ஆம் நூற்றாண்டுக்கு முன், மலாய் பெண்கள் கெம்பான் துணி மட்டுமே அணிந்தனர். இஸ்லாம் வருகைக்குப் பிறகு, அவர்கள் அடக்கமான பாஜு குருங் அணியத் தொடங்கினர். பாஜு குருங் பொதுவாக தளர்வான, நீண்ட ஆடையாக அறியப்படுகிறது, சில நேரங்களில் முழங்கால் வரை நீண்டு, மடிப்புடன் கூடிய நீண்ட பாவாடையுடன் இணைக்கப்படுகிறது. இது முகம் மற்றும் கைகள் மட்டுமே வெளிப்படும் வகையில் முழு உடலையும் மூடுகிறது, இஸ்லாமிய உடை விதிகளுக்கு இணங்குவதாக கருதப்படுகிறது. பாஜு குருங் சாங்கேட் அல்லது பாட்டிக் போன்ற பாரம்பரிய துணிகளுடன் இணைக்கப்படலாம். செலண்டாங் அல்லது தலைப்பாகை உடன் இணைக்கப்படுகிறது. பாஜு குருங் முறையான நிகழ்வுகள் அல்லது அன்றாட விவகாரங்களுக்கு ஏற்றது." }, bajuMelayu: { en: "The traditional attire for Malay men is the Baju Melayu. Baju Melayu is a loose shirt worn with long pants. This outfit is usually paired with a samping cloth tied at the waist and a songkok on the head.", ms: "Pakaian tradisional bagi kaum lelaki Melayu ialah baju Melayu. Baju Melayu merupakan kemeja longgar yang dipakai dengan seluar panjang. Pakaian ini selalunya dipadankan dengan kain samping yang diikat di bahagian pinggang dan bersongkok.", zh: "马来男性的传统服装是马来衬衫(Baju Melayu)。马来衬衫是一种宽松的衬衫,搭配长裤穿着。这种服装通常配以系在腰间的samping布料,头戴songkok帽。", ta: "மலாய் ஆண்களின் பாரம்பரிய உடை பாஜு மேலாயு ஆகும். பாஜு மேலாயு என்பது நீண்ட கால்சட்டையுடன் அணியப்படும் தளர்வான சட்டை ஆகும். இந்த உடை பொதுவாக இடுப்பில் கட்டப்படும் சாம்பிங் துணியுடனும், தலையில் சோங்கோக் தொப்பியுடனும் இணைக்கப்படுகிறது." }, cheongsam: { en: "Cheongsam, also known as Qipao in Mandarin, originated from Shanghai, China in the 1920s. It evolved from Manchu clothing and became popular during the Republic of China era. The form-fitting dress traditionally features a high collar, asymmetrical opening, and slits on the sides. Made from silk or brocade with intricate embroidery, it symbolizes Chinese feminine beauty and cultural identity. Modern variations include different lengths, fabric choices, and design elements while maintaining its characteristic silhouette.", ms: "Cheongsam juga dikenali sebagai Qipao dalam bahasa Mandarin. Cheongsam berasal dari Shanghai, China pada tahun 1920-an. Ia evolusi daripada pakaian Manchu dan menjadi simbol elegan wanita Cina. Di Malaysia, ia dipakai semasa perayaan seperti Tahun Baru Cina.", zh: "旗袍,源于1920年代中国上海,由满族服饰演变而来。它在中华民国时期广受欢迎。这种贴身连衣裙传统上特点是高领、斜襟和侧开叉。通常由丝绸或锦缎制成,配有精致的刺绣,象征着中国女性之美和文化身份。现代旗袍的变化包括不同的长度、面料选择和设计元素,但保持了其特有的轮廓。", ta: "சியோங்க்சாம், மாண்டரினில் கிபாவ் என அழைக்கப்படுகிறது, 1920களில் சீனாவின் ஷாங்காயில் தோன்றியது. இது மஞ்சூ ஆடையிலிருந்து உருவாகி, சீனக் குடியரசு காலத்தில் பிரபலமானது. உடலுக்கு ஏற்ற இந்த ஆடை பாரம்பரியமாக உயர் காலர், சமச்சீரற்ற திறப்பு மற்றும் பக்கவாட்டில் கீறல்களைக் கொண்டுள்ளது. சிக்கலான சித்திரத்தையலுடன் பட்டு அல்லது புடவையால் செய்யப்பட்ட இது, சீன பெண் அழகு மற்றும் கலாச்சார அடையாளத்தை குறிக்கிறது. நவீன மாறுபாடுகளில் அதன் சிறப்பு வடிவத்தை தக்க வைத்துக்கொண்டு வெவ்வேறு நீளங்கள், துணி தேர்வுகள் மற்றும் வடிவமைப்பு கூறுகள் அடங்கும்." }, changsan: { en: "The Changshan (长衫) is a traditional Chinese men's long robe originating from the Qing Dynasty. Characterized by its straight collar, side opening, and loose fit, it is commonly worn during formal occasions and Chinese New Year celebrations. In Malaysia, it remains popular for cultural performances and wedding ceremonies.", ms: "Changshan (长衫) adalah jubah panjang lelaki Cina tradisional yang berasal dari Dinasti Qing. Ciri-cirinya termasuk kolar lurus, bukaan sisi dan potongan longgar. Ia biasanya dipakai dalam majlis-majlis rasmi dan sambutan Tahun Baru Cina. Di Malaysia, ia masih popular untuk persembahan kebudayaan dan majlis perkahwinan.", zh: "长衫源于中国清代,是汉族男性传统服饰。其特点为直立领、侧开襟和宽松剪裁。在马来西亚,长衫常用于正式场合、春节庆祝及婚礼仪式,保持文化传承。", ta: "சாங்ஷான் (长衫) கிங் வம்சத்தில் தோன்றிய சீன ஆண்களின் பாரம்பரிய நீண்ட ஆடை. நேரான காலர், பக்க திறப்பு மற்றும் தளர்வான வடிவம் ஆகியவை இதன் அம்சங்கள். மலேசியாவில் கலாச்சார நிகழ்ச்சிகள் மற்றும் திருமண விழாக்களில் பிரபலமாக உள்ளது." }, indianFemale: { en: "The saree is a traditional Indian female garment consisting of 5-9 yards of unstitched fabric draped elegantly around the body. In Malaysia, the saree is commonly worn with a short blouse (choli) and petticoat, often made from silk or chiffon with gold embroidery. It is particularly worn during Deepavali celebrations and Indian weddings.", ms: "Sari ialah pakaian tradisional wanita India sepanjang 5-9 ela yang dililit dengan anggun. Di Malaysia, sari biasanya dipakai dengan blaus pendek (choli) dan kain dalam, sering diperbuat daripada sutera atau chiffon dengan sulaman emas. Ia dikenakan semasa sambutan Deepavali dan majlis perkahwinan India.", zh: "纱丽是印度女性传统服饰,由5-9码未经剪裁的布料优雅裹身。在马来西亚,纱丽通常搭配短上衣(choli)和衬裙,常用丝绸或雪纺材质配金线刺绣,常见于屠妖节庆祝和印度婚礼。", ta: "சேலை என்பது 5-9 மாட்த்துண்டு துணியால் உருவாக்கப்பட்ட இந்திய பெண்களின் பாரம்பரிய ஆடை. மலேசியாவில் பொதுவாக குறுகிய சட்டை (சோளி) மற்றும் அடிக்கோடணியுடன் அணியப்படுகிறது. தீபாவளி மற்றும் இந்திய திருமணங்களில் இது அணியப்படுகிறது." }, indianMale: { en: "Dhoti is a traditional garment for men in the Indian subcontinent, consisting of a rectangular white cloth wrapped around the waist, tied at the crotch area and the front or back. It is also worn by Indian men during weddings and festivals.", ms: "Dhotī atau doti ialah pakaian tradisi untuk kaum lelaki di tanah benua India terdiri daripada kain empat segi panjang berwarna putih yang dililit di bahagian pinggang dan diikat pada celah paha dan bahagian depan atau belakang. Ia juga dipakai oleh lelaki India semasa perkahwinan dan juga semasa hari perayaan. Kain asas ini boleh datang dalam pelbagai warna malah berhias sulam atau manik kecil supaya kelihatan menarik. Ada juga dhoti yang berwarna kuning pudar atau kuning susu.", zh: "多蒂是印度次大陆男性的传统服装,由一块长方形白色布料围绕腰部缠绕,在裆部和前部或后部系紧。印度男性在婚礼和节日期间也会穿着它。这种基本布料可能有各种颜色,甚至装饰有刺绣或小珠子,使其更具吸引力。还有一些多蒂是淡黄色或奶黄色的。", ta: "தோட்டி என்பது இந்திய துணைக்கண்டத்தில் ஆண்களுக்கான பாரம்பரிய ஆடையாகும், இது இடுப்பில் சுற்றி, தொடையிடுக்குப் பகுதியில் கட்டப்பட்டு, முன் அல்லது பின் பகுதியில் கட்டப்படும் செவ்வக வெள்ளைத் துணியாகும். இந்திய ஆண்கள் திருமணங்கள் மற்றும் பண்டிகைகளின் போதும் இதை அணிகிறார்கள். இந்த அடிப்படைத் துணி பல்வேறு வண்ணங்களில் வரலாம், சிறிய மணிகள் அல்லது எம்பிராய்டரியுடன் அழகாக அலங்கரிக்கப்படலாம். மஞ்சள் அல்லது பால் மஞ்சள் நிறத்திலும் தோட்டிகள் உள்ளன." }, siameseFemale: { en: "Traditional Siamese female attire features a 'pha sin' wrap skirt with horizontal stripes, paired with a sabai shawl draped over one shoulder. The outfit showcases Thai-Malay cultural fusion through its silk fabrics and gold brocade patterns.", ms: "Pakaian tradisional wanita Siam terdiri daripada kain 'pha sin' berjalur melintang dengan selendang sabai di sebelah bahu. Memaparkan gabungan budaya Thai-Melayu melalui sutera dan corak broked emas.", zh: "暹罗女性传统服饰包括横纹'pha sin'裹裙搭配单肩披纱笼,通过丝绸面料和金锦缎图案展现泰马文化融合。", ta: "சியாமீஸ் பெண்களின் பாரம்பரிய உடையில் கிடை அமைப்புடன் கூடிய 'பா சின்' பாவாடை மற்றும் ஒரு தோளில் சுற்றிய சபாய் துணி அடங்கும். பட்டுத் துணிகள் மற்றும் தங்க நெசவு வடிவங்கள் மூலம் தாய்-மலாய் கலாச்சார இணைவைக் காட்டுகிறது." }, siameseMale: { en: "Traditional Siamese Male Attire - Suea Phra Ratchathan (\u0E40\u0E2A\u0E37\u0E49\u0E2D\u0E1E\u0E23\u0E30\u0E23\u0E32\u0E0A\u0E17\u0E32\u0E19):\n- Chong kraben (\u0E42\u0E08\u0E07\u0E01\u0E23\u0E30\u0E40\u0E1A\u0E19): Luxurious silk cloth wrapped as loose trousers\n- Suea phra ratchathan: Formal jacket with standing collar and frog buttons\nMade from phrae wa silk with gold prada technique, worn by Malaysian Siamese communities during Songkran and temple ceremonies.", ms: "Pakaian Tradisional Lelaki Siam - Suea Phra Ratchathan (\u0E40\u0E2A\u0E37\u0E49\u0E2D\u0E1E\u0E23\u0E30\u0E23\u0E32\u0E0A\u0E17\u0E32\u0E19):\n- Chong kraben: Kain sutera mewah dililit sebagai seluar longgar\n- Suea phra ratchathan: Jaket formal berkolar tegak dengan butang frog\nDiperbuat daripada sutera phrae wa dengan teknik prada emas, dipakai komuniti Siam Malaysia semasa Songkran dan upacara kuil.", zh: "\u66B9\u7F57\u7537\u6027\u4F20\u7EDF\u670D\u9970 - \u5FA1\u8D50\u5916\u5957 (\u0E40\u0E2A\u0E37\u0E49\u0E2D\u0E1E\u0E23\u0E30\u0E23\u0E32\u0E0A\u0E17\u0E32\u0E19):\n- \u5E54\u88E4 (\u0E42\u0E08\u0E07\u0E01\u0E23\u0E30\u0E40\u0E1A\u0E19): \u5962\u534E\u4E1D\u7EF8\u5236\u6210\u7684\u88F9\u5F0F\u5BBD\u677E\u88E4\n- \u5FA1\u8D50\u5916\u5957: \u7ACB\u9886\u76D8\u6263\u6B63\u88C5\u5916\u5957\n\u91C7\u7528Phrae Wa\u4E1D\u7EF8\u914D\u91D1\u7B94\u5DE5\u827A\u5236\u4F5C\uFF0C\u9A6C\u6765\u897F\u4E9A\u66B9\u7F57\u793E\u7FA4\u5728\u5B8B\u5E72\u8282\u548C\u5BFA\u5E99\u4EEA\u5F0F\u4E2D\u7A7F\u7740\u3002", ta: "\u0B9A\u0BBF\u0BAF\u0BBE\u0BAE\u0BC0\u0BB8\u0BCD \u0B86\u0BA3\u0BCD\u0B95\u0BB3\u0BBF\u0BA9\u0BCD \u0BAA\u0BBE\u0BB0\u0BAE\u0BCD\u0BAA\u0BB0\u0BBF\u0BAF \u0B89\u0B9F\u0BC8 - \u0B9A\u0BC1\u0BB5\u0BBF\u0BAF\u0BBE \u0BAA\u0BCD\u0BB0\u0BBE \u0BB0\u0BBE\u0B9F\u0BCD\u0B9A\u0BBE\u0BA4\u0BA9\u0BCD (\u0E40\u0E2A\u0E37\u0E49\u0E2D\u0E1E\u0E23\u0E30\u0E23\u0E32\u0E0A\u0E17\u0E32\u0E19):\n- \u0B9A\u0BCB\u0B99\u0BCD \u0B95\u0BCD\u0BB0\u0BBE\u0BAA\u0BC6\u0BA9\u0BCD: \u0BAA\u0B9F\u0BCD\u0B9F\u0BC1 \u0BA4\u0BC1\u0BA3\u0BBF\u0BAF\u0BBE\u0BB2\u0BCD \u0B9A\u0BC6\u0BAF\u0BCD\u0BAF\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F \u0BA4\u0BB3\u0BB0\u0BCD\u0BB5\u0BBE\u0BA9 \u0B95\u0BBE\u0BB2\u0BCD\u0B9A\u0B9F\u0BCD\u0B9F\u0BC8\n- \u0B9A\u0BC1\u0BB5\u0BBF\u0BAF\u0BBE \u0BAA\u0BCD\u0BB0\u0BBE \u0BB0\u0BBE\u0B9F\u0BCD\u0B9A\u0BBE\u0BA4\u0BA9\u0BCD: \u0BA8\u0BBF\u0BAE\u0BBF\u0BB0\u0BCD\u0BA8\u0BCD\u0BA4 \u0B95\u0BBE\u0BB2\u0BB0\u0BCD \u0BAE\u0BB1\u0BCD\u0BB1\u0BC1\u0BAE\u0BCD \u0BA4\u0BB5\u0BB3\u0BC8 \u0BAA\u0BCA\u0BA4\u0BCD\u0BA4\u0BBE\u0BA9\u0BCD\u0B95\u0BB3\u0BCD \u0B95\u0BCA\u0BA3\u0BCD\u0B9F \u0BAE\u0BC1\u0BB1\u0BC8\u0BAF\u0BBE\u0BA9 \u0B9C\u0BBE\u0B95\u0BCD\u0B95\u0BC6\u0B9F\u0BCD\n\u0BA4\u0B99\u0BCD\u0B95 \u0BAA\u0BBF\u0BB0\u0BA4\u0BBE \u0BA8\u0BC1\u0B9F\u0BCD\u0BAA\u0BA4\u0BCD\u0BA4\u0BC1\u0B9F\u0BA9\u0BCD \u0B83\u0BAA\u0BCD\u0BB0\u0BC7 \u0BB5\u0BBE \u0BAA\u0B9F\u0BCD\u0B9F\u0BBF\u0BB2\u0BCD \u0B9A\u0BC6\u0BAF\u0BCD\u0BAF\u0BAA\u0BCD\u0BAA\u0B9F\u0BCD\u0B9F\u0BA4\u0BC1, \u0BAE\u0BB2\u0BC7\u0B9A\u0BBF\u0BAF \u0B9A\u0BBF\u0BAF\u0BBE\u0BAE\u0BC0\u0BB8\u0BCD \u0B9A\u0BAE\u0BC2\u0B95\u0B99\u0BCD\u0B95\u0BB3\u0BBE\u0BB2\u0BCD \u0B9A\u0BCA\u0B99\u0BCD\u0B95\u0BCD\u0BB0\u0BBE\u0BA9\u0BCD \u0BAE\u0BB1\u0BCD\u0BB1\u0BC1\u0BAE\u0BCD \u0B95\u0BCB\u0BB5\u0BBF\u0BB2\u0BCD \u0B9A\u0B9F\u0B99\u0BCD\u0B95\u0BC1\u0B95\u0BB3\u0BBF\u0BB2\u0BCD \u0B85\u0BA3\u0BBF\u0BAF\u0BAA\u0BCD\u0BAA\u0B9F\u0BC1\u0B95\u0BBF\u0BB1\u0BA4\u0BC1." } }; // Add title to GUI var titleText = new Text2(translations.title[storage.currentLanguage], { size: 80, fill: 0xFFFFFF, fontWeight: 'bold' }); titleText.anchor.set(0.5, 0); titleText.y = 20; LK.gui.top.addChild(titleText); // Create mute button var muteButtonText = { en: { mute: "🔇 Mute Music", unmute: "🔊 Unmute Music" }, ms: { mute: "🔇 Senyapkan Muzik", unmute: "🔊 Bunyikan Muzik" }, zh: { mute: "🔇 静音", unmute: "🔊 取消静音" }, ta: { mute: "🔇 இசையை அமுக்கு", unmute: "🔊 இசையை இயக்கு" } }; // Create panel for mute button var mutePanel = LK.getAsset('uiPanel', { anchorX: 0.5, anchorY: 0.5, width: 240, height: 80, tint: 0x333333 }); mutePanel.x = 150; mutePanel.y = 2732 - 150; // Moved to bottom of the screen to match mute button position mainContent.addChild(mutePanel); // Create mute button with MuteSymbol icon var muteButton = new Container(); muteButton.x = 150; muteButton.y = 2732 - 150; // Moved to bottom of the screen to avoid overlap with play button // Add background for mute button var muteButtonBg = muteButton.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, width: 100, height: 100, tint: 0x333333 }); // Add MuteSymbol icon var muteSymbol = muteButton.attachAsset('MuteSymbol', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); // Make button interactive muteButton.interactive = true; muteButton.down = function (x, y, obj) { var isMuted = MusicManager.toggleMute(); // Visual feedback tween(muteButtonBg, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(muteButtonBg, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.easeOut }); } }); // Adjust opacity based on mute state tween(muteSymbol, { alpha: isMuted ? 0.5 : 1 }, { duration: 200, easing: tween.easeOut }); }; mainContent.addChild(muteButton); // Add gender selection var genderSelector = new GenderSelector(); genderSelector.x = 2048 / 2 - 600; // Position to left side of character genderSelector.y = 2732 / 2; // Center vertically with character genderSelector.setup(); mainContent.addChild(genderSelector); // Add character var character = new Character(); character.x = 2048 / 2; character.y = 2732 / 2 - 100; mainContent.addChild(character); // Replace babaNyonyaTop with Nyonya for female characters itemSelector.items.babanyonya.female.top = [{ name: 'Nyonya', label: { en: 'Kebaya Nyonya', ms: 'Kebaya Nyonya', zh: '娘惹峇峇服', ta: 'கெபாயா நியோனியா' } }]; // ItemSelector instance already created earlier in the code // Add language selector var languageSelector = new LanguageSelector(); languageSelector.x = 2048 / 2; languageSelector.y = 2732 - 150; // Positioned higher to avoid bottom edge and other UI elements languageSelector.setup(); mainContent.addChild(languageSelector); // Add action buttons // Create panel background for reset button var resetPanel = LK.getAsset('uiPanel', { anchorX: 0.5, anchorY: 0.5, width: 240, height: 100, tint: 0xF44336 }); resetPanel.x = 2048 - 200; resetPanel.y = 200; mainContent.addChild(resetPanel); var resetButton = new UIButton(translations.reset[storage.currentLanguage], 200, 80, 0xF44336); resetButton.x = 2048 - 200; resetButton.y = 200; mainContent.addChild(resetButton); // Add wardrobe button var wardrobeText = { en: "Ethnic Collection", ms: "Koleksi Etnik", zh: "民族服装集", ta: "இன ஆடை தொகுப்பு" }; // Create panel background for wardrobe button var wardrobePanel = LK.getAsset('uiPanel', { anchorX: 0.5, anchorY: 0.5, width: 260, height: 110, tint: 0x8A2BE2 }); wardrobePanel.x = 2048 - 200; wardrobePanel.y = 320; mainContent.addChild(wardrobePanel); // Create a wardrobe button with larger size and better contrast var wardrobeButton = new UIButton(wardrobeText[storage.currentLanguage], 240, 90, 0x8A2BE2); // Set button position wardrobeButton.x = 2048 - 200; wardrobeButton.y = 320; // Make text larger and bolder for better readability wardrobeButton.buttonText.style.size = 40; wardrobeButton.buttonText.style.fill = "#FFFFFF"; mainContent.addChild(wardrobeButton); // Create wardrobe component var wardrobe = new Wardrobe(); wardrobe.x = 2048 / 2; wardrobe.y = 2732 / 2; wardrobe.updateLanguage(storage.currentLanguage); mainContent.addChild(wardrobe); // Connect components genderSelector.setChangeCallback(function (gender) { // Change character base to gender-specific asset character.setGender(gender); // Clear any existing attire when gender changes to prevent baju kurung showing by default for (var layerName in character.layers) { if (layerName !== 'base' && character.layers[layerName]) { character.removeChild(character.layers[layerName]); character.layers[layerName] = null; } } }); // Initialize ItemSelector with needed functionality itemSelector.setSelectionCallback(function (item) { character.equip(item); // Show cultural info for baju kurung when selected if (item.itemName === 'bajuKurung') { // Display cultural information panel with baju kurung script culturalInfoPanel.show('bajuKurung'); } // Show cultural info for baju melayu when selected if (item.itemName === 'bajumelayu') { // Display cultural information panel with baju melayu script culturalInfoPanel.show('bajuMelayu'); } // Show cultural info for cheongsam when selected if (item.itemName === 'cheongsam') { // Display cultural information panel with cheongsam script culturalInfoPanel.show('cheongsam'); } // Show cultural info for Changsan when selected if (item.itemName === 'Changsan') { // Display cultural information panel with Changsan script culturalInfoPanel.show('changsan'); } // Show cultural info for saree when selected if (item.itemName === 'saree') { // Display cultural information panel with indianFemale script culturalInfoPanel.show('indianFemale'); } // Show cultural info for Dhotti when selected if (item.itemName === 'Dhotti') { // Display cultural information panel with indianMale script culturalInfoPanel.show('indianMale'); } // Show cultural info for siameseTop when selected if (item.itemName === 'siameseTop') { // Display cultural information panel with siameseMale script culturalInfoPanel.show('siameseMale'); } // Show cultural info for Indigenous when selected if (item.itemName === 'Indigenous') { // Display cultural information panel with indigenousFemale script culturalInfoPanel.show('indigenousFemale'); } // Show cultural info directly if this is indigenousVest when selected from Kadazan category if (item.itemName === 'indigenousVest' && item.category === 'kadazan') { // Display cultural information panel with kadazanFemale script culturalInfoPanel.show('kadazanFemale'); } // Show cultural info directly if this is Kadazanman when selected if (item.itemName === 'Kadazanman') { // Display cultural information panel with kadazanMale script culturalInfoPanel.show('kadazanMale'); } }); languageSelector.setChangeCallback(function (language) { // Update all UI text titleText.setText(translations.title[language]); resetButton.setText(translations.reset[language]); wardrobeButton.setText(wardrobeText[language]); // No need to update mute button text since we're using an icon now // Update gender selector genderSelector.updateLanguage(language); wardrobe.updateLanguage(language); }); // Add cultural info panel var culturalInfoPanel = new CulturalInfoPanel(); culturalInfoPanel.x = 2048 / 2; culturalInfoPanel.y = 2732 / 2 - 300; // Position even higher on screen for better visibility mainContent.addChild(culturalInfoPanel); // Add error message element var errorMessage = new Text2("", { size: 40, fill: 0xFF0000 }); errorMessage.anchor.set(0.5, 0); errorMessage.y = 2732 - 180; // Position above language selector errorMessage.visible = false; LK.gui.bottom.addChild(errorMessage); // Function to show error message temporarily function showError(message, duration) { errorMessage.setText(message); errorMessage.visible = true; LK.setTimeout(function () { errorMessage.visible = false; }, duration || 3000); } // Function to check if character is wearing baju kurung, bajuMelayu, cheongsam, Changsan, or saree and show the cultural info function checkForBajuKurung() { // Check if character is wearing baju kurung, bajuMelayu, cheongsam, Changsan, or saree var wearing = false; var itemName = ""; // Check all layers for (var layerName in character.layers) { if (layerName !== 'base' && character.layers[layerName]) { var item = character.layers[layerName]; // Check if this is baju kurung if (item.itemName === 'bajuKurung') { wearing = true; itemName = 'bajuKurung'; break; } // Check if this is baju melayu if (item.itemName === 'bajumelayu') { wearing = true; itemName = 'bajuMelayu'; break; } // Check if this is cheongsam if (item.itemName === 'cheongsam') { wearing = true; itemName = 'cheongsam'; break; } // Check if this is Changsan if (item.itemName === 'Changsan') { wearing = true; itemName = 'changsan'; break; } // Check if this is saree if (item.itemName === 'saree') { wearing = true; itemName = 'indianFemale'; break; } // Check if this is Dhotti if (item.itemName === 'Dhotti') { wearing = true; itemName = 'indianMale'; break; } // Check if this is Singhman if (item.itemName === 'Singhman') { wearing = true; itemName = 'singhMale'; break; } // Check if this is Singhwoman if (item.itemName === 'Singhwoman') { wearing = true; itemName = 'seraniFemale'; break; } // Check if this is siameseDress (Pha Sin) if (item.itemName === 'siameseDress') { wearing = true; itemName = 'siameseFemale'; break; } // Check if this is siameseTop (Suea Phra Ratchathan) if (item.itemName === 'siameseTop') { wearing = true; itemName = 'siameseMale'; break; } // Check if this is Seraniwoman if (item.itemName === 'Seraniwoman') { wearing = true; itemName = 'singhFemale'; break; } // Check if this is Seraniman if (item.itemName === 'Seraniman') { wearing = true; itemName = 'seraniMale'; break; } // Check if this is Indigenous if (item.itemName === 'Indigenous') { wearing = true; itemName = 'indigenousFemale'; break; } // Check if this is indigenousVest with Kadazan category if (item.itemName === 'indigenousVest' && item.category === 'kadazan') { wearing = true; itemName = 'kadazanFemale'; break; } // Check if this is Kadazanman if (item.itemName === 'Kadazanman') { wearing = true; itemName = 'kadazanMale'; break; } // Check if this is Ibanman if (item.itemName === 'Ibanman') { wearing = true; itemName = 'ibanMale'; break; } // Check if this is Ibanwoman if (item.itemName === 'Ibanwoman') { wearing = true; itemName = 'ibanFemale'; break; } // Check if this is babaNyonyaTop with male gender if (item.itemName === 'babaNyonyaTop' && character.gender === 'male') { wearing = true; itemName = 'babanyonyaMale'; break; } } } // If wearing baju kurung, bajuMelayu, cheongsam, Changsan, or saree, show cultural info if (wearing && itemName) { culturalInfoPanel.show(itemName); } } resetButton.setCallback(function () { // Reset character by clearing all items for (var layerName in character.layers) { if (layerName !== 'base' && character.layers[layerName]) { character.removeChild(character.layers[layerName]); character.layers[layerName] = null; } } }); // Add cultural info for Seraniman to setSelectionCallback itemSelector.setSelectionCallback(function (item) { character.equip(item); // Show cultural info for Seraniman when selected if (item.itemName === 'Seraniman') { if (typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('seraniMale'); } } // Show cultural info for Ibanman when selected if (item.itemName === 'Ibanman') { if (typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('ibanMale'); } } // Show cultural info for Ibanwoman when selected if (item.itemName === 'Ibanwoman') { if (typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('ibanFemale'); } } // Show cultural info for babaNyonyaTop when selected for male character if (item.itemName === 'babaNyonyaTop' && character.gender === 'male') { if (typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('babanyonyaMale'); } } // Show cultural info for Nyonya when selected if (item.itemName === 'Nyonya') { if (typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('babanyonyaFemale'); } } // Show cultural info for Chettiman when selected if (item.itemName === 'Chettiman') { if (typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('chettiMale'); } } // Show cultural info for Chettiwoman when selected if (item.itemName === 'Chettiwoman') { if (typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('chettiFemale'); } } }); // Setup wardrobe button wardrobeButton.setCallback(function () { // Mark that initial setup is done so items can be displayed storage.initialSetupDone = true; wardrobe.show(); // Hide title text when wardrobe is open titleText.visible = false; }); // Setup wardrobe outfit selection wardrobe.setOutfitSelectedCallback(function (outfitData) { // Apply outfit to character character.loadData(outfitData); // Set character as current outfit automatically for (var categoryId in character.layers) { if (categoryId !== 'base' && character.layers[categoryId]) { if (character.layers[categoryId].select) { character.layers[categoryId].select(); } } } wardrobe.hide(); LK.getSound('itemSelect').play(); }); // Play background music using music manager MusicManager.playMusic('Fashionshow'); // Game update function game.update = function () { // Game logic updates would go here if needed }; // Add event handler for character character.down = function (x, y, obj) { // Check if character is wearing baju kurung, baju melayu, cheongsam, or Changsan for (var layerName in character.layers) { if (layerName !== 'base' && character.layers[layerName]) { var item = character.layers[layerName]; if (item.itemName === 'bajuKurung' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('bajuKurung'); break; } if (item.itemName === 'bajumelayu' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('bajuMelayu'); break; } if (item.itemName === 'cheongsam' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('cheongsam'); break; } if (item.itemName === 'Changsan' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('changsan'); break; } if (item.itemName === 'saree' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('indianFemale'); break; } if (item.itemName === 'Dhotti' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('indianMale'); break; } if (item.itemName === 'Singhman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('singhMale'); break; } if (item.itemName === 'Singhwoman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('seraniFemale'); break; } if (item.itemName === 'siameseDress' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('siameseFemale'); break; } if (item.itemName === 'siameseTop' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('siameseMale'); break; } if (item.itemName === 'Seraniwoman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('singhFemale'); break; } if (item.itemName === 'Seraniman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('seraniMale'); break; } if (item.itemName === 'Indigenous' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('indigenousFemale'); break; } if (item.itemName === 'indigenousVest' && item.category === 'kadazan' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('kadazanFemale'); break; } if (item.itemName === 'Kadazanman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('kadazanMale'); break; } if (item.itemName === 'Ibanman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('ibanMale'); break; } if (item.itemName === 'Ibanwoman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('ibanFemale'); break; } // Check for babaNyonyaTop with male gender if (item.itemName === 'babaNyonyaTop' && character.gender === 'male' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('babanyonyaMale'); break; } // Check for Nyonya if (item.itemName === 'Nyonya' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('babanyonyaFemale'); break; } // Check for Nyonya if (item.itemName === 'Nyonya' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('babanyonyaFemale'); break; } // Check for Chettiman if (item.itemName === 'Chettiman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('chettiMale'); break; } // Check for Chettiwoman if (item.itemName === 'Chettiwoman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('chettiFemale'); break; } if (item.itemName === 'Chettiman' && typeof culturalInfoPanel !== 'undefined') { culturalInfoPanel.show('chettiMale'); break; } } } }; // End of game code
===================================================================
--- original.js
+++ change.js
@@ -2777,14 +2777,14 @@
height: 80,
tint: 0x333333
});
mutePanel.x = 150;
-mutePanel.y = 80;
+mutePanel.y = 2732 - 150; // Moved to bottom of the screen to match mute button position
mainContent.addChild(mutePanel);
// Create mute button with MuteSymbol icon
var muteButton = new Container();
muteButton.x = 150;
-muteButton.y = 80;
+muteButton.y = 2732 - 150; // Moved to bottom of the screen to avoid overlap with play button
// Add background for mute button
var muteButtonBg = muteButton.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,