Hello,
I have a simple physics playground using SFML for the graphics and Box2D for the physics. However, I am unable to get a proper way to deal with memory management or garbage collection. A way to remove the bodies after they are no longer used. The code itself works. Just can't figure out a good way to deal with the bodies that are no longer on the screen or not needed.
Also, while I'm at, is there a better way to show code on the forums? Like a code-box? Instead of just high-lightingting the selected code.
#include <iostream>
#include <SFML\System.hpp>
#include <SFML\Graphics.hpp>
#include <Box2D\Box2D.h>
using namespace std;
const int MAX_BOX_BODIES = 10;
const int MAX_CIRCLE_BODIES = 10;
const float SCALE = 32.0f;
int box_bodies, circle_bodies;
void AddBox(b2World& world,int mx,int my);
void AddCircle(b2World& world, int mx,int my);
void AddPlatform(b2World& world, int x, int y);
void AddTrampoline(b2World& world, int x, int y);
sf::RenderWindow GameWin;
sf::Event event;
b2Body* bodies;
bool Running = true;
bool PhysicsPaused = true;
int main(int argc, char* argv[])
{
GameWin.create(sf::VideoMode(800, 600, 32), "Physics Test");
b2Vec2 graivty(0, 9.8f);
b2World world(graivty);
AddPlatform(world, 400, 5);
AddPlatform(world, 400, 580);
AddTrampoline(world, 400, 300);
while (GameWin.isOpen())
{
while (GameWin.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
GameWin.close();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
{
GameWin.close();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
int mx = sf::Mouse::getPosition(GameWin).x;
int my = sf::Mouse::getPosition(GameWin).y;
AddBox(world, mx, my);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
int mx = sf::Mouse::getPosition(GameWin).x;
int my = sf::Mouse::getPosition(GameWin).y;
AddCircle(world, mx, my);
}
}
world.Step(1 / 60.0f, 8, 3);
GameWin.clear();
for ( bodies = world.GetBodyList(); bodies != 0; bodies = bodies->GetNext())
{
if (bodies->GetType() == b2_dynamicBody && bodies->GetUserData() == "Box")
{
sf::RectangleShape rect;
rect.setSize(sf::Vector2f(10.0f, 10.0f));
rect.setOrigin(sf::Vector2f(16.0f, 16.0f));
rect.setFillColor(sf::Color(255, 0, 0));
rect.setPosition(SCALE *bodies->GetPosition().x, SCALE * bodies->GetPosition().y);
rect.setRotation(bodies->GetAngle() * 180 / b2_pi);
GameWin.draw(rect);
}
else if (bodies->GetType() == b2_dynamicBody && bodies->GetUserData() == "Circle")
{
sf::CircleShape circ;
circ.setRadius(10.0f);
circ.setFillColor(sf::Color(0, 255, 0));
circ.setPosition(bodies->GetPosition().x * SCALE, bodies->GetPosition().y * SCALE);
circ.setRotation(bodies->GetAngle() * 180 / b2_pi);
GameWin.draw(circ);
}
else if (bodies->GetType() == b2_staticBody && bodies->GetUserData() == "Platform")
{
sf::RectangleShape rect;
rect.setSize(sf::Vector2f(600, 10));
rect.setFillColor(sf::Color(0, 0, 255));
rect.setOrigin(rect.getLocalBounds().width / 2, rect.getLocalBounds().height / 2);
rect.setPosition(bodies->GetPosition().x * SCALE, bodies->GetPosition().y * SCALE);
GameWin.draw(rect);
box_bodies++;
}
else if (bodies->GetType() == b2_staticBody && bodies->GetUserData() == "Trampoline")
{
sf::RectangleShape rect;
rect.setSize(sf::Vector2f(100, 30));
rect.setFillColor(sf::Color(0, 0, 255));
rect.setOrigin(rect.getLocalBounds().width / 2, rect.getLocalBounds().height / 2);
rect.setPosition(bodies->GetPosition().x * SCALE, bodies->GetPosition().y * SCALE);
GameWin.draw(rect);
}
}
GameWin.display();
}
return 0;
}
void AddBox(b2World& world, int mx, int my)
{
b2BodyDef def;
def.position = b2Vec2(mx / SCALE, my / SCALE);
def.type = b2_dynamicBody;
def.userData = "Box";
b2Body* body = world.CreateBody(&def);
b2PolygonShape shape;
shape.SetAsBox((32.0f / 2) / SCALE, (32.0f / 2) / SCALE);
b2FixtureDef fix;
fix.density = 5.0f;
fix.friction = 1.0f;
fix.restitution = 0.1f;
fix.shape = &shape;
body->CreateFixture(&fix);
box_bodies++;
if (box_bodies == MAX_BOX_BODIES)
{
for (body = world.GetBodyList(); body = 0; body = body->GetNext())
{
world.DestroyBody(body);
}
}
}
void AddCircle(b2World& world,int mx,int my)
{
b2BodyDef def;
def.type = b2_dynamicBody;
def.position = b2Vec2(mx / SCALE, my / SCALE);
def.userData = "Circle";
b2Body* body = world.CreateBody(&def);
b2CircleShape circle;
circle.m_radius = 15.0f / SCALE;
b2FixtureDef fix;
fix.density = 5.0f;
fix.friction = 1.0f;
fix.restitution = 0.9f;
fix.shape = &circle;
body->CreateFixture(&fix);
}
void AddPlatform(b2World& world, int x, int y)
{
b2BodyDef def;
def.position = b2Vec2(x / SCALE, y / SCALE);
def.type = b2_staticBody;
def.userData = "Platform";
b2Body* body = world.CreateBody(&def);
b2PolygonShape shape;
shape.SetAsBox(10, 0);
b2FixtureDef fix;
fix.density = 2.0f;
fix.restitution = 0.1f;
fix.friction = 0.5f;
fix.shape = &shape;
body->CreateFixture(&fix);
}
void AddTrampoline(b2World& world, int x, int y)
{
b2BodyDef def;
def.position = b2Vec2(x / SCALE, y / SCALE);
def.type = b2_staticBody;
def.userData = "Trampoline";
b2Body* body = world.CreateBody(&def);
b2PolygonShape shape;
shape.SetAsBox(1, 0);
b2FixtureDef fix;
fix.density = 2.0f;
fix.restitution = 1.5f;
fix.friction = 0.5f;
fix.shape = &shape;
body->CreateFixture(&fix);
}