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..
//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 ClassMain.cpp
#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]