126 lines
3.3 KiB
TypeScript
126 lines
3.3 KiB
TypeScript
import { GYRO_DEADZONE, GYRO_MAX_TILT, GYRO_SENSITIVITY } from '../utils/constants';
|
|
|
|
/**
|
|
* Gestion du gyroscope pour iOS et Android
|
|
* Retourne une valeur normalisée entre -1 et 1
|
|
*/
|
|
export class GyroControl {
|
|
private tiltValue: number = 0;
|
|
private isActive: boolean = false;
|
|
private baseOrientation: number | null = null;
|
|
private calibrationMode: boolean = false;
|
|
|
|
constructor() {
|
|
this.setupGyroscope();
|
|
}
|
|
|
|
/**
|
|
* Configure les listeners du gyroscope
|
|
* Note: La permission doit avoir été demandée AVANT (via MenuScene sur iOS)
|
|
*/
|
|
private setupGyroscope(): void {
|
|
if (!window.DeviceOrientationEvent) {
|
|
console.warn('Gyroscope non disponible sur cet appareil');
|
|
return;
|
|
}
|
|
|
|
// Activer directement le gyroscope
|
|
// La permission a déjà été demandée dans MenuScene pour iOS
|
|
this.enableGyroscope();
|
|
}
|
|
|
|
/**
|
|
* Active le listener du gyroscope
|
|
*/
|
|
private enableGyroscope(): void {
|
|
window.addEventListener('deviceorientation', (event) => {
|
|
this.handleOrientation(event);
|
|
});
|
|
this.isActive = true;
|
|
console.log('✅ Gyroscope activé');
|
|
}
|
|
|
|
/**
|
|
* Gère les événements d'orientation
|
|
*/
|
|
private handleOrientation(event: DeviceOrientationEvent): void {
|
|
if (!this.isActive) return;
|
|
|
|
// Utiliser gamma (inclinaison gauche/droite)
|
|
// gamma: -90 à 90 degrés
|
|
let gamma = event.gamma || 0;
|
|
|
|
// Calibration : définir l'orientation de base au premier appel
|
|
if (this.baseOrientation === null && !this.calibrationMode) {
|
|
this.baseOrientation = gamma;
|
|
}
|
|
|
|
// Calculer l'inclinaison relative à l'orientation de base
|
|
let relativeTilt = gamma - (this.baseOrientation || 0);
|
|
|
|
// Appliquer la deadzone
|
|
if (Math.abs(relativeTilt) < GYRO_DEADZONE) {
|
|
this.tiltValue = 0;
|
|
return;
|
|
}
|
|
|
|
// Normaliser entre -1 et 1
|
|
let normalizedTilt = relativeTilt / GYRO_MAX_TILT;
|
|
|
|
// Clamper entre -1 et 1
|
|
normalizedTilt = Math.max(-1, Math.min(1, normalizedTilt));
|
|
|
|
this.tiltValue = normalizedTilt;
|
|
}
|
|
|
|
/**
|
|
* Retourne la valeur actuelle du tilt normalisée (-1 à 1)
|
|
*/
|
|
public getTiltValue(): number {
|
|
return this.tiltValue;
|
|
}
|
|
|
|
/**
|
|
* Retourne la vitesse calculée depuis le tilt
|
|
*/
|
|
public getVelocity(): number {
|
|
return this.tiltValue * GYRO_SENSITIVITY;
|
|
}
|
|
|
|
/**
|
|
* Calibre le gyroscope (définit l'orientation actuelle comme neutre)
|
|
*/
|
|
public calibrate(): void {
|
|
this.calibrationMode = true;
|
|
this.baseOrientation = null;
|
|
setTimeout(() => {
|
|
this.calibrationMode = false;
|
|
}, 100);
|
|
}
|
|
|
|
/**
|
|
* Active/désactive le gyroscope
|
|
*/
|
|
public setActive(active: boolean): void {
|
|
this.isActive = active;
|
|
if (!active) {
|
|
this.tiltValue = 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Vérifie si le gyroscope est actif
|
|
*/
|
|
public getIsActive(): boolean {
|
|
return this.isActive;
|
|
}
|
|
|
|
/**
|
|
* Détruit le contrôleur (cleanup)
|
|
*/
|
|
public destroy(): void {
|
|
this.isActive = false;
|
|
this.tiltValue = 0;
|
|
}
|
|
}
|