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

Author Topic: SFML / Box2D  (Read 5813 times)

0 Members and 1 Guest are viewing this topic.

Ambience

  • Newbie
  • *
  • Posts: 3
    • View Profile
SFML / Box2D
« on: May 20, 2011, 03:53:29 pm »
I've only been coding C++ for about 2 months so excuse my inexperience. I have created a little program that implements collision detection into SFML basically using a class I found on the wiki with my own "window border" detection that's a little buggy. You can find this source below...

Anyway, I want to implement FULL physics (gravity, collision, friction, etc) and B2D seems to be a perfect way to do this. Though I am completely lost in how to implement it into SFML.

From my understanding I have to create the "world" with B2D which sets the worlds gravity, then I have to individually add objects to the world. I have implemented the world (I THINK) successfully by doing this..
Code: [Select]

//int iterations = 10;
//float timestep = 1 / 60;
bool doSleep = true;
float scale = 30;
b2Vec2 Gravity(0, 9.8f);
b2AABB worldAABB;
worldAABB.lowerBound.Set( -1000 / scale, -1000 / scale );
worldAABB.upperBound.Set( 1000 / scale, 1000 / scale );

b2World* world;
world = new b2World(worldAABB, Gravity, doSleep);


The main problem I am having (granted, I haven't gone fully through the Box2D documentation yet) is adding SFML sprites into this Box2D world. The other problem I am having is how I would go about rendering the B2D world into the SFML window.

A fantastic help would be if anyone could replace the collision class used in the code below with Box2D implementation so I can see how it's done. However, I would be just as grateful if anyone could simply answer my questions on how to add SFML sprites to the Box2D world and render that world to the SFML window.

Collision Class
Main.cpp
Code: [Select]

#include <iostream>
#include <SFML\Graphics.hpp>
#include <SFML\Window.hpp>
#include "Collision.h"

using namespace sf;
void HandleKeys(RenderWindow &myWindow, Sprite &mySprite, Sprite &mySprite2);
void HandleCollision(RenderWindow &myWindow, Sprite &mySprite, Sprite &mySprite2);
void CheckWindowCollision(RenderWindow &myWindow, Sprite &mySprite, Sprite &mySprite2);

int main()
{
int cDetection;
std::cout << "1: Only check sprites for collision" << std::endl;
std::cout << "2: Check if sprites collide into eachother OR the walls (buggy)" << std::endl;
std::cout << "---------------------------------------------------------------" << std::endl;
std::cout << "What type of collision detection (1/2): ";
std::cin >> cDetection;

RenderWindow myWindow(VideoMode(800, 600, 32), "Collision Detection");
Image myImage;
myImage.LoadFromFile("circle.png");

Sprite mySprite(myImage);
Sprite mySprite2(myImage);

mySprite.SetColor(Color(0, 255, 255, 255));
mySprite.SetPosition(0.f, 100.f);
mySprite.SetScale(1.f, 1.f);

    mySprite2.SetColor(Color(0, 255, 255, 255));
    mySprite2.SetPosition(350.f, 100.f);
    mySprite2.SetScale(1.f, 1.f);

while (myWindow.IsOpened())
{
Event myEvent;
while (myWindow.GetEvent(myEvent))
{
if (myEvent.Type == Event::Closed)
myWindow.Close();
}

Collision cTest;

if (cTest.CircleTest(mySprite, mySprite2))
HandleCollision(myWindow, mySprite, mySprite2);

HandleKeys(myWindow, mySprite, mySprite2);

if (cDetection == 2)
CheckWindowCollision(myWindow, mySprite, mySprite2);

/*
if (myWindow.GetInput().IsMouseButtonDown(Mouse::Left))
std::cout << "MouseX: " << myWindow.GetInput().GetMouseX() << " || MouseY: "
<< myWindow.GetInput().GetMouseY() << std::endl;
*/

myWindow.Clear(Color::Color(255, 255, 255));
myWindow.Draw(mySprite);
myWindow.Draw(mySprite2);
myWindow.Display();

}
return 0;
}

void CheckWindowCollision(RenderWindow &myWindow, Sprite &mySprite, Sprite &mySprite2)
{
/*****Handle First Sprite*****/
if ( mySprite.GetPosition().x + mySprite.GetSize().x >= myWindow.GetWidth() )
mySprite.Move(-1, 0);
if ( mySprite.GetPosition().x <= 0 )
mySprite.Move(1, 0);
if ( mySprite.GetPosition().y + mySprite.GetSize().y >= myWindow.GetHeight() )
mySprite.Move(0, -1);
if ( mySprite.GetPosition().y <= 0)
mySprite.Move(0, 1);

/*****Handle Second Sprite*****/
if ( mySprite2.GetPosition().x + mySprite2.GetSize().x >= myWindow.GetWidth() )
mySprite2.Move(-1, 0);
if ( mySprite2.GetPosition().x <= 0 )
mySprite2.Move(1, 0);
if ( mySprite2.GetPosition().y + mySprite2.GetSize().y >= myWindow.GetHeight() )
mySprite2.Move(0, -1);
if ( mySprite2.GetPosition().y <= 0)
mySprite2.Move(0, 1);
}

void HandleCollision(RenderWindow &myWindow, Sprite &mySprite, Sprite &mySprite2)
{
/*****Handle First Direction*****/
if ((mySprite2.GetPosition().x > mySprite.GetPosition().x && myWindow.GetInput().IsKeyDown(Key::D)))
mySprite2.Move(1, 0);
if ((mySprite2.GetPosition().x > mySprite.GetPosition().x && myWindow.GetInput().IsKeyDown(Key::Left)))
mySprite.Move(-1, 0);
if ((mySprite2.GetPosition().y > mySprite.GetPosition().y && myWindow.GetInput().IsKeyDown(Key::S)))
mySprite2.Move(0, 1);
if ((mySprite2.GetPosition().y > mySprite.GetPosition().y && myWindow.GetInput().IsKeyDown(Key::Up)))
mySprite.Move(0, -1);

/*****Handle Second Direction*****/
if ((mySprite2.GetPosition().x < mySprite.GetPosition().x && myWindow.GetInput().IsKeyDown(Key::A)))
mySprite2.Move(-1, 0);
if ((mySprite2.GetPosition().x < mySprite.GetPosition().x && myWindow.GetInput().IsKeyDown(Key::Right)))
mySprite.Move(1, 0);
if ((mySprite2.GetPosition().y < mySprite.GetPosition().y && myWindow.GetInput().IsKeyDown(Key::W)))
mySprite2.Move(0, -1);
if ((mySprite2.GetPosition().y < mySprite.GetPosition().y && myWindow.GetInput().IsKeyDown(Key::Down)))
mySprite.Move(0, 1);

/***********************This would simply STOP objects instead of pushing them***********************
if ((mySprite2.GetPosition().y < mySprite.GetPosition().y && myWindow.GetInput().IsKeyDown(Key::S)))
mySprite2.Move(0, -1);
if ((mySprite2.GetPosition().y < mySprite.GetPosition().y && myWindow.GetInput().IsKeyDown(Key::Up)))
mySprite.Move(0, 1);
************************This would simply STOP objects instead of pushing them***********************/
}
void HandleKeys(RenderWindow &myWindow, Sprite &mySprite, Sprite &mySprite2)
{
Collision cTest;
float ElapsedTime = myWindow.GetFrameTime();

/*****Handle Sprite 1*****/
// Handle left
if ( (myWindow.GetInput().IsKeyDown(Key::A)) && (!cTest.CircleTest(mySprite2, mySprite)) )
mySprite.Move( -100 * ElapsedTime, 0 );
// Handle right
if ( (myWindow.GetInput().IsKeyDown(Key::D)) && (!cTest.CircleTest(mySprite2, mySprite)) )
mySprite.Move( 100 * ElapsedTime, 0 );
// Handle down
if ( (myWindow.GetInput().IsKeyDown(Key::W)) && (!cTest.CircleTest(mySprite2, mySprite)) )
mySprite.Move( 0, -100 * ElapsedTime );
// Handle up
if ( (myWindow.GetInput().IsKeyDown(Key::S)) && (!cTest.CircleTest(mySprite2, mySprite)) )
mySprite.Move( 0, 100 * ElapsedTime );

/*****Handle Sprite 2*****/
// Handle left
if ( (myWindow.GetInput().IsKeyDown(Key::Left)) && (!cTest.CircleTest(mySprite, mySprite2)) )
mySprite2.Move( -100 * ElapsedTime, 0 );
// Handle right
if ( (myWindow.GetInput().IsKeyDown(Key::Right)) && (!cTest.CircleTest(mySprite, mySprite2)) )
mySprite2.Move( 100 * ElapsedTime, 0 );
// Handle down
if ( (myWindow.GetInput().IsKeyDown(Key::Up)) && (!cTest.CircleTest(mySprite, mySprite2)) )
mySprite2.Move( 0, -100 * ElapsedTime );
// Handle up
if ( (myWindow.GetInput().IsKeyDown(Key::Down)) && (!cTest.CircleTest(mySprite, mySprite2)) )
mySprite2.Move( 0, 100 * ElapsedTime );
}


tags: box2d b2d sfml implementation physics gravity[/b]

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
SFML / Box2D
« Reply #1 on: May 23, 2011, 01:25:25 am »

Ambience

  • Newbie
  • *
  • Posts: 3
    • View Profile
SFML / Box2D
« Reply #2 on: May 23, 2011, 04:50:13 pm »
**EDIT**
Thanks a lot, I really appreciate the link. I had about 10 errors to start with, but they weren't hard to fix and now it works like a charm. Thanks to you I have a great start to learning how to implement physics into SFML with the B2D library!

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
SFML / Box2D
« Reply #3 on: May 23, 2011, 07:08:00 pm »
Actually if you could send me a fix for those issues that would be highly appreciated. A patch or even better a merge request would be nice.

Ambience

  • Newbie
  • *
  • Posts: 3
    • View Profile
SFML / Box2D
« Reply #4 on: May 23, 2011, 10:45:31 pm »
Yea, sure. I think the only line I had to change was..
Code: [Select]

class DebugDraw : public b2DebugDraw

to...
Code: [Select]

class DebugDraw : public b2Draw


I'm pretty sure that fixed all 10 of my errors, but I might have forgotten something. Let me know if it works.