jueves, 11 de agosto de 2011

XNA – Colisiones 2D, BoundingSphere


Los BoundingSphere a diferencia de los BoundingBox, el área que afecta es un redondo. Como usarlo Primero hay que declarlo.
BoundingSphere bsphere;
Después en el método Update.
bsphere_1 = new BoundingSphere(new Vector3(new Vector2(redondo_1.Width / 2,redondo_1.Height / 2) + posicion_1, 0), redondo_1.Width / 2);
Vector3 center: Acá ponemos el centro de la textura y luego le sumamos la posición para que el centro siempre se mueva con la textura. float radius: Es hasta donde llega el redondo desde el centro hacia fuera, con eso sabe de que diámetro sera.
Las funciones para chequear colisiones son las mismas que las que usamos en BoundingBox(Intersect y Contains). También nosotros podemos comprar BoundingBox con BoundingSphere, por ejemplo.
if(bbox.Intersect(bsphere))
{//blablabla}
Ejemplo El ejemplo sera similar al del anterior tutorial. Primero añadimos una fuente, y 2 texturas redondas, una mas chiquita que otra. Y las declaramos.
Texture2D redondo_1;
Vector2 posicion_1;
BoundingSphere bsphere_1;
 
Texture2D redondo_2;
Vector2 posicion_2;
BoundingSphere bsphere_2;
 
SpriteFont font;
bool intersect;
bool contains;
Luego la iniciamos.
protected override void Initialize()
{
posicion_1 = new Vector2(100, 100);
posicion_2 = new Vector2(500, 100);
base.Initialize();}
 
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
redondo_1 = Content.Load<
Texture2D >("redondogrande");
redondo_2 = Content.Load< Texture2D >("redondochico");
font = Content.Load< SpriteFont >("Font");}
Luego en el Update.
protected override void Update(GameTime gameTime)
{
KeyboardState ks = Keyboard.GetState();
if (ks.IsKeyDown(Keys.Right) == true)posicion_1.X += 3;
if (ks.IsKeyDown(Keys.Left) == true)posicion_1.X -= 3;
if (ks.IsKeyDown(Keys.Down) == true)posicion_1.Y += 3;
if (ks.IsKeyDown(Keys.Up) == true)posicion_1.Y -= 3;
 
bsphere_1 = new BoundingSphere(new Vector3(new Vector2(redondo_1.Width / 2,redondo_1.Height / 2) + posicion_1, 0), redondo_1.Width / 2);
bsphere_2 = new BoundingSphere(new Vector3(new Vector2(redondo_2.Width / 2,redondo_2.Height / 2) + posicion_2, 0), redondo_2.Width / 2);
 
if (bsphere_1.Contains(bsphere_2) == ContainmentType.Contains)
{
contains = true;
}
else
{
contains = false;
}
 
if (bsphere_1.Intersects(bsphere_2))
{intersect = true;
}
else{
intersect = false;
}
 
base.Update(gameTime);}
Y en el Draw.
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
 
spriteBatch.Begin();
spriteBatch.Draw(redondo_1, posicion_1, Color.White);
spriteBatch.Draw(redondo_2, posicion_2, Color.White);
spriteBatch.DrawString(font, "La caja grande contiene a la caja chica =" +contains.ToString(), new Vector2(50, 50), Color.White);spriteBatch.DrawString(font, "La caja grande intersecta con la caja chica=" +intersect.ToString(),new Vector2(50, 75), Color.White);
spriteBatch.End();
 
base.Draw(gameTime);}
Al final tendríamos algo como esto.
Acá termina este tutorial sobre BoundingSphere, para el próximo haremos un PingPong usando todo lo aprendido.
Codigo Completo
using System;using System.Collections.Generic;
using System.Linq;using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
 
namespace MiJuego_Tutorial_7
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
 
Texture2D redondo_1;
Vector2 posicion_1;
BoundingSphere bsphere_1;
 
Texture2D redondo_2;
Vector2 posicion_2;
BoundingSphere bsphere_2;
 
SpriteFont font;
bool intersect;
bool contains;
 
public Game1(){
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
 
protected override void Initialize(){
posicion_1 = new Vector2(100, 100);
posicion_2 = new Vector2(500, 100);
 
base.Initialize();}
 
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);redondo_1 = Content.Load< Texture2D >("redondogrande");
redondo_2 = Content.Load< Texture2D >("redondochico");
font = Content.Load< SpriteFont >("Font");
}
 
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
 
protected override void Update(GameTime gameTime)
{
KeyboardState ks = Keyboard.GetState();
if (ks.IsKeyDown(Keys.Right) == true)posicion_1.X += 3;
if (ks.IsKeyDown(Keys.Left) == true)posicion_1.X -= 3;
if (ks.IsKeyDown(Keys.Down) == true)posicion_1.Y += 3;
if (ks.IsKeyDown(Keys.Up) == true)posicion_1.Y -= 3;
 
bsphere_1 = new BoundingSphere(new Vector3(new Vector2(redondo_1.Width / 2, redondo_1.Height / 2) + posicion_1, 0), redondo_1.Width / 2);
bsphere_2 = new BoundingSphere(new Vector3(new Vector2(redondo_2.Width / 2, redondo_2.Height / 2) + posicion_2, 0), redondo_2.Width / 2);
 
if (bsphere_1.Contains(bsphere_2) == ContainmentType.Contains)
{
contains = true;
}
else
{
contains = false;
}
 
if (bsphere_1.Intersects(bsphere_2))
{
intersect = true;
}
else
{
intersect = false;
}
 
base.Update(gameTime);}
 
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
 
spriteBatch.Begin();spriteBatch.Draw(redondo_1, posicion_1, Color.White);spriteBatch.Draw(redondo_2, posicion_2, Color.White);
spriteBatch.DrawString(font, "La caja grande contiene a la caja chica =" + contains.ToString(),new Vector2(50, 50), Color.White);spriteBatch.DrawString(font, "La caja grande intersecta con la caja chica=" + intersect.ToString(),new Vector2(50, 75), Color.White);
spriteBatch.End();
 
base.Draw(gameTime);}}}