using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using Microsoft.Kinect; using Newtonsoft.Json; using NAudio.Wave; using MicroLibrary; using System.IO; using System.Diagnostics; using System.Drawing.Drawing2D; namespace FFDDR { public partial class FFDDR : Form { // Wavprocessor variables private string[] wavInfo; private long wavFrameIncrement = 0; private WaveFileReader reader; private WaveOut output; private int m = 0; private Graphics graphics; private MicroTimer timer; private int beatBoxChanger = 0; private long timeSinceLastBeat = 0; // SkeletonTracker variables private const float RenderWidth = 640.0f; private const float RenderHeight = 480.0f; private KinectSensor sensor; private Skeleton[] skeletonArray; private SkeletonManager skeletonManager; private PictureBox[] pboxShowCalibrated; private Vector4 centreScreen; private bool twoPlayer = false; private float deadspotSize = 50; private int circleRadius = 400; private float footSize = 30, defaultFootSize = 20, enlargedFootSize = 70; float defaultScreenHeight; float backgroundScaler = 0.4f; int quadrentLeft, quadrentRight; int blueScore = 0, redScore = 0, yellowScore = 0, greenScore = 0; private float xCoordLeft, yCoordLeft, xCoordRight, yCoordRight; List footstepList; BeatPicturebox mainScreen; int colourChanger = 0; public FFDDR() { InitializeComponent(); } private void FFDDR_Load(object sender, EventArgs e) { #region Beat detect defaultScreenHeight = this.Height; //scoreLabel.Left = (int)(0.7f * (float)this.Width); //scoreLabel. //label1.Font.SizeInPoints = 5; // The song to convert + read reader = new WaveFileReader(@"C:\Users\Chris\Downloads\become.wav"); output = new WaveOut(); output.Init(reader); //output.Play(); //graphics = mainScreen.CreateGraphics(); mainScreen = new BeatPicturebox(); mainScreen.Left = 0; mainScreen.Top = 0; mainScreen.Width = mainScreen1.Width; mainScreen.Height = mainScreen1.Height; this.Controls.Add(mainScreen); mainScreen.BringToFront(); mainScreen.BackColor = Color.Transparent;//(Color)ColorTranslator.FromHtml("#353535"); this.DoubleBuffered = true; // The song to play wavInfo = WavProcessor.ReadWav(@"C:\Users\Chris\Downloads\", "become", 1024, 30); // Play one buffer every (songLength/temp.length(numbuffer)) milliseconds. Both values are contained in the Json string[] WavFrame temp = (WavFrame)JsonConvert.DeserializeObject(wavInfo[0]); timer = new MicroTimer(); timer.Interval = (int)((temp.songLength / wavInfo.Length) * 1000); // Have the ability to ignore late-firing timer events. Enable if drift issues exist, currently works with. // timer.IgnoreEventIfLateBy = (int)((temp.songLength / wavInfo.Length) )/ 4; //timer.Enabled = true; timer.MicroTimerElapsed += new MicroTimer.MicroTimerElapsedEventHandler(timerTick); footstepList = new List(); #endregion #region Initialize and start Kinect foreach (var potentialSensor in KinectSensor.KinectSensors) { if (potentialSensor.Status == KinectStatus.Connected) { this.sensor = potentialSensor; break; } } if (null != this.sensor) { // Turn on the skeleton stream to receive skeleton frames this.sensor.SkeletonStream.Enable(); // Add an event handler to be called whenever there is new color frame data this.sensor.SkeletonFrameReady += this.SensorSkeletonFrameReady; // Start the sensor! try { this.sensor.Start(); sensor.ElevationAngle = -5; } catch (IOException) { this.sensor = null; } } #endregion skeletonManager = new SkeletonManager(6); graphics = mainScreen.CreateGraphics(); centreScreen.X = mainScreen.Width / 2; centreScreen.Z = mainScreen.Height / 2; mainScreen.Paint += screen1_Paint; #region Display pictureboxes showing calibration information pboxShowCalibrated = new PictureBox[6]; for (int i = 0; i < pboxShowCalibrated.Length; i++) { pboxShowCalibrated[i] = new PictureBox(); pboxShowCalibrated[i].Height = 40; pboxShowCalibrated[i].Width = 40; pboxShowCalibrated[i].Left = this.Width - (pboxShowCalibrated[i].Width + 17); pboxShowCalibrated[i].Top = (i * 50); pboxShowCalibrated[i].BackColor = Color.DarkGray; pboxShowCalibrated[i].Visible = true; this.Controls.Add(pboxShowCalibrated[i]); } #endregion redLabel.BringToFront(); blueLabel.BringToFront(); greenLabel.BringToFront(); yellowLabel.BringToFront(); /* blueLabel = new Label(); redLabel = new Label(); greenLabel = new Label(); yellowLabel = new Label(); blueLabel.Font = new Font("Microsoft Sans Serif", 20); redLabel.Font = new Font("Microsoft Sans Serif", 20); greenLabel.Font = new Font("Microsoft Sans Serif", 20); yellowLabel.Font = new Font("Microsoft Sans Serif", 20); redLabel.BackColor = Color.Red; redLabel.Left = (int)(10); blueLabel.Left = (int)(0.8f * mainScreen.Width); yellowLabel.Left = (int)(0.2f * mainScreen.Width); greenLabel.Left = (int)(0.8f * mainScreen.Width); redLabel.Top = (int)(10); blueLabel.Top = (int)(0.1 * mainScreen.Height); yellowLabel.Top = (int)(0.85 * mainScreen.Height); greenLabel.Top = (int)(0.85 * mainScreen.Height); redLabel.BringToFront(); redLabel.Visible = true; redLabel.Enabled = true; label1.BringToFront(); redLabel.Text = "Test"; redLabel.Location = new System.Drawing.Point(10,10 ); redLabel.Name = "redLabel"; redLabel.Size = new System.Drawing.Size(173, 20); // When song finished this is out of bounds. fix this. WavFrame currentFrame = (WavFrame)JsonConvert.DeserializeObject(wavInfo[wavFrameIncrement]); for (int j = 0; j < currentFrame.bandPowers.Length; j++) { colourChanger++; timeSinceLastBeat++; wavFrameIncrement++; /* if (mainScreen.InvokeRequired) { //mainScreen.Invoke(new MethodInvoker(delegate { mainScreen.Refresh(); })); mainScreen.Invoke(new MethodInvoker(delegate { mainScreen.CreateGraphics().FillRectangle(new SolidBrush(Color.White), 0, 0, mainScreen.Width, mainScreen.Height); })); } */ if (colourChanger >= 75) { colourChanger = 0; Random random = new Random(); if (random.Next(0, 2) == 1) { quadrentRight = random.Next(0, 5); } else { quadrentLeft = random.Next(0, 5); } } if (footSize > defaultFootSize) { footSize *= 0.92f; if (footSize < defaultFootSize) footSize = defaultFootSize; } for (int i = 0; i < footstepList.Count; i++) { footstepList[i].radius *= 1.05f; if (footstepList[i].radius > enlargedFootSize) footstepList.Remove(footstepList[i]); } if (wavInfo.Length > wavFrameIncrement) { WavFrame currentFrame = (WavFrame)JsonConvert.DeserializeObject(wavInfo[wavFrameIncrement]); /* for (int j = 0; j < currentFrame.bandPowers.Length; j++) { // Calling control change drawing beat visualizer bands) from another thread. if (mainScreen.InvokeRequired) { mainScreen.Invoke(new MethodInvoker(delegate { mainScreen.CreateGraphics().DrawRectangle(new Pen(Color.DarkBlue), j * 15, 0, 10, 6 * currentFrame.bandPowers[j]); })); } } */ // If a beat exists on the current frame, display it via BeatBox if (currentFrame.beatExists == true) { ChangeBeatBox(); } } else System.Environment.Exit(1); } catch { System.Environment.Exit(1); } } private void ChangeBeatBox() { // Alternate the box which chanhges to the beat. //graphics = mainScreen.CreateGraphics(); if (timeSinceLastBeat >= 20) { /* beatBoxChanger++; timeSinceLastBeat = 0; PictureBox p; if ((beatBoxChanger %= 2) == 1) { p = beatBox; } else p = beatBox1; if (beatBox.BackColor == Color.DarkBlue) { p.BackColor = Color.Turquoise; } else p.BackColor = Color.DarkBlue; */ //footSize = enlargedFootSize; footstepList.Add(new FootStep((float)defaultFootSize, xCoordLeft, yCoordLeft)); footstepList.Add(new FootStep((float)defaultFootSize, xCoordRight, yCoordRight)); timeSinceLastBeat = 0; } } private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e) { skeletonArray = new Skeleton[0]; using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame()) { if (skeletonFrame != null) { skeletonArray = new Skeleton[skeletonFrame.SkeletonArrayLength]; skeletonFrame.CopySkeletonDataTo(skeletonArray); skeletonManager.Update(skeletonArray); } if (skeletonArray.Length != 0) { //screen.Refresh(); //screen2.Refresh(); twoPlayer = false; for (int i = 0; i < skeletonArray.Length; i++) { if (skeletonManager.calibrated[i] == false) { if (skeletonManager.Calibrate(i) == 1) { output.Play(); timer.Enabled = true; } } if (skeletonManager.calibrated[i] == true) { if (skeletonManager.skeletons[i].TrackingState == SkeletonTrackingState.NotTracked) { skeletonManager.calibrated[i] = false; //pboxShowCalibrated[i].BackColor = Color.DarkGray; } else { //pboxShowCalibrated[i].BackColor = Color.Cyan; //if (twoPlayer == false) graphics = screen.CreateGraphics(); //else graphics = screen2.CreateGraphics(); //graphics = mainScreen.CreateGraphics(); //mainScreen.g twoPlayer = true; int playerQuadrentLeft = skeletonManager.FindQuadrant(skeletonManager.leftFoot[i].Z, skeletonManager.leftFoot[i].X, skeletonManager.centre[i]); int playerQuadrentRight = skeletonManager.FindQuadrant(skeletonManager.rightFoot[i].Z, skeletonManager.rightFoot[i].X, skeletonManager.centre[i]); xCoordLeft = (centreScreen.X - footSize / 2) + (skeletonManager.leftFoot[i].X - skeletonManager.centre[i].X) * (mainScreen.Width / 2) / 1f; yCoordLeft = (centreScreen.Z- footSize / 2) + (skeletonManager.leftFoot[i].Z - skeletonManager.centre[i].Z) * (mainScreen.Height / 2) / 1f; xCoordRight = (centreScreen.X- footSize / 2) + (skeletonManager.rightFoot[i].X - skeletonManager.centre[i].X) * (mainScreen.Width / 2) / 1f; yCoordRight = (centreScreen.Z- footSize / 2) + (skeletonManager.rightFoot[i].Z - skeletonManager.centre[i].Z) * (mainScreen.Height / 2) / 1f; mainScreen.Invalidate(); //drawBackground(); } } } } } } private void DrawQuadrent(int num, Graphics graphics) { if (num == 1) { drawSegment(graphics, mainScreen.Width, mainScreen.Height, circleRadius, 180, 90, "#FFFFFF", "#DE00C0"); //graphics.FillRectangle(new SolidBrush(Color.Red), 0, 0, screen.Width / 2, screen.Height / 2); } else if (num == 2) { drawSegment(graphics, mainScreen.Width, mainScreen.Height, circleRadius, 270, 90, "#FFFFFF", "#00DCE8"); //graphics.FillRectangle(new SolidBrush(Color.Blue), screen.Width / 2, 0, screen.Width / 2, screen.Height / 2); } else if (num == 3) { drawSegment(graphics, mainScreen.Width, mainScreen.Height, circleRadius, 0, 90, "#FFFFFF", "#00E800"); //graphics.FillRectangle(new SolidBrush(Color.Green), screen.Height / 2, screen.Width / 2, screen.Width / 2, screen.Height / 2); } else if (num == 4) { drawSegment(graphics, mainScreen.Width, mainScreen.Height, circleRadius, 90, 90, "#FFFFFF", "#E8E800"); //graphics.FillRectangle(new SolidBrush(Color.Yellow), 0, screen.Height / 2, screen.Width / 2, screen.Height / 2); } //graphics.FillEllipse(new SolidBrush(Color.Black), screen.Width / 2 - (deadspotSize / 2), screen.Height / 2 - (deadspotSize / 2), deadspotSize, deadspotSize); } public void screen1_Paint(object sender, PaintEventArgs e) { Graphics graphics = e.Graphics; GraphicsPath path = new GraphicsPath(); //test = e.Graphics; path.AddEllipse(0, -((mainScreen.Width - mainScreen.Height) / 2), mainScreen.Width, mainScreen.Width); // Create a path gradient brush based on the elliptical path. PathGradientBrush pthGrBrush = new PathGradientBrush(path); // Set the color along the entire boundary to Color[] color = { (Color)ColorTranslator.FromHtml("#353535") }; pthGrBrush.SurroundColors = color; // Set the center color to aqua. pthGrBrush.CenterColor = (Color)ColorTranslator.FromHtml("#E8E8E8"); ; // Use the path gradient brush to fill the ellipse. //graphics.FillPath(pthGrBrush, path); // Set the focus scales for the path gradient brush. pthGrBrush.FocusScales = new PointF(0.4f, 0.4f); // Use the path gradient brush to fill the ellipse again. // Show this filled ellipse to the right of the first filled ellipse. //graphics.TranslateTransform(220.0f, 0.0f); //e.Graphics.FillPath(pthGrBrush, path); // Debug.Write("h"); redLabel.Text = redScore.ToString(); blueLabel.Text = blueScore.ToString(); yellowLabel.Text = yellowScore.ToString(); greenLabel.Text = greenScore.ToString(); if (quadrentLeft != 1 && quadrentRight != 1) drawSegment(graphics, mainScreen.Width, mainScreen.Height, circleRadius, 180, 90, "#DE00C0", "#780068"); if (quadrentLeft != 2 && quadrentRight != 2) drawSegment(graphics, mainScreen.Width, mainScreen.Height, circleRadius, 270, 90, "#000087", "#0000E8"); if (quadrentLeft != 3 && quadrentRight != 3) drawSegment(graphics, mainScreen.Width, mainScreen.Height, circleRadius, 0, 90, "#008700", "#00E800"); if (quadrentLeft != 4 && quadrentRight != 4) drawSegment(graphics, mainScreen.Width, mainScreen.Height, circleRadius, 90, 90, "#878700", "#E8E800"); DrawQuadrent(quadrentLeft, graphics); DrawQuadrent(quadrentRight, graphics); for (int n = 0; n < footstepList.Count; n++) { if (n < footstepList.Count) { graphics.DrawEllipse(new Pen(Color.Black), footstepList[n].xPos - (footstepList[n].radius / 2), footstepList[n].yPos - (footstepList[n].radius / 2), footstepList[n].radius, footstepList[n].radius); } } graphics.FillEllipse(new SolidBrush(Color.Black), (int)(xCoordLeft), (int)(yCoordLeft), footSize, footSize); graphics.FillEllipse(new SolidBrush(Color.Black), (int)(xCoordRight), (int)(yCoordRight), footSize, footSize); } private void drawBackground() { Graphics graphics = mainScreen.CreateGraphics(); GraphicsPath path = new GraphicsPath(); path.AddEllipse(0, -((mainScreen.Width - mainScreen.Height) / 2), mainScreen.Width, mainScreen.Width); // Create a path gradient brush based on the elliptical path. PathGradientBrush pthGrBrush = new PathGradientBrush(path); // Set the color along the entire boundary to Color[] color = { (Color)ColorTranslator.FromHtml("#353535") }; pthGrBrush.SurroundColors = color; // Set the center color to aqua. pthGrBrush.CenterColor = (Color)ColorTranslator.FromHtml("#E8E8E8"); ; // Use the path gradient brush to fill the ellipse. //graphics.FillPath(pthGrBrush, path); // Set the focus scales for the path gradient brush. pthGrBrush.FocusScales = new PointF(backgroundScaler, backgroundScaler); // Use the path gradient brush to fill the ellipse again. // Show this filled ellipse to the right of the first filled ellipse. //graphics.TranslateTransform(220.0f, 0.0f); // graphics.FillPath(pthGrBrush, path); } private void drawSegment(Graphics graphics, float width, float height, int radius, int startAngle, int finAngle, string innerColour, string outerColour) { //graphics.FillPie(new SolidBrush(colour), (width / 2) - (radius / 2), (height / 2) - (radius / 2), radius, radius, startAngle, finAngle); // Create a path that consists of a single ellipse. GraphicsPath path = new GraphicsPath(); path.AddEllipse((width / 2) - (radius / 2), (height / 2) - (radius / 2), 140, 70); path.AddPie((width / 2) - (radius / 2), (height / 2) - (radius / 2), radius, radius, startAngle, finAngle); // Use the path to construct a brush. PathGradientBrush pthGrBrush = new PathGradientBrush(path); // Set the center point to a location that is not // the centroid of the path. pthGrBrush.CenterPoint = new PointF((width / 2), (height / 2)); //orange // Set the color at the center of the path to blue. pthGrBrush.CenterColor = (Color)ColorTranslator.FromHtml(innerColour); // Set the color along the entire boundary // of the path to aqua. Color[] colors = { (Color)ColorTranslator.FromHtml(outerColour) }; pthGrBrush.SurroundColors = colors; //graphics.FillEllipse(pthGrBrush, 0, 0, 140, 70); graphics.FillPie(pthGrBrush, (width / 2) - (radius / 2), (height / 2) - (radius / 2), radius, radius, startAngle, finAngle); } /* private void FFDDR_ResizeEnd(object sender, EventArgs e) { mainScreen.Left = 0; mainScreen.Height = this.Height; mainScreen.Top = 0; mainScreen.Width = this.Width; drawBackground(); } */ private void FFDDR_Resize(object sender, EventArgs e) { mainScreen.Left = 0; mainScreen.Height = this.Height; mainScreen.Top = 0; mainScreen.Width = this.Width; drawBackground(); } } public class FootStep { public float radius; public float xPos, yPos; public FootStep(float Radius, float XPos, float YPos) { radius = Radius; xPos = XPos; yPos = YPos; } } }