// Updated the Ball and Paddle private void UpdateGameObjects(float fTimeSinceLastUpdateInSeconds, Graphics cBackBuffer) { // Subtract the Time Passed from the Time to Wait before changing Target Pitches mfTimeBeforeChangingTargetPitchInSeconds -= fTimeSinceLastUpdateInSeconds; // Move the Target Pitch by it's Velocity float fOldUnitTargetPitch = mfCurrentUnitTargetPitch; mfCurrentUnitTargetPitch += mfTargetPitchChangeVelocity * fTimeSinceLastUpdateInSeconds; // If the moving Target Pitch passed it's desired Pitch if (mfTargetPitchChangeVelocity != 0.0f && ((fOldUnitTargetPitch <= mfUnitTargetPitchToAchieve && mfCurrentUnitTargetPitch >= mfUnitTargetPitchToAchieve) || (fOldUnitTargetPitch >= mfUnitTargetPitchToAchieve && mfCurrentUnitTargetPitch <= mfUnitTargetPitchToAchieve))) { // Set the Current Target Pitch to the Pitch To Achieve mfCurrentUnitTargetPitch = mfUnitTargetPitchToAchieve; // Randomly specify how long we should wait at this Target Pitch for mfTimeBeforeChangingTargetPitchInSeconds = ((float)mcRandom.NextDouble() * mfMAX_TARGET_PITCH_WAIT_TIME); // Set the Target Pitch Velocity to zero mfTargetPitchChangeVelocity = 0.0f; } // If the Pitch To Match should change, AND it's not changing already if (mfTimeBeforeChangingTargetPitchInSeconds <= 0.0f && mfTargetPitchChangeVelocity == 0.0f) { // Specify the new Target Pitch to achieve mfUnitTargetPitchToAchieve = (float)mcRandom.NextDouble(); // Specify the new Target Pitch Velocity mfTargetPitchChangeVelocity = (float)(mcRandom.Next(1, 10) * 0.1f); // If the Velocity should be negative if (mfUnitTargetPitchToAchieve < mfCurrentUnitTargetPitch) { mfTargetPitchChangeVelocity *= -1.0f; } } // Update the Pitch Meter to Match mcPitchMeterToMatch.UpdatePitchIndicatorsPosition(mfCurrentUnitTargetPitch); // Update the Players Pitch Meter mcPitchMeter.AutoDetectPitchAndUpdateMeter(); // Get how far away from the Target Pitch the Player is float fPitchDifference = Math.Abs(mcPitchMeter.mfPitchIndicatorUnitPosition - mfCurrentUnitTargetPitch); // If the Player is close enough to the Target Pitch if (fPitchDifference <= mfMAX_UNIT_PITCH_DIFFERENCE_TO_EARN_POINTS) { // Give the Player points based on how close they are to the Target Pitch miScore += (int)(Math.Abs(fPitchDifference - mfMAX_UNIT_PITCH_DIFFERENCE_TO_EARN_POINTS) * 1000); } // Subtract the Time passed from the Remaining Game Time mfGameTimeRemaining -= fTimeSinceLastUpdateInSeconds; // If the Game should be over if (mfGameTimeRemaining < 0.0f) { // If the Player beat their old High Score if (miScore > CProfiles.Instance().mcCurrentProfile.iScorePitchMatcher) { // Update and save the Players new High Score CProfiles.Instance().mcCurrentProfile.iScorePitchMatcher = miScore; CProfiles.Instance().SaveProfilesToFile(); } // Restart the Game Reset(); } }
// Update the Bow And Arrow and the Arrow private void UpdateGameObjects(float fTimeSinceLastUpdateInSeconds, Graphics cBackBuffer) { // If the Player is Aiming if (meTargetPracticeState == ETargetPracticeGameStates.Aiming) { // Use the Players current Pitch as the Bow And Arrow Rotation Amount mcPitchMeter.AutoDetectPitchAndUpdateMeter(); miBowAndArrowRotation = (int)(mcPitchMeter.mfPitchIndicatorUnitPosition * -45.0f); // Save the amount of Power being used mfUnitBowAndArrowPower = ((CSoundInput.Instance().fAmplitude - 90.0f) / 20.0f); // Make sure the Power is in a valid range of Zero to One if (mfUnitBowAndArrowPower < 0.0f) { mfUnitBowAndArrowPower = 0.0f; } else if (mfUnitBowAndArrowPower > 1.0f) { mfUnitBowAndArrowPower = 1.0f; } } // Else the Arrow has been fired else { // If the Arrow is not "dead" yet if (mfResetArrowWaitTime <= 0.0f) { // Update the Arrows Velocity by Gravity mcArrowVelocity += (mcGRAVITY_ACCELERATION * fTimeSinceLastUpdateInSeconds); // Calculate the Arrows new Position mrArrow.X += (mcArrowVelocity.X * fTimeSinceLastUpdateInSeconds); mrArrow.Y += (mcArrowVelocity.Y * fTimeSinceLastUpdateInSeconds); // Get the Rotation angle of the Arrow so that it faces the direction it is travelling float fArrowRotationInRadians = 0.0f; bool bChangeRotation = true; if (mcArrowVelocity.Y < 0.0f) { fArrowRotationInRadians = (float)(Math.PI + Math.Atan(mcArrowVelocity.X / mcArrowVelocity.Y)); } else if (mcArrowVelocity.Y > 0.0f) { fArrowRotationInRadians = (float)(Math.Atan(mcArrowVelocity.X / mcArrowVelocity.Y)); } // Else the Arrow has no Y Velocity else { if (mcArrowVelocity.X > 0.0f) { fArrowRotationInRadians = (float)(Math.PI / 2.0f); } else if (mcArrowVelocity.X < 0.0f) { fArrowRotationInRadians = (float)((3.0f * Math.PI) / 2.0f); } // Else the Arrow has no X Velocity else { // Rotation is undefined, so leave rotationa as is bChangeRotation = false; } } // If the Rotation should be updated if (bChangeRotation) { // Convert the Radians to Degrees and store the result miArrowRotation = 90 - (int)(fArrowRotationInRadians * (180.0f / Math.PI)); } } // If the Arrow should be reset if (mrArrow.IntersectsWith(mrTarget) || mrArrow.X > 800 || mrArrow.Y > 485) { // If the Arrow just "died" if (mfResetArrowWaitTime == 0.0f) { // If the Arrow hit the Target if (mrArrow.IntersectsWith(mrTarget)) { // Record it as a hit mbArrowHitTarget = true; // Update the Players Score miScore++; // If the Players Score is more than their current High Score if (miScore > CProfiles.Instance().mcCurrentProfile.iScoreTargetPractice) { // Update the Players High Score and Save CProfiles.Instance().mcCurrentProfile.iScoreTargetPractice = miScore; CProfiles.Instance().SaveProfilesToFile(); } // Play the Hit sound CFMOD.PlaySound(msSoundHit, false); } // Else if the Arrow did not hit anything else if (mrArrow.X > 800 || mrArrow.Y > 485) { // Record that it was not a hit mbArrowHitTarget = false; // Reset the Players Score miScore = 0; // Play the Miss sound CFMOD.PlaySound(msSoundMiss, false); } // Reset the Arrows Velocity to zero mcArrowVelocity *= 0.0f; } // Update how long we have waited for mfResetArrowWaitTime += fTimeSinceLastUpdateInSeconds; // If we have waited long enough since the Arrow "died" if (mfResetArrowWaitTime > 1.0f) { // Reset the Arrows Position MoveArrowToBow(); // If the Arrow hit the Target if (mbArrowHitTarget) { // Create a new Target to hit MoveTargetToNewRandomLocation(); } // Reset the Arrow Wait Time mfResetArrowWaitTime = 0.0f; // Change the Game State to Aiming meTargetPracticeState = ETargetPracticeGameStates.Aiming; } } } }
// Function to Draw the Game in it's current state to the Back Buffer private void DrawGame(float fTimeSinceLastUpdateInSeconds, Graphics cBackBuffer) { // Brush and Pen to draw with Brush cBrush; Pen cPen; // Clear the screen to Black cBackBuffer.Clear(Color.Black); // Loop though all Targets in the Target List int iTargetIndex = 0; int iNumberOfTargets = mcTargetList.Count; for (iTargetIndex = 0; iTargetIndex < iNumberOfTargets; iTargetIndex++) { // Save a handle to this Target for readability CTarget cTarget = mcTargetList[iTargetIndex]; // Rectangle used to draw Target to the screen Rectangle rRect = new Rectangle((int)cTarget.rRect.X, (int)cTarget.rRect.Y, (int)cTarget.rRect.Width, (int)cTarget.rRect.Height); // If the Target is Facing Left if (cTarget.bFacingLeft) { // Draw this Target to the screen facing Left cBackBuffer.DrawImage(mcTargetFacingLeftImage, rRect, 0, 0, mcTargetFacingLeftImage.Width, mcTargetFacingLeftImage.Height, GraphicsUnit.Pixel, mcTargetImageAttributes); } // Else the Target is Facing Right else { // Draw this Target to the screen facing Right cBackBuffer.DrawImage(mcTargetFacingRightImage, rRect, 0, 0, mcTargetFacingLeftImage.Width, mcTargetFacingLeftImage.Height, GraphicsUnit.Pixel, mcTargetImageAttributes); } } // Draw the Pitch Meter mcPitchMeter.AutoDetectPitchAndUpdateMeter(); mcPitchMeter.Draw(cBackBuffer); // Draw the area in which the Targets can be "hit" cPen = new Pen(Color.White); cBackBuffer.DrawRectangle(cPen, miSHOOT_TARGET_AREA_LEFT, miSHOOT_TARGET_AREA_TOP, (miSHOOT_TARGET_AREA_RIGHT - miSHOOT_TARGET_AREA_LEFT), (miSHOOT_TARGET_AREA_BOTTOM - miSHOOT_TARGET_AREA_TOP)); // Display to press Space Bar to Pause the game cBrush = new SolidBrush(Color.LightBlue); cBackBuffer.DrawString("Pause - Space Bar", mcFontText, cBrush, 475, 530); // Display to press R to Restart the game cBackBuffer.DrawString("Restart - R", mcFontText, cBrush, 150, 530); // Display the players Score cBackBuffer.DrawString("Score " + miScore, mcFontText, cBrush, 10, 10); // Display the instructions cBackBuffer.DrawString("Try and hit as many ducks as possible", mcFontText, cBrush, 190, 10); // If the Song is still loading if (mcWindowsMediaPlayer.status == "Connecting...") { cBackBuffer.DrawString("Loading Tune", mcFontChooseMusicTitle, cBrush, 230, 200); } // Clean up the Brush and Pen resources cBrush.Dispose(); cPen.Dispose(); }
// Update this form private void UpdateForm(object sender, PaintEventArgs e) { // Get a handle to this forms Graphics object so we can draw to it Graphics cGraphics = e.Graphics; // Get input from PD (audio input from player), without keeping the Pitch within range CSoundInput.Instance().GetPDInput(false); // If we should be Detecting the Pitch if (mbDetectingPitch) { // Get the Players current Pitch int iPitch = (int)CSoundInput.Instance().fPitch; // Increment the Hits on the Players current Pitch miaPitchHits[iPitch]++; // If this is the lowest Pitch heard so far and it's been hit at least 10 times if ((CSoundInput.Instance().fPitch < CSoundInput.Instance().iLowerPitchRange || CSoundInput.Instance().iLowerPitchRange <= 10) && CSoundInput.Instance().fPitch > 1.0f && miaPitchHits[iPitch] >= 10) { // Record this as the new lowest Pitch CSoundInput.Instance().iLowerPitchRange = iPitch; // If the Pitch is too low if (CSoundInput.Instance().iLowerPitchRange < 0) { CSoundInput.Instance().iLowerPitchRange = 0; } } // If this is the highest Pitch heard so far if ((CSoundInput.Instance().fPitch > CSoundInput.Instance().iUpperPitchRange || CSoundInput.Instance().iUpperPitchRange <= 10) && CSoundInput.Instance().fPitch > 1.0f && miaPitchHits[iPitch] >= 10) { // Record this as the new highest Pitch CSoundInput.Instance().iUpperPitchRange = iPitch; // If the High Pitch isn't at least 10 Pitches louder than the low if ((CSoundInput.Instance().iUpperPitchRange - CSoundInput.Instance().iLowerPitchRange) < 10) { // Increase the High Pitch to 10 Pitches louder CSoundInput.Instance().iUpperPitchRange = CSoundInput.Instance().iLowerPitchRange + 10; // If the Pitch is too high if (CSoundInput.Instance().iUpperPitchRange > 130) { CSoundInput.Instance().iUpperPitchRange = 130; } } } } // Else we are not Detecting the Pitch else { // Draw the Pitch Meter mcPitchMeter.AutoDetectPitchAndUpdateMeter(); mcPitchMeter.Draw(cGraphics); } // Show the Current Pitch textCurrentPitch.Text = CSoundInput.Instance().fPitch.ToString(); // Show the High and Low Pitch Values numericHighPitch.Value = CSoundInput.Instance().iUpperPitchRange; numericLowPitch.Value = CSoundInput.Instance().iLowerPitchRange; }
// Update the Ball and Paddle private void UpdateGameObjects(float fTimeSinceLastUpdateInSeconds, Graphics cBackBuffer) { // Temp local variables int iBallXDistanceTravelled = 0; // How far the Ball has moved in the X direction int iBallYDistanceTravelled = 0; // How far the Ball has moved in the Y direction Rectangle rBallOldPosition = mrBall; // Rectangle used to test Ball against collisions Rectangle rBallCollisionRect; // Rectangle used to test Ball against collisions // Move the Pitch Meter according to any Input Pitch mcPitchMeter.AutoDetectPitchAndUpdateMeter(); // If some Pitch Input was received if (CSoundInput.Instance().bInputReceived) { // Calculate what Percent of force should be used to move the Paddle float fPercentToMove = mcPitchMeter.mfPitchIndicatorUnitPosition - 0.5f; fPercentToMove *= 2.0f; // Calculate how many pixels to move the Paddle float fAmountToMove = fPercentToMove * (-miPADDLE_MAX_SPEED_PER_SECOND * fTimeSinceLastUpdateInSeconds); // Move the Paddle mrPaddle.Y += (int)fAmountToMove; } // Calculate how far the Ball should move iBallXDistanceTravelled = (int)(mcBallDirection.X * fTimeSinceLastUpdateInSeconds); iBallYDistanceTravelled = (int)(mcBallDirection.Y * fTimeSinceLastUpdateInSeconds); // Move the Ball mrBall.X += iBallXDistanceTravelled; mrBall.Y += iBallYDistanceTravelled; // Test for collision between the Ball and the Walls // Rectangle to use to test collisions against the Ball rBallCollisionRect = mrBall; // If the Ball has travelled further than it's width or height in the last frame if (Math.Abs(iBallXDistanceTravelled) >= mrBall.Width || Math.Abs(iBallYDistanceTravelled) >= mrBall.Height) { // If the Ball is moving right if (iBallXDistanceTravelled > 0) { // If the Ball is moving down if (iBallYDistanceTravelled > 0) { rBallCollisionRect.Location = rBallOldPosition.Location; rBallCollisionRect.Width = mrBall.Right - rBallOldPosition.Left; rBallCollisionRect.Height = mrBall.Bottom - rBallOldPosition.Top; } // Else the Ball is moving up else { rBallCollisionRect.X = rBallOldPosition.X; rBallCollisionRect.Y = mrBall.Top; rBallCollisionRect.Width = mrBall.Right - rBallOldPosition.Left; rBallCollisionRect.Height = rBallOldPosition.Bottom - mrBall.Top; } } // Else the Ball is moving left else { // If the Ball is moving down if (iBallYDistanceTravelled > 0) { rBallCollisionRect.X = mrBall.Left; rBallCollisionRect.Y = rBallOldPosition.Top; rBallCollisionRect.Width = rBallOldPosition.Right - mrBall.Left; rBallCollisionRect.Height = mrBall.Bottom - rBallOldPosition.Top; } // Else the Ball is moving up else { rBallCollisionRect.Location = mrBall.Location; rBallCollisionRect.Width = rBallOldPosition.Right - mrBall.Left; rBallCollisionRect.Height = rBallOldPosition.Bottom - mrBall.Top; } } } // If the Ball hit the Top Wall if (rBallCollisionRect.IntersectsWith(mrTopWall)) { // Reverse it's Y direction mcBallDirection.Y = -mcBallDirection.Y; // Place it to be hitting the Wall (not in the Wall) mrBall.Y = mrTopWall.Bottom; // Play Sound CFMOD.PlaySound(msSoundBallBounce, false); } // If the Ball hit the Bottom Wall else if (rBallCollisionRect.IntersectsWith(mrBottomWall)) { // Reverse it's Y direction mcBallDirection.Y = -mcBallDirection.Y; // Place it to be hitting the Wall (not in the Wall) mrBall.Y = mrBottomWall.Top - mrBall.Height; // Play Sound CFMOD.PlaySound(msSoundBallBounce, false); } // If the Ball hit the Right wall if (rBallCollisionRect.IntersectsWith(mrRightWall)) { // Reverse it's X direction mcBallDirection.X = -mcBallDirection.X; // Place it to be hitting the Wall (not in the Wall) mrBall.X = mrRightWall.Left - mrBall.Width; // Play Sound CFMOD.PlaySound(msSoundBallBounce, false); } // Test for collision between the Ball and the Paddle // NOTE: Test for collision between Paddle before left wall incase ball is // travelling too fast and would pass through both if (rBallCollisionRect.IntersectsWith(mrPaddle)) { // Increase the Balls speed slightly float fSpeed = mcBallDirection.Length(); fSpeed += miBALL_SPEED_INCREMENT; // Make sure Ball does not go too fast if (fSpeed > miBALL_MAX_SPEED) { fSpeed = miBALL_MAX_SPEED; } // Reverse the Balls X direction mcBallDirection.X = -mcBallDirection.X; // Add some randomness to the Balls Y direction float fRandomness = mcRandom.Next(-25, 25); fRandomness /= 100.0f; mcBallDirection.Normalize(); mcBallDirection.Y += fRandomness; // Set the Balls speed mcBallDirection.Normalize(); mcBallDirection.Scale(fSpeed); // Place the Ball on the Paddle (not inside it) mrBall.X = mrPaddle.Right; // Play Sound CFMOD.PlaySound(msSoundBallBounce, false); } // Else if the Ball hit the Left wall else if (rBallCollisionRect.IntersectsWith(mrLeftWall)) { // Player loses a life miLives--; // If the Player is dead if (miLives == 0) { // Save the Players Score int iScore = miScore; // Restart the Game Reset(); // Restore the Players Score miScore = iScore; // Play Game Over sound CFMOD.PlaySound(msSoundGameOver, false); // Check if the Player has beat their High Score if (CProfiles.Instance().mcCurrentProfile.iScoreSpong < miScore) { // Save the Players new High Score CProfiles.Instance().mcCurrentProfile.iScoreSpong = miScore; CProfiles.Instance().SaveProfilesToFile(); } // Exit this function so the Game restarts now return; } // Play sound of losing a Ball CFMOD.PlaySound(msSoundBallDied, false); // Reset the Balls position and direction ResetBall(); // Reset the Next Ball Wait Timer mfNextBallWaitTime = 0.0f; // Enter the Wait For Next Ball state mePongState = EPongGameStates.WaitForNextBall; } // Update the Players Score miScore += (int)(fTimeSinceLastUpdateInSeconds * 1000.0f); }