/** * CharacterCustomizationSystem.js * ================================ * KRVAVA ลฝETEV - Complete Character Customization (Phase 17) * * Features: * - Gender selection (Kai/Ana story reversal) * - RGB color picker (unlimited colors!) * - Body customization (skin, height, type) * - Starting outfit selection * - Character creation UI * - Save/load system * * @author NovaFarma Team * @date 2025-12-23 */ class CharacterCustomizationSystem { constructor(scene) { this.scene = scene; // Character data this.character = { gender: 'male', // 'male' or 'female' name: 'Kai', // Hair hairColor: { r: 139, g: 69, b: 19 }, // Brown default hairStyle: 'dreadlocks', glowingHair: false, rainbowHair: false, // Body skinTone: 'medium', // 'light', 'medium', 'tan', 'dark' bodyType: 'normal', // 'slim', 'normal', 'athletic', 'heavy' height: 'normal', // 'short', 'normal', 'tall' // Outfit startingOutfit: 'farmer', // 'farmer', 'casual', 'formal' // Story searchingFor: 'Ana' // Twin's name (reverses with gender) }; // UI this.customizationUI = null; this.isCreating = false; // Presets this.hairColorPresets = [ { name: 'Black', r: 0, g: 0, b: 0 }, { name: 'Brown', r: 139, g: 69, b: 19 }, { name: 'Blonde', r: 255, g: 215, b: 0 }, { name: 'Red', r: 255, g: 69, b: 0 }, { name: 'White', r: 255, g: 255, b: 255 }, { name: 'Blue', r: 0, g: 191, b: 255 }, { name: 'Green', r: 0, g: 255, b: 127 }, { name: 'Pink', r: 255, g: 105, b: 180 }, { name: 'Purple', r: 138, g: 43, b: 226 }, { name: 'Rainbow', r: -1, g: -1, b: -1 } // Special ]; console.log('๐Ÿ‘ค CharacterCustomizationSystem initialized'); } /** * Start character creation */ startCreation() { this.isCreating = true; console.log('๐Ÿ‘ค Character creation started'); // Create UI this.createCustomizationUI(); // Show UI this.showUI(); } /** * Create customization UI */ createCustomizationUI() { const width = this.scene.cameras.main.width; const height = this.scene.cameras.main.height; this.customizationUI = this.scene.add.container(width / 2, height / 2); this.customizationUI.setScrollFactor(0); this.customizationUI.setDepth(10000); this.customizationUI.setVisible(false); // Background const bg = this.scene.add.rectangle(0, 0, 1000, 700, 0x1a1a1a, 0.95); bg.setStrokeStyle(4, 0xFFD700); this.customizationUI.add(bg); // Title const title = this.scene.add.text(0, -320, '๐Ÿ‘ค CHARACTER CREATION', { fontSize: '36px', fontFamily: 'Arial', color: '#FFD700', fontStyle: 'bold' }); title.setOrigin(0.5); this.customizationUI.add(title); // Preview (character sprite) this.characterPreview = this.scene.add.rectangle(0, -150, 200, 300, 0x8B4513); this.characterPreview.setStrokeStyle(2, 0xFFFFFF); this.customizationUI.add(this.characterPreview); const previewLabel = this.scene.add.text(0, -310, 'Preview', { fontSize: '18px', color: '#FFFFFF' }); previewLabel.setOrigin(0.5); this.customizationUI.add(previewLabel); // Gender selection this.createGenderSelector(); // Hair color picker this.createColorPicker(); // Body options this.createBodyOptions(); // Outfit selector this.createOutfitSelector(); // Confirm button const confirmBtn = this.scene.add.rectangle(0, 310, 200, 50, 0x228B22); confirmBtn.setStrokeStyle(3, 0x32CD32); confirmBtn.setInteractive(); confirmBtn.on('pointerdown', () => this.confirmCreation()); this.customizationUI.add(confirmBtn); const confirmText = this.scene.add.text(0, 310, 'START GAME!', { fontSize: '24px', fontFamily: 'Arial', color: '#FFFFFF', fontStyle: 'bold' }); confirmText.setOrigin(0.5); this.customizationUI.add(confirmText); console.log('โœ… Customization UI created'); } /** * Create gender selector */ createGenderSelector() { const label = this.scene.add.text(-400, 50, 'Gender:', { fontSize: '20px', color: '#FFFFFF', fontStyle: 'bold' }); this.customizationUI.add(label); // Male button const maleBtn = this.scene.add.rectangle(-350, 100, 120, 40, 0x0066CC); maleBtn.setStrokeStyle(2, 0x00AAFF); maleBtn.setInteractive(); maleBtn.on('pointerdown', () => this.setGender('male')); this.customizationUI.add(maleBtn); const maleText = this.scene.add.text(-350, 100, 'โ™‚ Kai (Male)', { fontSize: '16px', color: '#FFFFFF' }); maleText.setOrigin(0.5); this.customizationUI.add(maleText); // Female button const femaleBtn = this.scene.add.rectangle(-210, 100, 120, 40, 0xCC0066); femaleBtn.setStrokeStyle(2, 0xFF0099); femaleBtn.setInteractive(); femaleBtn.on('pointerdown', () => this.setGender('female')); this.customizationUI.add(femaleBtn); const femaleText = this.scene.add.text(-210, 100, 'โ™€ Ana (Female)', { fontSize: '16px', color: '#FFFFFF' }); femaleText.setOrigin(0.5); this.customizationUI.add(femaleText); } /** * Create color picker */ createColorPicker() { const label = this.scene.add.text(-400, 150, 'Hair Color:', { fontSize: '20px', color: '#FFFFFF', fontStyle: 'bold' }); this.customizationUI.add(label); // Preset colors let x = -400; let y = 200; this.hairColorPresets.forEach((preset, index) => { const colorBox = this.scene.add.rectangle(x, y, 30, 30, preset.r === -1 ? 0xFFFFFF : Phaser.Display.Color.GetColor(preset.r, preset.g, preset.b)); colorBox.setStrokeStyle(2, 0xFFFFFF); colorBox.setInteractive(); colorBox.on('pointerdown', () => this.setHairColor(preset)); this.customizationUI.add(colorBox); // Rainbow special effect if (preset.name === 'Rainbow') { const rainbowText = this.scene.add.text(x, y, '๐ŸŒˆ', { fontSize: '20px' }); rainbowText.setOrigin(0.5); this.customizationUI.add(rainbowText); } x += 40; if ((index + 1) % 5 === 0) { x = -400; y += 40; } }); // Glowing option const glowCheckbox = this.scene.add.rectangle(-400, 280, 20, 20, 0x444444); glowCheckbox.setStrokeStyle(2, 0xFFFFFF); glowCheckbox.setInteractive(); glowCheckbox.on('pointerdown', () => this.toggleGlowing()); this.customizationUI.add(glowCheckbox); this.glowLabel = this.scene.add.text(-370, 280, 'โœจ Glowing Hair', { fontSize: '16px', color: '#FFFFFF' }); this.glowLabel.setOrigin(0, 0.5); this.customizationUI.add(this.glowLabel); } /** * Create body options */ createBodyOptions() { let y = 50; // Skin tone const skinLabel = this.scene.add.text(200, y, 'Skin Tone:', { fontSize: '18px', color: '#FFFFFF', fontStyle: 'bold' }); this.customizationUI.add(skinLabel); const skinTones = ['light', 'medium', 'tan', 'dark']; skinTones.forEach((tone, index) => { const btn = this.scene.add.rectangle(200 + (index * 60), y + 40, 50, 30, this.getSkinColor(tone)); btn.setStrokeStyle(2, 0xFFFFFF); btn.setInteractive(); btn.on('pointerdown', () => this.setSkinTone(tone)); this.customizationUI.add(btn); }); // Body type y += 100; const bodyLabel = this.scene.add.text(200, y, 'Body Type:', { fontSize: '18px', color: '#FFFFFF', fontStyle: 'bold' }); this.customizationUI.add(bodyLabel); const bodyTypes = ['slim', 'normal', 'athletic', 'heavy']; bodyTypes.forEach((type, index) => { const btn = this.scene.add.rectangle(200, y + 40 + (index * 45), 150, 35, 0x444444); btn.setStrokeStyle(2, 0xFFFFFF); btn.setInteractive(); btn.on('pointerdown', () => this.setBodyType(type)); this.customizationUI.add(btn); const text = this.scene.add.text(200, y + 40 + (index * 45), type.toUpperCase(), { fontSize: '14px', color: '#FFFFFF' }); text.setOrigin(0.5); this.customizationUI.add(text); }); } /** * Create outfit selector */ createOutfitSelector() { const label = this.scene.add.text(200, 250, 'Starting Outfit:', { fontSize: '18px', color: '#FFFFFF', fontStyle: 'bold' }); this.customizationUI.add(label); const outfits = [ { id: 'farmer', name: 'Farmer Outfit' }, { id: 'casual', name: 'Casual Clothes' }, { id: 'formal', name: 'Formal Wear' } ]; outfits.forEach((outfit, index) => { const btn = this.scene.add.rectangle(200, 290 + (index * 45), 180, 35, 0x444444); btn.setStrokeStyle(2, 0xFFFFFF); btn.setInteractive(); btn.on('pointerdown', () => this.setOutfit(outfit.id)); this.customizationUI.add(btn); const text = this.scene.add.text(200, 290 + (index * 45), outfit.name, { fontSize: '14px', color: '#FFFFFF' }); text.setOrigin(0.5); this.customizationUI.add(text); }); } /** * Set gender */ setGender(gender) { this.character.gender = gender; if (gender === 'male') { this.character.name = 'Kai'; this.character.searchingFor = 'Ana'; } else { this.character.name = 'Ana'; this.character.searchingFor = 'Kai'; } console.log(`๐Ÿ‘ค Gender set to: ${gender} (searching for ${this.character.searchingFor})`); this.updatePreview(); } /** * Set hair color */ setHairColor(preset) { if (preset.name === 'Rainbow') { this.character.rainbowHair = true; this.character.hairColor = { r: 255, g: 0, b: 255 }; // Default to purple } else { this.character.rainbowHair = false; this.character.hairColor = { r: preset.r, g: preset.g, b: preset.b }; } console.log(`๐Ÿ’‡ Hair color: ${preset.name}`); this.updatePreview(); } /** * Toggle glowing hair */ toggleGlowing() { this.character.glowingHair = !this.character.glowingHair; console.log(`โœจ Glowing hair: ${this.character.glowingHair}`); this.updatePreview(); } /** * Set skin tone */ setSkinTone(tone) { this.character.skinTone = tone; console.log(`๐Ÿ‘ค Skin tone: ${tone}`); this.updatePreview(); } /** * Set body type */ setBodyType(type) { this.character.bodyType = type; console.log(`๐Ÿ‘ค Body type: ${type}`); this.updatePreview(); } /** * Set outfit */ setOutfit(outfitId) { this.character.startingOutfit = outfitId; console.log(`๐Ÿ‘• Outfit: ${outfitId}`); this.updatePreview(); } /** * Get skin color */ getSkinColor(tone) { const colors = { light: 0xFFE4C4, medium: 0xDEB887, tan: 0xD2B48C, dark: 0x8B7355 }; return colors[tone] || colors.medium; } /** * Update character preview */ updatePreview() { // Update preview sprite color const skinColor = this.getSkinColor(this.character.skinTone); this.characterPreview.setFillStyle(skinColor); // TODO: Update actual sprite appearance console.log('๐Ÿ‘ค Preview updated'); } /** * Confirm creation */ confirmCreation() { this.isCreating = false; console.log('โœ… Character creation complete!'); console.log(this.character); // Save character data this.saveCharacter(); // Hide UI this.hideUI(); // Start game with customized character this.startGame(); } /** * Save character data */ saveCharacter() { try { localStorage.setItem('krvava_zetev_character', JSON.stringify(this.character)); console.log('๐Ÿ’พ Character saved'); } catch (error) { console.error('Failed to save character:', error); } } /** * Load character data */ loadCharacter() { try { const saved = localStorage.getItem('krvava_zetev_character'); if (saved) { this.character = JSON.parse(saved); console.log('๐Ÿ“ฅ Character loaded'); return true; } } catch (error) { console.error('Failed to load character:', error); } return false; } /** * Start game */ startGame() { console.log(`๐ŸŽฎ Starting game as ${this.character.name}!`); console.log(`Quest: Find ${this.character.searchingFor}!`); // Apply character to game this.applyCharacterToGame(); // Show notification this.showNotification({ title: 'Welcome to Krvava ลฝetev!', text: `Play as ${this.character.name}. Find ${this.character.searchingFor}!`, icon: '๐Ÿ‘ค' }); } /** * Apply character to game */ applyCharacterToGame() { // TODO: Apply character appearance to player sprite // TODO: Set story variables based on gender console.log('๐Ÿ‘ค Character applied to game'); } /** * Show UI */ showUI() { if (this.customizationUI) { this.customizationUI.setVisible(true); } } /** * Hide UI */ hideUI() { if (this.customizationUI) { this.customizationUI.setVisible(false); } } /** * Get character data */ getCharacter() { return { ...this.character }; } /** * Helper: Show notification */ showNotification(notification) { console.log(`๐Ÿ“ข ${notification.icon} ${notification.title}: ${notification.text}`); const ui = this.scene.scene.get('UIScene'); if (ui && ui.showNotification) { ui.showNotification(notification); } } }