User prompt
Don't mix the female attire with the male attire when we selected the specified gender
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'createElement')' in or related to this line: 'var styleElement = document.createElement('style');' Line Number: 1495
User prompt
/* Remove specific blocking element */ .blocking-overlay { display: none !important; visibility: hidden !important; }
User prompt
I want to complain that the whole asset Changsan is blocked by yellow square, please remove it so that the whole asset Changsan is visible
User prompt
Remove the uneccessary extra asset for Chinese male attire please!!
User prompt
For Chinese male attire only has the asset Changsan, remove the extra asset
User prompt
Remove yellow block for Chinese male attire
User prompt
Add the asset Changsan as Chinese male's attire, which can be selected at the wardrobe
User prompt
At the homepage only has Character Base, remove extra Baju Kurung at the homepage, I'm really angry for your shitting work!!
User prompt
Remove Baju Kurung at the front page as it disturbed the home page
User prompt
Remove Bajukurungbutton entirely from the front page
User prompt
Remove green block at the front page
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'selectedGender')' in or related to this line: 'var currentGender = genderSelector.selectedGender;' Line Number: 706
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'currentCategory')' in or related to this line: 'if (itemSelector.currentCategory === 'chinese' && genderSelector.selectedGender === 'male') {' Line Number: 1355
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'currentCategory')' in or related to this line: 'if (itemSelector.currentCategory === 'chinese' && genderSelector.selectedGender === 'male') {' Line Number: 1355
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'currentCategory')' in or related to this line: 'if (itemSelector.currentCategory === 'chinese' && genderSelector.selectedGender === 'male') {' Line Number: 1355
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'currentCategory')' in or related to this line: 'if (itemSelector.currentCategory === 'chinese' && genderSelector.selectedGender === 'male') {' Line Number: 1355
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'currentCategory')' in or related to this line: 'itemSelector.currentCategory = 'malay'; // Initialize current category' Line Number: 1352
User prompt
Asset Changsan for Chinese male only
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'currentCategory')' in or related to this line: 'itemSelector.currentCategory = 'malay'; // Initialize current category' Line Number: 1352
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'currentCategory')' in or related to this line: 'itemSelector.currentCategory = 'malay'; // Initialize current category' Line Number: 1352
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'currentCategory')' in or related to this line: 'itemSelector.currentCategory = 'malay'; // Initialize current category' Line Number: 1352
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'currentCategory')' in or related to this line: 'if (itemSelector.currentCategory === 'chinese' && genderSelector.selectedGender === 'male') {' Line Number: 1355
User prompt
Add asset Changsan as Chinese male's attire
User prompt
Remove all the current asset for Chinese male and replace it with the asset changsan for Chinese male
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { savedCharacters: [], currentLanguage: "en" }); /**** * Classes ****/ var CategorySelector = Container.expand(function () { var self = Container.call(this); self.categories = [{ 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: '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: 'modern', label: { en: 'Modern', ms: 'Moden', zh: '现代', ta: 'நவீன' } }]; 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 = 250; var startX = -((self.categories.length - 1) * spacing) / 2; for (var i = 0; i < self.categories.length; i++) { var cat = self.categories[i]; var lang = storage.currentLanguage; var btn = new UIButton(cat.label[lang], 180, 60, 0x87CEFA); btn.x = startX + i * spacing; 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.7 : 1, // Scale male character width to 70% 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; // 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; }; 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 Changsan, use the image asset directly if (itemName === 'Changsan') { itemGraphics = self.attachAsset('Changsan', { anchorX: 0.5, anchorY: 0.5 }); } else { itemGraphics = self.attachAsset(itemName, { anchorX: 0.5, anchorY: 0.5 }); } // 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); 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; } // Scale up the attire when selected to fit 728x1528 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 728x1528 area while maximizing size var maxWidth = 728; 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); // Apply larger scale with animation tween(self.children[0], { scaleX: self.originalScale.x * scaleFactor, scaleY: self.originalScale.y * scaleFactor }, { duration: 500, easing: tween.easeOut }); } return self; }; self.down = function (x, y, obj) { // Handle item selection self.select(); }; 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 () { var spacing = 200; var startX = -((self.genders.length - 1) * spacing) / 2; for (var i = 0; i < self.genders.length; i++) { var gender = self.genders[i]; var lang = storage.currentLanguage; var btn = new UIButton(gender.label[lang], 180, 60, 0x87CEFA); btn.x = startX + i * spacing; btn.genderId = gender.id; btn.setCallback(function () { var genderId = this.genderId; LK.getSound('categoryChange').play(); self.selectedGender = genderId; self.updateButtonStates(); if (self.onGenderChange) { self.onGenderChange(genderId); } }.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.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 = { 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: [{ name: 'chineseFan', label: { en: 'Fan', ms: 'Kipas', zh: '扇子', ta: 'விசிறி' } }] } }, indian: { female: { top: [{ name: 'saree', label: { en: 'Saree', ms: 'Sari', zh: '纱丽', ta: 'சேலை' } }], accessory: [{ name: 'bindiForeheadMark', label: { en: 'Bindi', ms: 'Bindi', zh: '额头装饰', ta: 'பொட்டு' } }] }, male: { top: [{ name: 'kurta', label: { en: 'Kurta', ms: 'Kurta', zh: '库尔塔', ta: 'குர்தா' } }], bottom: [{ name: 'dhoti', 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: { top: [{ name: 'indigenousVest', label: { en: 'Traditional Vest', ms: 'Rompi Tradisional', zh: '传统背心', ta: 'பாரம்பரிய மேலாடை' } }], headdress: [{ name: 'headDress', label: { en: 'Headdress', ms: 'Hiasan Kepala', zh: '头饰', ta: 'தலை அணி' } }] } }, iban: { female: { top: [{ name: 'indigenousVest', label: { en: 'Ngepan Vest', ms: 'Rompi Ngepan', zh: '伊班族背心', ta: 'நெகபன் மேலாடை' } }], headdress: [{ name: 'headDress', label: { en: 'Pua Kumbu Headdress', ms: 'Hiasan Kepala Pua Kumbu', zh: '伊班族头饰', ta: 'புவா குமபு தலை அணி' } }] }, male: { top: [{ name: 'ibanVest', label: { en: 'Iban Vest', ms: 'Rompi Iban', zh: '伊班族背心', ta: 'இபான் மேலாடை' } }], headdress: [{ name: 'headDress', label: { en: 'Pua Kumbu Headdress', ms: 'Hiasan Kepala Pua Kumbu', zh: '伊班族头饰', ta: 'புவா குமபு தலை அணி' } }] } }, kadazan: { female: { top: [{ name: 'indigenousVest', label: { en: 'Sinuangga Vest', ms: 'Rompi Sinuangga', zh: '卡达山族背心', ta: 'சினுவாங்க மேலாடை' } }], headdress: [{ name: 'headDress', label: { en: 'Kadazan Headdress', ms: 'Hiasan Kepala Kadazan', zh: '卡达山族头饰', ta: 'கடசான் தலை அணி' } }] }, male: { top: [{ name: 'kadazanVest', label: { en: 'Kadazan Vest', ms: 'Rompi Kadazan', zh: '卡达山族背心', ta: 'கடசான் மேலாடை' } }], headdress: [{ name: 'headDress', label: { en: 'Kadazan Headdress', ms: 'Hiasan Kepala Kadazan', zh: '卡达山族头饰', ta: 'கடசான் தலை அணி' } }] } }, modern: { female: { top: [{ name: 'modernTop', label: { en: 'Modern Top', ms: 'Atasan Moden', zh: '现代上衣', ta: 'நவீன மேல்' } }], bottom: [{ name: 'modernBottom', label: { en: 'Modern Bottom', ms: 'Bawahan Moden', zh: '现代裤子', ta: 'நவீன கீழ்' } }] }, male: { top: [{ name: 'modernMaleTop', label: { en: 'Modern Top', ms: 'Atasan Moden', zh: '现代上衣', ta: 'நவீன மேல்' } }], bottom: [{ name: 'modernBottom', label: { en: 'Modern Bottom', ms: 'Bawahan Moden', zh: '现代裤子', ta: 'நவீன கீழ்' } }] } } }; 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 = -80; 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 = []; // Get items for the current category, gender and type if (self.items[self.currentCategory] && self.items[self.currentCategory][currentGender] && self.items[self.currentCategory][currentGender][self.currentType]) { currentItems = self.items[self.currentCategory][currentGender][self.currentType] || []; } // Filter items to ensure gender-specific clothing var filteredItems = currentItems.filter(function (item) { // 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: buttonWidth, height: buttonHeight }); itemContainer.addChild(bg); // Create item preview with large display var itemPreview = new ClothingItem(self.currentType, self.currentCategory, item.name); // Calculate appropriate scale to maximize image display within button var maxWidth = itemPreview.originalWidth || itemPreview.width; var maxHeight = itemPreview.originalHeight || itemPreview.height; // Calculate scale factors to fill button area while preserving aspect ratio var wScale = buttonWidth / maxWidth; var hScale = buttonHeight / maxHeight; // Use object-fit: contain approach - take minimum scale to ensure entire image is visible var scaleFactor = Math.min(wScale, hScale) * 0.9; // 90% of max size to add some padding // Apply scaling to ensure image fits within button area itemPreview.scale.set(scaleFactor, scaleFactor); // Center the preview in the button 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; 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 = callback; 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 = 200; var startX = -((self.languages.length - 1) * spacing) / 2; for (var i = 0; i < self.languages.length; i++) { var lang = self.languages[i]; var btn = new UIButton(lang.name, 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 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: 1800, 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); var outfitContainer = new Container(); self.addChild(outfitContainer); 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 = ['malay', 'chinese', 'indian', 'indigenous', 'iban', 'kadazan', '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 }; } 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; } // Calculate grid layout var itemsPerRow = 3; // Reduced items per row for larger buttons var itemSize = 350; // Larger item size for better visibility var padding = 60; // Increased padding for better separation var startX = -(itemsPerRow - 1) / 2 * (itemSize + padding); var startY = 50; // Translations for ethnic categories var categoryLabels = { malay: { en: 'Malay', ms: 'Melayu', zh: '马来', ta: 'மலாய்' }, chinese: { en: 'Chinese', ms: 'Cina', zh: '华人', ta: 'சீன' }, indian: { en: 'Indian', ms: 'India', zh: '印度', ta: 'இந்திய' }, indigenous: { en: 'Indigenous', ms: 'Orang Asli', zh: '原住民', ta: 'பழங்குடி' }, iban: { en: 'Iban', ms: 'Iban', zh: '伊班族', ta: 'இபான்' }, kadazan: { en: 'Kadazan', ms: 'Kadazan', zh: '卡达山族', ta: 'கடசான்' }, modern: { en: 'Modern', ms: 'Moden', zh: '现代', ta: 'நவீன' } }; for (var i = 0; i < outfitsToDisplay.length; i++) { var row = Math.floor(i / itemsPerRow); var col = i % 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); 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 () { self.visible = true; self.loadOutfits(); return self; }; self.hide = function () { self.visible = false; 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: 0xE6E6FA }); /**** * Game Code ****/ // Initialize ItemSelector var itemSelector = new ItemSelector(); itemSelector.x = 2048 / 2; itemSelector.y = 400; itemSelector.currentCategory = 'malay'; // Initialize current category game.addChild(itemSelector); // Initialize with category selection after adding to the game itemSelector.setCategory('malay'); // Indian traditional // Indigenous traditional // Modern fusion // Sounds // Music // Initialize storage defaults if they don't exist if (storage.savedCharacters === undefined) { storage.savedCharacters = []; } if (storage.currentLanguage === undefined) { storage.currentLanguage = "en"; } var translations = { title: { en: 'Malaysian Mosaic', ms: 'Mozek Malaysia', zh: '马来西亚镶嵌', ta: 'மலேசிய மொசைக்' }, save: { en: 'Save', ms: 'Simpan', 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; game.addChild(background); // Add title to GUI var titleText = new Text2(translations.title[storage.currentLanguage], { size: 80, fill: 0x4682B4 }); titleText.anchor.set(0.5, 0); titleText.y = 20; LK.gui.top.addChild(titleText); // Add gender selection var genderSelector = new GenderSelector(); genderSelector.x = 2048 / 2; genderSelector.y = 180; genderSelector.setup(); game.addChild(genderSelector); // Add character var character = new Character(); character.x = 2048 / 2; character.y = 2732 / 2 - 100; game.addChild(character); // ItemSelector instance already created earlier in the code // Add language selector var languageSelector = new LanguageSelector(); languageSelector.x = 2048 / 2; languageSelector.y = 2732 - 100; languageSelector.setup(); game.addChild(languageSelector); // Add action buttons var saveButton = new UIButton(translations.save[storage.currentLanguage], 200, 80, 0x4CAF50); saveButton.x = 2048 - 300; saveButton.y = 100; game.addChild(saveButton); var resetButton = new UIButton(translations.reset[storage.currentLanguage], 200, 80, 0xF44336); resetButton.x = 2048 - 300; resetButton.y = 200; game.addChild(resetButton); // Add wardrobe button var wardrobeText = { en: "Ethnic Collection", ms: "Koleksi Etnik", zh: "民族服装集", ta: "இன ஆடை தொகுப்பு" }; var wardrobeButton = new UIButton(wardrobeText[storage.currentLanguage], 200, 80, 0x9370DB); wardrobeButton.x = 2048 - 300; wardrobeButton.y = 300; game.addChild(wardrobeButton); // Create wardrobe component var wardrobe = new Wardrobe(); wardrobe.x = 2048 / 2; wardrobe.y = 2732 / 2; wardrobe.updateLanguage(storage.currentLanguage); game.addChild(wardrobe); // Connect components genderSelector.setChangeCallback(function (gender) { // Change character base to gender-specific asset character.setGender(gender); }); // Initialize ItemSelector with needed functionality itemSelector.setSelectionCallback(function (item) { character.equip(item); }); languageSelector.setChangeCallback(function (language) { // Update all UI text titleText.setText(translations.title[language]); saveButton.setText(translations.save[language]); resetButton.setText(translations.reset[language]); wardrobeButton.setText(wardrobeText[language]); // Update gender selector genderSelector.updateLanguage(language); wardrobe.updateLanguage(language); }); // Button actions saveButton.setCallback(function () { var savedCharacters = storage.savedCharacters || []; savedCharacters.push(character.getData()); storage.savedCharacters = savedCharacters; LK.getSound('characterSaved').play(); // Visual feedback LK.effects.flashScreen(0x00FF00, 300); }); 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; } } }); // Setup wardrobe button wardrobeButton.setCallback(function () { wardrobe.show(); }); // 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 LK.playMusic('malaysiaMix'); // Note: DOM manipulation is not supported in the LK sandbox // The blocking overlay can only be hidden via game engine methods, not direct CSS // Game update function game.update = function () { // Game logic updates would go here if needed };
===================================================================
--- original.js
+++ change.js
@@ -801,9 +801,15 @@
// Get items for the current category, gender and type
if (self.items[self.currentCategory] && self.items[self.currentCategory][currentGender] && self.items[self.currentCategory][currentGender][self.currentType]) {
currentItems = self.items[self.currentCategory][currentGender][self.currentType] || [];
}
- var filteredItems = currentItems;
+ // Filter items to ensure gender-specific clothing
+ var filteredItems = currentItems.filter(function (item) {
+ // 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