Colisiones en 2D. Creacion de un juego simple.

enero 1, 2008 at 10:29 am (Tutoriales) (, , , , , , , , , , , , , , , )

Este tutorial, abarcara sobre Colisiones en 2D y crearemos un juego de evitar obstaculos. En otros sitios, como en XNA – AnimeRed, vienen tutoriales sobre colisiones en 2D. Sin embargo, el codigo de ejemplo esta muy breve y utiliza conceptos de tercera dimension para objetos en 2D, que son completamente validos, pero hay otras formas de crear colisiones en XNA, sin tener que utilizar Vectores de tres dimensiones.

El metodo que voy a mostrar, es uno de muchisimos que existen para detectar si un objeto tiene una colision o no, utilizando el concepto de rectangulos. Si un rectangulo intersecta con otro. Cabe resaltar que este metodo no es preciso. Seguramente veran que el programa detecta que el objeto esta colisionando con el otro, aunque visualmente no lo esten. Es uno de los inconvenientes. Pero es el mas sencillo y basico y excelente para principiantes.

 Antes que nada, lo que necesitamos para continuar con este tutorial son dos imagenes, que haremos colisionar. Pueden dibujar cualquier cosa en paint, un punto y una raya por ejemplo. Una de esas imagenes caera desde arriba y otra es la que moveremos con el teclado de izquierda a derecha.

Ya que tenemos nuestras imagenes, Crearemos un proyecto nuevo (Windows Game) y lo llamaremos como deseemos. Agregaremos los dibujos al proyecto como habia mostrado previamente y nos iremos al codigo.

  1. Vamos a agregar el siguiente codigo en la clase Game1.cs


//Las texturas a mostrar

Texture2D objeto;

Texture2D persona;

//El spritebatch


SpriteBatch spriteBatch;

//El vector que almacenara la posicion de la textura Persona

Vector2 posicionPersona;

//La velocidad con la que se desplazara a traves del eje ‘x’


const int velocidadPersona = 5;

//La lista de objetos que se dejaran caer desde arriba.

List<Vector2> posicionObjetos = new List<Vector2>();

float probabilidad = 0.01f;

//La velocidad con la que caeran


const int velocidadObjeto = 2;

//Un numero aleatorio, que determinara junto con la probabilidad, en que posicion ‘x’ apareceran.

Random aleatorio = new Random();

//Esta variable, determinara si la persona esta tocando o no a los objetos que caen.


bool personaColisiona = false;

Los valores de la velocidad y la probabilidad son arbitrarios y pueden ser modificados libremente, para que se den cuenta en que repercute que sean cambiados. 

Ahora debemos inicializar estas variables. Las texturas, como ya sabemos debemos inicializarlas en metodo LoadGraphicsContent. La lista “posicionObjetos” nos permitira, colocar y ordenar los objetos para irlos sacando de la lista y mostrandolos en pantalla poco a poco.


protected override void Initialize()

{
// TODO: Add your initialization logic here


base.Initialize();

posicionPersona.X = (Window.ClientBounds.Width – persona.Width) / 2;
posicionPersona.Y = (Window.ClientBounds.Height – persona.Height);
}


protected override void LoadGraphicsContent(bool loadAllContent)

{
if (loadAllContent)

{
persona = content.Load<Texture2D>(“persona”);
objeto = content.Load<Texture2D>(“objeto”);

spriteBatch = new SpriteBatch(graphics.GraphicsDevice);

}

// TODO: Load any ResourceManagementMode.Manual content

}

Ya que inicializamos estos valores. Vamos a crear toda la logica del juego. En este punto del tutorial realizaremos:

  • Mover el personaje izquierda o derecha.
  • Mantener al personaje dentro de la pantalla.
  • Hacer que los objetos caigan del cielo
  • Crear rectangulos para cada objeto que caiga y determinar si colisiona o no con el personaje.
  • Cuando los rectangulos hayan salido de la pantalla, eliminarlos de la lista.

Copiar el siguiente codigo en el metodo Update:

protected override void Update(GameTime gameTime)

{
// Allows the game to exit


if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)

this.Exit();

// TODO: Add your update logic here

//Crea el rectangulo del personaje, que nos permitira saber con que objeto se encuentra colisionando


Rectangle rectanguloPersona = new Rectangle((int)posicionPersona.X, (int)posicionPersona.Y, persona.Width, persona.Height);

personaColisiona = false;

//Input del teclado

KeyboardState dameTeclas = Keyboard.GetState();

if(dameTeclas.IsKeyDown(Keys.Left)) // La persona se mueve a la izquierda


{
posicionPersona.X -= velocidadPersona;
}
if(dameTeclas.IsKeyDown(Keys.Right)) //El personaje se mueve hacia la derecha.

{
posicionPersona.X += velocidadPersona;
}
//Esta poricion de codigo, mantiene a la persona dentro de los limites de la pantalla.


posicionPersona.X = MathHelper.Clamp(posicionPersona.X, 0, Window.ClientBounds.Width – persona.Width);

if(aleatorio.NextDouble() < probabilidad)

{
float x = (float) aleatorio.NextDouble() * (Window.ClientBounds.Width – objeto.Width);

posicionObjetos.Add(new Vector2(x,-objeto.Height));

}
//en este For, cuenta la cantidad de objetos que hay en la lista y crea un rectangulo para cada objeto.

for (int i = 0; i < posicionObjetos.Count; i++)

{
// determina la posicion X del objeto y traslada la posicion Y del objeto para hacerlo caer.


posicionObjetos[i] =
new Vector2(posicionObjetos[i].X,

posicionObjetos[i].Y + velocidadObjeto);
//Crea el rectangulo que nos permitira crear la colision con el rectangulo del personaje

Rectangle rectanguloObjeto = new Rectangle((int)posicionObjetos[i].X, (int)posicionObjetos[i].Y, objeto.Width, objeto.Height);

//Si el rectangulo de la persona, intersecta el rectangulo del objeto, entonces


//La variable ‘personaColisiona’ se convierte a un valor positivo.

if(rectanguloPersona.Intersects(rectanguloObjeto))

{
personaColisiona = true;

}
//Si la posicion Y del objeto que cae, es mayor a la altura de la pantalla, entonces


//Eliminamos el objeto de la lista. Si no hicieramos esto y dejaramos el programa

//abierto; los recursos de la computadora serian consumidos poco a poco.


if (posicionObjetos[i].Y > Window.ClientBounds.Height)

{
posicionObjetos.RemoveAt(i);
i–;
}
}
base.Update(gameTime);

}

Ya casi terminamos con el programa,  aun no podemos ejecutar el proyecto puesto a que no mostrara ninguna imagen en la pantalla, hasta ahora solo hemos creado la logica del juego. Debemos dibujar las texturas en pantalla y como le daremos a conocer al usuario si el objeto ha colisionado o no.

protected override void Draw(GameTime gameTime)

{GraphicsDevice device = graphics.GraphicsDevice;graphics.GraphicsDevice.Clear(Color.CornflowerBlue);//Iniciamos el spritebatch

spriteBatch.Begin();// Dibujamos a la persona

spriteBatch.Draw(persona, posicionPersona, Color.White);//Le decimos al compilador que por cada Objeto que haya en la lista de Objetos//Vamos a dibujar la textura, en la posicion que va a ser generada aleatoriamente.

foreach (Vector2 posicionObjeto in posicionObjetos){spriteBatch.Draw(objeto, posicionObjeto, Color.White);}//Si el valor de ‘personaColisiona’ = true entonces, el fondo de la pantalla se hara Rojo

//De lo contraro el fondo seguira siendo el mismo.

if (personaColisiona)device.Clear(Color.Red);elsedevice.Clear(Color.CornflowerBlue);//Terminamos con el spritebatch

spriteBatch.End();// TODO Add your drawing code here

base.Draw(gameTime);}Y con esto terminamos el tutorial de Colisiones Simples. Este metodo es el mismo que se muestra en la pagina de “XNA Creators“. Solo que aqui me salte unos pasos y agregare unos detalles y mejores ideas.

Este juego es bastante simple y puede ser muy muy aburrido. Pero es basicamente como funciona el juego de Invasores del Espacio. Ideas para hacer este juego mucho mejor.

  • Agregar una textura que represente una bala y trasladarla a traves el eje ‘Y’ y determinar si el objeto colisiona o no. Si el objeto colisiona, mostrar un sprite donde se destruya el objeto y aparte eliminarlo de la lista.
  • Cambiar la textura del personaje por un avion.
  • Cambiar la textura del objeto por otro avion de diferente color.
  • Crear un ScrollingBackground.
  • Hacer que los otros aviones disparen.

Con esto, crearemos un juego de aviones que se disparan los unos a los otros. De momento no puedo subir proyectos, pero en cuanto pueda lo hare. Para los que quieran realizar lo mostrado arriba, ahi les van unos tips.

Para trasladar la bala que tu dispararas a traves del eje Y, utilizaremos el mismo algoritmo que usamos para hacer caer los objetos desde arriba. Solo que ahora, la posicion X de la bala debe ser igual a la posicion X del avion antes de ser disparada.

Para hacer que muestre la animacion de destruccion pueden hacer un sprite de explosion o descargar uno de Charas-project, animarlo com lo habia mostrado anteriormente y llamar el metodo “Destruir();” (por ejemplo) cuando haya la interseccion entre la bala y el objeto. La posicion X y Y de la animacion de destruccion debe ser la posicion X-Y del avion contrario. Un Codigo de ejemplo seria:


if (personaColisiona)

Destruir();

El codigo para remover el objeto de la lista, cuando lo toque la bala, seria algo asi:


for (int i = 0; i < posicionObjetos.Count; i++)

{


if (rectanguloPersona.Intersects(rectanguloObjeto))

{
personaColisiona = true;

posicionObjetos.RemoveAt(i);

}
}

Para hacer que tu avion dispare, deberas crear otra instruccion que uando presiones la tecla de “espacio” por ejemplo; Mandes llamar al metodo “disparar();” que deberas crear en el cual tendras un codigo similar al que utilizas para crear un objeto en la lista y dejarlo caer. Solo que ahora, la bala se trasladara hacia arriba en el eje Y.

Para que los aviones disparen, utilizaras el mismo algoritmo para disparar(); pero la posicion X de esa bala debe ser la posicion X del avion que la dispara y la posicion Y, debe ser invertida, puesto a que el fuego enemigo viaja hacia a ti, no contigo.

 Con esto solo les doy una posibilidad de muchisimas que existen para trabajar con colisiones en segunda dimension. Publicare otro tutorial sobre como crear un scrolling background vertical, saludos.

Anuncios

2 comentarios

  1. drocruz said,

    Hola que tal, pues escribo esto para agradecerte por los tutoriales que estas creando ya que en la red hay muy pocos y sobre todo si los buscas en español, la neta compa que gracias por esto, me gustaria darte una recomendacion, pon los ejemplos para descarga ya que asi tambien ases mas facil su comprecion, un saludo tu amigo Pedro Cruz.

  2. SeriesDescarga Colabora said,

    Hola podrías subir el proyecto? gracias

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: