Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Some problem BOX2D/SFML  (Read 1557 times)

0 Members and 2 Guests are viewing this topic.

norb

  • Newbie
  • *
  • Posts: 2
    • View Profile
Some problem BOX2D/SFML
« on: July 24, 2010, 11:13:10 pm »
Hello,

I just start to watch SFML and BOX2D adn try to play with those tools. And of course i have some problem ^^

Point 1 : (yes there is more than one point ^^)

I have this function (found on a forum) that work quite fine.

Code: [Select]
b2Body * CreateBody(b2World *World, b2BodyType type, sf::Shape &Shape, const sf::Vector2f &Position, const sf::Vector2f &Size)
{

   // Create the body
      b2BodyDef def;
      def.type = type;
      def.position.Set(Position.x/PIXELS_METER, Position.y/PIXELS_METER);
      b2Body* Body = World->CreateBody(&def);
      b2PolygonShape pol;
      pol.SetAsBox((Size.x)/PIXELS_METER, (Size.y)/PIXELS_METER);
      b2FixtureDef fix;
      fix.shape = &pol;
      fix.density = 1.0f;
      fix.friction = 1.3f;
      Body->CreateFixture(&fix);
      Shape = sf::Shape::Rectangle(0.f, 0.f, Size.x*2, Size.y*2, sf::Color::White);
 Shape.SetCenter(Size);
 Shape.SetPosition(Position);

      return Body;
}  


You can see the *2 for creating the shape, I have read that the .setbox take do a *2 of the value that's why we need that.
The problem :
I create my screen with like that :
Code: [Select]

const int ScreenWidth  = 800;
const int ScreenHeight = 600;
...
sf::RenderWindow App(sf::VideoMode(ScreenWidth,ScreenHeight,32), "Main");
...
sf::Shape ground;
b2Body *groundBody = CreateBody(&World, b2_staticBody, ground, sf::Vector2f(ScreenWidth, ScreenHeight), sf::Vector2f(ScreenWidth, 10.f));
...


So you can see that i place ScreenWidth as the width of the object so with the *2 normally I should be able to only place ScreenWidth/2 but if I Place ScreenWidth/2 my "ground" don't take the size of my screen ....
Screen (white bar is the ground):



Point 2:
I want to place a sprite (sf::sprite), i create another function exacly the same as the last one
Code: [Select]
b2Body * CreateBodySpr(b2World *World, b2BodyType type, sf::Sprite &Shape, const sf::Vector2f &Position, const sf::Vector2f &Size)
{
   // Create the body
      b2BodyDef def;
      def.type = type;
      def.position.Set(Position.x/PIXELS_METER, Position.y/PIXELS_METER);
      b2Body* Body = World->CreateBody(&def);
      b2PolygonShape pol;
 pol.SetAsBox((Size.x)/(PIXELS_METER), (Size.y)/(PIXELS_METER));
      b2FixtureDef fix;
      fix.shape = &pol;
      fix.density = 1.0f;
      fix.friction = 0.3f;
      Body->CreateFixture(&fix);
 Shape.SetColor(sf::Color::Red);
 Shape.SetCenter(Size);  
      Shape.SetPosition(Position);

      return Body;
}


before a prepare my Sprite :
Code: [Select]

...
sf::Image img = sf::Image();
img.LoadFromFile("data/mario.png");
sf::Sprite mario;
mario.SetImage(img);
b2Body *marioBody = CreateBodySpr(&World, b2_dynamicBody, mario, sf::Vector2f(ScreenWidth, ScreenHeight-50), sf::Vector2f(img.GetWidth(), img.GetHeight()));
...


The problem :
Here my sprite don't touch the other sprite so i think because of the *2 that i can't place here and decide to go on with a /2 and change the line :
Code: [Select]
pol.SetAsBox((Size.x)/(PIXELS_METER), (Size.y)/(PIXELS_METER));
by
Quote
pol.SetAsBox((Size.x/2)/(PIXELS_METER), (Size.y/2)/(PIXELS_METER));


and only with that it was not working finally trying to understand i also change the line
Code: [Select]
Shape.SetCenter(Size);
by
Code: [Select]
Shape.SetCenter(Size.x / 2, Size.y / 2);

My problem is that i don't understand why it's working for me it don't make sense ... so if someone can explain to me it should be great

screen before the change :



Point 3:
I haven't found explanation regarding the folowing code :
Code: [Select]
World.SetContinuousPhysics(true);
what it exactly do do i need it

The global Code :
If someone need it here the code i have :

If you have any comment please feel free ^^

Code: [Select]
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <sfml/Graphics.hpp>
#include <list>
#include <Box2D.h>

using namespace std ;

#define PIXELS_METER 30.f
#define PI 3.1415926

double degreeToRadian(double degree) {
        double radian = 0;
        radian = degree * (PI/180);
        return radian;
}

double radianToDegree(double radian) {
        double degree = 0;
        degree = radian * (180/PI);
        return degree;
}


float RandomFloat(void) {
return (rand() / (float)RAND_MAX);
}

float RandomFloat(float Min,float Max) {
return (RandomFloat() * (Max - Min)) + Min;
}

b2Body * CreateBodySpr(b2World *World, b2BodyType type, sf::Sprite &Shape, const sf::Vector2f &Position, const sf::Vector2f &Size)
{
   // Create the body
      b2BodyDef def;
      def.type = type;
      def.position.Set(Position.x/PIXELS_METER, Position.y/PIXELS_METER);
      b2Body* Body = World->CreateBody(&def);
      b2PolygonShape pol;
 pol.SetAsBox((Size.x/2)/(PIXELS_METER), (Size.y/2)/(PIXELS_METER));
      b2FixtureDef fix;
      fix.shape = &pol;
      fix.density = 1.0f;
      fix.friction = 0.3f;
      Body->CreateFixture(&fix);
 Shape.SetColor(sf::Color::Red);
 Shape.SetCenter(Size.x / 2, Size.y / 2);  
      Shape.SetPosition(Position);

      return Body;
}


b2Body * CreateBody(b2World *World, b2BodyType type, sf::Shape &Shape, const sf::Vector2f &Position, const sf::Vector2f &Size)
{

   // Create the body
      b2BodyDef def;
      def.type = type;
      def.position.Set(Position.x/PIXELS_METER, Position.y/PIXELS_METER);
      b2Body* Body = World->CreateBody(&def);
      b2PolygonShape pol;
      pol.SetAsBox((Size.x)/PIXELS_METER, (Size.y)/PIXELS_METER);
      b2FixtureDef fix;
      fix.shape = &pol;
      fix.density = 1.0f;
      fix.friction = 1.3f;
      Body->CreateFixture(&fix);
      Shape = sf::Shape::Rectangle(0.f, 0.f, Size.x*2, Size.y*2, sf::Color::White);
 Shape.SetCenter(Size);
 Shape.SetPosition(Position);

      return Body;
}

b2Body * CreateBodyR(b2World *World, b2BodyType type, sf::Shape &Shape, const sf::Vector2f &Position, float Radius)
{
   // Create the body
b2BodyDef def;
def.type = type;
def.position.Set(Position.x/PIXELS_METER, Position.y/PIXELS_METER);
b2Body* Body = World->CreateBody(&def);

// Creating the box2d circle shape (size in pixels)
b2CircleShape circle;
circle.m_p.Set(Position.x/PIXELS_METER, Position.y/PIXELS_METER);
circle.m_radius = Radius/PIXELS_METER;

b2FixtureDef fix;
fix.shape = &circle;
fix.density = 1.0f;
fix.friction = 0.3f;


Body->CreateFixture(&fix);

Shape = sf::Shape::Circle(Position, Radius, sf::Color::White);
      return Body;
}


void Synchronize(b2Body *Body, sf::Drawable &Shape)
{
   Shape.SetRotation(-radianToDegree(Body->GetAngle()));
   Shape.SetPosition(Body->GetPosition().x*PIXELS_METER, Body->GetPosition().y*PIXELS_METER);
}



class myclass
{
public :
b2Body *physic;
sf::Shape toaff;
int number;

public :
myclass(int x, b2Body *pP, sf::Shape pAff)
{
number = x;
this->physic = pP;
this->toaff = pAff;
}

void myupd()
{
Synchronize(physic, toaff);
}

void mdraw(sf::RenderWindow *App)
{
App->Draw(toaff);
}

~myclass()
{

}
};

typedef list<myclass*> LISTSTR;

//global vars
const int ScreenWidth  = 800;
const int ScreenHeight = 600;
const int Speed   = 300;



sf::String Text;

typedef void (*pFunc)();


int main()
{

LISTSTR::iterator i;
    LISTSTR lstObj;  


sf::RenderWindow App(sf::VideoMode(ScreenWidth,ScreenHeight,32), "Main");


bool doSleep = true;
b2Vec2 gravity(0, 9.8f);
int iteration = 10;
float scale = 30;
float timestep = 1 /60;


b2World World( gravity, doSleep);
//World.SetContactListener(collisionManager);
World.SetContinuousPhysics(true);

sf::Shape ground;
b2Body *groundBody = CreateBody(&World, b2_staticBody, ground, sf::Vector2f(ScreenWidth, ScreenHeight), sf::Vector2f(ScreenWidth/2, 10.f));


sf::Image img = sf::Image();
img.LoadFromFile("data/mario.png");
sf::Sprite mario;

cout << "W : " << img.GetWidth() << "\r\n";
cout << "H : " << img.GetHeight() << "\r\n";
mario.SetImage(img);
b2Body *marioBody = CreateBodySpr(&World, b2_dynamicBody, mario, sf::Vector2f(ScreenWidth, ScreenHeight-50), sf::Vector2f(img.GetWidth(), img.GetHeight()));
   

int count = 0;
while(App.IsOpened())
{

if (count > 1000)
{
float RandomH = RandomFloat(10, 100);
float RandomW = RandomFloat(10, 100);

float RandomY = RandomFloat(0, ScreenHeight-RandomH);
float RandomX = RandomFloat(0, ScreenWidth- RandomW);

sf::Uint8 R = sf::Randomizer::Random(0,255);
sf::Uint8 G = sf::Randomizer::Random(0, 255);
sf::Uint8 B = sf::Randomizer::Random(0, 255);
sf::Uint8 A = sf::Randomizer::Random(10, 250);
A = 255;
float densite = RandomFloat(0, 30);


sf::Shape Shape;

b2Body *Body;
if (sf::Randomizer::Random(0, 10) > 5)
Body = CreateBody(&World, b2_dynamicBody, Shape, sf::Vector2f(RandomX, RandomY), sf::Vector2f(RandomH, RandomW));
else
Body = CreateBodyR(&World, b2_dynamicBody, Shape, sf::Vector2f(RandomX, RandomY), RandomW);
Shape.SetColor(sf::Color(R,G,B,A));

myclass *tmp = new myclass(lstObj.size(), Body, Shape );
lstObj.insert(lstObj.end(), tmp);
count = 0;
}
count++;

World.Step(App.GetFrameTime(), 10, 1);
World.ClearForces();

sf::Event event;
while(App.GetEvent(event))
{
if(event.Type == event.Closed)
App.Close();
}


App.Clear(sf::Color(100,149,237));

if (App.GetInput().IsKeyDown(sf::Key::Escape))
App.Close();

if (App.GetInput().IsKeyDown(sf::Key::Right))
marioBody->SetLinearVelocity(b2Vec2(3,marioBody->GetLinearVelocity().y));
else if (App.GetInput().IsKeyDown(sf::Key::Left))
marioBody->SetLinearVelocity(b2Vec2(-3,marioBody->GetLinearVelocity().y));
else
marioBody->SetLinearVelocity(b2Vec2(0,marioBody->GetLinearVelocity().y));


//faut trouver qq chose ici pour empecher les double saut !!!
if (App.GetInput().IsKeyDown(sf::Key::Up) && marioBody->GetLinearVelocity().y < 1 && marioBody->GetLinearVelocity().y > -1)
marioBody->ApplyLinearImpulse(b2Vec2(0, -9.0f), marioBody->GetWorldCenter());


Synchronize(groundBody, ground);
App.Draw(ground);

Synchronize(marioBody, mario);
App.Draw(mario);

for (i =  lstObj.begin(); i != lstObj.end(); ++i)
{
((myclass*)*i)->myupd();
((myclass*)*i)->mdraw(&App);
}


//App.Draw(sprite);

//Window draw
App.Display();

}
return 0;
}




Some screen :





Thanks in advance.

norb

  • Newbie
  • *
  • Posts: 2
    • View Profile
Some problem BOX2D/SFML
« Reply #1 on: August 02, 2010, 08:30:47 pm »
up ?