sábado, 28 de marzo de 2015

Simulacion de fisica con cubos en Box2D


Descargar Assets para este proyecto


#include <SFML\Graphics.hpp>
#include <Box2D\Box2D.h>

//Es necesario para convertir de pixeles a coordenadas del mundo real
static const float ESCALA = 30.f;

//Creo funciones para crear las cajas y el suelo
void CrearCaja(b2World &world, float mouseX, float mouseY );
void CrearSuelo(b2World &world, float posX , float posY );

int main()
{
 //Creo mi ventana
 sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Generar Cubos con el Mouse");
 window.setFramerateLimit(60);

 //Preparo el World para Box2D
 b2Vec2 gravity( 0.f , 9.8f);
 b2World world( gravity );

 //mando a llamar a mi funcion para crear el suelo
 CrearSuelo( world , 400.f , 500.f );

 //Preparo mi texturas
 sf::Texture texturaCaja;
 sf::Texture texturaSuelo;

 texturaCaja.loadFromFile("box1.png");
 texturaSuelo.loadFromFile("ground.png");

 //inicio mi gameloop
 while (window.isOpen())
 {
  //le indico que generara las cajas con el boton izquierdo del mouse
  if (sf::Mouse::isButtonPressed( sf :: Mouse :: Left ) )
  {
   //obtengo las posiciones donde se hizo clic
   int mouseX = sf::Mouse::getPosition(window).x;
   int mouseY = sf::Mouse::getPosition(window).y;
  //y genero las cajas pasando la posiciones donde se dio clic
   CrearCaja( world , mouseX , mouseY );
  }

  //con esto inicio la simulacion de fisica de box2d
  world.Step( 1 / 60.f , 8 , 3 );

  //Limpio la pantalla a un color blanco
  window.clear(sf::Color::White);

  //Realizo un contador de bodies
  int contador = 0;

  //Realizo un bodyiterator para crear un ciclo de bodies creados
  for (b2Body *bodyIterator = world.GetBodyList(); bodyIterator != 0; bodyIterator = bodyIterator->GetNext())
  {
   if (bodyIterator->GetType() == b2_dynamicBody)
   {
    sf::Sprite sprite;
    sprite.setTexture( texturaCaja );
    sprite.setOrigin( 16.f , 16.f );
    sprite.setPosition(ESCALA * bodyIterator->GetPosition().x, ESCALA * bodyIterator->GetPosition().y);
    sprite.setRotation( bodyIterator -> GetAngle() * 180 / b2_pi );
    window.draw( sprite );
    ++contador;
   }

   else
   {
    sf::Sprite suelo;
    suelo.setTexture( texturaSuelo );
    suelo.setOrigin(400.f, 8.f);
    suelo.setPosition(bodyIterator->GetPosition().x * ESCALA, bodyIterator->GetPosition().y * ESCALA);
    suelo.setRotation(180 / b2_pi * bodyIterator->GetAngle());
    window.draw( suelo );
   }
  }

  window.display();

  //Creo un evento de salida
  sf::Event event;

  while (window.pollEvent(event))
  {
   if (event.type == sf::Event::Closed)
    window.close();
  }
 }

 return 0;
}

void CrearCaja(b2World &world, float mouseX, float mouseY)
{
 //defino mi body
 b2BodyDef bodyDef;
 bodyDef.position = b2Vec2( mouseX / ESCALA , mouseY / ESCALA );
 bodyDef.type = b2_dynamicBody;
 b2Body *body = world.CreateBody(&bodyDef);

 //Creo la forma de la caja
 b2PolygonShape caja;
 caja.SetAsBox( (128.f / 2 ) / ESCALA , ( 128.f / 2 ) / ESCALA );

 //Creo mi fixture
 b2FixtureDef fixtureDef;
 fixtureDef.density = 1.f;
 fixtureDef.friction = 0.7f;
 fixtureDef.shape = &caja;

 body->CreateFixture( &fixtureDef );
}

void CrearSuelo(b2World &world, float posX, float posY)
{
 //defino mi bodyDef
 b2BodyDef bodyDef;
 bodyDef.position = b2Vec2( posX / ESCALA , posY / ESCALA );
 bodyDef.type = b2_staticBody;
 b2Body *body = world.CreateBody( &bodyDef );

 //Creo su forma
 b2PolygonShape suelo;
 suelo.SetAsBox((800.f / 2) / ESCALA , ( 16.f / 2 ) / ESCALA );

 //Creo su fixture
 b2FixtureDef fixtureDef;
 fixtureDef.density = 0.f;
 fixtureDef.shape = &suelo;
 body->CreateFixture( &fixtureDef );
}



No hay comentarios:

Publicar un comentario