Publicado por: Carlos domingo, marzo 06, 2011

Muy simple y solo como ejemplo de la primera aplicación que hice.

Crear el proyecto

NewProject

Crear los sprites con los que se jugara, muy simples ya que solo están como ejemplo:

Sprites

Crear la clase que manejara a los jugadores: Paddle

  1. /// <summary>
  2. /// Creata una paleta
  3. /// </summary>
  4. class Paddle
  5. {
  6.     /// <summary>
  7.     /// Variable con la posicion
  8.     /// </summary>
  9.     public Point pos;
  10.  
  11.     /// <summary>
  12.     /// Velocidad de la paleta
  13.     /// </summary>
  14.     public int speed;
  15.  
  16.     /// <summary>
  17.     /// Constructor
  18.     /// </summary>
  19.     /// <param name="x"></param>
  20.     /// <param name="y"></param>
  21.     public Paddle(int x, int y)
  22.     {
  23.         /// La paleta inicia en la posicion que se le pase al constructor
  24.         pos = new Point(x, y);
  25.         /// Velocidad por defecto
  26.         speed = 3;
  27.     }
  28. }

Crear la clase que maneja el objeto : Ball

  1. /// <summary>
  2. /// Creaa un objeto con la pelota
  3. /// </summary>
  4. class Ball
  5. {
  6.     /// <summary>
  7.     /// Posicion de la pelota
  8.     /// </summary>
  9.     public Point pos;
  10.     /// <summary>
  11.     /// Velocidad horizontal y vertical
  12.     /// </summary>
  13.     public int h_speed, v_speed;
  14.  
  15.     /// <summary>
  16.     /// Constructor
  17.     /// </summary>
  18.     /// <param name="x"></param>
  19.     /// <param name="y"></param>
  20.     public Ball(int x, int y)
  21.     {
  22.         /// La posicion inicial de la pelota se le pasa al constructor
  23.         pos = new Point(x, y);
  24.         /// La velocidad inicial y la direccion es randomica
  25.         Random rand = new Random();
  26.         h_speed = rand.Next(3, 7);
  27.         if (rand.Next(0, 2) == 0) h_speed *= -1;
  28.         rand = new Random();
  29.         v_speed = rand.Next(3, 7);
  30.         if (rand.Next(0, 2) == 0) v_speed *= -1;
  31.             
  32.     }
  33. }

En la clase Game1.cs, crear variables que contengan a los “jugadores” y la pelota, además una variable que maneje generación de valores randomicos y una con el estado del teclado.

  1. GraphicsDeviceManager graphics;
  2. SpriteBatch spriteBatch;
  3. Texture2D t_paddle1, t_paddle2, t_ball;
  4. Paddle paddle1;
  5. Paddle paddle2;
  6. Ball ball;
  7. Random rand = new Random();
  8. KeyboardState currentState;

Crear un método que inicializa las posiciones de los Sprites en el juego, se llama ResetGame, e  incluimos una llamada desde el constructor:

  1. /// <summary>
  2. /// Allows the game to perform any initialization it needs to before starting to run.
  3. /// This is where it can query for any required services and load any non-graphic
  4. /// related content.  Calling base.Initialize will enumerate through any components
  5. /// and initialize them as well.
  6. /// </summary>
  7. protected override void Initialize()
  8. {
  9.     // TODO: Add your initialization logic
  10.     base.Initialize();
  11.  
  12.     ResetGame();
  13. }
  14.  
  15. /// <summary>
  16. /// Inicializa los valores del juego
  17. /// </summary>
  18. void ResetGame()
  19. {
  20.     paddle1 = new Paddle(10, 200);
  21.     paddle2 = new Paddle(770, 200);
  22.     ball = new Ball(385, 285);
  23. }

 

En el método LoadContent, que se ha generado automáticamente agregamos la carga de nuestros Sprites:

  1. /// <summary>
  2. /// LoadContent will be called once per game and is the place to load
  3. /// all of your content.
  4. /// </summary>
  5. protected override void LoadContent()
  6. {
  7.     // Create a new SpriteBatch, which can be used to draw textures.
  8.     spriteBatch = new SpriteBatch(GraphicsDevice);
  9.  
  10.     // TODO: use this.Content to load your game content here
  11.     t_paddle1 = Content.Load<Texture2D>("paddle");
  12.     t_paddle2 = Content.Load<Texture2D>("paddle");
  13.     t_ball = Content.Load<Texture2D>("ball");
  14.  
  15. }

En el método Draw, agregamos:

  1. /// <summary>
  2. /// This is called when the game should draw itself.
  3. /// </summary>
  4. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  5. protected override void Draw(GameTime gameTime)
  6. {
  7.     GraphicsDevice.Clear(Color.CornflowerBlue);
  8.  
  9.     // TODO: Add your drawing code here
  10.     spriteBatch.Begin();
  11.     spriteBatch.Draw(t_paddle1, new Rectangle(paddle1.pos.X, paddle1.pos.Y, t_paddle1.Width, t_paddle1.Height), Color.CornflowerBlue);
  12.     spriteBatch.Draw(t_paddle2, new Rectangle(paddle2.pos.X, paddle2.pos.Y, t_paddle2.Width, t_paddle2.Height), Color.CornflowerBlue);
  13.     spriteBatch.Draw(t_ball, new Rectangle(ball.pos.X, ball.pos.Y, t_ball.Width, t_ball.Height), Color.CornflowerBlue);
  14.     spriteBatch.End();
  15.  
  16.     base.Draw(gameTime);
  17. }

Si se compila y ejecuta en este momento, tenemos el siguiente resultado:

InitGame

Movimientos Humano y Computadora, Detección de colisiones

Dado que se jugara HumanoVsComputadora, lo primero que se hace es capturar la entrada de teclado y actualizar el movimiento de la paleta del Humano, además validamos que no salgamos de los límites de la ventana, esto lo hacemos desde un nuevo método, UpdatePaddles:

  1. void UpdatePaddles()
  2. {
  3.     /// Capturamos las pulsaciones del teclado
  4.     currentState = Keyboard.GetState();
  5.     Keys[] currentKeys = currentState.GetPressedKeys();
  6.     /// Solo hacer caso de las teclas que requerimos
  7.     foreach (Keys key in currentKeys)
  8.     {
  9.         if (key == Keys.Up)
  10.             paddle1.pos.Y -= paddle1.speed;
  11.         if (key == Keys.Down)
  12.             paddle1.pos.Y += paddle1.speed;
  13.         if (key == Keys.Escape)
  14.             this.Exit();
  15.     }
  16.     /// Varificar que no salimos de la ventana
  17.     if (paddle1.pos.Y <= 10) paddle1.pos.Y = 10;
  18.     if (paddle2.pos.Y <= 10) paddle2.pos.Y = 10;
  19.     if (paddle1.pos.Y + t_paddle1.Height >= Window.ClientBounds.Height - 10)
  20.         paddle1.pos.Y = Window.ClientBounds.Height - t_paddle1.Height - 10;            
  21.     if (paddle2.pos.Y + t_paddle2.Height >= Window.ClientBounds.Height - 10)
  22.             paddle2.pos.Y = Window.ClientBounds.Height - t_paddle2.Height - 10;
  23. }

La “inteligencia” de la computadora, se reduce a que su paleta sigue la posición Vertical de la pelota, por lo que el anterior método quedaría así:

  1. void UpdatePaddles()
  2. {
  3.     /// Capturamos las pulsaciones del teclado
  4.     currentState = Keyboard.GetState();
  5.     Keys[] currentKeys = currentState.GetPressedKeys();
  6.     /// Solo hacer caso de las teclas que requerimos
  7.     foreach (Keys key in currentKeys)
  8.     {
  9.         if (key == Keys.Up)
  10.             paddle1.pos.Y -= paddle1.speed;
  11.         if (key == Keys.Down)
  12.             paddle1.pos.Y += paddle1.speed;
  13.         if (key == Keys.Escape)
  14.             this.Exit();
  15.     }
  16.     /// La paleta de la computadora solo sigue a la pelota
  17.     paddle2.speed = ball.h_speed;
  18.     if (paddle2.pos.Y + (t_paddle2.Height / 2) > ball.pos.Y)
  19.         paddle2.pos.Y -= paddle2.speed;
  20.     else if (paddle2.pos.Y + (t_paddle2.Height / 2) < ball.pos.Y)
  21.         paddle2.pos.Y += paddle2.speed;
  22.     /// Varificar que no salimos de la ventana
  23.     if (paddle1.pos.Y <= 10) paddle1.pos.Y = 10;
  24.     if (paddle2.pos.Y <= 10) paddle2.pos.Y = 10;
  25.     if (paddle1.pos.Y + t_paddle1.Height >= Window.ClientBounds.Height - 10)
  26.         paddle1.pos.Y = Window.ClientBounds.Height - t_paddle1.Height - 10;
  27.     if (paddle2.pos.Y + t_paddle2.Height >= Window.ClientBounds.Height - 10)
  28.         paddle2.pos.Y = Window.ClientBounds.Height - t_paddle2.Height - 10;
  29. }

Ahora se requiere mover la pelota, se lo hace desde un nuevo método UpdateBall:

  1. void UpdateBall()
  2. {
  3.     /// Actualiza la posicion de la pelota
  4.     ball.pos.X += ball.h_speed;
  5.     ball.pos.Y += ball.v_speed;
  6.  
  7.     /// Verificar limites
  8.     /// Inferior
  9.     if (ball.pos.Y > (Window.ClientBounds.Height - 10 - t_ball.Height))
  10.         ball.v_speed *= -1;
  11.     /// Superior
  12.     if (ball.pos.Y < 10)
  13.         ball.v_speed *= -1;
  14. }

Finalmente implementamos un “detector de colisiones”, que simplemente compara las posiciones de los Sprites de la pantalla, y según eso calcula la nueva dirección de la pelota, velocidad después de “golpearla” y si una de las paletas no ha alcanzado a golpear la bola, en cuyo caso el juego comienza de nuevo, llamando al método ResetGame:

  1. void CheckCollisions()
  2. {
  3.     /// Verificar si la pelota esta yendo a la izquierda
  4.     if (ball.h_speed < 0)
  5.     {
  6.         /// Verifica si la pelota a rebasado la paleta
  7.         if (ball.pos.X < paddle1.pos.X + 20)
  8.         {
  9.             /// Si la pelota no fue golpeada, fin del juego
  10.             if ((ball.pos.Y + t_ball.Height < paddle1.pos.Y) || (ball.pos.Y > paddle1.pos.Y + t_paddle1.Height))
  11.             {
  12.                 ResetGame();
  13.             }
  14.             else
  15.             {
  16.                 /// Se golpea la pelota, se cambia su direccion
  17.                 /// y se le da una velocidad inicial randomica, entre 3 y 7
  18.                 if (ball.h_speed < 0)
  19.                     ball.h_speed = rand.Next(3, 7);
  20.                 else ball.h_speed = rand.Next(-6, -2);
  21.  
  22.                 if (ball.v_speed < 0)
  23.                     ball.v_speed = rand.Next(3, 7);
  24.                 else ball.v_speed = rand.Next(-6, -2);
  25.             }
  26.         }
  27.     }
  28.     else
  29.     {
  30.         /// Verifica si la pelota a rebasado la paleta
  31.         if (ball.pos.X + t_ball.Width > paddle2.pos.X)
  32.         {
  33.             /// Si la pelota no fue golpeada, fin del juego
  34.             if ((ball.pos.Y + t_ball.Height < paddle2.pos.Y) || (ball.pos.Y > paddle2.pos.Y + t_paddle2.Height))
  35.             {
  36.                 ResetGame();
  37.             }
  38.             else
  39.             {
  40.                 /// Se golpea la pelota, se cambia su direccion
  41.                 /// y se le da una velocidad inicial randomica, entre 3 y 7
  42.                 if (ball.h_speed < 0)
  43.                     ball.h_speed = rand.Next(3, 7);
  44.                 else ball.h_speed = rand.Next(-6, -2);
  45.  
  46.                 if (ball.v_speed < 0)
  47.                     ball.v_speed = rand.Next(3, 7);
  48.                 else ball.v_speed = rand.Next(-6, -2);
  49.             }
  50.         }
  51.     }
  52. }

Implementamos la lógica de actualización del juego, desde le método Update:

  1. /// <summary>
  2. /// Allows the game to run logic such as updating the world,
  3. /// checking for collisions, gathering input, and playing audio.
  4. /// </summary>
  5. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  6. protected override void Update(GameTime gameTime)
  7. {
  8.     // Allows the game to exit
  9.     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
  10.         this.Exit();
  11.  
  12.     // TODO: Add your update logic here
  13.     UpdatePaddles();
  14.     UpdateBall();
  15.     CheckCollisions();
  16.  
  17.     base.Update(gameTime);
  18. }

F5 y a jugar!

Los fuentes, aquí:

Populares!

- Copyright © - Oubliette - -Metrominimalist- Powered by Blogger - Designed by Johanes Djogan -