You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

428 lines
15 KiB

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
{
/// <summary>
/// Logique d'interaction pour MainWindow.xaml
/// </summary>
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.
Console.WriteLine($"Geste reconnu : {e.GestureName}");
}
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<Ellipse>())
{
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<Ellipse>().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
}
}
private void OnGestureRecognized(object sender, GestureRecognizedEventArgs e)
{
if (e.GestureName == "Clap Hands")
{
// Ici, vous devez récupérer les coordonnées de la main de l'utilisateur via Kinect
// double handX = ...; // Coordonnée X de la main
// double handY = ...; // Coordonnée Y de la main
// RemoveCircleAtPosition(handX, handY);
}
}
}
}