Advertisement
SuperLemrick

StarRacer

Jun 9th, 2015
303
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 36.19 KB | None | 0 0
  1. ////////////////////////////////////////////////////////////////
  2. // Copyright 2013, CompuScholar, Inc.
  3. //
  4. // This source code is for use by the students and teachers who
  5. // have purchased the corresponding TeenCoder or KidCoder product.
  6. // It may not be transmitted to other parties for any reason
  7. // without the written consent of CompuScholar, Inc.
  8. // This source is provided as-is for educational purposes only.
  9. // CompuScholar, Inc. makes no warranty and assumes
  10. // no liability regarding the functionality of this program.
  11. //
  12. ////////////////////////////////////////////////////////////////
  13.  
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Linq;
  17. using Microsoft.Xna.Framework;
  18. using Microsoft.Xna.Framework.Audio;
  19. using Microsoft.Xna.Framework.Content;
  20. using Microsoft.Xna.Framework.GamerServices;
  21. using Microsoft.Xna.Framework.Graphics;
  22. using Microsoft.Xna.Framework.Input;
  23. using Microsoft.Xna.Framework.Media;
  24. using Microsoft.Xna.Framework.Net;
  25. using Microsoft.Xna.Framework.Storage;
  26. using SpriteLibrary;
  27.  
  28.  
  29. namespace StarRacer
  30. {
  31.     // This utility class represents one camera's view.
  32.     // It is provided fully complete as part of the activity starter.
  33.  
  34.     // NOTE:  Although we build the Camera class for general-purpose
  35.     // panning in world X and Y coordinates, we will only use the Y
  36.     // coordinates for this game since we are scrolling vertically!
  37.     // You may wish to use the Camera class in other games.
  38.     class Camera
  39.     {
  40.         // the position of the upper-left coordinate of the camera
  41.         public Vector2 UpperLeft = new Vector2();
  42.        
  43.         // these members are used to keep the camera view within
  44.         // valid world coordinates
  45.         public int ViewWidth = 0;
  46.         public int ViewHeight = 0;
  47.         public int WorldWidth = 0;
  48.         public int WorldHeight = 0;
  49.        
  50.         // this method will prevent the camera's display from straying
  51.         // outside the bounds of world coordinates
  52.         public void LockCamera()
  53.         {
  54.             if (UpperLeft.X < 0)
  55.                 UpperLeft.X = 0;
  56.             if ((UpperLeft.X + ViewWidth) > WorldWidth)
  57.                 UpperLeft.X = WorldWidth - ViewWidth;
  58.  
  59.             if (UpperLeft.Y < 0)
  60.                 UpperLeft.Y = 0;
  61.             if ((UpperLeft.Y + ViewHeight) > WorldHeight)
  62.                 UpperLeft.Y = WorldHeight - ViewHeight;
  63.         }
  64.  
  65.         // this utility method will return true if the specified object is at all
  66.         // visible within the camera view
  67.         public bool IsVisible(Vector2 objectUpperLeft, int objectWidth, int objectHeight)
  68.         {
  69.             // all coordinates are in world coordinates
  70.             Rectangle cameraRect = new Rectangle((int)UpperLeft.X, (int)UpperLeft.Y, ViewWidth, ViewHeight);
  71.             Rectangle objectRect = new Rectangle((int)objectUpperLeft.X, (int)objectUpperLeft.Y, objectWidth, objectHeight);
  72.  
  73.             return cameraRect.Intersects(objectRect);
  74.         }
  75.  
  76.     }
  77.  
  78.     /// <summary>
  79.     /// This is the main type for your game
  80.     /// </summary>
  81.     ///
  82.     public class StarRacer : Microsoft.Xna.Framework.Game
  83.     {
  84.         // all memeber variables are provided complete as part of the activity starter.
  85.         GraphicsDeviceManager graphics;
  86.         SpriteBatch spriteBatch;
  87.  
  88.         // declare textures to hold all images used in the game
  89.         Texture2D asteroidBig1Texture;
  90.         Texture2D asteroidBig2Texture;
  91.         Texture2D asteroidMed1Texture;
  92.         Texture2D asteroidMed2Texture;
  93.         Texture2D asteroidSmall1Texture;
  94.         Texture2D asteroidSmall2Texture;
  95.         Texture2D finishLineTexture;
  96.         Texture2D gameOverlayTexture;
  97.         Texture2D starsBackground1Texture;
  98.         Texture2D starsBackground2Texture;
  99.         Texture2D starsBackground3Texture;
  100.         Texture2D starsBackground4Texture;
  101.         Texture2D starship1Texture;
  102.         Texture2D starship2Texture;
  103.  
  104.         // declare sprites for each player's star racer
  105.         Sprite StarShip1;
  106.         Sprite StarShip2;
  107.        
  108.         // declare lists to hold the asteroid sprites and the names of the asteroid images
  109.         LinkedList<Sprite> Asteroids = new LinkedList<Sprite>() ;
  110.  
  111.         // declare lists to hold the starfield background sprites and image names
  112.         LinkedList<Sprite> StarFields = new LinkedList<Sprite>() ;
  113.        
  114.         // declare sprites to hold the finish line and overlay images
  115.         Sprite finishLine = new Sprite();
  116.         Sprite overlay = new Sprite();
  117.  
  118.         // constant values to control the number of starfields, asteroids, rates of acceleration, etc
  119.         const int NUM_STARFIELDS = 20;
  120.         const int NUM_ASTERIODS = 50;
  121.         const double ACCELERATION_FACTOR = 0.25;
  122.         const int X_STEER_FACTOR = 5;
  123.         const int VIEWPORT_HEIGHT = 600;
  124.         const int VIEWPORT_WIDTH = 398;
  125.         const int WORLD_WIDTH = 398;
  126.         const int VIEW_PORT_SEPARATION = 4; // number of pixels between viewports
  127.         const int WORLD_HEIGHT = NUM_STARFIELDS * VIEWPORT_HEIGHT;
  128.  
  129.         Random randomNumGen = new Random(DateTime.Now.Millisecond);
  130.  
  131.         // this enumeration identifies the possible types of screens the user can see
  132.         enum GameScreen
  133.         {
  134.             TITLE = 0,
  135.             PAUSED = 1,
  136.             PLAYING = 2,
  137.             GAMEOVER = 3,
  138.             OPTIONS = 4
  139.         }
  140.  
  141.         // which screen are we currently looking at?
  142.         GameScreen currentScreen;
  143.  
  144.         // this flag is true if the game AI is controlling player 2
  145.         bool isGameAIEnabled = false;
  146.  
  147.         // previous keyboard state
  148.         KeyboardState oldKeyboardState;
  149.  
  150.         // previous gamepad states
  151.         GamePadState oldGamePadState1;
  152.         GamePadState oldGamePadState2;
  153.  
  154.         // declare viewports for player1, and player2
  155.         Viewport leftViewport;
  156.         Viewport rightViewport;
  157.  
  158.         // declare cameras to track player 1 and player 2
  159.         Camera player1Camera;
  160.         Camera player2Camera;
  161.  
  162.         // declare font for displaying messages
  163.         SpriteFont gameFont;
  164.  
  165.         // this string will hold the "player X wins" message
  166.         String gameOverMessage;
  167.  
  168.         // This method is provided fully complete as part of the activity starter.
  169.         public StarRacer()
  170.         {
  171.             graphics = new GraphicsDeviceManager(this);
  172.             Content.RootDirectory = "Content";
  173.         }
  174.  
  175.         /// <summary>
  176.         /// Allows the game to perform any initialization it needs to before starting to run.
  177.         /// This is where it can query for any required services and load any non-graphic
  178.         /// related content.  Calling base.Initialize will enumerate through any components
  179.         /// and initialize them as well.
  180.         /// </summary>
  181.         // This method is provided fully complete as part of the activity starter.
  182.         protected override void Initialize()
  183.         {
  184.             // make sure window is large enough for our VIEWPORT_HEIGHT and VIEWPORT_WIDTH
  185.             graphics.PreferredBackBufferWidth = VIEWPORT_WIDTH * 2 + VIEW_PORT_SEPARATION;
  186.             graphics.PreferredBackBufferHeight = VIEWPORT_HEIGHT;
  187.             graphics.IsFullScreen = false;
  188.             graphics.ApplyChanges();
  189.  
  190.             // call base initialize first to get LoadContent() called and make
  191.             // all textures available for sprite setup
  192.             base.Initialize();
  193.  
  194.             // create the Viewport and Camera for each player
  195.             initializeViews();
  196.  
  197.             // create the overlay sprite
  198.             overlay = new Sprite();
  199.             overlay.SetTexture(gameOverlayTexture);
  200.             overlay.UpperLeft = Vector2.Zero;
  201.  
  202.             // start with the title screen, of course
  203.             currentScreen = GameScreen.TITLE;
  204.  
  205.         }
  206.  
  207.         // The student should complete this method during an activity.
  208.         private void initializeViews()
  209.         {
  210.             leftViewport = new Viewport();
  211.             leftViewport.X = 0;
  212.             leftViewport.Y = 0;
  213.             leftViewport.Width = VIEWPORT_WIDTH;
  214.             leftViewport.Height = VIEWPORT_HEIGHT;
  215.  
  216.             player1Camera = new Camera();
  217.             player1Camera.ViewHeight = VIEWPORT_HEIGHT;
  218.             player1Camera.ViewWidth = VIEWPORT_WIDTH;
  219.             player1Camera.WorldHeight = WORLD_HEIGHT;
  220.             player1Camera.WorldWidth = WORLD_WIDTH;
  221.  
  222.             rightViewport = new Viewport();
  223.             rightViewport.X = VIEWPORT_WIDTH + 4;
  224.             rightViewport.Y = 0;
  225.             rightViewport.Width = VIEWPORT_WIDTH;
  226.             rightViewport.Height = VIEWPORT_HEIGHT;
  227.  
  228.             player2Camera = new Camera();
  229.             player2Camera.ViewHeight = VIEWPORT_HEIGHT;
  230.             player2Camera.ViewWidth = VIEWPORT_WIDTH;
  231.             player2Camera.WorldHeight = WORLD_HEIGHT;
  232.             player2Camera.WorldWidth = WORLD_WIDTH;
  233.         }
  234.  
  235.         // This method is provided fully complete as part of the activity starter.
  236.         private void startGame()
  237.         {
  238.             // create the starry background
  239.             initializeStarField();
  240.  
  241.             // create random asteroids
  242.             initializeAsteroids();
  243.  
  244.             // create star ships
  245.             initializeStarShips();
  246.  
  247.             // initialize the camera position based on the star ships
  248.             if (player1Camera != null)
  249.                 player1Camera.UpperLeft.Y = StarShip1.UpperLeft.Y - VIEWPORT_HEIGHT * 4 / 5;
  250.             if (player2Camera != null)
  251.                 player2Camera.UpperLeft.Y = StarShip2.UpperLeft.Y - VIEWPORT_HEIGHT * 4 / 5;
  252.  
  253.         }
  254.  
  255.         // This method is provided fully complete as part of the activity starter.
  256.         private void initializeStarShips()
  257.         {
  258.             // set up player one's spaceship
  259.             StarShip1 = new Sprite();
  260.             StarShip1.SetTexture(starship1Texture);
  261.             StarShip1.UpperLeft = new Vector2(VIEWPORT_WIDTH / 2 - StarShip1.GetWidth(), WORLD_HEIGHT - 150);
  262.             StarShip1.SetVelocity(0, 0);
  263.             StarShip1.MaxSpeed = 10;
  264.  
  265.             // set up player two's spaceship
  266.             StarShip2 = new Sprite();
  267.             StarShip2.SetTexture(starship2Texture);
  268.             StarShip2.UpperLeft = new Vector2(VIEWPORT_WIDTH / 2 + StarShip1.GetWidth(), WORLD_HEIGHT - 150);
  269.             StarShip2.SetVelocity(0, 0);
  270.             StarShip2.MaxSpeed = 10;
  271.         }
  272.  
  273.         // This method is provided fully complete as part of the activity starter.
  274.         private void initializeStarField()
  275.         {
  276.             //create linked list of star background textures we can pick randomly from
  277.             LinkedList<Texture2D> starTextures = new LinkedList<Texture2D>();
  278.             starTextures.AddLast(starsBackground1Texture);
  279.             starTextures.AddLast(starsBackground2Texture);
  280.             starTextures.AddLast(starsBackground3Texture);
  281.             starTextures.AddLast(starsBackground4Texture);
  282.                        
  283.             //generate random tiles for background
  284.             StarFields.Clear();
  285.  
  286.             // create starfields for background images
  287.             for (int i = 0; i < NUM_STARFIELDS; i++)
  288.             {
  289.                Sprite starField = new Sprite();
  290.  
  291.                 // position starfield below the previous one
  292.                starField.UpperLeft = new Vector2(0,i * VIEWPORT_HEIGHT);
  293.  
  294.                // choose random starfield tile image
  295.                int imageNum = randomNumGen.Next(0, starTextures.Count);
  296.                Texture2D texture = starTextures.ElementAt(imageNum);
  297.                starField.SetTexture(texture);
  298.                
  299.                // add to the StarField
  300.                StarFields.AddLast(starField);
  301.             }
  302.  
  303.             // Now add finish line tile
  304.             finishLine.SetTexture(finishLineTexture);
  305.             finishLine.UpperLeft = new Vector2(0, 30);  // position below the overlay!
  306.  
  307.         }
  308.  
  309.         // This method is provided fully complete as part of the activity starter.
  310.         void initializeAsteroids()
  311.         {
  312.             //create linked list of star background textures we can pick randomly from
  313.             LinkedList<Texture2D> asteroidTextures = new LinkedList<Texture2D>();
  314.             asteroidTextures.AddLast(asteroidBig1Texture);
  315.             asteroidTextures.AddLast(asteroidBig2Texture);
  316.             asteroidTextures.AddLast(asteroidMed1Texture);
  317.             asteroidTextures.AddLast(asteroidMed2Texture);
  318.             //asteroidTextures.AddLast(asteroidSmall1Texture);
  319.             //asteroidTextures.AddLast(asteroidSmall2Texture);
  320.  
  321.             // generate randomly sized asteroids with random location on the background
  322.             Asteroids.Clear();
  323.             for (int i = 0; i < NUM_ASTERIODS; i++)
  324.             {
  325.                 Sprite asteroid = new Sprite();
  326.                 asteroid.UpperLeft = new Vector2(randomNumGen.Next(0,WORLD_WIDTH), randomNumGen.Next (0, WORLD_HEIGHT));
  327.  
  328.                 // choose random asteroid image
  329.                 int imageNum = randomNumGen.Next(0, asteroidTextures.Count);
  330.                 Texture2D texture = asteroidTextures.ElementAt(imageNum);
  331.                 asteroid.SetTexture(texture);
  332.                
  333.                 // give asteroid random direction and speed
  334.                 int vX = randomNumGen.Next(-3, 4);  //set random x velocity
  335.                 int vY = randomNumGen.Next(-2, 3);  //set (slower) random y velocity
  336.                 asteroid.SetVelocity(vX,vY);
  337.  
  338.                 // add to Asteroids list
  339.                 Asteroids.AddLast(asteroid);
  340.             }
  341.         }
  342.         /// <summary>
  343.         /// LoadContent will be called once per game and is the place to load
  344.         /// all of your content.
  345.         /// </summary>
  346.         // This method is provided fully complete as part of the activity starter.
  347.         protected override void LoadContent()
  348.         {
  349.             // Create a new SpriteBatch, which can be used to draw textures.
  350.             spriteBatch = new SpriteBatch(GraphicsDevice);
  351.  
  352.             // laod the font for menus
  353.             gameFont = Content.Load<SpriteFont>("Miramo");
  354.  
  355.             // load all textures used in the game
  356.             asteroidBig1Texture = Content.Load<Texture2D>("Images\\asteroid_big1");
  357.             asteroidBig2Texture = Content.Load<Texture2D>("Images\\asteroid_big2");
  358.             asteroidMed1Texture = Content.Load<Texture2D>("Images\\asteroid_med1");
  359.             asteroidMed2Texture = Content.Load<Texture2D>("Images\\asteroid_med2");
  360.             asteroidSmall1Texture = Content.Load<Texture2D>("Images\\asteroid_small1");
  361.             asteroidSmall2Texture = Content.Load<Texture2D>("Images\\asteroid_small2");
  362.             finishLineTexture = Content.Load<Texture2D>("Images\\finishline");
  363.             gameOverlayTexture = Content.Load<Texture2D>("Images\\game_overlay");
  364.             starsBackground1Texture = Content.Load<Texture2D>("Images\\stars_background1");
  365.             starsBackground2Texture = Content.Load<Texture2D>("Images\\stars_background2");
  366.             starsBackground3Texture = Content.Load<Texture2D>("Images\\stars_background3");
  367.             starsBackground4Texture = Content.Load<Texture2D>("Images\\stars_background4");
  368.             starship1Texture = Content.Load<Texture2D>("Images\\starship");
  369.             starship2Texture = Content.Load<Texture2D>("Images\\starship2");
  370.  
  371.         }
  372.  
  373.         /// <summary>
  374.         /// UnloadContent will be called once per game and is the place to unload
  375.         /// all content.
  376.         /// </summary>
  377.         // This method is provided fully complete as part of the activity starter.
  378.         protected override void UnloadContent()
  379.         {
  380.             // TODO: Unload any non ContentManager content here
  381.         }
  382.  
  383.         /// <summary>
  384.         /// Allows the game to run logic such as updating the world,
  385.         /// checking for collisions, gathering input, and playing audio.
  386.         /// </summary>
  387.         /// <param name="gameTime">Provides a snapshot of timing values.</param>
  388.         // This method is provided fully complete as part of the activity starter.
  389.         protected override void Update(GameTime gameTime)
  390.         {
  391.  
  392.             // get the current keyboard state and make sure we have a previous one
  393.             KeyboardState currentKeyboard = Keyboard.GetState();
  394.             if (oldKeyboardState == null)
  395.                 oldKeyboardState = currentKeyboard;
  396.  
  397.             // get the current gamepad states and make sure we have previous ones
  398.             GamePadState currentGamePad1 = GamePad.GetState(PlayerIndex.One);
  399.             GamePadState currentGamePad2 = GamePad.GetState(PlayerIndex.Two);
  400.  
  401.             if (oldGamePadState1 == null)
  402.                 oldGamePadState1 = currentGamePad1;
  403.  
  404.             if (oldGamePadState2 == null)
  405.                 oldGamePadState2 = currentGamePad2;
  406.  
  407.  
  408.             // call the appropriate update method based on the current screen
  409.             switch (currentScreen)
  410.             {
  411.                 case GameScreen.TITLE:
  412.                     updateTitle(gameTime, currentKeyboard, currentGamePad1 , currentGamePad2);
  413.                     break;
  414.                 case GameScreen.OPTIONS:
  415.                     updateOptions(gameTime, currentKeyboard, currentGamePad1 , currentGamePad2);
  416.                     break;
  417.                 case GameScreen.PLAYING:
  418.                     updatePlaying(gameTime, currentKeyboard, currentGamePad1 , currentGamePad2);
  419.                     break;
  420.                 case GameScreen.PAUSED:
  421.                     updatePaused(gameTime, currentKeyboard, currentGamePad1, currentGamePad2);
  422.                     break;
  423.                 case GameScreen.GAMEOVER:
  424.                     updateGameOver(gameTime, currentKeyboard, currentGamePad1, currentGamePad2);
  425.                     break;
  426.             }
  427.  
  428.             // save our current keyboard state
  429.             oldKeyboardState = currentKeyboard;
  430.  
  431.             // save the current gamepad states
  432.             oldGamePadState1 = currentGamePad1;
  433.             oldGamePadState2 = currentGamePad2;
  434.  
  435.             base.Update(gameTime);
  436.         }
  437.  
  438.         // This method is provided fully complete as part of the activity starter.
  439.         private bool wasKeyPressed(Keys key, KeyboardState currentKeyboard)
  440.         {
  441.             if ((currentKeyboard.IsKeyUp(key) && oldKeyboardState.IsKeyDown(key)))
  442.                 return true;
  443.             else
  444.                 return false;
  445.         }
  446.  
  447.         // This method is provided fully complete as part of the activity starter.
  448.         private bool wasButtonAPressed(GamePadState currentGamePad1, GamePadState currentGamePad2)
  449.         {
  450.            
  451.             // if the A button was pressed on either the player1 gamepad or
  452.             // player 2 gamepad, return "true"
  453.             if ((currentGamePad1.Buttons.A == ButtonState.Released) &&
  454.                 (oldGamePadState1.Buttons.A == ButtonState.Pressed))
  455.                 return true;
  456.             else if ((currentGamePad2.Buttons.A == ButtonState.Released) &&
  457.                 (oldGamePadState2.Buttons.A == ButtonState.Pressed))
  458.                 return true;
  459.             else
  460.                 return false;
  461.  
  462.         }
  463.  
  464.         // This method is provided fully complete as part of the activity starter.
  465.         private bool wasButtonBPressed(GamePadState currentGamePad1, GamePadState currentGamePad2)
  466.         {
  467.            
  468.             // if the B button was pressed on either the player1 gamepad or
  469.             // player 2 gamepad, return "true"
  470.             if ((currentGamePad1.Buttons.B == ButtonState.Released) &&
  471.                 (oldGamePadState1.Buttons.B == ButtonState.Pressed))
  472.                 return true;
  473.             else if ((currentGamePad1.Buttons.B == ButtonState.Released) &&
  474.                 (oldGamePadState1.Buttons.B == ButtonState.Pressed))
  475.                 return true;
  476.             else
  477.                 return false;
  478.  
  479.         }
  480.  
  481.         // This method is provided fully complete as part of the activity starter.
  482.         private bool wasButtonStartPressed(GamePadState currentGamePad1, GamePadState currentGamePad2)
  483.         {
  484.             // if the Start button was pressed on either the player1 gamepad or
  485.             // player 2 gamepad, return "true"
  486.             if ((currentGamePad1.Buttons.Start == ButtonState.Released) &&
  487.                 (oldGamePadState1.Buttons.Start == ButtonState.Pressed))
  488.                 return true;
  489.             else if ((currentGamePad2.Buttons.Start == ButtonState.Released) &&
  490.                 (oldGamePadState2.Buttons.Start == ButtonState.Pressed))
  491.                 return true;
  492.             else
  493.                 return false;
  494.         }
  495.  
  496.         // This method is provided fully complete as part of the activity starter.
  497.         private bool wasButtonBackPressed(GamePadState currentGamePad1, GamePadState currentGamePad2)
  498.         {
  499.            
  500.             // if the Back button was pressed on either the player1 gamepad or
  501.             // player 2 gamepad, return "true"
  502.             if ((currentGamePad1.Buttons.Back == ButtonState.Released) &&
  503.                 (oldGamePadState1.Buttons.Back == ButtonState.Pressed))
  504.                 return true;
  505.             else if ((currentGamePad2.Buttons.Back == ButtonState.Released) &&
  506.                 (oldGamePadState2.Buttons.Back == ButtonState.Pressed))
  507.                 return true;
  508.             else
  509.                 return false;
  510.         }
  511.  
  512.         // This method is provided fully complete as part of the activity starter.
  513.         private void updateTitle(GameTime gameTime, KeyboardState currentKeyboard, GamePadState currentGamePad1, GamePadState currentGamePad2)
  514.         {
  515.             // if the space bar (or the gamepad Start button) was pressed from the title screen
  516.             if (wasKeyPressed(Keys.Space,currentKeyboard) || wasButtonStartPressed (currentGamePad1 , currentGamePad2 ))
  517.             {
  518.                 // move on to the options screen
  519.                 currentScreen = GameScreen.OPTIONS;
  520.             }
  521.         }
  522.  
  523.         // This method is provided fully complete as part of the activity starter.
  524.         private void updateOptions(GameTime gameTime, KeyboardState currentKeyboard, GamePadState currentGamePad1, GamePadState currentGamePad2)
  525.         {
  526.             // if the '1' key (or the gamepad A button) was pressed
  527.             if (wasKeyPressed(Keys.D1, currentKeyboard) || wasButtonAPressed (currentGamePad1 , currentGamePad2 ))
  528.             {
  529.                 // start a one-player game
  530.                 isGameAIEnabled = true;
  531.                 startGame();
  532.                 currentScreen = GameScreen.PAUSED;
  533.             }
  534.  
  535.             // if the '2' key (or the gamepad B button)was pressed
  536.             if (wasKeyPressed(Keys.D2, currentKeyboard) || wasButtonBPressed (currentGamePad1 , currentGamePad2 ))
  537.             {
  538.                 // start a two-player game
  539.                 isGameAIEnabled = false;
  540.                 startGame();
  541.                 currentScreen = GameScreen.PAUSED;
  542.             }
  543.  
  544.             // if the 'Escape' key (or the gamepad Back button) was pressed
  545.             if (wasKeyPressed(Keys.Escape, currentKeyboard) || wasButtonBackPressed(currentGamePad1 , currentGamePad2 ))
  546.             {
  547.                 Exit();
  548.             }
  549.         }
  550.        
  551.         // This method is provided fully complete as part of the activity starter.
  552.         private void updatePlaying(GameTime gameTime, KeyboardState currentKeyboard, GamePadState currentGamePad1, GamePadState currentGamePad2)
  553.         {
  554.             // Escape key (or gamepad Start button)pauses the game when playing
  555.             if (wasKeyPressed(Keys.Escape, currentKeyboard) || wasButtonStartPressed(currentGamePad1 , currentGamePad2 ))
  556.             {
  557.                 currentScreen = GameScreen.PAUSED;
  558.                 return; // don't do anything else if we're now paused!
  559.             }
  560.  
  561.             // check player 1 keys
  562.             if (currentKeyboard.IsKeyDown(Keys.W) || (currentGamePad1.ThumbSticks.Left.Y > 0))
  563.             {
  564.                 // 'W' (or gamepad thumbstick up) means accelerate up
  565.                 StarShip1.Accelerate(0, -ACCELERATION_FACTOR);
  566.             }
  567.  
  568.             if (currentKeyboard.IsKeyDown(Keys.A) || (currentGamePad1.ThumbSticks.Left.X < 0))
  569.             {
  570.                 // 'A' (or gamepad thumbstick left) means move a bit to the left
  571.                 StarShip1.UpperLeft.X -= X_STEER_FACTOR;
  572.                 if (StarShip1.UpperLeft.X < 0)
  573.                     StarShip1.UpperLeft.X = 0;
  574.             }
  575.  
  576.             if (currentKeyboard.IsKeyDown(Keys.D) || (currentGamePad1.ThumbSticks.Left.X > 0))
  577.             {
  578.                 // 'D' (or gamepad thumbstick right) means move a bit to the right
  579.                 StarShip1.UpperLeft.X += X_STEER_FACTOR;
  580.                 if (StarShip1.UpperLeft.X + StarShip1.GetWidth() > VIEWPORT_WIDTH)
  581.                     StarShip1.UpperLeft.X = VIEWPORT_WIDTH - StarShip1.GetWidth();
  582.            }
  583.  
  584.             if (currentKeyboard.IsKeyDown(Keys.X) || (currentGamePad1.ThumbSticks.Left.Y < 0))
  585.             {
  586.                 // 'X' (or gamepad thumbstick down) means slow down
  587.                 if (StarShip1.GetVelocity().Y < 0)
  588.                 {
  589.                     StarShip1.Accelerate(0, ACCELERATION_FACTOR);
  590.                 }
  591.             }
  592.  
  593.             // now check player2 input unless it's an AI-controlled player
  594.             if (!isGameAIEnabled)
  595.             {
  596.                 // check player 2 controls
  597.                 if (currentKeyboard.IsKeyDown(Keys.Up) || (currentGamePad2.ThumbSticks.Left.Y > 0))
  598.                 {
  599.                     // up arrow means accelerate up
  600.                     StarShip2.Accelerate(0, -ACCELERATION_FACTOR);
  601.                 }
  602.  
  603.                 if (currentKeyboard.IsKeyDown(Keys.Down) || (currentGamePad2.ThumbSticks.Left.Y < 0))
  604.                 {
  605.                     // down arrow means slow down
  606.                     if (StarShip2.GetVelocity().Y < 0)
  607.                     {
  608.                         StarShip2.Accelerate(0, ACCELERATION_FACTOR);
  609.                     }
  610.                 }
  611.  
  612.                 if (currentKeyboard.IsKeyDown(Keys.Left) || (currentGamePad2.ThumbSticks.Left.X < 0))
  613.                 {
  614.                     // left arrow means move a bit to the left
  615.                     StarShip2.UpperLeft.X -= X_STEER_FACTOR;
  616.                     if (StarShip2.UpperLeft.X < 0)
  617.                         StarShip2.UpperLeft.X = 0;
  618.                 }
  619.  
  620.                 if (currentKeyboard.IsKeyDown(Keys.Right) || (currentGamePad2.ThumbSticks.Left.X > 0))
  621.                 {
  622.                     // right arrow means move a bit to the right
  623.                     StarShip2.UpperLeft.X += X_STEER_FACTOR;
  624.                     if (StarShip2.UpperLeft.X + StarShip2.GetWidth() > VIEWPORT_WIDTH)
  625.                         StarShip2.UpperLeft.X = VIEWPORT_WIDTH - StarShip2.GetWidth();
  626.                 }
  627.             }
  628.             else
  629.             {
  630.                 // call the AI routine to control the second space ship
  631.                 DoSimpleAI();
  632.             }
  633.            
  634.             // move both ships in the Y direction
  635.             // (X velocity we leave at zero so we can move strictly according to left/right keys above)
  636.             StarShip1.Move();
  637.             StarShip2.Move();
  638.  
  639.             // move the cameras along with the space ship, keeping ship 4/5 of the way down the screen
  640.             if (player1Camera != null)
  641.                 player1Camera.UpperLeft.Y = StarShip1.UpperLeft.Y - VIEWPORT_HEIGHT * 4 / 5;
  642.             if (player2Camera != null)
  643.                 player2Camera.UpperLeft.Y = StarShip2.UpperLeft.Y - VIEWPORT_HEIGHT * 4 / 5;
  644.            
  645.             // make sure camera remains within valid world coordinates near the finish line!
  646.             if (player1Camera != null)
  647.                 player1Camera.LockCamera();
  648.             if (player2Camera != null)
  649.                 player2Camera.LockCamera();
  650.  
  651.             // move all the asteroids, allowing them to wrap around the screen.
  652.             // not realistic, but to the player it might as well be a new asteroid!
  653.             foreach (Sprite asteroid in Asteroids)
  654.             {
  655.                 asteroid.MoveAndWrap(WORLD_WIDTH, WORLD_HEIGHT);
  656.             }
  657.  
  658.             // see if any asteroids have hit a ship
  659.             checkCollisions();
  660.  
  661.             // check to see if anyone has won
  662.             if (StarShip1.UpperLeft.Y <= (finishLine.UpperLeft.Y + finishLine.GetHeight()))
  663.             {
  664.                 currentScreen = GameScreen.GAMEOVER;
  665.                 gameOverMessage = "Player 1 has won!";
  666.             }
  667.             if (StarShip2.UpperLeft.Y <= finishLine.GetHeight())
  668.             {
  669.                 currentScreen = GameScreen.GAMEOVER;
  670.                 gameOverMessage = "Player 2 has won!";
  671.             }
  672.         }
  673.        
  674.  
  675.         // This method is provided fully complete as part of the activity starter.
  676.         private void updatePaused(GameTime gameTime, KeyboardState currentKeyboard, GamePadState currentGamePad1, GamePadState currentGamePad2)
  677.         {
  678.             // the 'C' key (or the gamepad Start button) will continue the game from Paused state
  679.             if (wasKeyPressed(Keys.C, currentKeyboard) || wasButtonStartPressed (currentGamePad1, currentGamePad2 ))
  680.                 currentScreen = GameScreen.PLAYING;
  681.  
  682.         }
  683.  
  684.         // This method is provided fully complete as part of the activity starter.
  685.         private void updateGameOver(GameTime gameTime, KeyboardState currentKeyboard, GamePadState currentGamePad1, GamePadState currentGamePad2)
  686.         {
  687.             // the space bar (or the Back button on a gamepad) will move to the options screen after the game is over
  688.             if (wasKeyPressed(Keys.Space,currentKeyboard) || wasButtonBackPressed (currentGamePad1 , currentGamePad2 ))
  689.                 currentScreen = GameScreen.OPTIONS;
  690.         }
  691.  
  692.         // This method is provided fully complete as part of the activity starter.
  693.         private void checkCollisions()
  694.         {
  695.             // check each asteroid to see if it has hit either (or both!) ships
  696.             foreach (Sprite asteroid in Asteroids)
  697.             {
  698.                 if (asteroid.IsCollided(StarShip1 ))
  699.                 {
  700.                     StarShip1.SetVelocity(0, 0);    // set ship 1's velocity to 0
  701.                 }
  702.  
  703.                 if (asteroid.IsCollided(StarShip2))
  704.                 {
  705.                     StarShip2.SetVelocity(0, 0);    // set ship 2's velocity to 0
  706.                 }
  707.  
  708.             }
  709.         }
  710.  
  711.         /// <summary>
  712.         /// This is called when the game should draw itself.
  713.         /// </summary>
  714.         /// <param name="gameTime">Provides a snapshot of timing values.</param>
  715.         // This method is provided fully complete as part of the activity starter.
  716.         protected override void Draw(GameTime gameTime)
  717.         {
  718.             // save viewport that covers the entire screen for later use
  719.             Viewport original = graphics.GraphicsDevice.Viewport;
  720.  
  721.             if (currentScreen == GameScreen.TITLE )
  722.             {
  723.                 drawTitle();
  724.             }
  725.             else if (currentScreen == GameScreen.OPTIONS )
  726.             {
  727.                 drawOptions();
  728.             }
  729.             else
  730.             {
  731.                 // draw the playing surface for all other screens
  732.                 // (makes a nice background during pause and gameover!)
  733.                 drawPlaying(original);
  734.             }
  735.  
  736.             // ensure viewport covers the whole screen for the next two screens
  737.             GraphicsDevice.Viewport = original;
  738.  
  739.             if (currentScreen == GameScreen.PAUSED )
  740.                 drawPausedMenu();
  741.  
  742.             if (currentScreen == GameScreen.GAMEOVER)
  743.                 drawGameOver();
  744.  
  745.             base.Draw(gameTime);
  746.         }
  747.  
  748.         // This method is provided fully complete as part of the activity starter.
  749.         private void drawPlaying(Viewport fullScreen)
  750.         {
  751.             // wipe out whatever was there before
  752.             GraphicsDevice.Clear(Color.Black);
  753.  
  754.             // draw left and right viewport
  755.             drawPlayerViewport(leftViewport, player1Camera);
  756.             drawPlayerViewport(rightViewport, player2Camera);
  757.  
  758.             // draw the overlay
  759.             GraphicsDevice.Viewport = fullScreen;
  760.             spriteBatch.Begin();
  761.             overlay.Draw(spriteBatch);
  762.             spriteBatch.End();
  763.  
  764.         }
  765.  
  766.         // The student will complete this method as part of an activity
  767.         private void drawPlayerViewport(Viewport currentViewport, Camera currentCamera)
  768.         {
  769.             graphics.GraphicsDevice.Viewport = currentViewport;
  770.             spriteBatch.Begin();
  771.  
  772.             DrawStarsAndAsteroids(currentCamera);
  773.  
  774.             if (currentCamera.IsVisible(StarShip1.UpperLeft, StarShip1.GetWidth(), StarShip1.GetHeight()))
  775.             {
  776.                 StarShip1.Draw(spriteBatch, currentCamera.UpperLeft);
  777.             }
  778.  
  779.             if (currentCamera.IsVisible(StarShip2.UpperLeft, StarShip2.GetWidth(), StarShip2.GetHeight()))
  780.             {
  781.                 StarShip2.Draw(spriteBatch, currentCamera.UpperLeft);
  782.             }
  783.  
  784.             spriteBatch.End();
  785.         }
  786.  
  787.         // This method is provided fully complete as part of the activity starter.
  788.         private void DrawStarsAndAsteroids(SpriteBatch spriteBatch, Camera currentCamera)
  789.         {
  790.             // Draw all starfields visible on the screen
  791.             foreach (Sprite starField in StarFields)
  792.             {
  793.                 if (currentCamera.IsVisible(starField.UpperLeft, starField.GetWidth(), starField.GetHeight()))
  794.                     starField.Draw(spriteBatch, currentCamera.UpperLeft);
  795.             }
  796.  
  797.             // Now add finish line tile if visible on the screen
  798.             if (currentCamera.IsVisible(finishLine.UpperLeft, finishLine.GetWidth(), finishLine.GetHeight()))
  799.                 finishLine.Draw(spriteBatch, currentCamera.UpperLeft);
  800.  
  801.             // Draw all asteroids visible on the screen
  802.             foreach (Sprite asteroid in Asteroids)
  803.             {
  804.                 if (currentCamera.IsVisible(asteroid.UpperLeft, asteroid.GetWidth(), asteroid.GetHeight()))
  805.                     asteroid.Draw(spriteBatch, currentCamera.UpperLeft);
  806.             }
  807.         }
  808.  
  809.         // This method is provided fully complete as part of the activity starter.
  810.         private void drawTitle()
  811.         {
  812.             GraphicsDevice.Clear(Color.DarkBlue);
  813.             spriteBatch.Begin();
  814.             spriteBatch.DrawString(gameFont, "Star Racer - Press Spacebar (or Start) to Continue", new Vector2(50, 250), Color.White);
  815.             spriteBatch.End();
  816.         }
  817.  
  818.         // This method is provided fully complete as part of the activity starter.
  819.         private void drawOptions()
  820.         {
  821.             GraphicsDevice.Clear(Color.DarkBlue);
  822.             spriteBatch.Begin();
  823.             spriteBatch.DrawString(gameFont, "Press 1 (or A) for 1 Player", new Vector2(150, 200), Color.White);
  824.             spriteBatch.DrawString(gameFont, "Press 2 (or B) for 2 Player", new Vector2(150, 250), Color.White);
  825.             spriteBatch.DrawString(gameFont, "Press Esc (or Back) to exit", new Vector2(150, 300), Color.White);
  826.             spriteBatch.End();
  827.         }
  828.  
  829.         // This method is provided fully complete as part of the activity starter.
  830.         private void drawPausedMenu()
  831.         {
  832.             spriteBatch.Begin();
  833.             spriteBatch.DrawString(gameFont, "Game Paused - Press C (or Start) to Continue", new Vector2(50, 250), Color.White);
  834.             spriteBatch.End();
  835.         }
  836.  
  837.         // This method is provided fully complete as part of the activity starter.
  838.         private void drawGameOver()
  839.         {
  840.             spriteBatch.Begin();
  841.             spriteBatch.DrawString(gameFont, gameOverMessage, new Vector2(200, 250), Color.White);
  842.             spriteBatch.DrawString(gameFont, "Press Spacebar (or Back) to Continue", new Vector2(200, 290), Color.White);
  843.             spriteBatch.End();
  844.         }
  845.  
  846.         // This method will be completed by the student in the artifical intelligence chapter
  847.         private void DoSimpleAI()
  848.         {
  849.  
  850.            
  851.             // run a better algorithm too, if present
  852.             DoBetterAI();
  853.         }
  854.  
  855.         // This method will be completed by the student in the artifical intelligence chapter
  856.         private void DoBetterAI()
  857.         {
  858.  
  859.         }
  860.  
  861.  
  862.     }
  863. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement