Files
mario/src/controls/GyroControl.ts
2025-12-14 11:15:50 +01:00

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;
}
}