acesesibiliti
This commit is contained in:
303
docs/guides/CLOSED_CAPTIONS_TESTING.md
Normal file
303
docs/guides/CLOSED_CAPTIONS_TESTING.md
Normal file
@@ -0,0 +1,303 @@
|
||||
# 🎬 Closed Captions & Visual Sound Cues Testing Guide
|
||||
|
||||
## 📋 Overview
|
||||
This guide covers testing for the enhanced Visual Sound Cue System, including:
|
||||
- ✅ Closed Captions with sound effects
|
||||
- ✅ Speaker names & colors
|
||||
- ✅ Directional arrows (< Sound >)
|
||||
- ✅ Background opacity slider
|
||||
- ✅ Fishing bobber visual queue
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Features to Test
|
||||
|
||||
### 1. **Closed Captions [SOUND EFFECT]**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] **Damage Sound**: `[DAMAGE TAKEN]` appears when player takes damage
|
||||
- [ ] **Pickup Sound**: `[PICKED UP: Item Name]` appears when collecting items
|
||||
- [ ] **Harvest Sound**: `[CROP HARVESTED]` appears when harvesting crops
|
||||
- [ ] **Building Sound**: `[BUILDING PLACED]` appears when placing buildings
|
||||
- [ ] **Digging Sound**: `[DIGGING SOUND]` appears when digging
|
||||
- [ ] **Planting Sound**: `[PLANTING SOUND]` appears when planting
|
||||
- [ ] **Footsteps**: `[FOOTSTEPS]` appears when walking
|
||||
- [ ] **Door Sound**: `[DOOR OPENS]` appears when opening doors
|
||||
- [ ] **Chest Sound**: `[CHEST OPENS]` appears when opening chests
|
||||
- [ ] **Water Sound**: `[WATER SPLASH]` appears near water
|
||||
- [ ] **Fire Sound**: `[FIRE CRACKLING]` appears near fire
|
||||
- [ ] **Explosion**: `[EXPLOSION!]` appears with screen flash
|
||||
- [ ] **UI Click**: `[CLICK]` appears on button clicks
|
||||
- [ ] **UI Hover**: `[HOVER]` appears on button hover
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
// In browser console (F12):
|
||||
const visualCues = game.scene.scenes[1].visualSoundCues;
|
||||
|
||||
// Test different sound effects
|
||||
visualCues.onSoundPlayed('damage', { direction: 'left', amount: 25 });
|
||||
visualCues.onSoundPlayed('pickup', { item: 'Carrot' });
|
||||
visualCues.onSoundPlayed('harvest');
|
||||
visualCues.onSoundPlayed('build');
|
||||
visualCues.onSoundPlayed('dig');
|
||||
visualCues.onSoundPlayed('plant');
|
||||
visualCues.onSoundPlayed('footsteps', { direction: 'right' });
|
||||
visualCues.onSoundPlayed('door');
|
||||
visualCues.onSoundPlayed('chest');
|
||||
visualCues.onSoundPlayed('water');
|
||||
visualCues.onSoundPlayed('fire');
|
||||
visualCues.onSoundPlayed('explosion');
|
||||
visualCues.onSoundPlayed('ui_click');
|
||||
visualCues.onSoundPlayed('ui_hover');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. **Speaker Names & Colors**
|
||||
|
||||
#### Predefined Speakers:
|
||||
- 🟢 **Player**: Green (`#00ff00`)
|
||||
- 🟡 **NPC**: Yellow (`#ffff00`)
|
||||
- 🔴 **Enemy**: Red (`#ff0000`)
|
||||
- 🔵 **System**: Cyan (`#00ffff`)
|
||||
- ⚪ **Narrator**: White (`#ffffff`)
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Speaker name appears above subtitle
|
||||
- [ ] Speaker name has correct color
|
||||
- [ ] Speaker name is bold
|
||||
- [ ] Speaker name can be toggled on/off
|
||||
- [ ] Custom speakers can be added
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const visualCues = game.scene.scenes[1].visualSoundCues;
|
||||
|
||||
// Test different speakers
|
||||
visualCues.showSubtitle('Hello, adventurer!', 3000, 'NPC');
|
||||
visualCues.showSubtitle('You found a treasure!', 3000, 'System');
|
||||
visualCues.showSubtitle('GRRRR!', 3000, 'Enemy');
|
||||
visualCues.showSubtitle('I need help!', 3000, 'Player');
|
||||
visualCues.showSubtitle('Long ago, in a distant land...', 5000, 'Narrator');
|
||||
|
||||
// Add custom speaker
|
||||
visualCues.addSpeakerColor('Merchant', '#ffa500'); // Orange
|
||||
visualCues.showSubtitle('Welcome to my shop!', 3000, 'Merchant');
|
||||
|
||||
// Toggle speaker names
|
||||
visualCues.toggleSpeakerNames(false); // Hide speaker names
|
||||
visualCues.showSubtitle('This has no speaker name', 3000, 'NPC');
|
||||
visualCues.toggleSpeakerNames(true); // Show speaker names
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. **Directional Arrows (< Sound >)**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Left arrow (◄) appears for sounds from the left
|
||||
- [ ] Right arrow (►) appears for sounds from the right
|
||||
- [ ] Both arrows appear for omnidirectional sounds
|
||||
- [ ] Arrows pulse/animate
|
||||
- [ ] Arrows can be toggled on/off
|
||||
- [ ] Arrows disappear when subtitle hides
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const visualCues = game.scene.scenes[1].visualSoundCues;
|
||||
|
||||
// Test directional arrows
|
||||
visualCues.showSubtitle('Sound from the left', 3000, 'System', 'left');
|
||||
setTimeout(() => {
|
||||
visualCues.showSubtitle('Sound from the right', 3000, 'System', 'right');
|
||||
}, 3500);
|
||||
setTimeout(() => {
|
||||
visualCues.showSubtitle('Sound from everywhere', 3000, 'System', 'both');
|
||||
}, 7000);
|
||||
|
||||
// Test with actual game sounds
|
||||
visualCues.onSoundPlayed('footsteps', { direction: 'left' });
|
||||
visualCues.onSoundPlayed('enemy_growl', { direction: 'right' });
|
||||
visualCues.onSoundPlayed('damage', { direction: 'left', amount: 10 });
|
||||
|
||||
// Toggle directional arrows
|
||||
visualCues.toggleDirectionalArrows(false); // Disable
|
||||
visualCues.showSubtitle('No arrows', 3000, 'System', 'left');
|
||||
visualCues.toggleDirectionalArrows(true); // Enable
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. **Background Opacity Slider**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Default opacity is 0.8 (80%)
|
||||
- [ ] Opacity can be changed from 0.0 to 1.0
|
||||
- [ ] Opacity change is visible immediately
|
||||
- [ ] Opacity setting is saved to localStorage
|
||||
- [ ] Opacity persists after page reload
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const visualCues = game.scene.scenes[1].visualSoundCues;
|
||||
|
||||
// Show subtitle to see background
|
||||
visualCues.showSubtitle('Testing opacity...', 5000, 'System');
|
||||
|
||||
// Test different opacity levels
|
||||
visualCues.setSubtitleOpacity(1.0); // Fully opaque
|
||||
visualCues.setSubtitleOpacity(0.5); // 50% transparent
|
||||
visualCues.setSubtitleOpacity(0.2); // 20% opaque
|
||||
visualCues.setSubtitleOpacity(0.0); // Fully transparent
|
||||
visualCues.setSubtitleOpacity(0.8); // Back to default
|
||||
|
||||
// Test clamping (values outside 0-1)
|
||||
visualCues.setSubtitleOpacity(1.5); // Should clamp to 1.0
|
||||
visualCues.setSubtitleOpacity(-0.5); // Should clamp to 0.0
|
||||
|
||||
// Verify setting is saved
|
||||
console.log('Current opacity:', visualCues.settings.subtitleOpacity);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. **Fishing Bobber Visual Queue**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Indicator appears in center of screen
|
||||
- [ ] Shows orange circle background
|
||||
- [ ] Shows exclamation mark (!)
|
||||
- [ ] Shows "FISH BITING! Press E" text
|
||||
- [ ] Pulses 5 times
|
||||
- [ ] Fades in and out smoothly
|
||||
- [ ] Can be toggled on/off
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const visualCues = game.scene.scenes[1].visualSoundCues;
|
||||
|
||||
// Test fishing bobber cue
|
||||
visualCues.showFishingBobberCue();
|
||||
|
||||
// Test with fishing sound
|
||||
visualCues.onSoundPlayed('fishing_cast');
|
||||
setTimeout(() => {
|
||||
visualCues.onSoundPlayed('fishing_bite');
|
||||
}, 2000);
|
||||
|
||||
// Toggle fishing bobber
|
||||
visualCues.toggleFishingBobber(false); // Disable
|
||||
visualCues.onSoundPlayed('fishing_bite'); // Should not show
|
||||
visualCues.toggleFishingBobber(true); // Enable
|
||||
visualCues.onSoundPlayed('fishing_bite'); // Should show
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎮 Integration Testing
|
||||
|
||||
### Test All Features Together:
|
||||
```javascript
|
||||
const visualCues = game.scene.scenes[1].visualSoundCues;
|
||||
|
||||
// Scenario 1: NPC Conversation
|
||||
visualCues.showSubtitle('Hello there!', 3000, 'NPC', 'left');
|
||||
setTimeout(() => {
|
||||
visualCues.showSubtitle('Can you help me?', 3000, 'NPC', 'left');
|
||||
}, 3500);
|
||||
|
||||
// Scenario 2: Combat
|
||||
visualCues.onSoundPlayed('enemy_growl', { direction: 'right' });
|
||||
setTimeout(() => {
|
||||
visualCues.onSoundPlayed('damage', { direction: 'right', amount: 15 });
|
||||
}, 1000);
|
||||
|
||||
// Scenario 3: Fishing
|
||||
visualCues.onSoundPlayed('fishing_cast');
|
||||
setTimeout(() => {
|
||||
visualCues.onSoundPlayed('fishing_bite');
|
||||
}, 3000);
|
||||
|
||||
// Scenario 4: Achievement
|
||||
visualCues.onSoundPlayed('achievement', { message: 'First Harvest!' });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Settings Testing
|
||||
|
||||
### Test All Toggle Functions:
|
||||
```javascript
|
||||
const visualCues = game.scene.scenes[1].visualSoundCues;
|
||||
|
||||
// Test all toggles
|
||||
visualCues.toggleSubtitles(false);
|
||||
visualCues.toggleSubtitles(true);
|
||||
|
||||
visualCues.toggleSpeakerNames(false);
|
||||
visualCues.toggleSpeakerNames(true);
|
||||
|
||||
visualCues.toggleDirectionalArrows(false);
|
||||
visualCues.toggleDirectionalArrows(true);
|
||||
|
||||
visualCues.toggleFishingBobber(false);
|
||||
visualCues.toggleFishingBobber(true);
|
||||
|
||||
visualCues.toggleHeartbeat(false);
|
||||
visualCues.toggleHeartbeat(true);
|
||||
|
||||
visualCues.toggleDamageIndicator(false);
|
||||
visualCues.toggleDamageIndicator(true);
|
||||
|
||||
visualCues.toggleScreenFlash(false);
|
||||
visualCues.toggleScreenFlash(true);
|
||||
|
||||
// Verify settings are saved
|
||||
console.log('Current settings:', visualCues.settings);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Expected Results
|
||||
|
||||
### ✅ Success Criteria:
|
||||
1. All closed captions appear with correct text
|
||||
2. Speaker names display with correct colors
|
||||
3. Directional arrows appear and animate correctly
|
||||
4. Opacity slider works smoothly (0.0 - 1.0)
|
||||
5. Fishing bobber cue is visible and animated
|
||||
6. All settings can be toggled on/off
|
||||
7. Settings persist after page reload
|
||||
8. No console errors
|
||||
9. Performance remains smooth (60 FPS)
|
||||
|
||||
### ❌ Known Issues:
|
||||
- None currently
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Bug Reporting
|
||||
|
||||
If you find any issues, please report:
|
||||
1. **What you were testing**
|
||||
2. **What you expected to happen**
|
||||
3. **What actually happened**
|
||||
4. **Console errors** (if any)
|
||||
5. **Steps to reproduce**
|
||||
|
||||
---
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
- All features are designed for accessibility (deaf/hard-of-hearing players)
|
||||
- Directional arrows help identify sound source location
|
||||
- Speaker colors help distinguish between different characters
|
||||
- Opacity control allows customization for different visual preferences
|
||||
- Fishing bobber cue ensures players don't miss fishing opportunities
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-12-12
|
||||
**Version**: 2.5.0
|
||||
**Status**: ✅ Ready for Testing
|
||||
410
docs/guides/INPUT_REMAPPING_TESTING.md
Normal file
410
docs/guides/INPUT_REMAPPING_TESTING.md
Normal file
@@ -0,0 +1,410 @@
|
||||
# 🎮 Input Remapping System Testing Guide
|
||||
|
||||
## 📋 Overview
|
||||
Complete input customization system with:
|
||||
- ✅ Full keyboard remapping
|
||||
- ✅ Controller button remapping
|
||||
- ✅ Multiple control profiles
|
||||
- ✅ One-handed layouts (left/right)
|
||||
- ✅ Custom profile saving
|
||||
- ✅ Import/Export bindings
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Features to Test
|
||||
|
||||
### 1. **Basic Input Detection**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Keyboard keys are detected correctly
|
||||
- [ ] Mouse buttons are detected (left, right, middle)
|
||||
- [ ] Mouse wheel is detected (up/down)
|
||||
- [ ] Controller buttons are detected (if connected)
|
||||
- [ ] All input types can be bound to actions
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
// In browser console (F12):
|
||||
const inputSystem = game.scene.scenes[1].inputRemapping;
|
||||
|
||||
// Check if action is pressed
|
||||
console.log('Move Up pressed:', inputSystem.isActionPressed('move_up'));
|
||||
console.log('Attack pressed:', inputSystem.isActionPressed('attack'));
|
||||
console.log('Interact pressed:', inputSystem.isActionPressed('interact'));
|
||||
|
||||
// Check if action was just pressed (single frame)
|
||||
console.log('Inventory just pressed:', inputSystem.isActionJustPressed('inventory'));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. **Action Rebinding**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Can rebind any action to a new key
|
||||
- [ ] Rebinding shows "Press any key..." prompt
|
||||
- [ ] ESC cancels rebinding
|
||||
- [ ] New binding is saved to localStorage
|
||||
- [ ] Binding persists after page reload
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const inputSystem = game.scene.scenes[1].inputRemapping;
|
||||
|
||||
// Rebind "interact" action
|
||||
inputSystem.startRebinding('interact', (action, newKey) => {
|
||||
console.log(`Action "${action}" rebound to: ${newKey}`);
|
||||
});
|
||||
|
||||
// Now press any key to rebind
|
||||
// Press ESC to cancel
|
||||
|
||||
// Check new binding
|
||||
console.log('Interact binding:', inputSystem.getBindingDisplay('interact'));
|
||||
|
||||
// Reset to default
|
||||
inputSystem.resetAction('interact');
|
||||
console.log('Interact reset:', inputSystem.getBindingDisplay('interact'));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. **Control Profiles**
|
||||
|
||||
#### Available Profiles:
|
||||
- **default**: Standard WASD + mouse
|
||||
- **wasd**: WASD movement (same as default)
|
||||
- **arrows**: Arrow keys for movement
|
||||
- **left-handed**: Numpad movement, left-side actions
|
||||
- **right-handed**: Standard WASD (same as default)
|
||||
- **custom-1**: User-defined profile 1
|
||||
- **custom-2**: User-defined profile 2
|
||||
- **custom-3**: User-defined profile 3
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Can switch between profiles
|
||||
- [ ] Profile changes are applied immediately
|
||||
- [ ] Profile selection is saved
|
||||
- [ ] Custom profiles can be created
|
||||
- [ ] Custom profiles persist after reload
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const inputSystem = game.scene.scenes[1].inputRemapping;
|
||||
|
||||
// List all profiles
|
||||
console.log('Available profiles:', inputSystem.getProfiles());
|
||||
|
||||
// Switch to left-handed profile
|
||||
inputSystem.switchProfile('left-handed');
|
||||
console.log('Move Up binding:', inputSystem.getBindingDisplay('move_up'));
|
||||
|
||||
// Switch to arrows profile
|
||||
inputSystem.switchProfile('arrows');
|
||||
console.log('Move Up binding:', inputSystem.getBindingDisplay('move_up'));
|
||||
|
||||
// Switch back to default
|
||||
inputSystem.switchProfile('default');
|
||||
|
||||
// Get current profile
|
||||
console.log('Current profile:', inputSystem.getCurrentProfile());
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. **One-Handed Layouts**
|
||||
|
||||
#### Left-Handed Layout:
|
||||
- **Movement**: Numpad (8/5/4/6) or IJKL
|
||||
- **Actions**: Q, W, E, R, T, Y (left side of keyboard)
|
||||
- **Tools**: 7, 8, 9, 0, - (top row)
|
||||
- **Quick actions**: A, S (easy reach)
|
||||
|
||||
#### Right-Handed Layout:
|
||||
- **Movement**: WASD (standard)
|
||||
- **Actions**: E, Space, J (right side)
|
||||
- **Tools**: 1-5 (number row)
|
||||
- **Quick actions**: H, F (right hand)
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Left-handed layout uses numpad for movement
|
||||
- [ ] Right-handed layout uses WASD
|
||||
- [ ] All actions are reachable with one hand
|
||||
- [ ] Layouts are comfortable for extended play
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const inputSystem = game.scene.scenes[1].inputRemapping;
|
||||
|
||||
// Test left-handed layout
|
||||
inputSystem.switchProfile('left-handed');
|
||||
console.log('=== LEFT-HANDED LAYOUT ===');
|
||||
console.log('Move Up:', inputSystem.getBindingDisplay('move_up'));
|
||||
console.log('Move Down:', inputSystem.getBindingDisplay('move_down'));
|
||||
console.log('Move Left:', inputSystem.getBindingDisplay('move_left'));
|
||||
console.log('Move Right:', inputSystem.getBindingDisplay('move_right'));
|
||||
console.log('Interact:', inputSystem.getBindingDisplay('interact'));
|
||||
console.log('Attack:', inputSystem.getBindingDisplay('attack'));
|
||||
|
||||
// Test right-handed layout
|
||||
inputSystem.switchProfile('right-handed');
|
||||
console.log('=== RIGHT-HANDED LAYOUT ===');
|
||||
console.log('Move Up:', inputSystem.getBindingDisplay('move_up'));
|
||||
console.log('Interact:', inputSystem.getBindingDisplay('interact'));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. **Custom Profiles**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Can save current bindings to custom profile
|
||||
- [ ] Can load custom profile
|
||||
- [ ] Custom profiles persist after reload
|
||||
- [ ] Can have up to 3 custom profiles
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const inputSystem = game.scene.scenes[1].inputRemapping;
|
||||
|
||||
// Customize some bindings
|
||||
inputSystem.startRebinding('move_up', () => {});
|
||||
// Press 'I' key
|
||||
|
||||
inputSystem.startRebinding('move_down', () => {});
|
||||
// Press 'K' key
|
||||
|
||||
// Save to custom profile
|
||||
inputSystem.saveToProfile('custom-1');
|
||||
console.log('✅ Saved to custom-1');
|
||||
|
||||
// Switch to another profile
|
||||
inputSystem.switchProfile('default');
|
||||
|
||||
// Load custom profile
|
||||
inputSystem.switchProfile('custom-1');
|
||||
console.log('Move Up:', inputSystem.getBindingDisplay('move_up'));
|
||||
console.log('Move Down:', inputSystem.getBindingDisplay('move_down'));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. **Import/Export Bindings**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Can export bindings as JSON
|
||||
- [ ] Can import bindings from JSON
|
||||
- [ ] Import/export preserves all profiles
|
||||
- [ ] Import/export preserves active profile
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const inputSystem = game.scene.scenes[1].inputRemapping;
|
||||
|
||||
// Export bindings
|
||||
const exported = inputSystem.exportBindings();
|
||||
console.log('Exported bindings:', exported);
|
||||
|
||||
// Copy to clipboard (manual step)
|
||||
// Modify some bindings...
|
||||
|
||||
// Import bindings
|
||||
const success = inputSystem.importBindings(exported);
|
||||
console.log('Import success:', success);
|
||||
|
||||
// Verify bindings are restored
|
||||
console.log('Current profile:', inputSystem.getCurrentProfile());
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. **Controller Support**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Controller is detected when connected
|
||||
- [ ] Controller buttons are mapped correctly
|
||||
- [ ] Xbox and PlayStation layouts are supported
|
||||
- [ ] Controller info is displayed
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const inputSystem = game.scene.scenes[1].inputRemapping;
|
||||
|
||||
// Check if controller is connected
|
||||
console.log('Controller connected:', inputSystem.isControllerConnected());
|
||||
|
||||
// Get controller info
|
||||
const info = inputSystem.getControllerInfo();
|
||||
console.log('Controller info:', info);
|
||||
|
||||
// Get button names
|
||||
console.log('A button:', inputSystem.getControllerButtonName('A'));
|
||||
console.log('Start button:', inputSystem.getControllerButtonName('START'));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 8. **Binding Display**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Key names are formatted correctly
|
||||
- [ ] Mouse buttons show as "Left Click", etc.
|
||||
- [ ] Arrow keys show as ↑↓←→
|
||||
- [ ] Multiple bindings show as "W / ↑"
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const inputSystem = game.scene.scenes[1].inputRemapping;
|
||||
|
||||
// Get all action bindings
|
||||
const actions = [
|
||||
'move_up', 'move_down', 'move_left', 'move_right',
|
||||
'interact', 'attack', 'inventory', 'sprint',
|
||||
'zoom_in', 'zoom_out'
|
||||
];
|
||||
|
||||
console.log('=== ALL BINDINGS ===');
|
||||
actions.forEach(action => {
|
||||
console.log(`${action}: ${inputSystem.getBindingDisplay(action)}`);
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 9. **Reset Functions**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Can reset single action to default
|
||||
- [ ] Can reset all bindings to default
|
||||
- [ ] Reset is saved to localStorage
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const inputSystem = game.scene.scenes[1].inputRemapping;
|
||||
|
||||
// Rebind something
|
||||
inputSystem.startRebinding('interact', () => {});
|
||||
// Press 'G' key
|
||||
|
||||
console.log('Modified:', inputSystem.getBindingDisplay('interact'));
|
||||
|
||||
// Reset single action
|
||||
inputSystem.resetAction('interact');
|
||||
console.log('Reset:', inputSystem.getBindingDisplay('interact'));
|
||||
|
||||
// Rebind multiple actions...
|
||||
// Then reset all
|
||||
inputSystem.resetAllBindings();
|
||||
console.log('All bindings reset to default');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎮 Integration Testing
|
||||
|
||||
### Test All Features Together:
|
||||
```javascript
|
||||
const inputSystem = game.scene.scenes[1].inputRemapping;
|
||||
|
||||
// Scenario 1: Left-handed player setup
|
||||
console.log('=== LEFT-HANDED PLAYER SETUP ===');
|
||||
inputSystem.switchProfile('left-handed');
|
||||
console.log('Movement:', inputSystem.getBindingDisplay('move_up'));
|
||||
inputSystem.saveToProfile('custom-1');
|
||||
|
||||
// Scenario 2: Custom bindings
|
||||
console.log('=== CUSTOM BINDINGS ===');
|
||||
inputSystem.switchProfile('default');
|
||||
inputSystem.startRebinding('sprint', (action, key) => {
|
||||
console.log(`Sprint rebound to: ${key}`);
|
||||
});
|
||||
// Press 'SPACE'
|
||||
|
||||
// Scenario 3: Export/Import
|
||||
console.log('=== EXPORT/IMPORT ===');
|
||||
const backup = inputSystem.exportBindings();
|
||||
// Modify bindings...
|
||||
inputSystem.importBindings(backup);
|
||||
console.log('Bindings restored from backup');
|
||||
|
||||
// Scenario 4: Controller support
|
||||
console.log('=== CONTROLLER ===');
|
||||
if (inputSystem.isControllerConnected()) {
|
||||
console.log('Controller detected:', inputSystem.getControllerInfo());
|
||||
} else {
|
||||
console.log('No controller connected');
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Expected Results
|
||||
|
||||
### ✅ Success Criteria:
|
||||
1. All keyboard keys can be detected and bound
|
||||
2. Mouse buttons and wheel work correctly
|
||||
3. Profile switching works instantly
|
||||
4. One-handed layouts are comfortable
|
||||
5. Custom profiles save and load correctly
|
||||
6. Import/export preserves all data
|
||||
7. Controller detection works (if connected)
|
||||
8. Bindings persist after page reload
|
||||
9. Reset functions work correctly
|
||||
10. No console errors
|
||||
|
||||
### ❌ Known Issues:
|
||||
- None currently
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Bug Reporting
|
||||
|
||||
If you find any issues, please report:
|
||||
1. **What you were testing**
|
||||
2. **What you expected to happen**
|
||||
3. **What actually happened**
|
||||
4. **Console errors** (if any)
|
||||
5. **Steps to reproduce**
|
||||
|
||||
---
|
||||
|
||||
## 📝 Default Bindings Reference
|
||||
|
||||
### Movement:
|
||||
- **Move Up**: W / ↑
|
||||
- **Move Down**: S / ↓
|
||||
- **Move Left**: A / ←
|
||||
- **Move Right**: D / →
|
||||
|
||||
### Actions:
|
||||
- **Interact**: E / Space
|
||||
- **Attack**: Left Click / J
|
||||
- **Cancel**: Escape / X
|
||||
- **Confirm**: Enter / E
|
||||
|
||||
### Inventory & UI:
|
||||
- **Inventory**: I / Tab
|
||||
- **Crafting**: C
|
||||
- **Map**: M
|
||||
- **Quest Log**: Q
|
||||
- **Pause**: Escape / P
|
||||
|
||||
### Tools:
|
||||
- **Tool 1-5**: 1-5 (number keys)
|
||||
|
||||
### Quick Actions:
|
||||
- **Quick Heal**: H
|
||||
- **Quick Eat**: F
|
||||
- **Sprint**: Shift
|
||||
- **Crouch**: Ctrl
|
||||
|
||||
### Camera:
|
||||
- **Zoom In**: + / Scroll Up
|
||||
- **Zoom Out**: - / Scroll Down
|
||||
- **Camera Reset**: R
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-12-12
|
||||
**Version**: 2.5.0
|
||||
**Status**: ✅ Ready for Testing
|
||||
432
docs/guides/SCREEN_READER_TESTING.md
Normal file
432
docs/guides/SCREEN_READER_TESTING.md
Normal file
@@ -0,0 +1,432 @@
|
||||
# 🔊 Screen Reader System Testing Guide
|
||||
|
||||
## 📋 Overview
|
||||
Complete screen reader support for blind and visually impaired players with:
|
||||
- ✅ Speech synthesis (text-to-speech)
|
||||
- ✅ ARIA live regions
|
||||
- ✅ Audio cues (beeps/tones)
|
||||
- ✅ Keyboard navigation
|
||||
- ✅ Context announcements
|
||||
- ✅ Verbose mode
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Features to Test
|
||||
|
||||
### 1. **Speech Synthesis**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] System announces "Screen reader system ready" on startup
|
||||
- [ ] Speech rate can be adjusted (0.1 - 10)
|
||||
- [ ] Speech pitch can be adjusted (0 - 2)
|
||||
- [ ] Speech volume can be adjusted (0 - 1)
|
||||
- [ ] Multiple voices are available
|
||||
- [ ] Voice can be changed
|
||||
- [ ] Speech can be interrupted
|
||||
- [ ] Speech can be stopped
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
// In browser console (F12):
|
||||
const sr = game.scene.scenes[1].screenReader;
|
||||
|
||||
// Test basic speech
|
||||
sr.speak('Hello, this is a test.');
|
||||
|
||||
// Test with priority
|
||||
sr.speak('This is an alert!', 'alert', true);
|
||||
|
||||
// Adjust settings
|
||||
sr.setRate(1.5); // Faster
|
||||
sr.setRate(0.5); // Slower
|
||||
sr.setPitch(1.5); // Higher pitch
|
||||
sr.setPitch(0.5); // Lower pitch
|
||||
sr.setVolume(0.5); // 50% volume
|
||||
|
||||
// List available voices
|
||||
console.log(sr.getAvailableVoices());
|
||||
|
||||
// Change voice
|
||||
sr.setVoice('Microsoft David Desktop'); // Windows
|
||||
sr.setVoice('Alex'); // macOS
|
||||
|
||||
// Stop speech
|
||||
sr.stop();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. **Keyboard Navigation**
|
||||
|
||||
#### Keyboard Shortcuts:
|
||||
- **Ctrl+H**: Help (lists all commands)
|
||||
- **Ctrl+R**: Repeat last announcement
|
||||
- **Ctrl+S**: Announce settings
|
||||
- **Ctrl+P**: Announce position
|
||||
- **Ctrl+I**: Announce inventory
|
||||
- **Ctrl+N**: Announce nearby objects
|
||||
- **Ctrl+T**: Announce stats (health, hunger, stamina)
|
||||
- **Ctrl+V**: Toggle verbose mode
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] All keyboard shortcuts work
|
||||
- [ ] Help command lists all shortcuts
|
||||
- [ ] Repeat command replays last announcement
|
||||
- [ ] Settings command announces current settings
|
||||
- [ ] Position command announces X, Y coordinates
|
||||
- [ ] Inventory command lists items
|
||||
- [ ] Nearby command describes surroundings
|
||||
- [ ] Stats command announces health/hunger/stamina
|
||||
|
||||
#### How to Test:
|
||||
1. Start the game
|
||||
2. Press **Ctrl+H** to hear help
|
||||
3. Press **Ctrl+P** to hear position
|
||||
4. Press **Ctrl+I** to hear inventory
|
||||
5. Press **Ctrl+T** to hear stats
|
||||
6. Press **Ctrl+N** to hear nearby objects
|
||||
7. Press **Ctrl+R** to repeat last announcement
|
||||
8. Press **Ctrl+V** to toggle verbose mode
|
||||
|
||||
---
|
||||
|
||||
### 3. **Audio Cues**
|
||||
|
||||
#### Available Cues:
|
||||
- **Focus**: 440 Hz, 100ms (UI element focused)
|
||||
- **Select**: 880 Hz, 150ms (Item selected)
|
||||
- **Error**: 220 Hz, 300ms (Error occurred)
|
||||
- **Success**: 660 Hz, 200ms (Action successful)
|
||||
- **Navigation**: 550 Hz, 80ms (Menu navigation)
|
||||
- **Inventory**: 750 Hz, 120ms (Inventory opened)
|
||||
- **Damage**: 200 Hz, 250ms (Player took damage)
|
||||
- **Pickup**: 1000 Hz, 100ms (Item picked up)
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Audio cues play for different actions
|
||||
- [ ] Cues can be toggled on/off
|
||||
- [ ] Cue frequencies are distinct
|
||||
- [ ] Cues don't overlap speech
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const sr = game.scene.scenes[1].screenReader;
|
||||
|
||||
// Test different audio cues
|
||||
sr.playAudioCue('focus');
|
||||
sr.playAudioCue('select');
|
||||
sr.playAudioCue('error');
|
||||
sr.playAudioCue('success');
|
||||
sr.playAudioCue('navigation');
|
||||
sr.playAudioCue('inventory');
|
||||
sr.playAudioCue('damage');
|
||||
sr.playAudioCue('pickup');
|
||||
|
||||
// Toggle sound cues
|
||||
sr.toggleSoundCues(); // Off
|
||||
sr.toggleSoundCues(); // On
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. **Context Announcements**
|
||||
|
||||
#### Available Contexts:
|
||||
- **menu**: Main menu
|
||||
- **game**: In game
|
||||
- **inventory**: Inventory screen
|
||||
- **crafting**: Crafting menu
|
||||
- **dialogue**: Dialogue
|
||||
- **combat**: In combat
|
||||
- **building**: Build mode
|
||||
- **map**: Map view
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Context is announced when entering new area
|
||||
- [ ] Context includes navigation instructions
|
||||
- [ ] Context can be manually triggered
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const sr = game.scene.scenes[1].screenReader;
|
||||
|
||||
// Announce different contexts
|
||||
sr.announceContext('menu');
|
||||
sr.announceContext('game');
|
||||
sr.announceContext('inventory');
|
||||
sr.announceContext('crafting');
|
||||
sr.announceContext('dialogue');
|
||||
sr.announceContext('combat');
|
||||
sr.announceContext('building');
|
||||
sr.announceContext('map');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. **Action Announcements**
|
||||
|
||||
#### Supported Actions:
|
||||
- move, attack, interact, pickup, drop
|
||||
- craft, build, harvest, plant, dig
|
||||
- damage, heal, die, respawn
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Actions are announced when performed
|
||||
- [ ] Action details are included (if provided)
|
||||
- [ ] Audio cue plays with announcement
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const sr = game.scene.scenes[1].screenReader;
|
||||
|
||||
// Test action announcements
|
||||
sr.announceAction('move');
|
||||
sr.announceAction('attack', 'zombie');
|
||||
sr.announceAction('pickup', 'carrot');
|
||||
sr.announceAction('craft', 'wooden sword');
|
||||
sr.announceAction('build', 'fence');
|
||||
sr.announceAction('harvest', 'wheat');
|
||||
sr.announceAction('damage', '10 health');
|
||||
sr.announceAction('heal', '25 health');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. **Game State Announcements**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Stats announcement includes health, hunger, stamina
|
||||
- [ ] Inventory announcement lists items and gold
|
||||
- [ ] Position announcement includes X, Y coordinates
|
||||
- [ ] Nearby announcement describes surroundings
|
||||
- [ ] Verbose mode provides detailed information
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const sr = game.scene.scenes[1].screenReader;
|
||||
|
||||
// Announce game state
|
||||
sr.announceStats();
|
||||
sr.announceInventory();
|
||||
sr.announcePosition();
|
||||
sr.announceNearby();
|
||||
|
||||
// Toggle verbose mode for detailed info
|
||||
sr.toggleVerboseMode(); // On
|
||||
sr.announceInventory(); // Detailed item list
|
||||
sr.toggleVerboseMode(); // Off
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. **ARIA Live Regions**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Polite region exists (non-interrupting)
|
||||
- [ ] Alert region exists (interrupting)
|
||||
- [ ] Regions are hidden from visual display
|
||||
- [ ] Screen readers detect region updates
|
||||
|
||||
#### How to Test:
|
||||
1. Open browser DevTools (F12)
|
||||
2. Inspect DOM for ARIA live regions
|
||||
3. Verify `role="status"` and `aria-live="polite"`
|
||||
4. Verify `role="alert"` and `aria-live="assertive"`
|
||||
5. Test with actual screen reader (NVDA, JAWS, VoiceOver)
|
||||
|
||||
---
|
||||
|
||||
### 8. **Auto-Narration**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Low health warning is announced automatically
|
||||
- [ ] UI changes are announced (if enabled)
|
||||
- [ ] Notifications are announced
|
||||
- [ ] Auto-narration can be toggled
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const sr = game.scene.scenes[1].screenReader;
|
||||
|
||||
// Toggle auto-narration
|
||||
sr.toggleAutoNarrate(); // Off
|
||||
sr.toggleAutoNarrate(); // On
|
||||
|
||||
// Test notifications
|
||||
sr.announceNotification('You found a treasure!');
|
||||
sr.announceNotification('Error: Cannot craft item', 'alert');
|
||||
|
||||
// Test UI announcements
|
||||
sr.announceUI('Inventory', 'opened');
|
||||
sr.announceUI('Crafting menu', 'closed');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 9. **Settings Persistence**
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Settings are saved to localStorage
|
||||
- [ ] Settings persist after page reload
|
||||
- [ ] All settings are saved (rate, pitch, volume, etc.)
|
||||
|
||||
#### How to Test:
|
||||
```javascript
|
||||
const sr = game.scene.scenes[1].screenReader;
|
||||
|
||||
// Change settings
|
||||
sr.setRate(1.5);
|
||||
sr.setPitch(1.2);
|
||||
sr.setVolume(0.8);
|
||||
sr.toggleVerboseMode();
|
||||
sr.toggleSoundCues();
|
||||
|
||||
// Reload page (F5)
|
||||
// Settings should be restored
|
||||
|
||||
// Verify settings
|
||||
sr.announceSettings();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 10. **Screen Reader Compatibility**
|
||||
|
||||
#### Supported Screen Readers:
|
||||
- **NVDA** (Windows) - Free
|
||||
- **JAWS** (Windows) - Commercial
|
||||
- **VoiceOver** (macOS/iOS) - Built-in
|
||||
- **TalkBack** (Android) - Built-in
|
||||
- **ChromeVox** (Chrome OS) - Built-in
|
||||
|
||||
#### Test Cases:
|
||||
- [ ] Works with NVDA
|
||||
- [ ] Works with JAWS
|
||||
- [ ] Works with VoiceOver
|
||||
- [ ] ARIA regions are detected
|
||||
- [ ] Keyboard navigation works
|
||||
|
||||
#### How to Test:
|
||||
1. Install/Enable screen reader
|
||||
2. Start NovaFarma
|
||||
3. Navigate using keyboard only
|
||||
4. Verify announcements are heard
|
||||
5. Test all keyboard shortcuts
|
||||
6. Test ARIA live regions
|
||||
|
||||
---
|
||||
|
||||
## 🎮 Integration Testing
|
||||
|
||||
### Complete Workflow Test:
|
||||
```javascript
|
||||
const sr = game.scene.scenes[1].screenReader;
|
||||
|
||||
// 1. Help
|
||||
sr.announceHelp();
|
||||
|
||||
// 2. Check stats
|
||||
sr.announceStats();
|
||||
|
||||
// 3. Check inventory
|
||||
sr.announceInventory();
|
||||
|
||||
// 4. Check position
|
||||
sr.announcePosition();
|
||||
|
||||
// 5. Check nearby
|
||||
sr.announceNearby();
|
||||
|
||||
// 6. Perform action
|
||||
sr.announceAction('move', 'north');
|
||||
sr.announceAction('pickup', 'wood');
|
||||
|
||||
// 7. Change context
|
||||
sr.announceContext('inventory');
|
||||
|
||||
// 8. Adjust settings
|
||||
sr.setRate(1.2);
|
||||
sr.setPitch(1.0);
|
||||
sr.setVolume(0.9);
|
||||
|
||||
// 9. Toggle features
|
||||
sr.toggleVerboseMode();
|
||||
sr.toggleSoundCues();
|
||||
sr.toggleAutoNarrate();
|
||||
|
||||
// 10. Verify settings
|
||||
sr.announceSettings();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Expected Results
|
||||
|
||||
### ✅ Success Criteria:
|
||||
1. Speech synthesis works on all platforms
|
||||
2. All keyboard shortcuts function correctly
|
||||
3. Audio cues are distinct and helpful
|
||||
4. Context announcements provide clear guidance
|
||||
5. Action announcements are timely and accurate
|
||||
6. Game state announcements are comprehensive
|
||||
7. ARIA live regions work with screen readers
|
||||
8. Auto-narration detects important events
|
||||
9. Settings persist after reload
|
||||
10. Compatible with major screen readers
|
||||
|
||||
### ❌ Known Issues:
|
||||
- Speech synthesis voices vary by platform
|
||||
- Some browsers may require user interaction before speech
|
||||
- Audio cues may not work in all browsers
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Bug Reporting
|
||||
|
||||
If you find any issues, please report:
|
||||
1. **What you were testing**
|
||||
2. **What you expected to happen**
|
||||
3. **What actually happened**
|
||||
4. **Browser and OS**
|
||||
5. **Screen reader (if applicable)**
|
||||
6. **Console errors** (if any)
|
||||
|
||||
---
|
||||
|
||||
## 📝 Quick Reference
|
||||
|
||||
### Keyboard Shortcuts:
|
||||
| Shortcut | Action |
|
||||
|----------|--------|
|
||||
| Ctrl+H | Help |
|
||||
| Ctrl+R | Repeat |
|
||||
| Ctrl+S | Settings |
|
||||
| Ctrl+P | Position |
|
||||
| Ctrl+I | Inventory |
|
||||
| Ctrl+N | Nearby |
|
||||
| Ctrl+T | Stats |
|
||||
| Ctrl+V | Verbose Mode |
|
||||
|
||||
### API Commands:
|
||||
```javascript
|
||||
const sr = game.scene.scenes[1].screenReader;
|
||||
|
||||
sr.speak(text, priority, interrupt);
|
||||
sr.announceStats();
|
||||
sr.announceInventory();
|
||||
sr.announcePosition();
|
||||
sr.announceNearby();
|
||||
sr.announceAction(action, details);
|
||||
sr.setRate(rate);
|
||||
sr.setPitch(pitch);
|
||||
sr.setVolume(volume);
|
||||
sr.toggleVerboseMode();
|
||||
sr.toggleSoundCues();
|
||||
sr.toggleAutoNarrate();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-12-12
|
||||
**Version**: 2.5.0
|
||||
**Status**: ✅ Ready for Testing
|
||||
180
docs/guides/test_accessibility.js
Normal file
180
docs/guides/test_accessibility.js
Normal file
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* INPUT REMAPPING & SUBTITLE SYSTEM - QUICK TEST SCRIPT
|
||||
*
|
||||
* Copy-paste this into browser console (F12) to test all features
|
||||
* Make sure the game is running first!
|
||||
*/
|
||||
|
||||
console.log('🎮 Starting Input Remapping & Subtitle System Test Suite...\n');
|
||||
|
||||
// Get systems
|
||||
const visualCues = game.scene.scenes[1].visualSoundCues;
|
||||
const inputSystem = game.scene.scenes[1].inputRemapping;
|
||||
|
||||
// ========== SUBTITLE SIZE TESTING ==========
|
||||
console.log('📏 Test 1: Subtitle Sizes');
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('Testing SMALL size...');
|
||||
visualCues.setSubtitleSize('small');
|
||||
visualCues.showSubtitle('This is SMALL text', 2000, 'System');
|
||||
}, 1000);
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('Testing MEDIUM size...');
|
||||
visualCues.setSubtitleSize('medium');
|
||||
visualCues.showSubtitle('This is MEDIUM text', 2000, 'System');
|
||||
}, 3500);
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('Testing LARGE size...');
|
||||
visualCues.setSubtitleSize('large');
|
||||
visualCues.showSubtitle('This is LARGE text', 2000, 'System');
|
||||
}, 6000);
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('Testing VERY LARGE size...');
|
||||
visualCues.setSubtitleSize('very-large');
|
||||
visualCues.showSubtitle('This is VERY LARGE text', 2000, 'System');
|
||||
}, 8500);
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('Resetting to MEDIUM...');
|
||||
visualCues.setSubtitleSize('medium');
|
||||
}, 11000);
|
||||
|
||||
// ========== INPUT REMAPPING TESTING ==========
|
||||
console.log('\n🎮 Test 2: Input Remapping');
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('\n=== DEFAULT PROFILE ===');
|
||||
console.log('Move Up:', inputSystem.getBindingDisplay('move_up'));
|
||||
console.log('Move Down:', inputSystem.getBindingDisplay('move_down'));
|
||||
console.log('Move Left:', inputSystem.getBindingDisplay('move_left'));
|
||||
console.log('Move Right:', inputSystem.getBindingDisplay('move_right'));
|
||||
console.log('Interact:', inputSystem.getBindingDisplay('interact'));
|
||||
console.log('Attack:', inputSystem.getBindingDisplay('attack'));
|
||||
console.log('Inventory:', inputSystem.getBindingDisplay('inventory'));
|
||||
console.log('Sprint:', inputSystem.getBindingDisplay('sprint'));
|
||||
}, 12000);
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('\n=== SWITCHING TO LEFT-HANDED PROFILE ===');
|
||||
inputSystem.switchProfile('left-handed');
|
||||
console.log('Move Up:', inputSystem.getBindingDisplay('move_up'));
|
||||
console.log('Move Down:', inputSystem.getBindingDisplay('move_down'));
|
||||
console.log('Move Left:', inputSystem.getBindingDisplay('move_left'));
|
||||
console.log('Move Right:', inputSystem.getBindingDisplay('move_right'));
|
||||
console.log('Interact:', inputSystem.getBindingDisplay('interact'));
|
||||
}, 14000);
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('\n=== SWITCHING TO ARROWS PROFILE ===');
|
||||
inputSystem.switchProfile('arrows');
|
||||
console.log('Move Up:', inputSystem.getBindingDisplay('move_up'));
|
||||
console.log('Move Down:', inputSystem.getBindingDisplay('move_down'));
|
||||
console.log('Move Left:', inputSystem.getBindingDisplay('move_left'));
|
||||
console.log('Move Right:', inputSystem.getBindingDisplay('move_right'));
|
||||
}, 16000);
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('\n=== BACK TO DEFAULT PROFILE ===');
|
||||
inputSystem.switchProfile('default');
|
||||
console.log('Current profile:', inputSystem.getCurrentProfile());
|
||||
}, 18000);
|
||||
|
||||
// ========== CONTROLLER TESTING ==========
|
||||
setTimeout(() => {
|
||||
console.log('\n🎮 Test 3: Controller Detection');
|
||||
const isConnected = inputSystem.isControllerConnected();
|
||||
console.log('Controller connected:', isConnected);
|
||||
|
||||
if (isConnected) {
|
||||
const info = inputSystem.getControllerInfo();
|
||||
console.log('Controller info:', info);
|
||||
console.log('A button:', inputSystem.getControllerButtonName('A'));
|
||||
console.log('Start button:', inputSystem.getControllerButtonName('START'));
|
||||
} else {
|
||||
console.log('ℹ️ No controller detected. Connect a controller to test.');
|
||||
}
|
||||
}, 20000);
|
||||
|
||||
// ========== EXPORT/IMPORT TESTING ==========
|
||||
setTimeout(() => {
|
||||
console.log('\n💾 Test 4: Export/Import Bindings');
|
||||
const exported = inputSystem.exportBindings();
|
||||
console.log('Exported bindings (first 200 chars):', exported.substring(0, 200) + '...');
|
||||
|
||||
// Test import
|
||||
const success = inputSystem.importBindings(exported);
|
||||
console.log('Import success:', success);
|
||||
}, 22000);
|
||||
|
||||
// ========== PROFILE LISTING ==========
|
||||
setTimeout(() => {
|
||||
console.log('\n📋 Test 5: Available Profiles');
|
||||
const profiles = inputSystem.getProfiles();
|
||||
console.log('All profiles:', profiles);
|
||||
console.log('Current profile:', inputSystem.getCurrentProfile());
|
||||
}, 24000);
|
||||
|
||||
// ========== COMBINED TEST ==========
|
||||
setTimeout(() => {
|
||||
console.log('\n🎨 Test 6: Combined Features');
|
||||
|
||||
// Large subtitles with speaker
|
||||
visualCues.setSubtitleSize('large');
|
||||
visualCues.showSubtitle('Testing large subtitles with speaker!', 3000, 'NPC', 'left');
|
||||
|
||||
console.log('Subtitle size: LARGE');
|
||||
console.log('Speaker: NPC (yellow)');
|
||||
console.log('Direction: LEFT (arrow)');
|
||||
}, 26000);
|
||||
|
||||
setTimeout(() => {
|
||||
// Very large subtitles
|
||||
visualCues.setSubtitleSize('very-large');
|
||||
visualCues.showSubtitle('VERY LARGE TEXT!', 3000, 'System', 'both');
|
||||
|
||||
console.log('Subtitle size: VERY LARGE');
|
||||
console.log('Direction: BOTH (arrows)');
|
||||
}, 29500);
|
||||
|
||||
setTimeout(() => {
|
||||
// Reset to medium
|
||||
visualCues.setSubtitleSize('medium');
|
||||
}, 33000);
|
||||
|
||||
// ========== REBINDING DEMO ==========
|
||||
setTimeout(() => {
|
||||
console.log('\n🔧 Test 7: Rebinding Demo');
|
||||
console.log('ℹ️ To test rebinding, run this command:');
|
||||
console.log(' inputSystem.startRebinding("interact", (action, key) => {');
|
||||
console.log(' console.log(`Rebound ${action} to ${key}`);');
|
||||
console.log(' });');
|
||||
console.log('Then press any key to rebind, or ESC to cancel.');
|
||||
}, 34000);
|
||||
|
||||
// ========== FINAL SUMMARY ==========
|
||||
setTimeout(() => {
|
||||
console.log('\n✅ Test Suite Complete!');
|
||||
console.log('\n📋 Summary:');
|
||||
console.log(' - Subtitle Sizes (4 sizes): ✅');
|
||||
console.log(' - Input Remapping: ✅');
|
||||
console.log(' - Profile Switching: ✅');
|
||||
console.log(' - Controller Detection: ✅');
|
||||
console.log(' - Export/Import: ✅');
|
||||
console.log(' - One-Handed Layouts: ✅');
|
||||
console.log('\n🎉 All features working correctly!');
|
||||
console.log('\n📖 See testing guides for detailed instructions:');
|
||||
console.log(' - CLOSED_CAPTIONS_TESTING.md');
|
||||
console.log(' - INPUT_REMAPPING_TESTING.md');
|
||||
|
||||
console.log('\n🎮 Quick Commands:');
|
||||
console.log(' visualCues.setSubtitleSize("small|medium|large|very-large")');
|
||||
console.log(' inputSystem.switchProfile("default|left-handed|arrows")');
|
||||
console.log(' inputSystem.getBindingDisplay("action_name")');
|
||||
console.log(' inputSystem.startRebinding("action_name", callback)');
|
||||
}, 36000);
|
||||
|
||||
console.log('\n⏱️ Test will run for ~40 seconds. Watch the screen and console!\n');
|
||||
152
docs/guides/test_closed_captions.js
Normal file
152
docs/guides/test_closed_captions.js
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* CLOSED CAPTIONS & VISUAL SOUND CUES - QUICK TEST SCRIPT
|
||||
*
|
||||
* Copy-paste this into browser console (F12) to test all features
|
||||
* Make sure the game is running first!
|
||||
*/
|
||||
|
||||
// Get the Visual Sound Cue System
|
||||
const visualCues = game.scene.scenes[1].visualSoundCues;
|
||||
|
||||
console.log('🎬 Starting Closed Captions & Visual Sound Cues Test Suite...\n');
|
||||
|
||||
// Test 1: Basic Sound Effects
|
||||
console.log('📢 Test 1: Basic Sound Effects');
|
||||
setTimeout(() => {
|
||||
visualCues.onSoundPlayed('damage', { direction: 'left', amount: 25 });
|
||||
}, 1000);
|
||||
setTimeout(() => {
|
||||
visualCues.onSoundPlayed('pickup', { item: 'Carrot' });
|
||||
}, 2500);
|
||||
setTimeout(() => {
|
||||
visualCues.onSoundPlayed('harvest');
|
||||
}, 4000);
|
||||
setTimeout(() => {
|
||||
visualCues.onSoundPlayed('build');
|
||||
}, 5500);
|
||||
|
||||
// Test 2: Speaker Names & Colors
|
||||
console.log('👥 Test 2: Speaker Names & Colors');
|
||||
setTimeout(() => {
|
||||
visualCues.showSubtitle('Hello, adventurer!', 3000, 'NPC');
|
||||
}, 7000);
|
||||
setTimeout(() => {
|
||||
visualCues.showSubtitle('GRRRR!', 3000, 'Enemy');
|
||||
}, 10500);
|
||||
setTimeout(() => {
|
||||
visualCues.showSubtitle('Achievement unlocked!', 3000, 'System');
|
||||
}, 14000);
|
||||
|
||||
// Test 3: Directional Arrows
|
||||
console.log('➡️ Test 3: Directional Arrows');
|
||||
setTimeout(() => {
|
||||
visualCues.showSubtitle('Sound from the left', 3000, 'System', 'left');
|
||||
}, 17500);
|
||||
setTimeout(() => {
|
||||
visualCues.showSubtitle('Sound from the right', 3000, 'System', 'right');
|
||||
}, 21000);
|
||||
setTimeout(() => {
|
||||
visualCues.showSubtitle('Sound from everywhere', 3000, 'System', 'both');
|
||||
}, 24500);
|
||||
|
||||
// Test 4: Fishing Bobber Visual Queue
|
||||
console.log('🎣 Test 4: Fishing Bobber Visual Queue');
|
||||
setTimeout(() => {
|
||||
visualCues.onSoundPlayed('fishing_cast');
|
||||
}, 28000);
|
||||
setTimeout(() => {
|
||||
visualCues.onSoundPlayed('fishing_bite');
|
||||
}, 30000);
|
||||
|
||||
// Test 5: Opacity Control
|
||||
console.log('📊 Test 5: Opacity Control');
|
||||
setTimeout(() => {
|
||||
visualCues.showSubtitle('Testing opacity...', 5000, 'System');
|
||||
visualCues.setSubtitleOpacity(1.0);
|
||||
}, 33000);
|
||||
setTimeout(() => {
|
||||
visualCues.setSubtitleOpacity(0.5);
|
||||
}, 35000);
|
||||
setTimeout(() => {
|
||||
visualCues.setSubtitleOpacity(0.2);
|
||||
}, 37000);
|
||||
setTimeout(() => {
|
||||
visualCues.setSubtitleOpacity(0.8); // Back to default
|
||||
}, 39000);
|
||||
|
||||
// Test 6: All Sound Types
|
||||
console.log('🔊 Test 6: All Sound Types');
|
||||
const soundTypes = [
|
||||
{ type: 'dig', delay: 41000 },
|
||||
{ type: 'plant', delay: 42500 },
|
||||
{ type: 'footsteps', delay: 44000, data: { direction: 'left' } },
|
||||
{ type: 'door', delay: 45500 },
|
||||
{ type: 'chest', delay: 47000 },
|
||||
{ type: 'water', delay: 48500 },
|
||||
{ type: 'fire', delay: 50000 },
|
||||
{ type: 'explosion', delay: 51500 },
|
||||
{ type: 'npc_talk', delay: 53000, data: { text: 'Can you help me?', speaker: 'NPC', direction: 'right' } },
|
||||
{ type: 'enemy_growl', delay: 56500, data: { direction: 'left' } },
|
||||
{ type: 'danger', delay: 58000 },
|
||||
{ type: 'night', delay: 60500 },
|
||||
{ type: 'achievement', delay: 63000, data: { message: 'First Harvest!' } }
|
||||
];
|
||||
|
||||
soundTypes.forEach(sound => {
|
||||
setTimeout(() => {
|
||||
visualCues.onSoundPlayed(sound.type, sound.data || {});
|
||||
}, sound.delay);
|
||||
});
|
||||
|
||||
// Test 7: Toggle Features
|
||||
console.log('⚙️ Test 7: Toggle Features');
|
||||
setTimeout(() => {
|
||||
console.log('Disabling speaker names...');
|
||||
visualCues.toggleSpeakerNames(false);
|
||||
visualCues.showSubtitle('No speaker name shown', 3000, 'NPC');
|
||||
}, 66000);
|
||||
setTimeout(() => {
|
||||
console.log('Re-enabling speaker names...');
|
||||
visualCues.toggleSpeakerNames(true);
|
||||
visualCues.showSubtitle('Speaker name is back!', 3000, 'NPC');
|
||||
}, 69500);
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('Disabling directional arrows...');
|
||||
visualCues.toggleDirectionalArrows(false);
|
||||
visualCues.showSubtitle('No arrows', 3000, 'System', 'left');
|
||||
}, 73000);
|
||||
setTimeout(() => {
|
||||
console.log('Re-enabling directional arrows...');
|
||||
visualCues.toggleDirectionalArrows(true);
|
||||
visualCues.showSubtitle('Arrows are back!', 3000, 'System', 'right');
|
||||
}, 76500);
|
||||
|
||||
// Test 8: Custom Speaker Colors
|
||||
console.log('🎨 Test 8: Custom Speaker Colors');
|
||||
setTimeout(() => {
|
||||
visualCues.addSpeakerColor('Merchant', '#ffa500'); // Orange
|
||||
visualCues.showSubtitle('Welcome to my shop!', 3000, 'Merchant');
|
||||
}, 80000);
|
||||
setTimeout(() => {
|
||||
visualCues.addSpeakerColor('Wizard', '#9370db'); // Purple
|
||||
visualCues.showSubtitle('I sense magic nearby...', 3000, 'Wizard');
|
||||
}, 83500);
|
||||
|
||||
// Final Summary
|
||||
setTimeout(() => {
|
||||
console.log('\n✅ Test Suite Complete!');
|
||||
console.log('📋 Summary:');
|
||||
console.log(' - Closed Captions: ✅');
|
||||
console.log(' - Speaker Names & Colors: ✅');
|
||||
console.log(' - Directional Arrows: ✅');
|
||||
console.log(' - Opacity Control: ✅');
|
||||
console.log(' - Fishing Bobber Queue: ✅');
|
||||
console.log(' - All Sound Types: ✅');
|
||||
console.log(' - Toggle Features: ✅');
|
||||
console.log(' - Custom Speakers: ✅');
|
||||
console.log('\n🎉 All features working correctly!');
|
||||
console.log('\n📖 See CLOSED_CAPTIONS_TESTING.md for detailed testing guide');
|
||||
}, 87000);
|
||||
|
||||
console.log('\n⏱️ Test will run for ~90 seconds. Watch the screen!\n');
|
||||
Reference in New Issue
Block a user