domingo, 1 de abril de 2012

Calculo de colisiones

Carrera de XNA – Capítulo 4 – Artículo 7

shooter_collision_optLas colisiones nos permiten detectar el “choque” entre dos elementos del juego.

El cálculo de colisiones es una de las tareas más comunes en todo tipo de juegos, desde plataformas, juegos de carreras, peleas, y hasta el más simple Pong utiliza este tipo de cálculo.

La colisión a detectar es entre la clase del jugador creada al principio y la clase Enemy que creamos recientemente.

 

Para esto dentro de nuestro Game1, crearemos el siguiente método UpdateCollision().

private void UpdateCollision()
{
    // Use the Rectangle's built-in intersect function to
    // determine if two objects are overlapping
    Rectangle rectangle1;
    Rectangle rectangle2;

    // Only create the rectangle once for the player
    rectangle1 = new Rectangle((int)player.Position.X,
    (int)player.Position.Y,
    player.Width,
    player.Height);

    // Do the collision between the player and the enemies
    for (int i = 0; i <enemies.Count; i++)
    {
        rectangle2 = new Rectangle((int)enemies[i].Position.X,
        (int)enemies[i].Position.Y,
        enemies[i].Width,
        enemies[i].Height);

        // Determine if the two objects collided with each
        // other
        if(rectangle1.Intersects(rectangle2))
        {
            // Subtract the health from the player based on
            // the enemy damage
            player.Health -= enemies[i].Damage;

            // Since the enemy collided with the player
            // destroy it
            enemies[i].Health = 0;

            // If the player health is less than zero we died
            if (player.Health <= 0)
            player.Active = false;
        }

    }
}

Analicemos un poco este método. Teniendo en cuenta que tanto nuestro jugador como nuestro enemigo son elementos gráficos, que se enmarcan dentro de rectángulos (mas allá de las partes curvas que no se dibujan) podemos detectar la colisión entre estos, sabiendo su posición, ancho y alto.

La clase Rectangle con su método Intersect nos resuelve esta lógica, pero debemos tener en cuenta que cuanto más “Redondeado” es nuestro objeto a dibujar, menos precisión tendremos en el cálculo.

Para finalizar con esta detección de colisiones, procederemos a llamar al método UpdateCollision() desde nuestro Update(), justo después de UpdateEnemies() que agregamos en el artículo pasado.

// Update the collision
UpdateCollision();

Al correr el juego, veremos como cada enemigo desaparece al colisionar con nuestro jugador. Pueden descargar el juego en este estado desde el siguiente link: http://sdrv.ms/JfxIeK

3 comentarios:

  1. muy interesante cada vez me interesa programar es como si tuviera el control de la situacion con referente al juego y poder descifrar que hace cada setencia

    ResponderEliminar
  2. Hay alguna forma más precisa de detectar colisiones cuando los objetos son más redondeados, en lugar de tener siempre que usar el rectángulo ?

    ResponderEliminar
  3. "El nombre 'player no existe en el contexto actual" nosotros veniamos usando 'jugador'

    ResponderEliminar