Files
game_development_workshop/js/avatar.js
T

147 lines
5.2 KiB
JavaScript

/**
* PPE SAFETY CHALLENGE - DYNAMIC 2D WORKER AVATAR SYSTEM
* Uses the step-by-step transparent character images from ppe_character_steps_transparent_png!
* Dynamically switches character states as safety gear is equipped.
*/
class WorkerAvatar {
constructor(containerId) {
this.container = document.getElementById(containerId);
this.equippedItems = new Set();
this.render();
}
setEquipped(itemIds) {
this.equippedItems = new Set(itemIds);
this.updateLayers();
}
equip(itemId) {
this.equippedItems.add(itemId);
this.updateLayers();
}
unequip(itemId) {
this.equippedItems.delete(itemId);
this.updateLayers();
}
has(itemId) {
return this.equippedItems.has(itemId);
}
getAvatarCenterCoordinates() {
if (!this.container) return { x: 170, y: 220, eyeX: 170, eyeY: 110, handX: 230, handY: 260 };
const rect = this.container.getBoundingClientRect();
const parentRect = this.container.parentElement.getBoundingClientRect();
const relX = rect.left - parentRect.left + (rect.width * 0.5);
const relY = rect.top - parentRect.top + (rect.height * 0.5);
return {
x: relX,
y: relY,
eyeX: relX,
eyeY: relY - 130,
handX: relX + 55,
handY: relY + 30
};
}
getStepImagePath() {
const hasHelmet = this.equippedItems.has('safety_helmet_grind') || this.equippedItems.has('safety_helmet_chem');
const hasGoggles = this.equippedItems.has('chem_splash_goggles') || this.equippedItems.has('safety_goggles_grind');
const hasFaceShield = this.equippedItems.has('face_shield_grind') || this.equippedItems.has('face_shield_chem');
const hasHearing = this.equippedItems.has('hearing_protection_grind') || this.equippedItems.has('hearing_protection_chem');
const hasLeatherGloves = this.equippedItems.has('leather_grinding_gloves');
const hasWorkGloves = this.equippedItems.has('work_gloves_grind') || this.equippedItems.has('standard_work_gloves');
const hasChemGloves = this.equippedItems.has('chem_resistant_gloves');
const hasVest = this.equippedItems.has('reflective_vest_grind');
const hasApron = this.equippedItems.has('chem_resistant_apron');
const hasCottonCoat = this.equippedItems.has('cotton_coat_chem');
const hasBoots = this.equippedItems.has('steel_toe_boots_grind') || this.equippedItems.has('chem_safety_shoes');
const hasMask = this.equippedItems.has('dust_mask_grind');
// 10. Full PPE with Mask
if (hasMask) {
return 'images/steps/10_full_ppe_with_mask.png';
}
// 9. Full Grinding Set with Boots
if (hasHelmet && (hasGoggles || hasFaceShield) && hasHearing && (hasLeatherGloves || hasChemGloves) && (hasVest || hasApron || hasBoots)) {
return 'images/steps/09_helmet_goggles_hearing_leather_gloves_vest_boots.png';
}
// 8. With Vest / Body Wear
if (hasHelmet && (hasGoggles || hasFaceShield) && hasHearing && (hasLeatherGloves || hasChemGloves) && (hasVest || hasApron || hasCottonCoat)) {
return 'images/steps/08_helmet_goggles_hearing_leather_gloves_vest.png';
}
// 7. With Leather / Chem Gloves
if (hasHelmet && (hasGoggles || hasFaceShield) && hasHearing && (hasLeatherGloves || hasChemGloves)) {
return 'images/steps/07_helmet_goggles_hearing_leather_gloves.png';
}
// 6. With Work Gloves
if (hasHelmet && (hasGoggles || hasFaceShield) && hasHearing && hasWorkGloves) {
return 'images/steps/06_helmet_goggles_hearing_work_gloves.png';
}
// 5. With Earmuffs / Hearing Protection
if (hasHelmet && (hasGoggles || hasFaceShield) && hasHearing) {
return 'images/steps/05_helmet_goggles_hearing.png';
}
// 4. With Face Shield
if (hasFaceShield || (hasHelmet && hasFaceShield)) {
return 'images/steps/04_helmet_goggles_face_shield.png';
}
// 3. With Goggles & Helmet
if (hasHelmet && hasGoggles) {
return 'images/steps/03_helmet_goggles.png';
}
// 2. Helmet Only
if (hasHelmet) {
return 'images/steps/02_helmet.png';
}
// Individual items
if (hasFaceShield) return 'images/steps/04_helmet_goggles_face_shield.png';
if (hasGoggles) return 'images/steps/03_helmet_goggles.png';
if (hasHearing) return 'images/steps/05_helmet_goggles_hearing.png';
if (hasLeatherGloves) return 'images/steps/07_helmet_goggles_hearing_leather_gloves.png';
if (hasWorkGloves) return 'images/steps/06_helmet_goggles_hearing_work_gloves.png';
// 1. Base Worker (No PPE)
return 'images/steps/01_no_ppe.png';
}
render() {
if (!this.container) return;
this.container.innerHTML = `
<div class="avatar-step-container" id="avatar-step-container">
<!-- Floor Contact Shadow -->
<div class="avatar-floor-shadow"></div>
<!-- Dynamic Character Step Image -->
<img src="images/steps/01_no_ppe.png" alt="Worker Character" class="avatar-step-img" id="avatar-step-img" />
</div>
`;
this.updateLayers();
}
updateLayers() {
if (!this.container) return;
const imgEl = document.getElementById('avatar-step-img');
if (imgEl) {
const targetSrc = this.getStepImagePath();
if (imgEl.getAttribute('src') !== targetSrc) {
imgEl.src = targetSrc;
}
}
}
}