旗袍,源于1920年代中国上海,由满族服饰演变而来...
User prompt
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: "செரானி (யூரேசியன்) பெண்களின் பாரம்பரிய உடையில் போர்த்துகீசிய ஸ்டைல் லேஸ் ப்ளவுஸ்கள் மலாய் ஸ்டைல் பாட்டிக் பாவாடைகளுடன் இணைக்கப்படுகிறது. மலேசியாவின் காலனித்துவ வரலாறு மற்றும் கிரியோல் மரபை இது பிரதிபலிக்கிறது." } }; Duplicate the appearing method of cultural info panel
User prompt
// Updated culturalInfoScripts var culturalInfoScripts = { siameseMale: { en: `Traditional Siamese Male Attire - Suea Phra Ratchathan (เสื้อพระราชทาน): - Chong kraben (โจงกระเบน): Luxurious silk cloth wrapped as loose trousers - Suea phra ratchathan: Formal jacket with standing collar and frog buttons Made 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 (เสื้อพระราชทาน): - Chong kraben: Kain sutera mewah dililit sebagai seluar longgar - Suea phra ratchathan: Jaket formal berkolar tegak dengan butang frog Diperbuat daripada sutera phrae wa dengan teknik prada emas, dipakai komuniti Siam Malaysia semasa Songkran dan upacara kuil.`, zh: `暹罗男性传统服饰 - 御赐外套 (เสื้อพระราชทาน): - 幔裤 (โจงกระเบน): 奢华丝绸制成的裹式宽松裤 - 御赐外套: 立领盘扣正装外套 采用Phrae Wa丝绸配金箔工艺制作,马来西亚暹罗社群在宋干节和寺庙仪式中穿着。`, ta: `சியாமீஸ் ஆண்களின் பாரம்பரிய உடை - சுவியா ப்ரா ராட்சாதன் (เสื้อพระราชทาน): - சோங் க்ராபென்: பட்டு துணியால் செய்யப்பட்ட தளர்வான கால்சட்டை - சுவியா ப்ரா ராட்சாதன்: நிமிர்ந்த காலர் மற்றும் தவளை பொத்தான்கள் கொண்ட முறையான ஜாக்கெட் தங்க பிரதா நுட்பத்துடன் ஃப்ரே வா பட்டில் செய்யப்பட்டது, மலேசிய சியாமீஸ் சமூகங்களால் சொங்க்ரான் மற்றும் கோவில் சடங்குகளில் அணியப்படுகிறது.` } }; // Updated ItemSelector configuration self.items = { siamese: { male: { top: [{ name: 'siameseTop', label: { en: 'Suea Phra Ratchathan', ms: 'Suea Phra Ratchathan', zh: '御赐外套', ta: 'சுவியா ப்ரா ராட்சாதன்' } }] } } }; // Updated infoMapping const infoMapping = { 'siameseTop': 'siameseMale', // ... other mappings ... };
User prompt
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: "சியாமீஸ் பெண்களின் பாரம்பரிய உடையில் கிடை அமைப்புடன் கூடிய 'பா சின்' பாவாடை மற்றும் ஒரு தோளில் சுற்றிய சபாய் துணி அடங்கும். பட்டுத் துணிகள் மற்றும் தங்க நெசவு வடிவங்கள் மூலம் தாய்-மலாய் கலாச்சார இணைவைக் காட்டுகிறது." }, add Pha Sin as the title of Siamese female attires (Siamese dress), and duplicate the appearing of cultural info for Pha Sin just like other attires
Code edit (1 edits merged)
Please save this source code
User prompt
Duplicate the appearing of cultural info panel for Dhotti just like other attires
User prompt
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. Add it to multicultural info panel for Dhotti, available in English, Malay, Simplified Chinese and Tamil
User prompt
// 1. Add to culturalInfoScripts var culturalInfoScripts = { // ... existing entries ... 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 மாட்த்துண்டு துணியால் உருவாக்கப்பட்ட இந்திய பெண்களின் பாரம்பரிய ஆடை. மலேசியாவில் பொதுவாக குறுகிய சட்டை (சோளி) மற்றும் அடிக்கோடணியுடன் அணியப்படுகிறது. தீபாவளி மற்றும் இந்திய திருமணங்களில் இது அணியப்படுகிறது." } }; // 2. Update ClothingItem class selection handler var ClothingItem = Container.expand(function (type, category, itemName) { var self = Container.call(this); // ... existing code ... self.select = function () { LK.getSound('itemSelect').play(); // Existing scaling and visual effects code here... // Cultural info mapping update const infoMapping = { 'saree': 'indianFemale', // ... other item mappings ... }; if (culturalInfoPanel && infoMapping[this.itemName]) { culturalInfoPanel.show(infoMapping[this.itemName]); } return self; }; return self; }); // 3. Ensure item configuration in ItemSelector var ItemSelector = Container.expand(function () { var self = Container.call(this); self.items = { indian: { female: { top: [{ name: 'saree', label: { en: 'Saree', ms: 'Sari', zh: '纱丽', ta: 'சேலை' } }] } } }; return self; });
User prompt
// Add to your existing culturalInfoScripts object var culturalInfoScripts = { // ... existing entries ... 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: "சாங்ஷான் (长衫) கிங் வம்சத்தில் தோன்றிய சீன ஆண்களின் பாரம்பரிய நீண்ட ஆடை. நேரான காலர், பக்க திறப்பு மற்றும் தளர்வான வடிவம் ஆகியவை இதன் அம்சங்கள். மலேசியாவில் கலாச்சார நிகழ்ச்சிகள் மற்றும் திருமண விழாக்களில் பிரபலமாக உள்ளது." }, indianMale: { en: "The traditional Indian male attire consists of a Kurta (long tunic) paired with a Dhoti or Sherwani. Made from cotton or silk, these garments often feature intricate embroidery. In Malaysia, they are worn during Deepavali, weddings, and cultural events.", ms: "Pakaian tradisional lelaki India terdiri daripada Kurta (jubah panjang) dipadankan dengan Dhoti atau Sherwani. Diperbuat daripada kapas atau sutera, sering dihiasi dengan sulaman rumit. Di Malaysia, ia dipakai semasa Deepavali, perkahwinan dan acara kebudayaan.", zh: "印度男性传统服饰包括长款束腰外衣(Kurta)搭配托蒂(Dhoti)或舍瓦尼(Sherwani)。棉或丝绸材质,常有精美刺绣。在马来西亚常见于屠妖节、婚礼及文化活动。", ta: "இந்திய ஆண்களின் பாரம்பரிய உடையில் குர்தா (நீண்ட சட்டை) டோட்டி அல்லது ஷெர்வானியுடன் இணைக்கப்படுகிறது. பருத்தி அல்லது பட்டு துணிகளில் சிக்கலான எம்ப்ராய்டரி உள்ளது. மலேசியாவில் தீபாவளி, திருமணங்கள் மற்றும் கலாச்சார நிகழ்வுகளில் அணியப்படுகிறது." }, ibanMale: { en: "Traditional Iban male attire features a 'baju burung' warrior jacket with intricate beadwork and a 'sirat' loincloth. The outfit is completed with a headdress adorned with hornbill feathers, symbolizing bravery and connection to nature.", ms: "Pakaian tradisional lelaki Iban terdiri daripada jaket pahlawan 'baju burung' dengan manik rumit dan kain 'sirat'. Lengkap dengan serban yang dihiasi bulu burung enggang, melambangkan keberanian dan hubungan dengan alam.", zh: "伊班族男性传统服饰包括带有复杂珠饰的'baju burung'战士夹克和'sirat'腰布。配有犀鸟羽毛头饰,象征勇敢及与自然的联系。", ta: "இபான் ஆண்களின் பாரம்பரிய உடையில் சிக்கலான மணிகள் வைக்கப்பட்ட 'பாஜு புருங்' ஜாக்கெட் மற்றும் 'சிராட்' மேல்துணி அடங்கும். இரைனோசெரஸ் இறகுகளால் அலங்கரிக்கப்பட்ட தலைப்பாகை தைரியம் மற்றும் இயற்கையுடன் உள்ள தொடர்பை குறிக்கிறது." }, // Add similar entries for other ethnic groups: kadazanFemale: { en: "Kadazan women wear the 'sinuangga' blouse with hand-woven cloth and silver belt. The outfit is accessorized with bead necklaces and a 'siung' headdress made from dried grass, representing cultural identity.", ms: "Wanita Kadazan memakai blaus 'sinuangga' dengan kain tenun tangan dan tali pinggang perak. Dilengkapi kalung manik dan serban 'siung' daripada rumput kering, melambangkan identiti budaya.", zh: "卡达山族女性穿着手工编织的'sinuangga'上衣配银腰带,搭配珠链和干草制成的'siung'头饰,体现文化身份。", 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: "சியாமீஸ் பெண்களின் பாரம்பரிய உடையில் கிடை அமைப்புடன் கூடிய 'பா சின்' பாவாடை மற்றும் ஒரு தோளில் சுற்றிய சபாய் துணி அடங்கும். பட்டுத் துணிகள் மற்றும் தங்க நெசவு வடிவங்கள் மூலம் தாய்-மலாய் கலாச்சார இணைவைக் காட்டுகிறது." }, 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: "பாபா ஆண்கள் மேற்கத்திய ஸ்டைல் கால்சட்டையுடன் 'பாஜு லோக்சுவான்' (நீண்ட சட்டை) அணிகின்றனர். சீன எம்ப்ராய்டரி மற்றும் ஐரோப்பிய தையல் தொழில்நுட்பத்தை இணைக்கும் இந்த உடை பேரணாகன் கலாச்சாரத்தை பிரதிபலிக்கிறது." }, chettiFemale: { en: "Chetti Melaka women wear the 'nyonya kebaya' with Malay-style batik sarong, accented with gold pin brooches. The outfit symbolizes the community's unique blend of Indian and Malay cultural elements.", ms: "Wanita Chetti Melaka memakai 'nyonya kebaya' dengan batik sarung gaya Melayu, dihiasi bros pin emas. Mewakili gabungan unik unsur budaya India dan Melayu dalam masyarakat mereka.", zh: "马六甲侨生女性穿着娘惹卡巴雅配马来风格蜡染纱笼,饰以金扣针,体现印度与马来文化元素的独特融合。", ta: "செட்டி மலாக்கா பெண்கள் மலாய் ஸ்டைல் பாட்டிக் சரோங்குடன் 'நியோனியா கெபாயா' அணிகின்றனர். தங்க ஊசி பிரோசுகளால் அலங்கரிக்கப்பட்ட இந்த உடை இந்திய மற்றும் மலாய் கலாச்சார கூறுகளின் தனித்துவமான கலவையை குறிக்கிறது." }, 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: "ஒராங் ஆஸ்லி பெண்கள் இயற்கை சாயங்கள் மற்றும் விதை மணிகளால் அலங்கரிக்கப்பட்ட கைநெசவு மரப்பட்டை ஆடைகளை அணிகின்றனர். வடிவங்கள் பழங்குடி பிரபஞ்சவியல் மற்றும் மழைக்காடு சூழலியல் உறவை குறிக்கின்றன." }, 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 ala Portugis dengan batik sarung gaya Melayu. Gabungan budaya ini mencerminkan sejarah penjajahan dan warisan kreol Malaysia.", zh: "Serani(欧亚混血)女性传统服饰融合葡萄牙风格蕾丝上衣与马来蜡染纱笼,体现马来西亚殖民历史与克里奥尔遗产。", ta: "செரானி (யூரேசியன்) பெண்களின் பாரம்பரிய உடையில் போர்த்துகீசிய ஸ்டைல் லேஸ் ப்ளவுஸ்கள் மலாய் ஸ்டைல் பாட்டிக் பாவாடைகளுடன் இணைக்கப்படுகிறது. மலேசியாவின் காலனித்துவ வரலாறு மற்றும் கிரியோல் மரபை இது பிரதிபலிக்கிறது." } };// In ClothingItem class self.select = function () { LK.getSound('itemSelect').play(); // Existing scaling code here... // Show cultural info for all ethnic items const infoMapping = { 'Changsan': 'changsan', 'Dhotti': 'indianMale', 'saree': 'indianFemale', 'Ibanman': 'ibanMale', 'Ibanwoman': 'ibanFemale', 'Kadazanman': 'kadazanMale', 'Indigenous': 'indigenousFemale', 'siameseDress': 'siameseFemale', 'siameseTop': 'siameseMale', 'Nyonya': 'babanyonyaFemale', 'babaNyonyaTop': 'babanyonyaMale', 'Chettiman': 'chettiMale', 'Chettiwoman': 'chettiFemale', 'Seraniman': 'seraniMale', 'Seraniwoman': 'seraniFemale' }; if (culturalInfoPanel && infoMapping[this.itemName]) { culturalInfoPanel.show(infoMapping[this.itemName]); } return self; };var culturalInfoScripts = { // Existing entries bajuKurung: {...}, bajuMelayu: {...}, cheongsam: {...}, // New entries changsan: { en: "The Changshan...", ms: "Changshan...", zh: "长衫...", ta: "சாங்ஷான்..." }, ibanMale: { en: "Traditional Iban male attire...", ms: "Pakaian tradisional lelaki Iban...", zh: "伊班族男性传统服饰...", ta: "இபான் ஆண்களின் பாரம்பரிய உடை..." }, ibanFemale: { en: "Iban women's traditional dress...", ms: "Pakaian tradisional wanita Iban...", zh: "伊班族女性传统服饰...", ta: "இபான் பெண்களின் பாரம்பரிய உடை..." }, kadazanMale: { en: "Kadazan men wear...", ms: "Lelaki Kadazan memakai...", zh: "卡达山族男性穿着...", ta: "கடசான் ஆண்கள் அணியும்..." }, // Add all other ethnic descriptions here // following the same pattern };// In ItemSelector items configuration items: { iban: { male: { top: [{ name: 'Ibanman', label: {en: 'Iban Attire', ...}, infoKey: 'ibanMale' // Add this }] }, female: { top: [{ name: 'Ibanwoman', label: {en: 'Iban Female Attire', ...}, infoKey: 'ibanFemale' // Add this }] } }, // Update all other categories similarly }// In CulturalInfoPanel class self.show = function (itemKey) { // Add font family based on language const fontMapping = { zh: "'Noto Sans SC', sans-serif", ta: "'Noto Sans Tamil', sans-serif", ms: "'Noto Sans', sans-serif", en: "'Roboto', sans-serif" }; this.infoText.style.fontFamily = fontMapping[storage.currentLanguage]; // Existing content loading code... };- Chinese: Changsan - Indian: Kurta/Dhotti (Male), Saree (Female) - Iban: Ibanman/Ibanwoman - Kadazan: Kadazanman/Kadazanwoman - Siamese: siameseTop/siameseDress - Baba Nyonya: babaNyonyaTop/Nyonya - Chetti: Chettiman/Chettiwoman - Indigenous: Indigenous - Serani: Seraniman/Seraniwoman
User prompt
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. Insert it for Malay version script
User prompt
Cheongsam, also known as Qipao in Mandarin, originated from Shanghai, China in the 1920s...
旗袍,源于1920年代中国上海,由满族服饰演变而来...
சியோங்க்சாம், மாண்டரினில் கிபாவ் என அழைக்கப்படுகிறது...
User prompt
Still appearing the same problems!!
User prompt
But I cannot see the Cultural Info Scripts after click on a character wearing bajuMelayu
User prompt
Pakaian tradisional bagi kaum lelaki Melayu ialah baju Melayu. Baju Melayu merupakan kameja longgar yang dipakai dengan seluar panjang. Pakaian ini selalunya dipadankan dengan kain samping yang diikat di bahagian pinggang dan bersongkok. Add this script as Cultural Information Panel for Malay male attire, with Baju Melayu as the title, make it available in English, Simplified Chinese and Tamil
User prompt
Update Seraniman asset to the male items for the Serani category
User prompt
Update Seraniwoman asset to the female items for the Serani category
User prompt
Keep on Integration failed, why??
User prompt
Add Chettiman for Chetti male attire
User prompt
Add Chettiwoman asset for Chetti female attire
User prompt
Replace chettiTop with Chettiwoman asset
User prompt
Plugins are still have errors!!
User prompt
Fix L38 and L39 error
User prompt
Add Chettiwoman asset in the Chetti female items button
User prompt
Add Chettiwoman asset as Chetti female attire
User prompt
Implement the specific size of Ibanman asset in the Iban male items button
User prompt
Implement the same size of image of Ibanman asset as the Iban male items button
/**** * 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: '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'); } }; return self; }); var CulturalInfoPanel = Container.expand(function () { var self = Container.call(this); // Create background panel var bg = self.attachAsset('uiPanel', { anchorX: 0.5, anchorY: 0.5, width: 1600, height: 1200, tint: 0xFFFAF0 // Ivory color }); // 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 + 40; self.addChild(self.titleText); // Info text with word wrapping self.infoText = new Text2("", { size: 40, fill: 0x333333, wordWrap: true, wordWrapWidth: 1400 }); self.infoText.anchor.set(0.5, 0); self.infoText.y = -bg.height / 2 + 130; self.addChild(self.infoText); // Close button var closeButton = new UIButton("X", 80, 80, 0xF44336); closeButton.x = bg.width / 2 - 60; closeButton.y = -bg.height / 2 + 60; 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; // Get current language var lang = storage.currentLanguage; // Update title based on language and item var titleTranslations = { 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: "சேலை" }, "default": { en: "Cultural Information", ms: "Maklumat Budaya", zh: "文化信息", ta: "கலாச்சார தகவல்" } }; // Set title based on item type or use default 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: [] } }, 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 = []; // 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] || []; } // 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'); } } }; 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 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', '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: 'இந்திய' }, 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: 0xE6E6FA }); /**** * Game Code ****/ // Initialize ItemSelector // Game constants 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 game.addChild(itemSelector); // Initialize with category selection after adding to the game itemSelector.setCategory('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"; } 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; game.addChild(background); // Add cultural information scripts var culturalInfoScripts = { 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: "தோட்டி என்பது இந்திய துணைக்கண்டத்தில் ஆண்களுக்கான பாரம்பரிய ஆடையாகும், இது இடுப்பில் சுற்றி, தொடையிடுக்குப் பகுதியில் கட்டப்பட்டு, முன் அல்லது பின் பகுதியில் கட்டப்படும் செவ்வக வெள்ளைத் துணியாகும். இந்திய ஆண்கள் திருமணங்கள் மற்றும் பண்டிகைகளின் போதும் இதை அணிகிறார்கள். இந்த அடிப்படைத் துணி பல்வேறு வண்ணங்களில் வரலாம், சிறிய மணிகள் அல்லது எம்பிராய்டரியுடன் அழகாக அலங்கரிக்கப்படலாம். மஞ்சள் அல்லது பால் மஞ்சள் நிறத்திலும் தோட்டிகள் உள்ளன." } }; // 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 - 600; // Position to left side of character genderSelector.y = 2732 / 2; // Center vertically with character genderSelector.setup(); game.addChild(genderSelector); // Add character var character = new Character(); character.x = 2048 / 2; character.y = 2732 / 2 - 100; game.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(); game.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; game.addChild(resetPanel); var resetButton = new UIButton(translations.reset[storage.currentLanguage], 200, 80, 0xF44336); resetButton.x = 2048 - 200; resetButton.y = 200; game.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; game.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"; 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); // 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'); } }); languageSelector.setChangeCallback(function (language) { // Update all UI text titleText.setText(translations.title[language]); resetButton.setText(translations.reset[language]); wardrobeButton.setText(wardrobeText[language]); // 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; game.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; } } } // 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; } } }); // Setup wardrobe button wardrobeButton.setCallback(function () { 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 LK.playMusic('malaysiaMix'); // 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; } } } };
===================================================================
--- original.js
+++ change.js
@@ -1976,8 +1976,14 @@
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: "தோட்டி என்பது இந்திய துணைக்கண்டத்தில் ஆண்களுக்கான பாரம்பரிய ஆடையாகும், இது இடுப்பில் சுற்றி, தொடையிடுக்குப் பகுதியில் கட்டப்பட்டு, முன் அல்லது பின் பகுதியில் கட்டப்படும் செவ்வக வெள்ளைத் துணியாகும். இந்திய ஆண்கள் திருமணங்கள் மற்றும் பண்டிகைகளின் போதும் இதை அணிகிறார்கள். இந்த அடிப்படைத் துணி பல்வேறு வண்ணங்களில் வரலாம், சிறிய மணிகள் அல்லது எம்பிராய்டரியுடன் அழகாக அலங்கரிக்கப்படலாம். மஞ்சள் அல்லது பால் மஞ்சள் நிறத்திலும் தோட்டிகள் உள்ளன."
}
};
// Add title to GUI
var titleText = new Text2(translations.title[storage.currentLanguage], {