Files
game_development_workshop/index.html
T

448 lines
20 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PPE Safety Challenge - Choose Right. Work Safe.</title>
<link rel="stylesheet" href="css/styles.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@600;700&family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
</head>
<body>
<!-- App Container -->
<div id="app-root" class="app-container">
<!-- Top Navigation / Header Bar -->
<header class="top-bar">
<div class="brand-badge">
<div class="safety-helmet-icon">
<svg viewBox="0 0 36 36" class="helmet-svg">
<path d="M 6 22 C 6 12 30 12 30 22 L 34 24 C 34 26 2 26 2 24 Z" fill="#facc15" stroke="#ca8a04" stroke-width="1.5"/>
<path d="M 14 11 L 22 11 L 21 23 L 15 23 Z" fill="#eab308"/>
<rect x="3" y="23" width="30" height="3" rx="1.5" fill="#ca8a04"/>
</svg>
</div>
<div class="brand-text">
<span class="game-title">PPE SAFETY CHALLENGE</span>
<span class="game-tagline">CHOOSE RIGHT. WORK SAFE.</span>
</div>
</div>
<div class="hud-center">
<div class="scenario-stepper" id="scenario-stepper">
<div class="step-pill active" id="step-pill-1">
<span class="step-num">1</span>
<span class="step-label">Grinding Ops</span>
</div>
<div class="step-dots">·······</div>
<div class="step-pill" id="step-pill-2">
<span class="step-num">2</span>
<span class="step-label">Chemical Handling</span>
</div>
</div>
</div>
<div class="hud-right">
<div class="score-display">
<span class="score-label">SAFETY SCORE</span>
<span class="score-val" id="hud-score">0</span>
<span class="score-star-icon">★</span>
<span class="score-stars-sub" id="hud-stars">☆</span>
</div>
<!-- Audio & Settings Controls -->
<button id="btn-sound-toggle" class="btn-icon-hud" title="Sound Effects (S)" aria-label="Sound Toggle">
<span>🔊</span>
</button>
<button id="btn-music-toggle" class="btn-icon-hud" title="Music Toggle (M)" aria-label="Music Toggle">
<span>🎵</span>
</button>
<button id="btn-audio-settings" class="btn-icon-hud" title="Audio Settings (O)" aria-label="Audio Settings">
<span>⚙️</span>
</button>
</div>
</header>
<!-- Main Dynamic Screen Container -->
<main id="main-viewport" class="main-viewport">
<!-- SCREEN 1: START / INTRO SCREEN -->
<section id="screen-start" class="screen-view active">
<div class="intro-card">
<div class="hero-graphic">
<div class="safety-shield-animated">
<svg viewBox="0 0 100 100" class="shield-svg">
<polygon points="50,5 92,20 92,55 50,95 8,55 8,20" class="shield-outline" />
<path d="M50 25 L50 75 M25 50 L75 50" class="shield-plus" />
</svg>
<div class="pulse-ring"></div>
</div>
</div>
<h1 class="hero-title">PPE SAFETY CHALLENGE</h1>
<p class="hero-subtitle">“Choose Right. Work Safe.”</p>
<div class="mission-briefing">
<h3>Interactive Workplace Safety Mission</h3>
<p>Select the correct Personal Protective Equipment (PPE) for critical industrial tasks. Learn how proper gear prevents severe workplace injuries before starting dangerous operations.</p>
<div class="learning-flow-banner">
<span class="flow-item">🔍 SEE SITUATION</span>
<span class="flow-arrow">➔</span>
<span class="flow-item">⚠️ IDENTIFY HAZARD</span>
<span class="flow-arrow">➔</span>
<span class="flow-item">🦺 SELECT PPE</span>
<span class="flow-arrow">➔</span>
<span class="flow-item">⚙️ START TASK</span>
</div>
</div>
<div class="start-controls">
<button id="btn-start-game" class="btn btn-primary btn-large glow-effect">
<span class="btn-icon-large">▶</span>
<span class="btn-text">START CHALLENGE</span>
</button>
<div class="controls-hint">
<span>⌨️ Mouse Click or Number Keys (1-9) to equip • Spacebar to Start Task</span>
</div>
</div>
</div>
</section>
<!-- SCREEN 2: ACTIVE GAMEPLAY VIEW -->
<section id="screen-game" class="screen-view">
<div class="gameplay-grid">
<!-- Left Column: Hazard Assessment & Worker Protection Status -->
<aside class="sidebar-hazard-panel card-panel">
<div class="panel-header">
<div class="scenario-badge" id="scene-badge">SCENARIO 1 OF 2</div>
<h2 class="scenario-title" id="scene-title">Chemical Handling & Dispensing</h2>
<p class="situation-desc" id="scene-desc">
An employee is transferring an industrial corrosive solvent between approved containers at a ventilated dispensing station.
</p>
</div>
<!-- Identify Hazards Box -->
<div class="hazard-identification-card">
<div class="card-subtitle-small">IDENTIFY THE HAZARDS</div>
<ul class="hazard-list" id="hazard-list">
<!-- Dynamically populated -->
</ul>
</div>
<!-- Worker Protection Status with Wireframe Silhouette -->
<div class="worker-protection-card">
<div class="card-subtitle-small">WORKER PROTECTION STATUS</div>
<div class="protection-status-content">
<!-- Blue Wireframe Silhouette -->
<div class="body-silhouette-box">
<svg viewBox="0 0 100 200" class="wireframe-body-svg">
<!-- Head -->
<circle cx="50" cy="24" r="14" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
<!-- Neck -->
<line x1="50" y1="38" x2="50" y2="46" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
<!-- Shoulders & Torso -->
<path d="M 24 55 L 76 55 L 68 115 L 32 115 Z" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
<!-- Left Arm -->
<path d="M 24 55 L 12 105 L 10 140" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
<!-- Right Arm -->
<path d="M 76 55 L 88 105 L 90 140" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
<!-- Left Leg -->
<path d="M 38 115 L 34 165 L 32 195" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
<!-- Right Leg -->
<path d="M 62 115 L 66 165 L 68 195" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
</svg>
</div>
<!-- Status Rows -->
<div class="protection-rows" id="coverage-grid">
<div class="status-row-item" data-slot="head">
<span class="row-icon">🧢</span>
<span class="row-label">Head</span>
<span class="row-badge status-q">?</span>
</div>
<div class="status-row-item" data-slot="eyes">
<span class="row-icon">👓</span>
<span class="row-label">Eyes / Face</span>
<span class="row-badge status-q">?</span>
</div>
<div class="status-row-item" data-slot="ears">
<span class="row-icon">🎧</span>
<span class="row-label">Hearing</span>
<span class="row-badge status-q">?</span>
</div>
<div class="status-row-item" data-slot="hands">
<span class="row-icon">🧤</span>
<span class="row-label">Hands</span>
<span class="row-badge status-q">?</span>
</div>
<div class="status-row-item" data-slot="body">
<span class="row-icon">🦺</span>
<span class="row-label">Body</span>
<span class="row-badge status-q">?</span>
</div>
<div class="status-row-item" data-slot="feet">
<span class="row-icon">🥾</span>
<span class="row-label">Feet</span>
<span class="row-badge status-q">?</span>
</div>
</div>
</div>
</div>
<!-- Tip Box -->
<div class="tip-card">
<div class="tip-title">💡 TIP</div>
<p class="tip-text" id="locker-guide-text">
Observe the scene, identify the hazards and select the correct PPE before starting the task.
</p>
</div>
</aside>
<!-- Middle Column: Interactive Scene & Worker Avatar -->
<div class="center-stage-panel card-panel">
<div class="scene-environment-container" id="scene-stage">
<!-- Scene canvas for particles/sparks/chemicals -->
<canvas id="stage-fx-canvas" class="stage-fx-canvas"></canvas>
<!-- Dynamic Background Scenery Layer -->
<div class="scene-backdrop" id="scene-backdrop">
<!-- Dynamically populated based on scenario -->
</div>
<!-- Worker Avatar Interactive SVG Layer -->
<div class="avatar-wrapper" id="avatar-container">
<!-- Injected by avatar.js -->
</div>
<!-- Freeze Frame / Critical Warning Alert Overlay -->
<div class="consequence-freeze-overlay" id="consequence-overlay">
<div class="freeze-banner">
<div class="freeze-header">
<span class="hazard-flasher" id="hazard-flasher-badge">⚠️ STOP! CRITICAL HAZARDS DETECTED</span>
</div>
<h3 class="consequence-title" id="consequence-title">Critical Protection Gaps Detected</h3>
<p class="consequence-desc" id="consequence-desc">
Multiple required protective gear items are missing or improper for this task. Unprotected body zones are exposed to severe workplace trauma.
</p>
<div class="missing-items-box">
<div class="missing-box-header">
<span class="box-label">⚠️ ALL REQUIRED CORRECTIONS (<span id="missing-count-num">0</span> ISSUES):</span>
</div>
<div class="missing-hazard-cards" id="consequence-hazard-list">
<!-- Dynamically rendered list of all missing & incorrect items -->
</div>
</div>
<button id="btn-fix-ppe" class="btn btn-warning glow-effect">
<span>🔧 FIX ALL WORKER PPE & RETRY</span>
</button>
</div>
</div>
<!-- Success Overlay Banner -->
<div class="success-overlay" id="success-overlay">
<div class="success-banner">
<div class="success-badge">
<span class="badge-icon">✅</span>
<span class="badge-title" id="success-title">SAFE TO START</span>
</div>
<p class="success-desc" id="success-desc">
Correct PPE selected. Your eyes, face, hands, hearing and feet are fully protected against all task hazards.
</p>
<div class="points-awarded-pill">
<span class="star-icon">⭐</span>
<span class="points-text" id="awarded-points-text">+100 Safety Points</span>
</div>
<button id="btn-next-scenario" class="btn btn-success glow-effect">
<span id="btn-next-scenario-text">NEXT SCENARIO ➔</span>
</button>
</div>
</div>
</div>
</div>
<!-- Right Column: PPE Selection Locker (3x3 Grid) & Action Buttons -->
<aside class="sidebar-locker-panel card-panel">
<div class="panel-header-locker">
<div class="locker-title-row">
<span class="locker-icon">🦺</span>
<h3 class="locker-title">PPE SAFETY LOCKER</h3>
</div>
<p class="locker-subtitle">Select and equip the correct PPE for this task.</p>
<p class="locker-instruction">Click an item to equip on the worker.</p>
</div>
<!-- 3x3 Equipment Grid -->
<div class="ppe-locker-grid" id="ppe-locker-grid">
<!-- Dynamically populated based on scenario (9 items in 3 columns) -->
</div>
<!-- Locker Action Buttons -->
<div class="locker-actions-dock">
<button id="btn-check-ppe" class="btn btn-check-ppe">
<span class="btn-check-icon">✓</span>
<span>CHECK MY PPE</span>
</button>
<button id="btn-test-safety" class="btn btn-start-task glow-ready">
<span class="btn-play-icon">▶</span>
<span id="btn-test-safety-text">START TASK</span>
</button>
</div>
</aside>
</div>
</section>
<!-- SCREEN 3: COMPLETION / FINAL SCORE SCREEN -->
<section id="screen-summary" class="screen-view">
<div class="summary-card">
<div class="summary-header">
<div class="victory-trophy">🏆</div>
<h1 class="summary-title">PPE SAFETY CHALLENGE COMPLETE</h1>
<p class="summary-subtitle">“Choose Right. Work Safe.”</p>
</div>
<div class="metrics-dashboard">
<div class="metric-box">
<span class="metric-label">FINAL SAFETY SCORE</span>
<span class="metric-val" id="summary-score">200 / 200</span>
<span class="metric-sub" id="summary-percentage">100% Safety Compliance</span>
</div>
<div class="metric-box">
<span class="metric-label">SCENARIOS COMPLETED</span>
<span class="metric-val">2 / 2</span>
<span class="metric-sub">Zero Workplace Accidents</span>
</div>
<div class="metric-box">
<span class="metric-label">SAFETY STARS</span>
<span class="metric-val star-gold" id="summary-stars">⭐⭐</span>
<span class="metric-sub" id="summary-rank">Master Safety Practitioner</span>
</div>
</div>
<!-- Key Takeaway Mantra -->
<div class="takeaway-banner">
<div class="takeaway-heading">CORE SAFETY WORKFLOW</div>
<div class="mantra-chain">
<div class="mantra-step">🛑 <strong>STOP</strong></div>
<div class="mantra-arrow">➔</div>
<div class="mantra-step">👁️ <strong>LOOK</strong></div>
<div class="mantra-arrow">➔</div>
<div class="mantra-step">⚠️ <strong>IDENTIFY HAZARDS</strong></div>
<div class="mantra-arrow">➔</div>
<div class="mantra-step">🦺 <strong>SELECT PPE</strong></div>
<div class="mantra-arrow">➔</div>
<div class="mantra-step">🛡️ <strong>WORK SAFELY</strong></div>
</div>
</div>
<!-- Scenarios Review Summary Accordion -->
<div class="scenarios-review-box">
<h4>Safety Assessment Summary</h4>
<div class="review-row">
<div class="rev-icon">⚡</div>
<div class="rev-info">
<strong>Scenario 1: Angle Grinding Operation</strong>
<p>Protected against flying hot sparks, high decibel noise (95+ dB), and sharp metal burrs using Full Face Shield + Glasses, Leather Grinding Gloves, Hearing Protection & Safety Boots.</p>
</div>
<div class="rev-status">✅ PASSED</div>
</div>
<div class="review-row">
<div class="rev-icon">🧪</div>
<div class="rev-info">
<strong>Scenario 2: Industrial Chemical Transfer</strong>
<p>Prevented chemical burn & splash injury using Chemical Splash Goggles, Heavy Nitrile Gauntlet Gloves, Chemical Resistant Apron & Rubber Safety Boots.</p>
</div>
<div class="rev-status">✅ PASSED</div>
</div>
</div>
<div class="summary-actions">
<button id="btn-replay" class="btn btn-primary btn-large">
<span>🔄 REPLAY SAFETY CHALLENGE</span>
</button>
<button id="btn-print-certificate" class="btn btn-secondary btn-large">
<span>📜 PRINT SAFETY CERTIFICATE</span>
</button>
</div>
</div>
</section>
</main>
<!-- Audio Settings Modal Dialog -->
<div class="modal-backdrop" id="modal-audio">
<div class="modal-card">
<div class="modal-header">
<h3>🔊 Audio & Sound Control</h3>
<button id="btn-close-audio-modal" class="btn-close" aria-label="Close modal">✕</button>
</div>
<div class="modal-body">
<div class="audio-control-row">
<label for="toggle-master-mute">Master Audio</label>
<input type="checkbox" id="toggle-master-mute" checked>
</div>
<div class="audio-control-row">
<label for="slider-music-vol">Background Music Volume (<span id="music-vol-num">25%</span>)</label>
<input type="range" id="slider-music-vol" min="0" max="100" value="25">
</div>
<div class="audio-control-row">
<label for="slider-sfx-vol">Sound Effects (SFX) Volume (<span id="sfx-vol-num">55%</span>)</label>
<input type="range" id="slider-sfx-vol" min="0" max="100" value="55">
</div>
<div class="audio-control-row">
<label for="toggle-ambient-hum">Industrial Ambience Hum</label>
<input type="checkbox" id="toggle-ambient-hum" checked>
</div>
<div class="audio-info-note">
ℹ️ The game features a real-time Web Audio synthesizer. Audio starts when you click <strong>Start Challenge</strong>. All safety information is also fully visual and accessible when muted.
</div>
</div>
<div class="modal-footer">
<button id="btn-save-audio" class="btn btn-primary">Done</button>
</div>
</div>
</div>
<!-- Printable Certificate Template (Hidden until printed) -->
<div id="printable-certificate" class="printable-certificate">
<div class="cert-border">
<div class="cert-header">
<div class="cert-logo">✚ PPE SAFETY CHALLENGE</div>
<h1>CERTIFICATE OF SAFETY EXCELLENCE</h1>
<p class="cert-sub">This certifies that</p>
<h2 class="cert-name">QUALIFIED INDUSTRIAL EMPLOYEE</h2>
<p class="cert-desc">has successfully demonstrated 100% competency in Hazard Identification & Personal Protective Equipment (PPE) Selection across all high-risk industrial scenarios.</p>
</div>
<div class="cert-footer">
<div class="cert-signature">
<div class="sig-line"></div>
<span>Safety & Environmental Health Officer</span>
</div>
<div class="cert-seal">
⭐ VERIFIED SAFE ⭐
</div>
<div class="cert-date">
<div class="sig-line" id="cert-date-val"></div>
<span>Completion Date</span>
</div>
</div>
</div>
</div>
</div>
<!-- Scripts -->
<script src="js/audio.js"></script>
<script src="js/scenarios.js"></script>
<script src="js/particles.js"></script>
<script src="js/avatar.js"></script>
<script src="js/game.js"></script>
</body>
</html>