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

Author Topic: SFML and Box2D  (Read 8848 times)

0 Members and 1 Guest are viewing this topic.

Astrof

  • Full Member
  • ***
  • Posts: 135
    • View Profile
SFML and Box2D
« on: April 03, 2009, 12:46:33 am »
I'm trying to set up Box2D with SFML.  I am kind of confused when it comes to setting up Box2D.  I was wondering if someone had example code that I could use or if someone could help me out with a few questions concerning both libs put together.  

Basically I have SFML::Drawables in my game.  How do I give them Shapes, etc in Box2D so that I can perform collisions with Box2D?  How do I set up the Box2D world (my window is 1024x768...so how big should my World be then)?  If I move an object in Box2D do I have to copy the movement back into the SFML Drawable?  

I am planning on using Box2D mainly for collision.

Imbue

  • Full Member
  • ***
  • Posts: 104
    • View Profile
SFML and Box2D
« Reply #1 on: April 03, 2009, 06:58:16 am »
Let me give you a hint that would have saved me some time: SFML defines rotation as degrees going clockwise, Box2D uses radians going counterclockwise.

Other things to consider: It's nice for game logic to have the ground level be at 0. SFML, by default, has Y getting greater towards the bottom of the screen. You can either tweak the numbers yourself, or use a sf::View to mirror the Y. Also, in Box2D, you'll want sizes to be in meters, not pixels. Again, convert between by yourself, or just use a sf::View.

You may also want to consider Chipmunk, if you haven't. Box2D has many more features, but for collision detection you probably don't care about them.

What kind of game are you making?

Astrof

  • Full Member
  • ***
  • Posts: 135
    • View Profile
SFML and Box2D
« Reply #2 on: April 03, 2009, 05:05:49 pm »
I'm making a scrolling space shooter so I don't think I'll really have a ground.  Also I saw that Box2D was faster than Chipmunk.  Also eventually I want to make a platformer (probably a Sonic Clone).

So what should I do to match units?  how do pixels and meters coincide (what conversion factor do I have to use)?

Astrof

  • Full Member
  • ***
  • Posts: 135
    • View Profile
SFML and Box2D
« Reply #3 on: April 07, 2009, 06:04:13 am »
So I tried to set up Box2D for my game and I broke it.  I'm pretty sure its the scaling factor I used to get from pixels to meters (I pretty much just divided by a factor of ten) and I completely broke Box2D.  It stuttered for a bit and after a while threw an exception.  

Anyway I wanted to re-ask how to scale my units.  I've never used an sf::View before nor do I know how to convert from pixel to meter coordinates.  I do know that my screen size is 1024 x 768.  My test image is a 32 x 32 circle.  How do I set up stuff then? Do I divide the screen size by the width and height to get units that way? All I know is I'm very confused when it comes to setting up Box2D (with SFML).

Imbue

  • Full Member
  • ***
  • Posts: 104
    • View Profile
SFML and Box2D
« Reply #4 on: April 07, 2009, 07:18:14 am »
You should read the sf::View tutorial. Then I'd recommend making a view in your meter units.

So you might make a view with:
sf::View v(-5, 10, 5, 0);
To view an area 10 by 10 meters. Then when you draw your sprites, you can draw them in meters. So you'll have to really scale them down a lot. e.g. if you sprite is 100 pixels wide, but it represents and object 1 meter wide, you may scale it with by .01.

Astrof

  • Full Member
  • ***
  • Posts: 135
    • View Profile
SFML and Box2D
« Reply #5 on: April 12, 2009, 06:21:13 pm »
Currently I'm trying to get by with just using a physics scale and scaling up and down between Box2D and SFML.  I might try to use views later.  

However currently I'm having trouble defining shapes between Box2D and SFML.  My player contains a Sprite of an image but overlaying the Sprite is a Circle for a shield.  Now for the b2Body associated with the player I want it to be a circle when the shields are up and a composition of shapes when shields are down.  Currently I'm testing collision with the Circle idea, but I can't seem to get it to work.  I think the problem is with how I set up the position, center, etc of shapes and sprites in SFML vs bodies and shapes in Box2D.    Anyone have any tips for this? I know the problem is probably simple, but it has been vexing me for a while.  

Here's a run down on how I set up the Shape in SFML:
I take the max of the player's width and height and add 10 to it, the final value being the diameter.  
I then set up the circle Shape given a Sprite's position, the diameter, etc.
I had to hack at the position until it centered it (not the best idea but it worked at the time) adding or subtracting by the Sprite's size to the Shape's x and y.  
I then pass the Shape's position to the b2Body.  

Now I know something is wrong but can't pinpoint it.  The collision appears to be off on one side and the body also appears to be slightly larger than I wanted (I pass the radius/physScale to the body).


EDIT: I hacked my way at it again and I kind of got it working.  Seems problem was Sprites "center" themselves at the top left corner while Circles center themselves...well at their center.  I knew this but somewhere I forgot something somewhere.  Still right now its a brute forced way...but yeah.

dwarfman78

  • Full Member
  • ***
  • Posts: 228
  • I'm bietzsche, Nietzsche !
    • MSN Messenger - cd4c@hotmail.com
    • View Profile
    • Email
SFML and Box2D
« Reply #6 on: April 14, 2009, 05:15:23 pm »
I'm using it this way :

Code: [Select]

if((*shape).GetNbPoints()<=8)
{// box2D can handle shapes with 8 points max

b2PolygonDef shapeDef;
shapeDef.vertexCount = (*shape).GetNbPoints();

// we set the shape at 0,0 so that the global SFML coordinates fit the Box2D coordinates system

(*shape).SetPosition(0,0);

for(unsigned int j=0; j<(unsigned int)shapeDef.vertexCount; ++j)
{// for each point of the shape
shapeDef.vertices[j].Set(ToolBox::toMeter((*shape).TransformToGlobal((*shape).GetPointPosition(j)).x),ToolBox::toMeter((*shape).TransformToGlobal((*shape).GetPointPosition(j)).y));
}

// we set the common shape params
// set the box density
shapeDef.density = density;

// override the default friction
shapeDef.friction = friction;

// finally we add the shape to the body
this->myBody->CreateShape(&(shapeDef));
}
else
{// SFML circle has more than 8 points ... if your shape has more than 8 points it'll be considered as a circle

// circle definition
b2CircleDef circleShape;

float centerPosX, pointPosX, centerPosY, pointPosY;

centerPosX = (*shape).GetPosition().x; // we set the xpos of the center
centerPosY = (*shape).GetPosition().y; // we set the y pos of the center

pointPosX = (*shape).GetPointPosition(1).x; // xpos of a point of the circle
pointPosY = (*shape).GetPointPosition(1).y; // ypos of the same point

// we calculate the radius sqrt((XA-XB)²+(YA-YB)²)
circleShape.radius = ((centerPosX-pointPosX)*(centerPosX-pointPosX));
circleShape.radius +=  ((centerPosY-pointPosY)*(centerPosY-pointPosY));
circleShape.radius = ToolBox::toMeter(sqrt(circleShape.radius));

// we set the density
circleShape.density = density;

// we set the friction
circleShape.friction = friction;

// finally we create the shape from the circleShape
this->myBody->CreateShape(&(circleShape));

}
@dwarfman78
github.com/dwarfman78

Astrof

  • Full Member
  • ***
  • Posts: 135
    • View Profile
SFML and Box2D
« Reply #7 on: April 14, 2009, 07:34:44 pm »
Awesome, I shall look through the code.  One question, what is Toolbox?

dwarfman78

  • Full Member
  • ***
  • Posts: 228
  • I'm bietzsche, Nietzsche !
    • MSN Messenger - cd4c@hotmail.com
    • View Profile
    • Email
SFML and Box2D
« Reply #8 on: April 15, 2009, 09:13:00 am »
Toolbox is a class of mine. It provides static methods such as meter to pixel

Code: [Select]

float ToolBox::toPix(float meters)
{
return meters*FACTOR;
}


Where FACTOR is a static float of 30.0f to convert from box2D coordinates in meters to SFML in pixels.

As said before, Box2D uses rads and SFML uses degrees so you need to convert too :


Code: [Select]

this->myDrawable->SetPosition(ToolBox::b2VecToSfVec(this->myBody->GetPosition())); this->myDrawable->SetRotation(-ToolBox::getInstance()->toDegree(this->myBody->GetAngle()));
@dwarfman78
github.com/dwarfman78