/// <summary> /// Listing semua ellipse yang jadi punch key /// </summary> /// <param name="_runningGameTime"></param> /// <param name="jointPoints"></param> /// <returns></returns> public List <Ellipse> PopulatePunchKey(double _runningGameTime, Dictionary <JointType, Point> jointPoints, int activeBodyNumber) { List <Ellipse> activeEllipses = new List <Ellipse>(); if (!JointPointValidation(jointPoints)) { return(activeEllipses); } //running game time HARUS selalu dibawah 1000 saat awal permulaan double beatPosition = (_runningGameTime / 1000) / (60 / activeMusicBPM); //iterasi sepanjang note2 yang aktif int startCheckedNote = (int)beatPosition; if (beatPosition - (double)((int)beatPosition) > Definitions.PunchKeyOffset) { startCheckedNote++; } for (int checkedNote = startCheckedNote; checkedNote < startCheckedNote + Definitions.PunchKeyLifeTime; checkedNote++) { //check if checked note has been added (converted to ellipsenote) to history if (lastGeneratedPunchNote[activeBodyNumber] < checkedNote) { lastGeneratedPunchNote[activeBodyNumber] = checkedNote; try { #region create a new punching note //the checked note sequence is on duty, and never been assigned, lets create ellipses based on the note! if (activeNoteSequence[checkedNote % activeNoteSequence.Count] != 0) { PunchingNote newPunchingNote = new PunchingNote(); newPunchingNote.punchNoteNumber = checkedNote; //extract the note from library var noteQuery = from note in activeNoteLibrary.noteLibrary where note.noteId == activeNoteSequence[checkedNote % activeNoteSequence.Count] select note; var selectedNote = (Note)noteQuery.FirstOrDefault(); var angleJointDict = selectedNote.UnParseDict(); foreach (var punchingJoint in selectedNote.serPunchingJoints.ToList()) { //add an ellipses on each note (each ser punching joint correspond to one ellipse) PunchingEllipse newPunchingEllipse = new PunchingEllipse(); #region calculating punching joint point int selectedLimbNumber = 0; bool expandedJoint = false; Point punchingJointPoint = new Point(); switch (punchingJoint) { case JointType.HandRight: case JointType.ElbowRight: selectedLimbNumber = (int)LimbNumber.rightArm; break; case JointType.HandLeft: case JointType.ElbowLeft: selectedLimbNumber = (int)LimbNumber.leftArm; break; case JointType.KneeRight: case JointType.AnkleRight: selectedLimbNumber = (int)LimbNumber.rightLeg; break; case JointType.KneeLeft: case JointType.AnkleLeft: selectedLimbNumber = (int)LimbNumber.leftLeg; break; } switch (punchingJoint) { case JointType.HandRight: case JointType.HandLeft: case JointType.AnkleRight: case JointType.AnkleLeft: expandedJoint = true; break; default: expandedJoint = false; break; } //execute ellipse location calculation if (!expandedJoint) { punchingJointPoint = ThirdPointPosition(angleJointDict[jointSequence[selectedLimbNumber, 1]], jointPoints[jointSequence[selectedLimbNumber, 0]], jointPoints[jointSequence[selectedLimbNumber, 1]], misc.TwoPointDistance(jointPoints[jointSequence[selectedLimbNumber, 1]], jointPoints[jointSequence[selectedLimbNumber, 2]])); } else if (expandedJoint && punchingJoint != JointType.Head) { punchingJointPoint = FourthPointPosition(angleJointDict[jointSequence[selectedLimbNumber, 1]], angleJointDict[jointSequence[selectedLimbNumber, 2]], jointPoints[jointSequence[selectedLimbNumber, 0]], jointPoints[jointSequence[selectedLimbNumber, 1]], misc.TwoPointDistance(jointPoints[jointSequence[selectedLimbNumber, 1]], jointPoints[jointSequence[selectedLimbNumber, 2]]), misc.TwoPointDistance(jointPoints[jointSequence[selectedLimbNumber, 2]], jointPoints[jointSequence[selectedLimbNumber, 3]]) ); } //generate special punch kepala (dengan clue shoulder) if (punchingJoint == JointType.Head) { if (angleJointDict[JointType.ShoulderRight] > 0) { punchingJointPoint = new Point(jointPoints[JointType.Head].X, jointPoints[JointType.SpineShoulder].Y); } else { punchingJointPoint = new Point(jointPoints[JointType.Head].X, jointPoints[JointType.Head].Y - misc.TwoPointDistance(jointPoints[JointType.Head], jointPoints[JointType.Neck])); } } //re generate special punch kaki if (punchingJoint == JointType.AnkleLeft || punchingJoint == JointType.AnkleRight) { var groundJoint = JointType.FootLeft; if (punchingJoint == JointType.AnkleRight) { groundJoint = JointType.FootRight; } punchingJointPoint.Y = jointPoints[groundJoint].Y; } //TODO pastikan semua punching point masih di dalam arena kinect depth if (punchingJointPoint.Y < 0) { punchingJointPoint.Y = 0; } if (punchingJointPoint.X < 0) { punchingJointPoint.X = 0; } #endregion newPunchingEllipse.ellipseSpawnPoint = punchingJointPoint; //setup punch elipse switch (punchingJoint) { case JointType.AnkleRight: case JointType.ElbowRight: case JointType.HandRight: case JointType.FootRight: newPunchingEllipse.ellipse.Fill = new SolidColorBrush(Definitions.rightPunchColor); break; case JointType.AnkleLeft: case JointType.ElbowLeft: case JointType.HandLeft: case JointType.FootLeft: newPunchingEllipse.ellipse.Fill = new SolidColorBrush(Definitions.leftPunchColor); break; case JointType.Head: newPunchingEllipse.ellipse.Fill = new SolidColorBrush(Definitions.headPunchColor); break; } newPunchingEllipse.ellipse.Width = Definitions.PunchKeyDiameter; newPunchingEllipse.ellipse.Height = newPunchingEllipse.ellipse.Width; Canvas.SetLeft(newPunchingEllipse.ellipse, newPunchingEllipse.ellipseSpawnPoint.X - 0.5 * Definitions.PunchKeyDiameter); Canvas.SetTop(newPunchingEllipse.ellipse, newPunchingEllipse.ellipseSpawnPoint.Y - 0.5 * Definitions.PunchKeyDiameter); newPunchingEllipse.ellipse.Visibility = Windows.UI.Xaml.Visibility.Visible; //setup timer elipse newPunchingEllipse.timerEllipse.Fill = new SolidColorBrush(Colors.Transparent); newPunchingEllipse.timerEllipse.Stroke = new SolidColorBrush(Definitions.timerColor); if (activeBodyNumber == 1) { newPunchingEllipse.timerEllipse.Stroke = new SolidColorBrush(Colors.Red); } newPunchingEllipse.timerEllipse.StrokeThickness = Definitions.PunchTimerStrokeThickness; newPunchingEllipse.timerEllipse.Width = Definitions.PunchTimerDiameter; newPunchingEllipse.timerEllipse.Height = newPunchingEllipse.timerEllipse.Width; Canvas.SetLeft(newPunchingEllipse.timerEllipse, newPunchingEllipse.ellipseSpawnPoint.X - 0.5 * Definitions.PunchTimerDiameter); Canvas.SetTop(newPunchingEllipse.timerEllipse, newPunchingEllipse.ellipseSpawnPoint.Y - 0.5 * Definitions.PunchTimerDiameter); newPunchingEllipse.timerEllipse.Visibility = Windows.UI.Xaml.Visibility.Visible; //setup helping line newPunchingEllipse.helpingLine.Stroke = new SolidColorBrush(Definitions.lineColor); newPunchingEllipse.helpingLine.X1 = jointPoints[punchingJoint].X; newPunchingEllipse.helpingLine.Y1 = jointPoints[punchingJoint].Y; newPunchingEllipse.helpingLine.X2 = punchingJointPoint.X; newPunchingEllipse.helpingLine.Y2 = punchingJointPoint.Y; newPunchingEllipse.helpingLine.StrokeThickness = 2; newPunchingEllipse.helpingLine.Visibility = Windows.UI.Xaml.Visibility.Visible; activeLine.Add(newPunchingEllipse.helpingLine); newPunchingEllipse.punchingJoint = punchingJoint; newPunchingNote.punchingEllipses.Add(newPunchingEllipse); } activePunchingNotes.Add(newPunchingNote); } #endregion } catch (Exception exc) { Debug.WriteLine("fail creating ellipse and note >" + exc.Message.ToString()); } } //cleaning (nge miss in) old active ellipses foreach (var punchingNote in activePunchingNotes.ToList()) { try { if (punchingNote.punchNoteNumber + Definitions.PunchKeyOffset < beatPosition) { foreach (var punchingEllipse in punchingNote.punchingEllipses.ToList()) { punchingEllipse.ellipse.Visibility = Windows.UI.Xaml.Visibility.Collapsed; if (punchingEllipse.ellipseStatus == PunchingEllipse.EllipseFlags.rendered) { punchingEllipse.ellipseStatus = PunchingEllipse.EllipseFlags.miss; afterPunchHistory.Add(punchingEllipse); } } activePunchingNotes.Remove(punchingNote); } } catch (Exception exc) { Debug.WriteLine("fail clearing old active punch note >" + exc.Message); } } //evaluasi apakah terjadi scoring punching di setiap ellipse (di setiap punching note yang aktif) double[] predicatePositionLimit = new double[predicateRatioLimit.Length]; for (int i = 0; i < predicatePositionLimit.Length; i++) { try { predicatePositionLimit[i] = checkedNote - (Definitions.PunchKeyLifeTime - Definitions.PunchKeyOffset) * (1 - predicateRatioLimit[i]); } catch (Exception exc) { Debug.WriteLine("fail converting predicate limit>" + exc.Message); } } foreach (var punchingNote in activePunchingNotes.ToList()) { foreach (var punchingEllipse in punchingNote.punchingEllipses.ToList()) { try { #region set unpunched ellipse (to be updated) if (punchingEllipse.ellipseStatus == PunchingEllipse.EllipseFlags.rendered) { //update timer punching double lerpPercentage = (((double)punchingNote.punchNoteNumber + Definitions.PunchKeyOffset) - beatPosition) / (Definitions.PunchKeyLifeTime); punchingEllipse.timerEllipse.Width = Definitions.PunchKeyDiameter + (int)(lerpPercentage * (double)(Definitions.PunchTimerDiameter - Definitions.PunchKeyDiameter)); punchingEllipse.timerEllipse.Height = punchingEllipse.timerEllipse.Width; Canvas.SetLeft(punchingEllipse.timerEllipse, punchingEllipse.ellipseSpawnPoint.X - 0.5 * punchingEllipse.timerEllipse.Width); Canvas.SetTop(punchingEllipse.timerEllipse, punchingEllipse.ellipseSpawnPoint.Y - 0.5 * punchingEllipse.timerEllipse.Height); punchingEllipse.timerEllipse.Visibility = Windows.UI.Xaml.Visibility.Visible; //update line punchingEllipse.helpingLine.X1 = jointPoints[punchingEllipse.punchingJoint].X; punchingEllipse.helpingLine.Y1 = jointPoints[punchingEllipse.punchingJoint].Y; punchingEllipse.helpingLine.X2 = punchingEllipse.ellipseSpawnPoint.X; punchingEllipse.helpingLine.Y2 = punchingEllipse.ellipseSpawnPoint.Y; //update main punching punchingEllipse.ellipse.Visibility = Windows.UI.Xaml.Visibility.Visible; } ////export main and timer ellipse else if (punchingEllipse.ellipseStatus == PunchingEllipse.EllipseFlags.intitialized) { activeEllipses.Add(punchingEllipse.timerEllipse); activeEllipses.Add(punchingEllipse.ellipse); punchingEllipse.ellipseStatus = PunchingEllipse.EllipseFlags.rendered; } #endregion } catch (Exception exc) { Debug.WriteLine("fail updating ellipse > " + exc.Message); } try { #region set punched ellipse //HACK , repair ankle punching position to ground var punchingGround = punchingEllipse.punchingJoint; if (punchingGround == JointType.AnkleRight) { punchingGround = JointType.FootRight; } if (punchingGround == JointType.AnkleLeft) { punchingGround = JointType.FootLeft; } if (punchingEllipse.ellipseStatus == PunchingEllipse.EllipseFlags.rendered && misc.TwoPointDistance(jointPoints[punchingGround], punchingEllipse.ellipseSpawnPoint) <= Definitions.PunchEffectiveArea * Definitions.PunchKeyDiameter) { punchingEllipse.ellipse.Visibility = Windows.UI.Xaml.Visibility.Collapsed; punchingEllipse.timerEllipse.Visibility = Windows.UI.Xaml.Visibility.Collapsed; for (int i = 0; i < predicatePositionLimit.Length; i++) { if (beatPosition < predicatePositionLimit[i]) { punchingEllipse.ellipseStatus = (PunchingEllipse.EllipseFlags)(i + 2); break; } } afterPunchHistory.Add(punchingEllipse); } #endregion } catch (Exception exc) { Debug.WriteLine("fail setting up punched ellipse > " + exc.Message); } } } } return(activeEllipses); }
private async void PunchEffect(PunchingEllipse punchingEllipse) { //do some cool effect stuff try { //print predicate BitmapImage effectSource = new BitmapImage(); string imagePath = ""; string sfxPath = ""; switch (punchingEllipse.ellipseStatus) { case PunchingEllipse.EllipseFlags.miss: imagePath = "ms-appx:///Assets/Effect/missEffect.png"; sfxPath = "ms-appx:///Assets/SFX/missSFX.wav"; break; case PunchingEllipse.EllipseFlags.bad: imagePath = "ms-appx:///Assets/Effect/badEffect.png"; sfxPath = "ms-appx:///Assets/SFX/badSFX.wav"; break; case PunchingEllipse.EllipseFlags.cool: imagePath = "ms-appx:///Assets/Effect/coolEffect.png"; sfxPath = "ms-appx:///Assets/SFX/coolSFX.wav"; break; case PunchingEllipse.EllipseFlags.great: imagePath = "ms-appx:///Assets/Effect/greatEffect.png"; sfxPath = "ms-appx:///Assets/SFX/greatSFX.wav"; break; case PunchingEllipse.EllipseFlags.perfect: imagePath = "ms-appx:///Assets/Effect/perfectEffect.png"; sfxPath = "ms-appx:///Assets/SFX/perfectSFX.wav"; break; } SFXPlayer.Source = new Uri(sfxPath); effectSource = new BitmapImage(new Uri(imagePath)); //apply audio effect SFXPlayer.Play(); //apply visual evect Image effectImage = new Image(); effectImage.Source = effectSource; effectImage.Width = Definitions.effectPredicateWidth; effectImage.Height = Definitions.effectPredicateHeight; Canvas.SetLeft(effectImage, punchingEllipse.ellipseSpawnPoint.X - effectImage.Width / 2); Canvas.SetTop(effectImage, punchingEllipse.ellipseSpawnPoint.Y - effectImage.Height / 2); gameCanvas.Children.Add(effectImage); PopInThemeAnimation predicateEffectAnim = new PopInThemeAnimation(); await Task.Delay(Definitions.punchEffectDuration); gameCanvas.Children.Remove(effectImage); effectImage = null; } catch (Exception exc) { Debug.WriteLine("rendering effect fail >" + exc.InnerException.Message); } }