27 de noviembre de 2010

[XNA] Creando el Pong (Parte 2) / Bounding Boxes

Ahora vamos a trabajar con la pelota. En primer lugar, como siempre, creamos las variables de la pelota solo que esta vez añadimos otro vector llamado velocidad:
        private Texture2D textura;
        private Vector2 posicion, velocidad;
        float angulo, celeridad;
Donde el angulo sera el angulo con el que saldrá la pelota el cual vendrá definido por un método que crearemos llamado anguloAleatorio() de tipo void  y que nos servirá para evitar la rutina en la trayectoria de la pelota:
        private void anguloAleatorio() 
        { 
            Random rAngulo = new Random(); 
            int r = 0; 
            while (r % 2 == 0) 
                r = rAngulo.Next(1, 7);
            angulo = MathHelper.ToRadians(r * 45); 
        }


En el método Initialize() posicionamos la pelota en el centro de la pantalla e iniciamos la velocidad:
            posicion = Vector2.Zero;
            anguloAleatorio();
            velocidad = new Vector2((float)(celeridad * Math.Cos(angulo)), (float)(celeridad * Math.Sin(angulo)));

En el LoadContent() cargamos la textura y establecemos la posición inicial:
textura = Game.Content.Load("Pelota"); 
posicion.X = GraphicsDevice.Viewport.Width / 2 - textura.Width / 2;
posicion.Y = GraphicsDevice.Viewport.Height / 2 - textura.Height / 2;
Para definir la trayectoria de la pelota, vamos al método Update() y escribimos:
 posicion += velocidad;
Por último solo nos queda dibujar la pelota en la pantalla:
 (Game as Pong).spriteBatch.Begin();
 (Game as Pong).spriteBatch.Draw(textura, posicion, Color.White);
  (Game as Pong).spriteBatch.End();
Y para que todo esto sea visible, tenemos que iniciarla en la clase Pong. Añadimos la variable pelota:
public Pelota pelota;
Y la inicializamos:
pelota = new Pelota(this);
Components.Add(pelota);

 Ya tenemos la pelota, ahora lo que vamos a hacer es que rebote en las paredes. Para conseguirlo lo que vamos a hacer es cambiar el sentido de la velocidad en el eje Y cuando la pelota sobrepase los limites de la pantalla. En primer lugar, al igual que en las palas, creamos un rectángulo para la pelota y en el método Update tras llamar al método actualizarRectángulo() escribimos:
if (posicion.Y <= 0 || posicion.Y >= Game.GraphicsDevice.Viewport.Height - textura.Height)
            {
                velocidad.Y = -1f * velocidad.Y;
            }
 Para las colisiones entre la pelota y las palas, vamos a hacer uso de colisiones Bounding Boxes. Para esto, vamos a la clase Pong.cs y en el método Update escribimos:

if (pelota.rectangulo.Intersects(jugador1.rectangulo) || pelota.rectangulo.Intersects(jugador2.rectangulo))
                pelota.velocidad.X *= -1.0f;
Si aumentamos el numero que multiplica a la velocidad, la pelota irá incrementando la velocidad con cada golpe. Cuanto mas alto sea el número que la multiplica más se aumentará la velocidad así que no os paséis o el cambio de velocidad seria muy brusco. Añadimos la colisión entre la pelota y el borde derecho y el borde izquierdo de la pantalla. Cuando la pelota colisiona con estos bordes, la puntuación del jugador del lado contrario aumenta y la pelota vuelve al centro de la pantalla. Para esto hemos creado un método llamado reiniciarPosicion() en la clase Pelota.cs :

 public void reiniciarPosicion()
        {
            posicion.X = GraphicsDevice.Viewport.Width / 2 - textura.Width / 2;
            posicion.Y = GraphicsDevice.Viewport.Height / 2 - textura.Height / 2;
            anguloAleatorio();
            velocidad = new Vector2((float)(celeridad * Math.Cos(angulo)), (float)(celeridad * Math.Sin(angulo)));
        }
 y hemos añadido las variables de puntuación llamadas puntuacionJ1 y puntuacionJ2 y las siguientes condiciones al método Update() de la clase Pong.cs:
if (pelota.rectangulo.Left <= 0)
            {
                puntuacionJ2 += 1;
                pelota.reiniciarPosicion();
                pelota.velocidad *= -1.0f;
            }
            else if (pelota.rectangulo.Right >= GraphicsDevice.Viewport.Width)
            {
                puntuacionJ1 += 1;
                pelota.reiniciarPosicion();
                pelota.velocidad *= -1.0f;
            } 
Ahora vamos a hacer que la partida no empiece a menos que pulsemos una tecla, en este caso la tecla Enter. Creamos una variable de tipo bool llamada empezar en la clase Pong.cs:
public bool empezar = false,sumarVictoria;
y en Update ponemos:


            if (estado.IsKeyDown(Keys.Enter))
            {
                empezar = true;
                final = false;
                puntuacionJ1 = 0;
                puntuacionJ2 = 0;
                sumarVictoria = true;
            }
y para hacer que la pelota no se mueva a menos que empezar sea igual a true, vamos a la clase Pelota.cs  y en el método Update, donde hemos puesto posicion += velocidad añadimos la condición de que para que esto se de, empezar tenga que ser true:

if((Game as Pong).empezar == true)
                posicion += velocidad;
Como una partida no puede ser infinita, vamos a hacer que cuando algún jugador llegue a cierta puntuación (yo voy a poner una puntuación máxima de 11 puntos) el juego se pare, es decir, empezar sea igual a false. Además, vamos a crear una nueva variable de tipo bool que llamaremos final y que iniciaremos como false. Para esto añadimos el siguiente código a Update de la clase Pong.cs:

if (puntuacionJ1 == 11 || puntuacionJ2 == 11)
            {
                empezar = false;
                final = true;
            }
También queremos controlar el número de victorias que acumula cada jugador. Así pues creamos dos nuevas variables de tipo int llamadas victoriasJ1 y victoriasJ2 iniciadas con el valor 0. Para controlar las victorias de cada jugador, añadimos el siguiente código a la condición anterior:


if (puntuacionJ1 > puntuacionJ2 && sumarVictoria == true)
                {
                    victoriasJ1++;
                    sumarVictoria = false;
                }
                else if (puntuacionJ2>puntuacionJ1 && sumarVictoria == true)
                {
                    victoriasJ2++;
                    sumarVictoria = false;
                }
Dicho esto solo nos queda mostrar en pantalla la puntuación, el numero de victorias, etc. Lo veremos en la tercera parte.

No hay comentarios:

Publicar un comentario