Simple SFML/Box2D help

  • (2 Pages)
  • +
  • 1
  • 2

25 Replies - 13014 Views - Last Post: 05 August 2011 - 09:53 PM Rate Topic: -----

#1 dartoscoder  Icon User is offline

  • D.I.C Regular

Reputation: 0
  • View blog
  • Posts: 313
  • Joined: 15-May 09

Simple SFML/Box2D help

Posted 04 August 2011 - 10:08 AM

I need to find a program that just very simply demonstrated how to use box2d and sfml.

Does anyone out there have one?

Or,
if you can help me fix this.
#include <box2d\box2d.h>
#include <SFML\window.hpp>
#include <SFML\graphics.hpp>

#define PIXLE_PER_METER  30.0f
#define METERS_PER_PIXLE (1.0f/PIXLE_PER_METER)

#define PPM PIXLE_PER_METER
#define MPP METERS_PER_PIXLE

float screenW = 800;
float screenH = 600;

int main()
{
    //set up the world
    b2Vec2 gravity(0.0f, 9.8f);
    b2World* world = new b2World(gravity, true);

    //set up the render window
    sf::RenderWindow* window = new sf::RenderWindow(sf::VideoMode(screenW, screenH, 32), "phys");
    window->Clear(sf::Color(0,0,0));

    b2BodyDef groundBodyDef;

    groundBodyDef.position.Set(screenW/2*MPP, screenH*MPP);

    b2Body* groundBody = world->CreateBody(&groundBodyDef);
    b2PolygonShape groundBox;
    groundBox.SetAsBox(800*MPP, 5*MPP);
    groundBody->CreateFixture(&groundBox, 0.0f);



    sf::Shape box = sf::Shape::Rectangle(0,0, groundBodyDef.position.x/MPP, groundBodyDef.position.y/MPP, sf::Color(255,0,0));

    sf::Event ev;

    while(window->IsOpened())
    {
        

        //random value just for now
        world->Step(60, 3, 5);


        while(window->GetEvent(ev))
        {
            if(ev.Type == sf::Event::Closed)
            {
                window->Close();
            }
        }

        window->Draw(box);
        window->Display();


    }

}



The sfml box takes up half the screen when i made it model after the groundBody object.

thanks,
dartos

Is This A Good Question/Topic? 0
  • +

Replies To: Simple SFML/Box2D help

#2 Hezekiah  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 208
  • View blog
  • Posts: 552
  • Joined: 12-July 09

Re: Simple SFML/Box2D help

Posted 04 August 2011 - 12:22 PM

Before I start giving advice I just want to say that I haven't worked with Box2D, however I have with SFML.

1) Instead of using the PPM and MPP macros, use a view, then you can specify the SFML coordinates in meters too.

2) I would personally create some kind of Object class:
class Object {
    public:
        Object(float positionX, float positionY, float width, float height, b2World& world, const sf::Color& color) {
            _def.position.Set(positionX, positionY);
            _body = world.CreateBody(&_def);
            _polygon.SetAsBox(width, height);
            _body->CreateFixture(&_polygon, 0.f);
            _shape = sf::Shape::Rectangle(0.f, 0.f, positionX, positionY, color);
        }
        //more functions
    private:
        b2BodyDef _def;
        b2Body* _body;
        b2PolygonShape _polygon;
        sf::Shape _shape;
};

Once again, I don't have any experience with Box2D and this code isn't tested. I would probably create some other classes too, but this one is the most important.

3) Remember to free dynamic memory.
Was This Post Helpful? 0
  • +
  • -

#3 dartoscoder  Icon User is offline

  • D.I.C Regular

Reputation: 0
  • View blog
  • Posts: 313
  • Joined: 15-May 09

Re: Simple SFML/Box2D help

Posted 04 August 2011 - 02:01 PM

okay thank you for that but how do i get the SFMl shape to be in sync with the Box2d ones.
Was This Post Helpful? 0
  • +
  • -

#4 dartoscoder  Icon User is offline

  • D.I.C Regular

Reputation: 0
  • View blog
  • Posts: 313
  • Joined: 15-May 09

Re: Simple SFML/Box2D help

Posted 04 August 2011 - 02:25 PM

View PostHezekiah, on 04 August 2011 - 01:22 PM, said:

Before I start giving advice I just want to say that I haven't worked with Box2D, however I have with SFML.

1) Instead of using the PPM and MPP macros, use a view, then you can specify the SFML coordinates in meters too.


How would i use a view instead?
Was This Post Helpful? 0
  • +
  • -

#5 ishkabible  Icon User is offline

  • spelling expret
  • member icon





Reputation: 1741
  • View blog
  • Posts: 5,895
  • Joined: 03-August 09

Re: Simple SFML/Box2D help

Posted 04 August 2011 - 02:27 PM

didn't you already have a topic about this? were i showed this and gave several links on it? could you be more specific as to what you are trying to do?
Was This Post Helpful? 0
  • +
  • -

#6 dartoscoder  Icon User is offline

  • D.I.C Regular

Reputation: 0
  • View blog
  • Posts: 313
  • Joined: 15-May 09

Re: Simple SFML/Box2D help

Posted 04 August 2011 - 03:52 PM

View Postishkabible, on 04 August 2011 - 03:27 PM, said:

didn't you already have a topic about this? were i showed this and gave several links on it? could you be more specific as to what you are trying to do?

Not this exact topic.

All i am trying to do is make a box in the right place by using coordinates from the box2d body.
The box should be at the bottom of the window.

the problem is that SFML flips the y axis and Box2d uses meters instead of pixels so... i think its the conversions that are screwing me up.
Was This Post Helpful? 0
  • +
  • -

#7 ishkabible  Icon User is offline

  • spelling expret
  • member icon





Reputation: 1741
  • View blog
  • Posts: 5,895
  • Joined: 03-August 09

Re: Simple SFML/Box2D help

Posted 04 August 2011 - 04:41 PM

SFML probably dose flip the y-axis as do most graphic libraries(they don't actually 'flip' it, it's just the way OSs do things i believe) but that is actually pretty easy fix, absolute value of the difference in fact. as for the conversions you have to base it on your world box. basically you need to match your world box to your screen and preform the conversions accordingly. it's a simple mater of weight ratios :)

This post has been edited by ishkabible: 04 August 2011 - 04:42 PM

Was This Post Helpful? 0
  • +
  • -

#8 dartoscoder  Icon User is offline

  • D.I.C Regular

Reputation: 0
  • View blog
  • Posts: 313
  • Joined: 15-May 09

Re: Simple SFML/Box2D help

Posted 04 August 2011 - 08:59 PM

I would do that but the world has no dimensions.

Here is my code thus far

#include <box2d\box2d.h>
#include <SFML\window.hpp>
#include <SFML\graphics.hpp>

#define PIXLE_PER_METER  30.0f
#define METERS_PER_PIXLE (1.0f/PIXLE_PER_METER)

#define PPM PIXLE_PER_METER
#define MPP METERS_PER_PIXLE

float screenW = 800;
float screenH = 600;

int main()
{
    //set up the world
    b2Vec2 gravity(0.0f, 9.8f);
    b2World* world = new b2World(gravity, true);
    

    //set up the render window
    sf::RenderWindow* window = new sf::RenderWindow(sf::VideoMode(screenW, screenH, 32), "phys");
    window->Clear(sf::Color(0,0,0));

    b2BodyDef groundBodyDef;

    groundBodyDef.position.Set(screenW/2*MPP, -screenH*MPP);

    b2Body* groundBody = world->CreateBody(&groundBodyDef);
    b2PolygonShape groundBox;
    groundBox.SetAsBox(400/PPM, 2/PPM);
    groundBody->CreateFixture(&groundBox, 0.0f);



    sf::Shape box = sf::Shape::Rectangle(0,0, 800, 4, sf::Color(255,0,0));

    box.SetPosition(groundBodyDef.position.x/MPP*2, groundBodyDef.position.y/MPP*2);



    sf::Event ev;

    while(window->IsOpened())
    {


        //random value just for now
        world->Step(60, 3, 5);


        while(window->GetEvent(ev))
        {
            if(ev.Type == sf::Event::Closed)
            {
                window->Close();
            }
        }

        window->Draw(box);
        window->Display();


    }

}



The problem is that the red SFML bar doesn't match up with the Box2d ground object.

This post has been edited by dartoscoder: 04 August 2011 - 09:06 PM

Was This Post Helpful? 0
  • +
  • -

#9 Hezekiah  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 208
  • View blog
  • Posts: 552
  • Joined: 12-July 09

Re: Simple SFML/Box2D help

Posted 04 August 2011 - 10:07 PM

In SFML the y axis is down, but I don't think Box2D cares which way is up (it can be the x axis too). You've already made gravity in the positive y direction, so that shouldn't be a problem. As for using views, try something like this:
//pixelWidth and pixelHeight are the size of the window in pixels
//meterWidth and meterHeight are the size of the window in meters
//title is the window title
sf::RenderWindow window(sf::VideoMode(pixelWidth, pixelHeight), title);
sf::View view(sf::FloatRect(0.f, 0.f, meterWidth, meterHeight));
window.SetView(view);
//now you can give SFML coordinates in meters too

Edit: I assume b2PolygonShape::SetAsBox takes half the width and height as parameters, in which case I understand why you make the sf::Shape twice as big. However I don't know why you have *2 in your call to box.SetPosition. I'm not sure if sf::Shape::Rectangle sets the center to the center of the rectangle. You might want to try adding:
box.SetCenter(400.f, 2.f);

This post has been edited by Hezekiah: 05 August 2011 - 01:09 AM

Was This Post Helpful? 0
  • +
  • -

#10 dartoscoder  Icon User is offline

  • D.I.C Regular

Reputation: 0
  • View blog
  • Posts: 313
  • Joined: 15-May 09

Re: Simple SFML/Box2D help

Posted 05 August 2011 - 06:27 AM

Thanks for the input on views that should help a alot.
as for the *2 the b2Polygon takes half heght and width (as you said) so i need to multiply that when i put it into the shape.
Was This Post Helpful? 0
  • +
  • -

#11 Hezekiah  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 208
  • View blog
  • Posts: 552
  • Joined: 12-July 09

Re: Simple SFML/Box2D help

Posted 05 August 2011 - 06:54 AM

I understand why you multiply the size by 2, but why are you doing the same to the position?
box.SetPosition(groundBodyDef.position.x/MPP*2, groundBodyDef.position.y/MPP*2);

This post has been edited by Hezekiah: 05 August 2011 - 06:55 AM

Was This Post Helpful? 0
  • +
  • -

#12 dartoscoder  Icon User is offline

  • D.I.C Regular

Reputation: 0
  • View blog
  • Posts: 313
  • Joined: 15-May 09

Re: Simple SFML/Box2D help

Posted 05 August 2011 - 07:12 AM

View PostHezekiah, on 05 August 2011 - 07:54 AM, said:

I understand why you multiply the size by 2, but why are you doing the same to the position?
box.SetPosition(groundBodyDef.position.x/MPP*2, groundBodyDef.position.y/MPP*2);


I see you point... Okay i fixed that and i put in views here is the new code:
#include <box2d\box2d.h>
#include <SFML\window.hpp>
#include <SFML\graphics.hpp>
#include <iostream>

#define PIXLE_PER_METER  644.0f
#define METERS_PER_PIXLE (1.0f/PIXLE_PER_METER)

#define PPM PIXLE_PER_METER
#define MPP METERS_PER_PIXLE

float screenW = 800.f;
float screenH = 600.f;

int main()
{
    //set up the world
    b2Vec2 gravity(0.0f, 9.8f);
    b2World* world = new b2World(gravity, true);




    //set up the render window
    sf::RenderWindow* window = new sf::RenderWindow(sf::VideoMode(screenW, screenH, 32), "phys");
    window->Clear(sf::Color(0,0,0));
    sf::View view(sf::FloatRect(0.f, 0.f, screenW/PPM, screenH/PPM));
    window->SetView(view);

    b2BodyDef groundBodyDef;

    groundBodyDef.position.Set(window->GetView().GetRect().GetWidth()/2/PPM, window->GetView().GetRect().GetHeight()/PPM);

    b2Body* groundBody = world->CreateBody(&groundBodyDef);
    b2PolygonShape groundBox;
    groundBox.SetAsBox(400/PPM, 2/PPM);
    groundBody->CreateFixture(&groundBox, 0.0f);


    b2BodyDef groundBodyDef2;

    groundBodyDef2.position.Set(screenW/2/PPM, screenH/2/PPM);

    b2Body* groundBody2 = world->CreateBody(&groundBodyDef2);
    b2PolygonShape groundBox2;
    groundBox2.SetAsBox(2.5f/PPM, 2.5f/PPM);
    groundBody2->CreateFixture(&groundBox2, 56.0f);



    sf::Shape box = sf::Shape::Rectangle(0,0, 800/PPM, 4/PPM, sf::Color(255,0,0));
    sf::Shape box2 = sf::Shape::Rectangle(0,0, 2.5f/PPM, 2.5f/PPM, sf::Color(255,0,0));

   box.SetPosition(groundBodyDef.position.x, groundBodyDef.position.y);
   box2.SetPosition(groundBodyDef2.position.x, groundBodyDef2.position.y);



    sf::Event ev;

    while(window->IsOpened())
    {


        //random value just for now
        world->Step(60, 3, 5);


        while(window->GetEvent(ev))
        {
            if(ev.Type == sf::Event::Closed)
            {
                window->Close();
            }
        }

        //just to make sure [email protected] si doing its job.
        std::cout << groundBodyDef2.position.x << std::endl;



        //Set the box's new position every pass over the loop.
        box2.SetPosition(groundBodyDef2.position.x, groundBodyDef2.position.y);

        window->Draw(box);
        window->Draw(box2);
        window->Display();


    }
    delete world;
    delete window;

}



But box2 doesn't update :helpsmilie:.

I am not sure why.
Was This Post Helpful? 0
  • +
  • -

#13 Hezekiah  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 208
  • View blog
  • Posts: 552
  • Joined: 12-July 09

Re: Simple SFML/Box2D help

Posted 05 August 2011 - 07:48 AM

Try:
groundBody.SetType(b2_dynamicBody);

I think the default type is a static body, which means it can't move. Setting it to a dynamic body means it can move.
Was This Post Helpful? 0
  • +
  • -

#14 dartoscoder  Icon User is offline

  • D.I.C Regular

Reputation: 0
  • View blog
  • Posts: 313
  • Joined: 15-May 09

Re: Simple SFML/Box2D help

Posted 05 August 2011 - 08:32 AM

Oh your right i forgot that. :death:

Let me try that now
Was This Post Helpful? 0
  • +
  • -

#15 dartoscoder  Icon User is offline

  • D.I.C Regular

Reputation: 0
  • View blog
  • Posts: 313
  • Joined: 15-May 09

Re: Simple SFML/Box2D help

Posted 05 August 2011 - 08:37 AM

well i put that in there. No dice. I still trying to figure it out
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2