//returns true if the missile has left the bounds of the canvas public static bool LeavingScreen(Missile msl) { return (msl.Where().X > Missile.canvas.ScaledWidth || msl.Where().X < 0); }
//predicates //returns true if missiles have faded away public static bool MissileDone(Missile msl) { return msl._mslAlpha <= 0; }
//Occurs each timer tick(30ms), moves, evalutes, and draws each missile. Adjusting difficulty //as the game progresses. Displays some informative text to the user on the canvas. private void timer1_Tick(object sender, EventArgs e) { //functionality for Marathon Game Mode if (radioButtonMarathon.Checked) { //every 100 difficulty ticks, gives each cannon more ammo, and increases //our static Missile Difficulty if (difficultyCounter % 100 == 0) { foreach (Missile msl in cannonList) msl.Ammo += (int)(Missile.Difficulty / 10) - 2; Missile.Difficulty += 2; difficultyCounter = 0; } //adds an enemy missile if enemy count is less than a value that scales with the //difficulty. With a 1 in 20 chance to add a missile per tick. if (foesList.Count < Missile.Difficulty / 5 && rnd.Next(1, 20) == 1) foesList.Add(new Missile()); } //functionality for Classic Game Mode if (radioButtonClassic.Checked) { //adds an enemy missile if the enemy count is less than the current levels //total enemy value. With a 1 in 20 chance to add a missile per tick. if (cmFoeCount < cmFoeTotal && rnd.Next(1, 20) == 1) { foesList.Add(new Missile()); cmFoeCount++; } //enough enemies have been destroyed, start a new round else if (cmFoeCount == cmFoeTotal && foesList.Count == 0) NewRound(); } //adds a new friendly missile if the user has left clicked on the CDrawer if (Missile.Canvas.GetLastMouseLeftClickScaled(out pollMouseLocation)) { //the method for determining the closest available cannon returns (0,0) if no //cannons are available. So only add a missile if the start point is not (0,0). Missile m = new Missile(pollMouseLocation, cannonList); if (m.StartLocation.X != 0 && m.StartLocation.Y != 0) { friendsList.Add(m); friendsLaunched++; } } //perfoms a move operation on each missile in both friend & foe lists foreach (Missile msl in friendsList) msl.Move(); foreach (Missile msl in foesList) msl.Move(); //removes all missiles that evaluate to true, via our predicates //from both friend & and foe lists friendsList.RemoveAll(Missile.MissileDone); friendsList.RemoveAll(Missile.LeavingScreen); foesList.RemoveAll(Missile.MissileDone); foesList.RemoveAll(Missile.LeavingScreen); //set friendly missiles to exploding if they are overlapping with a foe missile collided = friendsList.Intersect(foesList).ToList(); foreach (Missile msl in collided) msl.exploding = true; //set foe missiles to exploding if they are overlapping with a friendly missile collided = foesList.Intersect(friendsList).ToList(); foreach (Missile msl in collided) { msl.exploding = true; foesDestroyed++; } //remove cities that have been hit by enemy missiles collided = cityList.Intersect(foesList).ToList(); foreach (Missile msl in collided) while (cityList.Remove(msl)); //set cannons to exploding if they have been hit by enemy missiles collided = cannonList.Intersect(foesList).ToList(); foreach (Missile msl in collided) msl.exploding = true; //clears our CDrawer Missile.Loading = true; //render each missile object in all of our missile lists foreach (Missile msl in friendsList) msl.Render(); foreach (Missile msl in foesList) msl.Render(); foreach (Missile c in cityList) c.RenderCity(); //get the current mouse location before rendering the cannons Missile.Canvas.GetLastMousePositionScaled(out pollMouseLocation); foreach (Missile c in cannonList) c.RenderCannon(pollMouseLocation); //updates the Score and Difficulty text each tick Missile.Canvas.AddText("Score: " + (foesDestroyed * 100 + score), 15, 10, 530, 250, 100, Color.Black); Missile.Canvas.AddText("Diffuculty: " + Missile.DiffucultyString(), 15, 500, 530, 250, 100, Color.Black); //renders our CDrawer Missile.Loading = false; //updates the score text on the main form lblTotalEnemies.Text = foesList.Count.ToString(); lblEnemiesDestroyed.Text = foesDestroyed.ToString(); lblMisslesFired.Text = friendsLaunched.ToString(); if (friendsLaunched != 0) lblKillPerShot.Text = (Math.Round(foesDestroyed / friendsLaunched, 2)).ToString(); //used to set the Missile's static Difficulty after so many ticks difficultyCounter++; //the user has run out of cities and the game must end if (cityList.Count <= 0) { //ends the current game and starts timer2 for a little end game animation difficultyCounter = 2; Missile.Loading = true; timer2.Enabled = true; timer1.Enabled = false; } }