Finally! We have arrived to the final article! In this article we will tie everything together in the game class: Game1.cs. So let’s get right to it! As usual, we need private members to hold all the data. Here is where we need to reference the classes we have created.
1 2 3 4 5 6 7 8 9 10 11 12 13 | GraphicsDeviceManager graphics; ContentManager content; Paddle player1, player2; Background background; Ball ball1; SpriteBatch spriteBatch; SpriteFont font; int player1Score = 0; int player2Score = 0; MainMenu mainMenu; |
The main guts of pulling this all together is to create instances of all the private members and set their options. This is done in the constructor of the Game class. Be sure to add each item to the Component’s collection at the end!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | public Game1 () { graphics = new GraphicsDeviceManager ( this ); content = new ContentManager ( Services ); // Instantiate our Main Menu and setup event listeners. // This will allow us to know what mode the user wants. mainMenu = new MainMenu ( this ); mainMenu.QuitSelected += OnQuitSelected; mainMenu.EasySelected += new EventHandler ( OnEasySelected ); mainMenu.MediumSelected += new EventHandler ( OnMediumSelected ); mainMenu.HardSelected += new EventHandler ( OnHardSelected ); mainMenu.TwoPlayerSelected += new EventHandler ( OnTwoPlayerSelected ); // Setup player one, this is controlled by the arrow keys. player1 = new Paddle ( this ); player1.Y = 250; player1.TextureSource = @"Content\Textures\Paddle"; player1.Color = Color.GreenYellow; player1.DownKey = Keys.Down; player1.UpKey = Keys.Up; player1.Visible = false; player1.Enabled = false; // Setup player two, this paddle is controlled by S and W. player2 = new Paddle ( this ); player2.X = 768; player2.Y = 250; player2.TextureSource = @"Content\Textures\Paddle"; player2.Color = Color.Plum; player2.DownKey = Keys.S; player2.UpKey = Keys.W; player2.IsAI = true; player2.Enabled = false; player2.Visible = false; // Instantiate the ball and put it in the center. ball1 = new Ball ( this ); ball1.X = 384; ball1.Y = 284; ball1.TextureSource = @"Content\Textures\Ball"; ball1.Color = Color.Ivory; ball1.Enabled = false; ball1.Visible = false; // Give each player a reference to the ball // so they can do collision detection. player1.Ball = ball1; player2.Ball = ball1; // Instantiate the background background = new Background ( this ); background.TextureSource = @"Content\Textures\Background"; // Add all of our components to the list // so they update and draw automatically. Components.Add ( mainMenu ); Components.Add ( ball1 ); Components.Add ( player1 ); Components.Add ( player2 ); Components.Add ( background ); // Set our title! Window.Title = "Focused Games - Mini Game Series: Pong"; } |
In this next section, we are going to handle when users select options. This part is where the game is started and difficulty options are set so feel free to change them to make it easier on yourself.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | #region Main Menu Event Handlers /// <summary> /// Handles when the player selects the two player option in the main menu. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnTwoPlayerSelected (object sender, EventArgs e) { mainMenu.Enabled = false; mainMenu.Visible = false; // Gives the players some more speed. player1.Speed = 6f; player2.Speed = 6f; // Enables the player to control // the second paddle. player2.IsAI = false; ball1.Enabled = true; ball1.Visible = true; player1.Enabled = true; player1.Visible = true; player2.Enabled = true; player2.Visible = true; } /// <summary> /// Handles when the player selects the hard option in the main menu. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnHardSelected (object sender, EventArgs e) { mainMenu.Enabled = false; mainMenu.Visible = false; // Gives player 2 (the AI) more speed and the user // less speed. player1.Speed = 5f; player2.Speed = 10f; // Gives the computer the first move. ball1.VelocityX = 1; // Makes it so the computer will return to // the center after hitting the paddle. player2.ReCenter = true; ball1.Enabled = true; ball1.Visible = true; player1.Enabled = true; player1.Visible = true; player2.Enabled = true; player2.Visible = true; } /// <summary> /// Handles when the medium option is selected in the main menu. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnMediumSelected (object sender, EventArgs e) { mainMenu.Enabled = false; mainMenu.Visible = false; // Gives the AI a little more speed than the user. player1.Speed = 5f; player2.Speed = 5.5f; ball1.Enabled = true; ball1.Visible = true; player1.Enabled = true; player1.Visible = true; player2.Enabled = true; player2.Visible = true; } /// <summary> /// Handles when the player selects the easy option in the menu. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnEasySelected (object sender, EventArgs e) { mainMenu.Enabled = false; mainMenu.Visible = false; // Gives the user a lot more speed than the AI. player1.Speed = 5f; player2.Speed = 3f; ball1.Enabled = true; ball1.Visible = true; player1.Enabled = true; player1.Visible = true; player2.Enabled = true; player2.Visible = true; } /// <summary> /// Handles when the player wants to quit. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnQuitSelected (object sender, EventArgs e) { this.Exit (); } /// <summary> /// Resets the game back to the menu state. /// </summary> private void ResetMenu () { mainMenu.Enabled = true; mainMenu.Visible = true; ball1.Enabled = false; ball1.Visible = false; player1.Enabled = false; player1.Visible = false; player2.Enabled = false; player2.Visible = false; player1Score = 0; player2Score = 0; } #endregion |
Now we need to load some content for drawing later on!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | protected override void LoadGraphicsContent (bool loadAllContent) { if ( loadAllContent ) { // TODO: Load any ResourceManagementMode.Automatic content spriteBatch = new SpriteBatch ( graphics.GraphicsDevice ); font = content.Load<SpriteFont> ( @"Content\Fonts\LargeFont" ); } // TODO: Load any ResourceManagementMode.Manual content } protected override void UnloadGraphicsContent (bool unloadAllContent) { if ( unloadAllContent ) { // TODO: Unload any ResourceManagementMode.Automatic content content.Unload (); if ( font != null ) font = null; if ( spriteBatch != null ) { spriteBatch.Dispose (); spriteBatch = null; } } // TODO: Unload any ResourceManagementMode.Manual content } |
The next thing to do is handle updates, making sure that the score is increased for the correct player when the ball goes past the other player’s paddle. We also handle when the player hits Escape to bring back the menu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | protected override void Update (GameTime gameTime) { // If the ball has gone past the player's paddle, score for the // second paddle, and reset positions. if ( ball1.Destination.Right < player1.Destination.Left ) { player2Score++; player1.Y = 250; player2.Y = 250; ball1.VelocityY = 0; ball1.VelocityX = 1; ball1.Speed = 2.5f; ball1.X = 384; ball1.Y = 284; } // If the ball has gone past the computer's paddle, score for the // first paddle, and reset positions. else if ( ball1.Destination.Left > player2.Destination.Right ) { player1Score++; player1.Y = 250; player2.Y = 250; ball1.VelocityY = 0; ball1.VelocityX = -1; ball1.Speed = 2.5f; ball1.X = 384; ball1.Y = 284; } // If the user hits the escape key, go back to the menu if ( Keyboard.GetState ().IsKeyDown ( Keys.Escape ) ) ResetMenu (); base.Update ( gameTime ); } |
And the last thing we need to draw is handle drawing the scores when the menu isn’t being drawn. After this you should have a running game! If you are having problems, I suggest you look at the MGS: Pong Source v1.0 (1099).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | protected override void Draw (GameTime gameTime) { graphics.GraphicsDevice.Clear ( Color.CornflowerBlue ); base.Draw ( gameTime ); // If the menu isn't enabled, // draw each player's score. if ( !mainMenu.Enabled ) { Vector2 measure = font.MeasureString ( player2Score.ToString () ); spriteBatch.Begin (); spriteBatch.DrawString ( font, player1Score.ToString (), new Vector2 ( 40, 0 ), Color.White ); spriteBatch.DrawString ( font, player2Score.ToString (), new Vector2 ( 760 - measure.X, 0 ), Color.White ); spriteBatch.End (); } } |