using KinectUtils; using Lib; using Microsoft.Kinect; using MyGesturesBank; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading; namespace WpfApp { /// /// Logique d'interaction pour MainWindow.xaml /// public partial class MainWindow : Window, INotifyPropertyChanged { // Déclaration des variables nécessaires private int score = 0; private string feedback = ""; private DispatcherTimer gameTimer; private MediaPlayer mediaPlayer = new MediaPlayer(); private DispatcherTimer circleTimer; private double circleSize = 100; // Taille initiale du cercle private Random random = new Random(); private const double someThreshold = 50.0; // Par exemple, 50 pixels private const int MaxCircles = 5; // Maximum de 5 cercles à l'écran private const double CircleStartSize = 50.0; // Taille initiale du cercle private const double ReductionAmount = 2.0; // De combien le cercle réduit à chaque tick private const double MinimumCircleSize = 5.0; // Taille minimale avant de disparaître private KinectManager kinectManager; public event PropertyChangedEventHandler PropertyChanged; public KinectManager KinectManager { get { return kinectManager; } set { kinectManager = value; } } private KinectStream _currentKinectStream; public KinectStream CurrentKinectStream { get { return _currentKinectStream; } set { _currentKinectStream = value; OnPropertyChanged(nameof(CurrentKinectStream)); } } // Propriétés pour le score et le feedback public int Score { get => score; set { score = value; OnPropertyChanged(nameof(Score)); scoreText.Text = score.ToString(); // Mise à jour de l'interface utilisateur } } public string Feedback { get => feedback; set { feedback = value; OnPropertyChanged(nameof(Feedback)); feedbackText.Text = feedback; // Mise à jour de l'interface utilisateur } } public void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } private KinectStreamsFactory _factory; public KinectStreamsFactory Factory { get { return _factory; } set { _factory = value; } } public MainWindow() { InitializeComponent(); this.DataContext = this; // Ajout d'un gestionnaire d'erreurs média mediaPlayer.MediaFailed += MediaFailed; KinectManager = new KinectManager(); Factory = new KinectStreamsFactory(KinectManager, skeletonCanvas); CurrentKinectStream = Factory[KinectStreams.Color]; CurrentKinectStream.Start(); InitializeGame(); // Abonnement à l'événement GestureRecognized // GestureManager.GestureRecognized += OnGestureRecognized; } private void InitializeGame() { // Configuration initiale de Kinect et préparation de l'UI KinectManager = new KinectManager(); Factory = new KinectStreamsFactory(KinectManager, skeletonCanvas); CurrentKinectStream = Factory[KinectStreams.Color]; CurrentKinectStream.Start(); // Initialisation des gestes Kinect ici AllGesturesFactory allGesturesFactory = new AllGesturesFactory(); GestureManager.AddGestures(allGesturesFactory); // Préparation des timers sans les démarrer gameTimer = new DispatcherTimer(); gameTimer.Interval = TimeSpan.FromMilliseconds(50); gameTimer.Tick += GameTimer_Tick; // Ne pas démarrer le timer ici avec gameTimer.Start(); circleTimer = new DispatcherTimer(); circleTimer.Interval = TimeSpan.FromMilliseconds(100); circleTimer.Tick += CircleTimer_Tick; // Ne pas démarrer le timer ici avec circleTimer.Start(); // D'autres configurations initiales peuvent être ajoutées ici } private void MainWindow_Closing(object sender, CancelEventArgs e) { Debug.WriteLine(CurrentKinectStream.KinectManager.StatusText); CurrentKinectStream.Stop(); } private void ToColorImageStream(object sender, RoutedEventArgs e) { CurrentKinectStream.Stop(); CurrentKinectStream = Factory[KinectStreams.Color]; Debug.WriteLine(CurrentKinectStream.GetType().Name); CurrentKinectStream.Start(); } private void ToDepthImageStream(object sender, RoutedEventArgs e) { CurrentKinectStream.Stop(); CurrentKinectStream = Factory[KinectStreams.Depth]; Debug.WriteLine(CurrentKinectStream.GetType().Name); CurrentKinectStream.Start(); } private void ToInfraredImageStream(object sender, RoutedEventArgs e) { CurrentKinectStream.Stop(); CurrentKinectStream = Factory[KinectStreams.IR]; Debug.WriteLine(CurrentKinectStream.GetType().Name); CurrentKinectStream.Start(); } private void ToBodyImageStream(object sender, RoutedEventArgs e) { CurrentKinectStream.Stop(); CurrentKinectStream = Factory[KinectStreams.Body]; Debug.WriteLine(CurrentKinectStream.GetType().Name); CurrentKinectStream.Start(); } private void ToColorAndBodyImageStream(object sender, RoutedEventArgs e) { CurrentKinectStream.Stop(); CurrentKinectStream = Factory[KinectStreams.ColorAndBody]; Debug.WriteLine(CurrentKinectStream.GetType().Name); CurrentKinectStream.Start(); } private void GameTimer_Tick(object sender, EventArgs e) { // C'est ici que vous pouvez appeler CreateRandomCircle à des intervalles réguliers CreateRandomCircle(); } private void CircleTimer_Tick(object sender, EventArgs e) { // Réduisez la taille du cercle pour donner l'impression qu'il se "ferme" if (circleSize > 0) { circleSize -= 2; // Ajustez cette valeur pour modifier la vitesse de réduction du cercle clapCircle.Width = circleSize; clapCircle.Height = circleSize; } else { // Si le cercle est trop petit, réinitialisez-le pour le prochain clap ResetClapCircle(); } } private void CheckClapTiming() { // Supposons que le timing parfait est lorsque le cercle est entre 40 et 60 de taille if (circleSize >= 40 && circleSize <= 60) { UpdateGameStatus("Parfait!", 100); } else if (circleSize > 60 && circleSize <= 80) { UpdateGameStatus("Bien", 50); } else { UpdateGameStatus("Raté", 0); } // Réinitialisez la taille du cercle pour le prochain clap ResetClapCircle(); } private void GameCanvas_Loaded(object sender, RoutedEventArgs e) { CenterClapCircle(); } private void CenterClapCircle() { if (gameCanvas.ActualWidth == 0 || gameCanvas.ActualHeight == 0) return; double centerX = (gameCanvas.ActualWidth - clapCircle.Width) / 2; double centerY = (gameCanvas.ActualHeight - clapCircle.Height) / 2; Canvas.SetLeft(clapCircle, centerX); Canvas.SetTop(clapCircle, centerY); } private void ResetClapCircle() { circleSize = 100; // Réinitialiser la taille clapCircle.Width = circleSize; clapCircle.Height = circleSize; circleTimer.Start(); // Redémarrer le timer pour réduire le cercle } private void UpdateGameStatus(string feedback, int points) { Feedback = feedback; // "Parfait!", "Bien", "Raté", etc. Score += points; // Mettre à jour le score basé sur le feedback } private void StartGame() { try { // Chemin relatif au répertoire de sortie de l'application mediaPlayer.Open(new Uri("Tutti-Frutti.mp3", UriKind.Relative)); mediaPlayer.MediaOpened += MediaOpened; } catch (Exception ex) { MessageBox.Show($"Erreur lors de l'ouverture du fichier de musique : {ex.Message}"); } // Configurez et démarrez le timer pour le cercle qui se réduit circleTimer = new DispatcherTimer(); circleTimer.Interval = TimeSpan.FromMilliseconds(100); // Ajustez selon le rythme de la musique circleTimer.Tick += CircleTimer_Tick; circleTimer.Start(); GestureManager.StartAcquiringFrames(KinectManager); } public void OnGestureRecognizedHandler(object sender, GestureRecognizedEventArgs e) { // Ici, vous mettez le code pour traiter l'événement. // Par exemple, afficher le nom du geste reconnu. if (e.GestureName == "Clap Hands") { Score += 100; } } private void MediaOpened(object sender, EventArgs e) { mediaPlayer.Play(); ResetClapCircle(); CenterClapCircle(); // Appelez cette méthode pour centrer le cercle Score = 0; Feedback = ""; if (!gameTimer.IsEnabled) gameTimer.Start(); if (!circleTimer.IsEnabled) circleTimer.Start(); } private void StopGame() { mediaPlayer.Stop(); gameTimer.Stop(); // Arrêter le timer du jeu circleTimer.Stop(); // Arrêter le timer du cercle Feedback = "Jeu terminé"; // Mettre à jour le feedback } private void RemoveCircleAtPosition(double x, double y) { Ellipse circleToRemove = null; double minDistance = double.MaxValue; foreach (Ellipse circle in gameCanvas.Children.OfType()) { double centerX = Canvas.GetLeft(circle) + circle.Width / 2; double centerY = Canvas.GetTop(circle) + circle.Height / 2; double distance = Math.Sqrt(Math.Pow(centerX - x, 2) + Math.Pow(centerY - y, 2)); if (distance < minDistance) { minDistance = distance; circleToRemove = circle; } } if (circleToRemove != null && minDistance < someThreshold) { gameCanvas.Children.Remove(circleToRemove); } } // Vous pouvez lier cette méthode à un bouton dans l'interface utilisateur pour démarrer le jeu private void StartGameButton_Click(object sender, RoutedEventArgs e) { try { StartGame(); } catch (Exception ex) { MessageBox.Show($"Une erreur s'est produite : {ex.Message}"); } } private void MediaFailed(object sender, ExceptionEventArgs e) { MessageBox.Show($"Échec de la lecture de la musique : {e.ErrorException.Message}"); } // Optionnel: Ajouter un bouton d'arrêt dans l'interface utilisateur et lier cette méthode private void StopGameButton_Click(object sender, RoutedEventArgs e) { StopGame(); } private void CreateRandomCircle() { // Vérifier si nous avons déjà le nombre maximum de cercles à l'écran if (gameCanvas.Children.OfType().Count() < MaxCircles) { // Générer une position aléatoire dans les limites du Canvas double x = random.NextDouble() * (gameCanvas.ActualWidth - CircleStartSize); double y = random.NextDouble() * (gameCanvas.ActualHeight - CircleStartSize); // Créer un nouveau cercle Ellipse newCircle = new Ellipse { Width = CircleStartSize, Height = CircleStartSize, Fill = Brushes.Red, Opacity = 0.5 }; // Ajouter le cercle au Canvas gameCanvas.Children.Add(newCircle); Canvas.SetLeft(newCircle, x); Canvas.SetTop(newCircle, y); // Créer et démarrer un timer pour ce cercle DispatcherTimer circleTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) }; circleTimer.Tick += (sender, e) => ReduceCircleSize(sender, e, newCircle); circleTimer.Start(); } } private void ReduceCircleSize(object sender, EventArgs e, Ellipse circle) { if (circle.Width > MinimumCircleSize && circle.Height > MinimumCircleSize) { circle.Width -= ReductionAmount; circle.Height -= ReductionAmount; } else { DispatcherTimer timer = sender as DispatcherTimer; timer.Stop(); // Arrêter le timer gameCanvas.Children.Remove(circle); // Supprimer le cercle du Canvas } } } }