Compare commits

...

23 Commits
exo2 ... master

Author SHA1 Message Date
Nicolas FRANCO 1d920739fd 📝 final readme instructions
1 year ago
nico-dev 9b36be4df2 Merge branch 'begin_project_view'
1 year ago
nico-dev 415fd661cf Merge master
1 year ago
nico-dev 32d0e04176 merge conflicts
1 year ago
Lou BRODA d9ff91f991 Mise à jour de 'README.md'
1 year ago
Lou BRODA f910094e9b ADD : gestion Player 1 & 2 + texte plus grand (To Test)
1 year ago
nico-dev f1fdc7edf2 improvements
1 year ago
Lou BRODA 7aa6c3d99d ADD : Readme.md
1 year ago
nico-dev 703a1cfb35 fixes and improvements
1 year ago
Lou BRODA ba0db4525e ADD : ajout du question point pour position de tir/arrêt
1 year ago
nico-dev 28cda89dc7 🚧 v1
1 year ago
nico-dev c55e1ba3d1 🔧 visibility update for the ball and the goalkeeper
1 year ago
nico-dev 94ab4b3530 🚑 Remove all hard coded onPropretyChanged calls
1 year ago
nico-dev bd86c689c9 🚑
1 year ago
nico-dev 6d79b04277 added visibility manager
1 year ago
nico-dev 8b45bc52da 🔧 GestureFactory + improving penaltyMaster's game algorithm
1 year ago
nico-dev d48c9ae0ff merge conflicts
1 year ago
Lou BRODA b09fb6d690 ADD : gestion partie automatisée working
1 year ago
Lou BRODA 5bf99d41dd ADD : Début gestion partie
1 year ago
Lou BRODA 61f0ba8ec7 ADD : Gestion de l'affichage du sifflet et de l'action text
1 year ago
Lou BRODA 30b14882d5 ADD : Page Accueil + Navigation + Ballons
1 year ago
Lou BRODA 136adc749e ADD : images + début implémentation view
1 year ago
Lou BRODA 06b0eb3e7e ADD : création projet
1 year ago

@ -12,7 +12,6 @@ namespace KinectSensorStreams.ViewModel
public class MainWindowVM : ObservableObject
{
private BodyImageStream bodyImageStream;
private GestureManager gestureManager;
#region Properties
@ -32,15 +31,6 @@ namespace KinectSensorStreams.ViewModel
set { SetProperty(ref bodyImageStream, value); }
}
/// <summary>
/// The Gesture Manager property.
/// </summary>
public GestureManager GestureManager
{
get { return gestureManager; }
set { SetProperty(ref gestureManager, value); }
}
#endregion
#region Constructor
@ -50,9 +40,6 @@ namespace KinectSensorStreams.ViewModel
/// </summary>
public MainWindowVM()
{
// eventuellement a enlever :
GestureManager = new GestureManager();
StartCommand = new RelayCommand(Start);
BodyCommand = new RelayCommand(Body);
}

@ -7,6 +7,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KinectSensorStreams", "Kine
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KinectConnection", "KinectConnection\KinectConnection.csproj", "{E527438A-DFA2-4EC6-9891-D4956152B093}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PenaltyMaster3000", "PenaltyMaster3000\PenaltyMaster3000.csproj", "{F9E01E2C-70D7-43EB-B665-82424DB7BBC9}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KinectUtils", "KinectUtils\KinectUtils.csproj", "{2BC300E4-D3C1-4E17-A011-380EDB793182}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyGestureBank", "MyGestureBank\MyGestureBank.csproj", "{D70B7357-6FF8-4F35-A283-8DB4217C0C85}"
@ -32,6 +33,10 @@ Global
{E527438A-DFA2-4EC6-9891-D4956152B093}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E527438A-DFA2-4EC6-9891-D4956152B093}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E527438A-DFA2-4EC6-9891-D4956152B093}.Release|Any CPU.Build.0 = Release|Any CPU
{F9E01E2C-70D7-43EB-B665-82424DB7BBC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F9E01E2C-70D7-43EB-B665-82424DB7BBC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F9E01E2C-70D7-43EB-B665-82424DB7BBC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F9E01E2C-70D7-43EB-B665-82424DB7BBC9}.Release|Any CPU.Build.0 = Release|Any CPU
{2BC300E4-D3C1-4E17-A011-380EDB793182}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2BC300E4-D3C1-4E17-A011-380EDB793182}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2BC300E4-D3C1-4E17-A011-380EDB793182}.Release|Any CPU.ActiveCfg = Release|Any CPU

@ -0,0 +1,43 @@
using Microsoft.Kinect;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KinectUtils
{
public abstract class BaseMapping<T>
{
private bool running;
//public EventHandler<OnMapping> OnMapping { get; set; }
public void SubscribeToStartGesture(BaseGesture gesture)
{
}
public void SubscribeToEndGesture(BaseGesture gesture)
{
}
public void SubscribeToToggleGesture(BaseGesture gesture)
{
}
protected abstract T Mapping(Body body);
/*bool TestMapping(Body body, out T ouput)
{
}*/
protected void OnBodyFrameArrived(object obj, BodyFrameArrivedEventArgs args)
{
}
}
}

@ -27,9 +27,15 @@ namespace KinectUtils
public static IGestureFactory Factory { get; set; }
// Methods
/// <summary>
/// Add gestures using the factory.
/// </summary>
/// <param name="factory">The gesture factory.</param>
public static void AddGestures(IGestureFactory factory)
{
throw new NotImplementedException();
var gestures = factory.CreateGestures().ToList();
KnownGestures.AddRange(gestures);
}
public static void AddGestures(BaseGesture[] baseGestures) // params ???

@ -45,6 +45,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="BaseGesture.cs" />
<Compile Include="BaseMapping.cs" />
<Compile Include="Gesture.cs" />
<Compile Include="GestureManager.cs" />
<Compile Include="GestureRecognizedEventArgs.cs" />

@ -12,11 +12,26 @@ namespace KinectUtils
/// </summary>
public abstract class Posture : BaseGesture
{
private bool postureWasRecognized = false;
/// <summary>
/// Tests the posture.
/// </summary>
/// <param name="body">The body</param>
/// <returns></returns>
protected abstract bool TestPosture(Body body);
/// <summary>
/// The test gesture method.
/// </summary>
/// <param name="body">The body</param>
public override void TestGesture(Body body)
{
postureWasRecognized = TestPosture(body);
if (postureWasRecognized)
{
OnGestureRecognized();
}
}
}
}

@ -44,6 +44,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="PenaltyMasterGestureFactory.cs" />
<Compile Include="PostureHandDownLeft.cs" />
<Compile Include="PostureHandDownRight.cs" />
<Compile Include="PostureHandUpLeft.cs" />

@ -0,0 +1,45 @@
using MyGestureBank;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KinectUtils
{
/// <summary>
/// The penalty master gesture factory.
/// </summary>
public class PenaltyMasterGestureFactory : IGestureFactory
{
/// <summary>
/// Creates all baseGesture objects needed for the penaly master
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public IEnumerable<BaseGesture> CreateGestures()
{
// Postures
PostureHandUpRight postureHandUpRight = new PostureHandUpRight();
PostureHandUpLeft postureHandUpLeft = new PostureHandUpLeft();
PostureHandDownLeft postureHandDownLeft = new PostureHandDownLeft();
PostureHandDownRight postureHandDownRight = new PostureHandDownRight();
//PostureTwoHandsDown postureTwoHandsDown = new PostureTwoHandsDown();
//PostureTwoHandsUp postureTwoHandsUp = new PostureTwoHandsUp();
// Gesture
SoccerShootGesture soccerShootGesture = new SoccerShootGesture();
BaseGesture[] gestures = new BaseGesture[5];
gestures[0] = postureHandUpLeft;
gestures[1] = postureHandUpRight;
gestures[2] = postureHandDownLeft;
gestures[3] = postureHandDownRight;
//gestures[4] = postureTwoHandsDown;
//gestures[5] = postureTwoHandsUp;
gestures[4] = soccerShootGesture;
return gestures;
}
}
}

@ -19,21 +19,6 @@ namespace MyGestureBank
GestureName = "HandDownLeft";
}
/// <summary>
/// The test gesture method.
/// </summary>
/// <param name="body">The body</param>
public override void TestGesture(Body body)
{
if (TestPosture(body))
{
Console.WriteLine("Gesture recognized, hand down left");
Thread.Sleep(1000);
OnGestureRecognized();
}
}
/// <summary>
/// The test posture method.
/// </summary>
@ -43,7 +28,14 @@ namespace MyGestureBank
protected override bool TestPosture(Body body)
{
// Check if the left hand is below the left hip
return body.Joints[JointType.HandLeft].Position.Y < body.Joints[JointType.HipLeft].Position.Y;
bool handLeft = body.Joints[JointType.HandLeft].Position.Y < body.Joints[JointType.HipLeft].Position.Y;
var result = handLeft &&
body.Joints[JointType.HandRight].Position.Y > body.Joints[JointType.HipRight].Position.Y &&
body.Joints[JointType.HandRight].Position.Y < body.Joints[JointType.SpineShoulder].Position.Y;
return result;
}
}
}

@ -19,21 +19,6 @@ namespace MyGestureBank
GestureName = "HandDownRight";
}
/// <summary>
/// The test gesture method.
/// </summary>
/// <param name="body">The body</param>
public override void TestGesture(Body body)
{
if (TestPosture(body))
{
Console.WriteLine("Gesture recognized, hand down right");
Thread.Sleep(1000);
OnGestureRecognized();
}
}
/// <summary>
/// The test posture method.
/// </summary>
@ -43,7 +28,11 @@ namespace MyGestureBank
protected override bool TestPosture(Body body)
{
// Check if right hand is below the right hip
return body.Joints[JointType.HandRight].Position.Y < body.Joints[JointType.HipRight].Position.Y;
var result = body.Joints[JointType.HandRight].Position.Y < body.Joints[JointType.HipRight].Position.Y &&
body.Joints[JointType.HandLeft].Position.Y > body.Joints[JointType.SpineBase].Position.Y &&
body.Joints[JointType.HandLeft].Position.Y < body.Joints[JointType.SpineShoulder].Position.Y;
return result;
}
}
}

@ -19,21 +19,6 @@ namespace MyGestureBank
GestureName = "HandUpLeft";
}
/// <summary>
/// The test gesture method.
/// </summary>
/// <param name="body">The body</param>
public override void TestGesture(Body body)
{
if (TestPosture(body))
{
Console.WriteLine("Gesture recognized, hand up left");
Thread.Sleep(1000);
OnGestureRecognized();
}
}
/// <summary>
/// The test posture method.
/// </summary>
@ -44,7 +29,8 @@ namespace MyGestureBank
{
// Check if the left hand is above the left shoulder
return body.Joints[JointType.HandLeft].Position.Y > body.Joints[JointType.SpineShoulder].Position.Y &&
body.Joints[JointType.HandRight].Position.Y < body.Joints[JointType.SpineShoulder].Position.Y;
body.Joints[JointType.HandRight].Position.Y < body.Joints[JointType.SpineShoulder].Position.Y &&
body.Joints[JointType.HandRight].Position.Y > body.Joints[JointType.SpineBase].Position.Y;
}
}
}

@ -22,20 +22,6 @@ namespace MyGestureBank
GestureName = "HandUpRight";
}
/// <summary>
/// The test gesture method.
/// </summary>
/// <param name="body"></param>
public override void TestGesture(Body body)
{
if(TestPosture(body))
{
Console.WriteLine("Gesture recognized, hand up right");
Thread.Sleep(1000);
OnGestureRecognized();
}
}
/// <summary>
/// Tests the posture.
/// </summary>
@ -44,7 +30,8 @@ namespace MyGestureBank
protected override bool TestPosture(Body body)
{
return body.Joints[JointType.HandRight].Position.Y > body.Joints[JointType.SpineShoulder].Position.Y &&
body.Joints[JointType.HandLeft].Position.Y < body.Joints[JointType.SpineShoulder].Position.Y;
body.Joints[JointType.HandLeft].Position.Y < body.Joints[JointType.SpineShoulder].Position.Y &&
body.Joints[JointType.HandLeft].Position.Y > body.Joints[JointType.HipLeft].Position.Y;
}
}
}

@ -16,21 +16,7 @@ namespace MyGestureBank
{
public PostureTwoHandsDown()
{
GestureName = "Both hands middle.";
}
/// <summary>
/// The test gesture method.
/// </summary>
/// <param name="body">The body</param>
public override void TestGesture(Body body)
{
if (TestPosture(body))
{
Console.WriteLine("Gesture recognized, both hands middle");
Thread.Sleep(1000);
OnGestureRecognized();
}
GestureName = "HandsMid";
}
/// <summary>

@ -16,22 +16,7 @@ namespace MyGestureBank
{
public PostureTwoHandsUp()
{
GestureName = "Two Hands Up";
}
/// <summary>
/// The test gesture method.
/// </summary>
/// <param name="body">The body</param>
public override void TestGesture(Body body)
{
if (TestPosture(body))
{
Console.WriteLine("Gesture recognized, two hands up");
Thread.Sleep(1000);
OnGestureRecognized();
}
GestureName = "HandsUp";
}
/// <summary>

@ -9,6 +9,9 @@ using System.Threading.Tasks;
namespace MyGestureBank
{
/// <summary>
/// The soccer shoot gesture.
/// </summary>
public class SoccerShootGesture : Gesture
{
private CameraSpacePoint lastLeftFootPosition;
@ -20,17 +23,24 @@ namespace MyGestureBank
MaxNbOfFrames = 30;
}
/// <summary>
/// Tests if the gesture is recognized.
/// </summary>
/// <param name="body"></param>
public override void TestGesture(Body body)
{
if (TestPosture(body))
{
Console.WriteLine("Gesture recognized, shooting motion");
Thread.Sleep(1000);
OnGestureRecognized();
}
}
/// <summary>
/// Tests the end conditions of the gesture.
/// </summary>
/// <param name="body"></param>
/// <returns></returns>
protected override bool TestEndConditions(Body body)
{
float threshold = 0.05f;
@ -39,25 +49,42 @@ namespace MyGestureBank
return areFeetClose;
}
/// <summary>
/// Tests the intial conditions of the gesture.
/// </summary>
/// <param name="body"></param>
/// <returns></returns>
protected override bool TestInitialConditions(Body body)
{
// Position of the feet + hips and head
CameraSpacePoint currentLeftFootPosition = body.Joints[JointType.FootLeft].Position;
CameraSpacePoint currentRightFootPosition = body.Joints[JointType.FootRight].Position;
CameraSpacePoint currentHipPosition = body.Joints[JointType.SpineBase].Position;
CameraSpacePoint currentHeadPosition = body.Joints[JointType.Head].Position;
// X and Y that should be respected
bool isWithinDistanceX = Math.Abs(currentLeftFootPosition.X - currentRightFootPosition.X) < Math.Abs(currentHipPosition.Y - currentHeadPosition.Y);
bool isWithinRangeY = IsFootBetweenHeadAndSpinBase(body.Joints[JointType.FootRight].Position, body.Joints[JointType.Head].Position, body.Joints[JointType.SpineBase].Position);
return isWithinDistanceX && isWithinRangeY;
}
/// <summary>
/// Test the posture
/// </summary>
/// <param name="body"></param>
/// <returns></returns>
protected override bool TestPosture(Body body)
{
bool isWithinRangeY = IsFootBetweenHeadAndSpinBase(body.Joints[JointType.FootRight].Position, body.Joints[JointType.Head].Position, body.Joints[JointType.SpineBase].Position);
return isWithinRangeY;
}
/// <summary>
/// Tests the running gesture
/// </summary>
/// <param name="body"></param>
/// <returns></returns>
protected override bool TestRunningGesture(Body body)
{
CameraSpacePoint currentLeftFootPosition = body.Joints[JointType.FootLeft].Position;

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
</configuration>

@ -0,0 +1,9 @@
<Application x:Class="PenaltyMaster3000.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PenaltyMaster3000"
StartupUri="View/StartView.xaml">
<Application.Resources>
</Application.Resources>
</Application>

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace PenaltyMaster3000
{
/// <summary>
/// Logique d'interaction pour App.xaml
/// </summary>
public partial class App : Application
{
}
}

@ -0,0 +1,345 @@
using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace PenaltyMaster3000.Helpers
{
// [TODO] Change 'Goal' to 'Keeper' to avoid confusion.
/// <summary>
/// Manages the visibility of the goal's four corners + middle zone.
/// </summary>
public class VisibilityManager : ObservableObject
{
// Top right
private Visibility ballTopRightVisibility;
public Visibility BallTopRightVisibility
{
get => ballTopRightVisibility;
set => SetProperty(ref ballTopRightVisibility, value);
}
private Visibility goalTopRightVisibility;
public Visibility GoalTopRightVisibility
{
get => goalTopRightVisibility;
set => SetProperty(ref goalTopRightVisibility, value);
}
private Visibility questionPointTopRightVisibility;
public Visibility QuestionPointTopRightVisibility
{
get => questionPointTopRightVisibility;
set => SetProperty(ref questionPointTopRightVisibility, value);
}
// Top Left
private Visibility ballTopLeftVisibility;
public Visibility BallTopLeftVisibility
{
get => ballTopLeftVisibility;
set => SetProperty(ref ballTopLeftVisibility, value);
}
private Visibility goalTopLeftVisibility;
public Visibility GoalTopLeftVisibility
{
get => goalTopLeftVisibility;
set => SetProperty(ref goalTopLeftVisibility, value);
}
private Visibility questionPointTopLeftVisibility;
public Visibility QuestionPointTopLeftVisibility
{
get => questionPointTopLeftVisibility;
set => SetProperty(ref questionPointTopLeftVisibility, value);
}
// ---
// Middle
private Visibility ballTopMiddleVisibility;
public Visibility BallTopMiddleVisibility
{
get => ballTopMiddleVisibility;
set => SetProperty(ref ballTopMiddleVisibility, value);
}
private Visibility goalTopMiddleVisibility;
public Visibility GoalTopMiddleVisibility
{
get => goalTopMiddleVisibility;
set => SetProperty(ref goalTopMiddleVisibility, value);
}
private Visibility questionPointTopMiddleVisibility;
public Visibility QuestionPointTopMiddleVisibility
{
get => questionPointTopMiddleVisibility;
set => SetProperty(ref questionPointTopMiddleVisibility, value);
}
// Down middle
private Visibility ballDownMiddleVisibility;
public Visibility BallDownMiddleVisibility
{
get => ballDownMiddleVisibility;
set => SetProperty(ref ballDownMiddleVisibility, value);
}
private Visibility goalDownMiddleVisibility;
public Visibility GoalDownMiddleVisibility
{
get => goalDownMiddleVisibility;
set => SetProperty(ref goalDownMiddleVisibility, value);
}
private Visibility questionPointDownMiddleVisibility;
public Visibility QuestionPointDownMiddleVisibility
{
get => questionPointDownMiddleVisibility;
set => SetProperty(ref questionPointDownMiddleVisibility, value);
}
// ---
// Down right
private Visibility ballDownRightVisibility;
public Visibility BallDownRightVisibility
{
get => ballDownRightVisibility;
set => SetProperty(ref ballDownRightVisibility, value);
}
private Visibility goalDownRightVisibility;
public Visibility GoalDownRightVisibility
{
get => goalDownRightVisibility;
set => SetProperty(ref goalDownRightVisibility, value);
}
private Visibility questionPointDownRightVisibility;
public Visibility QuestionPointDownRightVisibility
{
get => questionPointDownRightVisibility;
set => SetProperty(ref questionPointDownRightVisibility, value);
}
// Down left
private Visibility ballDownLeftVisibility;
public Visibility BallDownLeftVisibility
{
get => ballDownLeftVisibility;
set => SetProperty(ref ballDownLeftVisibility, value);
}
private Visibility goalDownLeftVisibility;
public Visibility GoalDownLeftVisibility
{
get => goalDownLeftVisibility;
set => SetProperty(ref goalDownLeftVisibility, value);
}
private Visibility questionPointDownLeftVisibility;
public Visibility QuestionPointDownLeftVisibility
{
get => questionPointDownLeftVisibility;
set => SetProperty(ref questionPointDownLeftVisibility, value);
}
/// ---
/// Starting ball and GoalKeeper
private Visibility starterBall;
public Visibility StarterBall
{
get => starterBall;
set => SetProperty(ref starterBall, value);
}
private Visibility starterGoal;
public Visibility StarterGoal
{
get => starterGoal;
set => SetProperty(ref starterGoal, value);
}
/// <summary>
/// Checks if two elements on the same position are visible.
/// </summary>
/// <returns></returns>
public bool GetResult()
{
return AreElementsVisible(BallTopRightVisibility, GoalTopRightVisibility) ||
AreElementsVisible(BallTopMiddleVisibility, GoalTopMiddleVisibility) ||
AreElementsVisible(BallTopLeftVisibility, GoalTopLeftVisibility) ||
AreElementsVisible(BallDownRightVisibility, GoalDownRightVisibility) ||
AreElementsVisible(BallDownMiddleVisibility, GoalDownMiddleVisibility) ||
AreElementsVisible(BallDownLeftVisibility, GoalDownLeftVisibility);
}
// Méthode utilitaire pour vérifier si deux éléments sont visibles
private bool AreElementsVisible(Visibility element1, Visibility element2)
{
return element1 == Visibility.Visible && element2 == Visibility.Visible;
}
/// <summary>
/// Update the view with the question point position.
/// </summary>
/// <param name="gesturePosition"></param>
public void SetQuestionPoint(string gesturePosition)
{
switch (gesturePosition)
{
case "HandUpRight":
HideQuestionPoint();
QuestionPointTopRightVisibility = Visibility.Visible;
break;
case "HandUpLeft":
HideQuestionPoint();
QuestionPointTopLeftVisibility = Visibility.Visible;
break;
case "HandDownRight":
HideQuestionPoint();
QuestionPointDownRightVisibility = Visibility.Visible;
break;
case "HandDownLeft":
HideQuestionPoint();
QuestionPointDownLeftVisibility = Visibility.Visible;
break;
default: return;
}
}
/// <summary>
/// Update the view with the latest shot and defense.
/// </summary>
/// <param name="shotPosition"></param>
/// <param name="defensePosition"></param>
public async Task SetResult(string shotPosition, string defensePosition)
{
updateBall(shotPosition);
// Delay to add some drama to the game
await Task.Delay(500);
updateKeeper(defensePosition);
await Task.Delay(3000);
}
/// <summary>
/// Udaptes the ball position based on the gesture name.
/// </summary>
/// <param name="shotPosition"></param>
private void updateBall(string shotPosition)
{
if(StarterBall == Visibility.Visible)
{
StarterBall = Visibility.Hidden;
}
switch (shotPosition)
{
case "HandUpRight":
BallTopRightVisibility = Visibility.Visible;
break;
case "HandUpLeft":
BallTopLeftVisibility = Visibility.Visible;
break;
case "HandDownRight":
BallDownRightVisibility = Visibility.Visible;
break;
case "HandDownLeft":
BallDownLeftVisibility = Visibility.Visible;
break;
default: return;
}
}
/// <summary>
/// Updates the goalkeeper position based on the gesture name.
/// </summary>
/// <param name="defensePosition"></param>
private void updateKeeper(string defensePosition)
{
if(StarterGoal == Visibility.Visible)
{
StarterGoal = Visibility.Hidden;
}
switch (defensePosition)
{
case "HandUpRight":
GoalTopRightVisibility = Visibility.Visible;
break;
case "HandUpLeft":
GoalTopLeftVisibility = Visibility.Visible;
break;
case "HandDownRight":
GoalDownRightVisibility = Visibility.Visible;
break;
case "HandDownLeft":
GoalDownLeftVisibility = Visibility.Visible;
break;
default: return;
}
}
/// <summary>
/// Sets the visibility of the elements for the start of the game.
/// </summary>
public void GameStartedVisibility()
{
// Starter attributes visible
StarterBall = Visibility.Visible;
StarterGoal = Visibility.Visible;
// Rest should be hidden
BallTopRightVisibility = Visibility.Hidden;
GoalTopRightVisibility = Visibility.Hidden;
QuestionPointTopRightVisibility = Visibility.Hidden;
BallTopMiddleVisibility = Visibility.Hidden;
GoalTopMiddleVisibility = Visibility.Hidden;
QuestionPointTopMiddleVisibility = Visibility.Hidden;
BallTopLeftVisibility = Visibility.Hidden;
GoalTopLeftVisibility = Visibility.Hidden;
QuestionPointTopLeftVisibility = Visibility.Hidden;
BallDownRightVisibility = Visibility.Hidden;
GoalDownRightVisibility = Visibility.Hidden;
QuestionPointDownRightVisibility = Visibility.Hidden;
BallDownMiddleVisibility = Visibility.Hidden;
GoalDownMiddleVisibility = Visibility.Hidden;
QuestionPointDownMiddleVisibility = Visibility.Hidden;
BallDownLeftVisibility = Visibility.Hidden;
GoalDownLeftVisibility = Visibility.Hidden;
QuestionPointDownLeftVisibility = Visibility.Hidden;
}
public void HideQuestionPoint()
{
QuestionPointTopRightVisibility = Visibility.Hidden;
QuestionPointTopMiddleVisibility = Visibility.Hidden;
QuestionPointTopLeftVisibility= Visibility.Hidden;
QuestionPointDownRightVisibility= Visibility.Hidden;
QuestionPointDownMiddleVisibility= Visibility.Hidden;
QuestionPointDownLeftVisibility= Visibility.Hidden;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PenaltyMaster3000.Navigation
{
public interface INavigationService
{
void NavigateTo(string pageKey);
}
}

@ -0,0 +1,34 @@
using PenaltyMaster3000.View;
using PenaltyMaster3000.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PenaltyMaster3000.Navigation
{
public class NavigationService : INavigationService
{
private readonly StartView _startView;
public NavigationService(StartView startView)
{
_startView = startView;
}
public void NavigateTo(string pageKey)
{
switch(pageKey)
{
case "MainView":
MainView mainView = new MainView();
_startView.Content = mainView;
break;
default:
throw new ArgumentException($"PageKey {pageKey} non prise en charge.");
}
}
}
}

@ -0,0 +1,183 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{F9E01E2C-70D7-43EB-B665-82424DB7BBC9}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>PenaltyMaster3000</RootNamespace>
<AssemblyName>PenaltyMaster3000</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="CommunityToolkit.Mvvm, Version=8.2.0.0, Culture=neutral, PublicKeyToken=4aff67a105548ee2, processorArchitecture=MSIL">
<HintPath>..\packages\CommunityToolkit.Mvvm.8.2.2\lib\netstandard2.0\CommunityToolkit.Mvvm.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.Annotations, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.ComponentModel.Annotations.5.0.0\lib\net461\System.ComponentModel.Annotations.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Data" />
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Helpers\VisibilityManager.cs" />
<Compile Include="Navigation\INavigationService.cs" />
<Compile Include="Navigation\NavigationService.cs" />
<Compile Include="ViewModel\MainVM.cs" />
<Compile Include="ViewModel\StartVM.cs" />
<Compile Include="View\MainView.xaml.cs">
<DependentUpon>MainView.xaml</DependentUpon>
</Compile>
<Compile Include="View\StartView.xaml.cs">
<DependentUpon>StartView.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Resource Include="Images\goalkeeper_down_right.png" />
<Resource Include="Images\goalkeeper_down_middle.png" />
<Resource Include="Images\goalkeeper_down_left.png" />
<Resource Include="Images\goalkeeper_starting1.png" />
<Resource Include="Images\goalkeeper_starting2.png" />
<Resource Include="Images\goalkeeper_top_left.png" />
<Resource Include="Images\goalkeeper_top_middle.png" />
<Resource Include="Images\goalkeeper_top_right.png" />
</ItemGroup>
<ItemGroup>
<Page Include="View\MainView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="View\StartView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Resource Include="Images\goal_background.jpg" />
</ItemGroup>
<ItemGroup>
<Resource Include="Images\whistle.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Images\football_ball.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\KinectConnection\KinectConnection.csproj">
<Project>{E527438A-DFA2-4EC6-9891-D4956152B093}</Project>
<Name>KinectConnection</Name>
</ProjectReference>
<ProjectReference Include="..\KinectUtils\KinectUtils.csproj">
<Project>{2BC300E4-D3C1-4E17-A011-380EDB793182}</Project>
<Name>KinectUtils</Name>
</ProjectReference>
<ProjectReference Include="..\MyGestureBank\MyGestureBank.csproj">
<Project>{D70B7357-6FF8-4F35-A283-8DB4217C0C85}</Project>
<Name>MyGestureBank</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Resource Include="Images\white_question_point.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\CommunityToolkit.Mvvm.8.2.2\build\netstandard2.0\CommunityToolkit.Mvvm.targets" Condition="Exists('..\packages\CommunityToolkit.Mvvm.8.2.2\build\netstandard2.0\CommunityToolkit.Mvvm.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\CommunityToolkit.Mvvm.8.2.2\build\netstandard2.0\CommunityToolkit.Mvvm.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\CommunityToolkit.Mvvm.8.2.2\build\netstandard2.0\CommunityToolkit.Mvvm.targets'))" />
</Target>
</Project>

@ -0,0 +1,55 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
// Les informations générales relatives à un assembly dépendent de
// l'ensemble d'attributs suivant. Pour modifier les informations
// associées à un assembly.
[assembly: AssemblyTitle("PenaltyMaster3000")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PenaltyMaster3000")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly
// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de
// COM, affectez la valeur True à l'attribut ComVisible sur ce type.
[assembly: ComVisible(false)]
//Pour commencer à générer des applications localisables, définissez
//<UICulture>CultureUtiliséePourCoder</UICulture> dans votre fichier .csproj
//dans <PropertyGroup>. Par exemple, si vous utilisez le français
//dans vos fichiers sources, définissez <UICulture> à fr-FR. Puis, supprimez les marques de commentaire de
//l'attribut NeutralResourceLanguage ci-dessous. Mettez à jour "fr-FR" dans
//la ligne ci-après pour qu'elle corresponde au paramètre UICulture du fichier projet.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //où se trouvent les dictionnaires de ressources spécifiques à un thème
//(utilisé si une ressource est introuvable dans la page,
// ou dictionnaires de ressources de l'application)
ResourceDictionaryLocation.SourceAssembly //où se trouve le dictionnaire de ressources générique
//(utilisé si une ressource est introuvable dans la page,
// dans l'application ou dans l'un des dictionnaires de ressources spécifiques à un thème)
)]
// Les informations de version pour un assembly se composent des quatre valeurs suivantes :
//
// Version principale
// Version secondaire
// Numéro de build
// Révision
//
// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut
// en utilisant '*', comme indiqué ci-dessous :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Ce code a été généré par un outil.
// Version du runtime :4.0.30319.42000
//
// Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si
// le code est régénéré.
// </auto-generated>
//------------------------------------------------------------------------------
namespace PenaltyMaster3000.Properties
{
/// <summary>
/// Une classe de ressource fortement typée destinée, entre autres, à la consultation des chaînes localisées.
/// </summary>
// Cette classe a été générée automatiquement par la classe StronglyTypedResourceBuilder
// à l'aide d'un outil, tel que ResGen ou Visual Studio.
// Pour ajouter ou supprimer un membre, modifiez votre fichier .ResX, puis réexécutez ResGen
// avec l'option /str ou régénérez votre projet VS.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// Retourne l'instance ResourceManager mise en cache utilisée par cette classe.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PenaltyMaster3000.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Remplace la propriété CurrentUICulture du thread actuel pour toutes
/// les recherches de ressources à l'aide de cette classe de ressource fortement typée.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace PenaltyMaster3000.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

@ -0,0 +1,356 @@
<UserControl x:Class="PenaltyMaster3000.View.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PenaltyMaster3000.View"
mc:Ignorable="d"
Height="Auto" Width="Auto">
<Grid>
<Grid.Background>
<ImageBrush ImageSource="/Images/goal_background.jpg"
Stretch="UniformToFill"/>
</Grid.Background>
<Grid Margin="110,101,128,59">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Source="/Images/goalkeeper_top_right.png"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="0"
Visibility="{Binding VsMgr.GoalTopLeftVisibility}"/>
<Image Source="/Images/football_ball.png"
Width="50"
Height="50"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="0"
Visibility="{Binding VsMgr.BallTopLeftVisibility}"/>
<Image Source="/Images/white_question_point.png"
Width="40"
Height="40"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="0"
Visibility="{Binding VsMgr.QuestionPointTopLeftVisibility}"/>
<Image Source="/Images/goalkeeper_top_middle.png"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Visibility="{Binding VsMgr.GoalTopMiddleVisibility}"/>
<Image Source="/Images/football_ball.png"
Width="50"
Height="50"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Visibility="{Binding VsMgr.BallTopMiddleVisibility}"/>
<Image Source="/Images/white_question_point.png"
Width="40"
Height="40"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Visibility="{Binding VsMgr.QuestionPointTopMiddleVisibility}"/>
<Image Source="/Images/goalkeeper_top_left.png"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="2"
Visibility="{Binding VsMgr.GoalTopRightVisibility}"/>
<Image Source="/Images/football_ball.png"
Width="50"
Height="50"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="2"
Visibility="{Binding VsMgr.BallTopRightVisibility}"/>
<Image Source="/Images/white_question_point.png"
Width="40"
Height="40"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="2"
Visibility="{Binding VsMgr.QuestionPointTopRightVisibility}"/>
<Image Source="/Images/goalkeeper_down_right.png"
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="0"
Visibility="{Binding VsMgr.GoalDownLeftVisibility}"/>
<Image Source="/Images/football_ball.png"
Width="50"
Height="50"
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="0"
Visibility="{Binding VsMgr.BallDownLeftVisibility}"/>
<Image Source="/Images/white_question_point.png"
Width="40"
Height="40"
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="0"
Visibility="{Binding VsMgr.QuestionPointDownLeftVisibility}"/>
<Image Source="{Binding CurrentImageSource}"
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="1"
Visibility="{Binding VsMgr.StarterGoal}"/>
<Image Source="/Images/goalkeeper_down_middle.png"
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="1"
Visibility="{Binding VsMgr.GoalDownMiddleVisibility}"/>
<Image Source="/Images/football_ball.png"
Width="50"
Height="50"
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="1"
Visibility="{Binding VsMgr.BallDownMiddleVisibility}"/>
<Image Source="/Images/white_question_point.png"
Width="40"
Height="40"
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="1"
Visibility="{Binding VsMgr.QuestionPointDownMiddleVisibility}"/>
<Image Source="/Images/goalkeeper_down_left.png"
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="2"
Visibility="{Binding VsMgr.GoalDownRightVisibility}"/>
<Image Source="/Images/football_ball.png"
Width="50"
Height="50"
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="2"
Visibility="{Binding VsMgr.BallDownRightVisibility}"/>
<Image Source="/Images/white_question_point.png"
Width="40"
Height="40"
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="2"
Visibility="{Binding VsMgr.QuestionPointDownRightVisibility}"/>
</Grid>
<Image Source="/Images/football_ball.png"
Width="50"
Height="50"
VerticalAlignment="Bottom"
Visibility="{Binding VsMgr.StarterBall}"/>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" SharedSizeGroup="RowGroup"/>
<RowDefinition Height="*" SharedSizeGroup="RowGroup"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" SharedSizeGroup="ColumnGroup"/>
<ColumnDefinition Width="*" SharedSizeGroup="ColumnGroup"/>
</Grid.ColumnDefinitions>
<Image Source="/Images/whistle.png"
Grid.Column="1"
Grid.Row="0"
Visibility="{Binding WhistleImageVisibility}">
<Image.RenderTransform>
<TranslateTransform X="0" Y="0"/>
</Image.RenderTransform>
<Image.Effect>
<DropShadowEffect BlurRadius="10" Color="Black" Direction="315" ShadowDepth="2"/>
</Image.Effect>
<Image.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.(TranslateTransform.X)"
Duration="0:0:0.1"
AutoReverse="True"
From="0" To="-5" />
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.(TranslateTransform.Y)"
Duration="0:0:0.1"
AutoReverse="True"
From="0" To="5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
<TextBlock Text="{Binding ActionText}"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
Background="Red"
FontWeight="Bold"
FontSize="30"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Visibility="{Binding ActionTextVisibility}"/>
</Grid>
<Border Margin="80"
BorderBrush="#FF2196F3"
Background="#FFFFFF"
BorderThickness="2"
CornerRadius="10"
Padding="20"
Grid.Row="1"
Visibility="{Binding ScoreBoardVisibility}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Fond du panneau d'affichage -->
<Grid.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#3F51B5" Offset="0"/>
<GradientStop Color="#2196F3" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<Grid Grid.Column="1"
Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Score de l'équipe 1 -->
<TextBlock Text="{Binding Player1ScoreText}"
Foreground="White"
FontSize="80"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="20,0,0,0"
Grid.Column="0"/>
<!-- Séparateur central -->
<TextBlock Text="-"
Foreground="White"
FontSize="80"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Column="1"/>
<!-- Score de l'équipe 2 -->
<TextBlock Text="{Binding Player2ScoreText}"
Foreground="White"
FontSize="80"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0,0,20,0"
Grid.Column="2"/>
</Grid>
</Grid>
</Border>
<Border Margin="80"
BorderBrush="#FF2196F3"
Background="#FFFFFF"
BorderThickness="2"
CornerRadius="10"
Padding="20"
Grid.Row="1"
Visibility="{Binding FinalResultVisibility}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Fond du panneau d'affichage -->
<Grid.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#3F51B5" Offset="0"/>
<GradientStop Color="#2196F3" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<Grid Grid.Column="0"
Grid.ColumnSpan="3"
Grid.Row="0">
<TextBlock Text="{Binding FinalWinnerText}"
Foreground="White"
FontSize="40"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="20,0,0,0"/>
</Grid>
<Grid Grid.Column="1"
Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Score de l'équipe 1 -->
<TextBlock Text="{Binding Player1ScoreText}"
Foreground="White"
FontSize="80"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="20,0,0,0"
Grid.Column="0"/>
<!-- Séparateur central -->
<TextBlock Text="-"
Foreground="White"
FontSize="80"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Column="1"/>
<!-- Score de l'équipe 2 -->
<TextBlock Text="{Binding Player2ScoreText}"
Foreground="White"
FontSize="80"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0,0,20,0"
Grid.Column="2"/>
</Grid>
</Grid>
</Border>
</Grid>
</UserControl>

@ -0,0 +1,32 @@
using PenaltyMaster3000.ViewModel;
using System;
using System.Collections.Generic;
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.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace PenaltyMaster3000.View
{
/// <summary>
/// Logique d'interaction pour MainView.xaml
/// </summary>
public partial class MainView : UserControl
{
public MainVM MainVM { get; set; }
public MainView()
{
MainVM = new MainVM();
InitializeComponent();
DataContext = MainVM;
}
}
}

@ -0,0 +1,39 @@
<Window x:Class="PenaltyMaster3000.View.StartView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PenaltyMaster3000.View"
mc:Ignorable="d"
Title="StartView" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="PENALTY MASTER"
FontSize="40"
FontWeight="Bold"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="0"/>
<Border Width="400"
Height="100"
BorderBrush="#FF2196F3"
BorderThickness="2"
CornerRadius="10"
Padding="5"
Grid.Row="1">
<Button Width="400"
Height="100"
Content="Start"
FontSize="30"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="#FF2196F3"
Foreground="White"
BorderThickness="0"
Command="{Binding StartCommand}"/>
</Border>
</Grid>
</Window>

@ -0,0 +1,34 @@
using PenaltyMaster3000.Navigation;
using PenaltyMaster3000.ViewModel;
using System;
using System.Collections.Generic;
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.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace PenaltyMaster3000.View
{
/// <summary>
/// Logique d'interaction pour StartView.xaml
/// </summary>
public partial class StartView : Window
{
public StartVM StartVM { get; set; }
public StartView()
{
var navigationService = new NavigationService(this);
StartVM = new StartVM(navigationService);
InitializeComponent();
DataContext = StartVM;
}
}
}

@ -0,0 +1,500 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using KinectUtils;
using MyGestureBank;
using PenaltyMaster3000.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
namespace PenaltyMaster3000.ViewModel
{
public class MainVM : ObservableObject
{
public IGestureFactory GestureFactory { get; set; }
public String ShotHolder { get; set; }
public String DefenseHolder { get; set; }
private DispatcherTimer goalTimer = new DispatcherTimer();
private DispatcherTimer refereeTimer = new DispatcherTimer();
private DispatcherTimer scoreBoardTimer = new DispatcherTimer();
private Random random = new Random();
private bool image1Active = true;
private int player1Score = 0;
private int player2Score = 0;
private bool isShootCompleted;
private bool isSaveCompleted;
private bool isResultCompleted;
private bool isPlayer1Goalkeeper = false;
private int numberOfShoots = 0;
private string actualPlayer;
public string ActualPlayer
{
get => actualPlayer;
set => SetProperty(ref actualPlayer, value);
}
private string actionText;
public string ActionText
{
get => actionText;
set => SetProperty(ref actionText, value);
}
private Visibility actionTextVisibility;
public Visibility ActionTextVisibility
{
get => actionTextVisibility;
set => SetProperty(ref actionTextVisibility, value);
}
private Visibility whistleImageVisibility;
public Visibility WhistleImageVisibility
{
get => whistleImageVisibility;
set => SetProperty(ref whistleImageVisibility, value);
}
private Visibility scoreBoardVisibility;
public Visibility ScoreBoardVisibility
{
get => scoreBoardVisibility;
set => SetProperty(ref scoreBoardVisibility, value);
}
private Visibility finalResultVisibility;
public Visibility FinalResultVisibility
{
get => finalResultVisibility;
set => SetProperty(ref finalResultVisibility, value);
}
/// <summary>
/// The goal's visibility manager.
/// </summary>
private VisibilityManager vsMgr;
public VisibilityManager VsMgr
{
get => vsMgr;
set => SetProperty(ref vsMgr, value);
}
// PLAYER TEXTS
private string player1ScoreText;
public string Player1ScoreText
{
get => player1ScoreText;
set => SetProperty(ref player1ScoreText, value);
}
private string player2ScoreText;
public string Player2ScoreText
{
get => player2ScoreText;
set => SetProperty(ref player2ScoreText, value);
}
private string finalWinnerText;
public string FinalWinnerText
{
get => finalWinnerText;
set => SetProperty(ref finalWinnerText, value);
}
// ---
public BitmapImage CurrentImageSource
{
get
{
string imagePath = image1Active ? "/Images/goalkeeper_starting1.png" : "/Images/goalkeeper_starting2.png";
return new BitmapImage(new Uri(imagePath, UriKind.Relative));
}
}
public bool IsShootCompleted
{
get { return isShootCompleted; }
set
{
if (SetProperty(ref isShootCompleted, value))
{
if (value)
{
SaveCommand.Execute(null);
}
}
}
}
public bool IsSaveCompleted
{
get { return isSaveCompleted; }
set
{
if (SetProperty(ref isSaveCompleted, value))
{
if (value)
{
ResultCommand.Execute(null);
}
}
}
}
public bool IsResultCompleted
{
get { return isResultCompleted; }
set
{
if (SetProperty(ref isResultCompleted, value))
{
if (value)
{
ShootCommand.Execute(null);
}
}
}
}
// ---
public ICommand ShootCommand { get; private set; }
public ICommand SaveCommand { get; private set; }
public ICommand ResultCommand { get; private set; }
public MainVM()
{
this.GestureFactory = new PenaltyMasterGestureFactory();
VsMgr = new VisibilityManager();
ActualPlayer = "Player 1";
goalTimer.Interval = TimeSpan.FromSeconds(1);
goalTimer.Tick += GoalTimer_Tick;
goalTimer.Start();
ActionTextVisibility = Visibility.Hidden;
WhistleImageVisibility = Visibility.Hidden;
FinalResultVisibility = Visibility.Hidden;
ShootCommand = new RelayCommand(Shoot);
SaveCommand = new RelayCommand(Save);
ResultCommand = new RelayCommand(Result);
Shoot();
}
private void GoalTimer_Tick(object sender, EventArgs e)
{
image1Active = !image1Active;
OnPropertyChanged(nameof(CurrentImageSource));
}
/// <summary>
/// Hides the action text when it expires.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void RefereeTimer_Tick(object sender, EventArgs e)
{
ActionTextVisibility = Visibility.Hidden;
WhistleImageVisibility = Visibility.Hidden;
// Arrêter le timer
refereeTimer.Stop();
}
private void ScoreBoardTimer_Tick(object sender, EventArgs e)
{
// Rendre le texte invisible lorsque le timer expire
ScoreBoardVisibility = Visibility.Hidden;
scoreBoardTimer.Stop();
}
private async void Shoot()
{
StartupVisibility();
// Après que le timer a expiré, marquez le tir comme terminé
IsShootCompleted = true;
// Générez un index aléatoire pour choisir l'élément Goal à rendre visible
//int randomIndex = random.Next(goalVisibilities.Count);
// Let the player choose a angle to shoot
await DisplayActionText(ActualPlayer + " turn. Get ready !", 2);
await DisplayActionText("Choose an angle to shoot.", 2);
// Read a gesture for 5 seconds
// Save the shot on the ShotHolder attribute
ShotHolder = await ReadAPosture();
//Change the ActualPlayer value before call SaveMethod
SetActualPlayer(ActualPlayer);
// Call the save method
VsMgr.HideQuestionPoint();
await DisplayActionText("SHOOT!", 2);
await ReadShootingGesture();
Save();
}
private async void Save()
{
await DisplayActionText(ActualPlayer + " turn. Get ready !", 2);
await DisplayActionText("Choose an angle to defend.", 2);
DefenseHolder = await ReadAPosture();
// Arrêter le timer du déplacement automatique du Goal
goalTimer.Stop();
// IsSaveCompleted = false;
Result();
VsMgr.HideQuestionPoint();
}
private async void Result()
{
// Update the view with shot and defense.
await VsMgr.SetResult(ShotHolder, DefenseHolder);
// get the result (goal or not goal).
bool isBallAndGoalVisible = VsMgr.GetResult();
// Update the score
// Vérifiez si toutes les paires d'éléments Ball et Goal sont visibles
if (!isPlayer1Goalkeeper && !isBallAndGoalVisible)
{
// Une paire d'éléments est visible, incrémentation du score du Shooter
player1Score++;
}
else if (isPlayer1Goalkeeper && !isBallAndGoalVisible)
{
// Aucune paire d'éléments est visible, incrémentation du score du Goalkeeper
player2Score++;
}
Player1ScoreText = player1Score.ToString();
Player2ScoreText = player2Score.ToString();
ScoreBoardVisibility = Visibility.Visible;
// Arrêter le timer précédent s'il était en cours
if (scoreBoardTimer != null && scoreBoardTimer.IsEnabled)
{
scoreBoardTimer.Stop();
}
// Démarrer un nouveau timer pour rendre le texte invisible après 2 secondes
scoreBoardTimer = new DispatcherTimer();
scoreBoardTimer.Interval = TimeSpan.FromSeconds(2);
scoreBoardTimer.Tick += (sender, args) =>
{
ScoreBoardTimer_Tick(sender, args);
numberOfShoots++;
if (numberOfShoots >= 10 && numberOfShoots % 2 == 0 && player1Score != player2Score)
{
GameEnded();
}
else
{
// Après que le timer a expiré, marquez l'affichage du résultat comme terminé
IsResultCompleted = true;
}
};
scoreBoardTimer.Start();
isPlayer1Goalkeeper = !isPlayer1Goalkeeper;
StartupVisibility();
goalTimer.Start();
IsResultCompleted = false;
}
private void GameEnded()
{
if(player1Score > player2Score)
{
FinalWinnerText = "Player 1 wins the game !";
}
else
{
FinalWinnerText = "Player 2 wins the game !";
}
FinalResultVisibility = Visibility.Visible;
}
/// <summary>
/// Sets the starting visibility for the game.
/// </summary>
private void StartupVisibility()
{
VsMgr.GameStartedVisibility();
}
// new stuff
/// <summary>
/// Display an Action text.
/// </summary>
/// <param name="textToBeDisplayed"></param>
/// <param name="timeToBeDisplayedInSeconds"></param>
private Task DisplayActionText(string textToBeDisplayed, int timeToBeDisplayedInSeconds)
{
var tcs = new TaskCompletionSource<bool>();
// Set text to be displayed
ActionText = textToBeDisplayed;
ActionTextVisibility = Visibility.Visible;
// Hide scoreboard
ScoreBoardVisibility = Visibility.Hidden;
// Arrêter le timer précédent s'il était en cours
if (refereeTimer != null && refereeTimer.IsEnabled)
{
refereeTimer.Stop();
}
// Démarrer un nouveau timer pour rendre le texte invisible après x secondes
refereeTimer = new DispatcherTimer();
refereeTimer.Interval = TimeSpan.FromSeconds(timeToBeDisplayedInSeconds);
refereeTimer.Tick += (sender, args) =>
{
RefereeTimer_Tick(sender, args);
tcs.SetResult(true);
};
refereeTimer.Start();
return tcs.Task;
}
/*
* Use the gesture manager to read a gesture
*/
private Task<string> ReadAPosture()
{
var tcs = new TaskCompletionSource<string>();
string gestureRead = "";
// load all
GestureManager.AddGestures(this.GestureFactory);
// subscirbe to the OnGestureRecognized event
foreach (var gesture in GestureManager.KnownGestures)
{
gesture.GestureRecognized += (sender, args) =>
{
// If new gesture read, replace th gesture name
if(gestureRead != args.GestureName)
{
// save the recognized gesture
gestureRead = args.GestureName;
// display where
VsMgr.SetQuestionPoint(gestureRead);
if (!tcs.Task.IsCompleted)
{
tcs.SetResult(args.GestureName);
}
}
};
}
// Read frames for ReadTimeSeconds
GestureManager.StartAcquiringFrames(GestureManager.KinectManager);
return tcs.Task.ContinueWith(t =>
{
// Stop reading and unsub from the GestureRecognized event to prevent memory leaks
GestureManager.StopAcquiringFrame(GestureManager.KinectManager);
foreach (var gesture in GestureManager.KnownGestures)
{
gesture.GestureRecognized = null;
}
return t.Result;
});
}
private Task<bool> ReadShootingGesture()
{
var tcs = new TaskCompletionSource<bool>();
// load all
GestureManager.AddGestures(this.GestureFactory);
// subscribe to the OnGestureRecognized event
foreach (var gesture in GestureManager.KnownGestures)
{
var soccerShootGesture = gesture as SoccerShootGesture;
if (soccerShootGesture != null)
{
soccerShootGesture.GestureRecognized += (sender, args) =>
{
if (!tcs.Task.IsCompleted)
{
tcs.SetResult(true);
}
};
}
}
// Read frames for ReadTimeInSeconds
GestureManager.StartAcquiringFrames(GestureManager.KinectManager);
return tcs.Task.ContinueWith(t =>
{
// Stop reading and unsub from the GestureRecognized event to prevent memory leaks
GestureManager.StopAcquiringFrame(GestureManager.KinectManager);
foreach (var gesture in GestureManager.KnownGestures)
{
gesture.GestureRecognized = null;
}
return t.Result;
});
}
private void SetActualPlayer(string actualPlayer)
{
if(actualPlayer == "Player 1")
{
ActualPlayer = "Player 2";
}
else
{
ActualPlayer = "Player 1";
}
}
}
}

@ -0,0 +1,32 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using PenaltyMaster3000.Navigation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Navigation;
namespace PenaltyMaster3000.ViewModel
{
public class StartVM : ObservableObject
{
private readonly INavigationService _navigationService;
public ICommand StartCommand { get; set; }
public StartVM(INavigationService navigationService)
{
_navigationService = navigationService;
StartCommand = new RelayCommand(Start);
}
private void Start()
{
_navigationService.NavigateTo("MainView");
}
}
}

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CommunityToolkit.Mvvm" version="8.2.2" targetFramework="net48" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="7.0.0" targetFramework="net48" />
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
<package id="System.ComponentModel.Annotations" version="5.0.0" targetFramework="net48" />
<package id="System.Memory" version="4.5.5" targetFramework="net48" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net48" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" />
</packages>

@ -23,17 +23,17 @@ namespace PostureTester
SoccerShootGesture soccerShootGesture = new SoccerShootGesture();
BaseGesture[] gestures = new BaseGesture[1];
/*gestures[0] = postureHandUpLeft;
gestures[1] = postureHandUpRight;
gestures[2] = postureHandDownLeft;
gestures[3] = postureHandDownRight;
gestures[4] = postureTwoHandsDown;
gestures[5] = postureTwoHandsUp;*/
IGestureFactory factory = new PenaltyMasterGestureFactory();
gestures[0] = soccerShootGesture;
GestureManager.AddGestures(factory);
GestureManager.AddGestures(gestures);
foreach (var gesture in GestureManager.KnownGestures)
{
gesture.GestureRecognized += (sender, arg) =>
{
Console.WriteLine(arg.GestureName);
};
}
GestureManager.StartAcquiringFrames(GestureManager.KinectManager);

@ -0,0 +1,98 @@
# PenaltyMaster3000 ⚽️
## Bonjour et bienvenue sur le dépôt du projet PenaltyMaster3000 ! 👋
*******
Sommaire
1. [Accessibilité](#acces)
2. [Présentation du projet](#presentation)
3. [Règles du jeu](#regles)
3. [Solutions mises en place](#solutions)
4. [Structure du projet](#structure)
5. [Auteurs](#auteurs)
*******
<div id='acces'/>
## :rotating_light: Branches
* La totalité des tps et le projet se trouvent dans la branche `master` (__sauf pour la partie 3 de l'exo 2__)
* La partie 3 de l'exercice 2 (__mapping__) se trouve dans la branche `ex2-part3-mapping-et-factory`
* Les branches crées au long de la période n'ont pas été supprimées afin de mettre a disposition un historique du travail effectuer.
## Accessibilité ↗
> :warning: **Warning**: Le déploiement n'a pas encore été fait.
Pour lancer le projet **Penalty Master 3000**, vous devrez cloner le répertoire, ouvrir le projet dans Visual Studio et définir la solution PenaltyMaster3000 comme projet de démarrage.
*******
<div id='presentation'/>
## **Présentation** 🎉
Votre simulateur de séance de penalty en réalité virtuelle !
**PenaltyMaster3000** est un simulateur de séance de penalty multijoueur conçu pour la réalité virtuelle. Le jeu utilise la technologie **Kinect** pour suivre les mouvements des joueurs et les intégrer dans l'expérience de réalité virtuelle. Développé en **C#**, ce projet offre une immersion réaliste et interactive, permettant aux utilisateurs de vivre l'excitation d'une séance de penalty dans le confort de leur propre espace. En incarnant aussi bien le tireur que le gardien, vous pourrez défier vos amis dans un duel intense.
*******
<div id='regles'/>
## Règles du jeu 📖
Une fois la partie lancée, son déroulement est assez linéaire en suivant une même boucle de jeu :
- le tireur sélectionne de la zone de tir avec une certaine posture.
- le tireur simule un tir pour passer au tour du gardien.
- le gardien sélectionne sa zone d'arrêt avec une posture spécifique.
A la fin du tour, les joueurs changent de rôle et continue la partie.
Au bout de 10 tirs, le joueur ayant inscrit le plus de buts remporte la partie. En cas d'égalité, les joueurs repartent sur 1 tir supplémentaire chacun jusqu'il y ait un résultat positif pour l'un des joueurs.
Les 4 postures possibles sont : `main gauche en haut`, `main haut droite`, `main bas gauche` et `main bas droite`.
La gesture de tir consiste à lever son pied vers l'avant comme si l'on tirait dans un ballon (le pied doit monter assez haut).
*******
<div id='solutions'/>
## Solutions mises en place
**PenaltyMaster3000.csproj** : Ce projet est responsable de la logique du jeu PenaltyMaster3000. Il comprend les règles du jeu, le système de notation et les interactions des joueurs.
**MyGestureBank.csproj** : Ce projet contient une bibliothèque de gestes. Il est utilisé pour stocker, récupérer et gérer les gestes utilisés dans différentes applications.
**KinectUtils.csproj** : Ce projet est une bibliothèque d'utilitaires pour Kinect. Il fournit des fonctions d'aide et des classes pour simplifier le travail avec les données du capteur Kinect.
**PostureTester.csproj** : Ce projet est utilisé pour tester et valider les postures. Il utilise les données du capteur Kinect pour analyser et évaluer les postures des utilisateurs.
**KinectSensorStreams.csproj** : Ce projet gère le streaming de données du capteur Kinect. Il comprend des classes pour gérer différents types de flux de données, tels que la couleur, la profondeur et le corps.
**GestureTestApp.csproj** : Ce projet est une application pour tester les gestes. Il utilise la bibliothèque MyGestureBank pour tester et valider les gestes.
**KinectConnection.csproj** : Ce projet gère la connexion au capteur Kinect. Il comprend des classes pour initialiser le capteur, gérer les événements du capteur et gérer les données du capteur.
*******
<div id='structure'/>
## Structure du projet
La solution est divisée en de nombreux packages dont l'application WPF en .NET Framework composée des dossiers suivants :
- `Helpers/` : contient les classes d'aide comme [`VisibilityManager.cs`](Helpers/VisibilityManager.cs)
- `Images/` : contient les images utilisées dans le projet
- `Navigation/` : contient les classes concernant la navigation, incluant [`INavigationService.cs`](Navigation/INavigationService.cs) et [`NavigationService.cs`](Navigation/NavigationService.cs)
- `View/` : contient les vues (UI) de l'application, incluant [`MainView.xaml`](View/MainView.xaml) et [`StartView.xaml`](View/StartView.xaml)
- `ViewModel/` : contient les ViewModels pour les vues, incluant [`MainVM.cs`](ViewModel/MainVM.cs) et [`StartVM.cs`](ViewModel/StartVM.cs)
*******
<div id='auteurs'/>
## **Auteurs** 👥
Étudiant 3ème Annnée - BUT Informatique - IUT Clermont Auvergne - 2023-2024
`BRODA Lou` - `FRANCO Nicolas`
Loading…
Cancel
Save