Skip to content

Instantly share code, notes, and snippets.

@MrPlow442
Created July 11, 2013 17:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MrPlow442/5977338 to your computer and use it in GitHub Desktop.
Save MrPlow442/5977338 to your computer and use it in GitHub Desktop.
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <Box2D/Box2D.h>
#include <cmath>
#include <vector>
#include <iostream>
#include <sstream>
const float static SCALE = 30.0f; //constant for scaling pixel units of SFML into MKS and vice versa
/* Test class for game objects so that I don't have to copy a lot of code */
class GameObject
{
private:
b2Body* physicalBody;
sf::ConvexShape renderShape;
public:
static enum ObjectShape { Square, EqulateralTriangle };
GameObject(b2World& world, const GameObject::ObjectShape shape = GameObject::Square, const sf::Color &color = sf::Color::White, float xPos = 0.f, float yPos = 0.f, float sizeInPixels = 30.f)
{
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(xPos / SCALE , yPos / SCALE);
bodyDef.angle = -( b2_pi / 2.f );
physicalBody = world.CreateBody(&bodyDef);
b2PolygonShape bodyShape;
float sizeInMKS = sizeInPixels / SCALE;
switch (shape)
{
case EqulateralTriangle:
{
const int pointCount = 3;
b2Vec2 points[pointCount] = { b2Vec2(sizeInMKS,0), b2Vec2(-sizeInMKS,sizeInMKS), b2Vec2(-sizeInMKS,-sizeInMKS) };
bodyShape.Set(points, pointCount);
b2FixtureDef fixture;
fixture.shape = &bodyShape;
fixture.density = 1.0f;
fixture.friction = 0.3f;
fixture.restitution = 0.5f;
physicalBody->CreateFixture(&fixture);
renderShape.setPointCount(3);
renderShape.setPoint(0, sf::Vector2f((points[0].x * SCALE), (points[0].y * SCALE)));
renderShape.setPoint(1, sf::Vector2f((points[1].x * SCALE), (points[1].y * SCALE)));
renderShape.setPoint(2, sf::Vector2f((points[2].x * SCALE), (points[2].y * SCALE)));
break;
}
case Square:
default:
{
bodyShape.SetAsBox((sizeInPixels / 2.f) / SCALE, (sizeInPixels / 2.f) / SCALE);
b2FixtureDef fixture;
fixture.shape = &bodyShape;
fixture.density = 1.0f;
fixture.friction = 0.3f;
fixture.restitution = 0.5f;
physicalBody->CreateFixture(&fixture);
renderShape.setPointCount(4);
renderShape.setPoint(0, sf::Vector2f(0.f, 0.f));
renderShape.setPoint(1, sf::Vector2f(sizeInPixels, 0.f));
renderShape.setPoint(2, sf::Vector2f(sizeInPixels,sizeInPixels));
renderShape.setPoint(3, sf::Vector2f(0.f, sizeInPixels));
renderShape.setOrigin(sizeInPixels / 2.f, sizeInPixels / 2.f);
break;
}
}
renderShape.setFillColor(color);
renderShape.setPosition((physicalBody->GetPosition().x * SCALE), (physicalBody->GetPosition().y * SCALE));
renderShape.setRotation(physicalBody->GetAngle() * (180.0f/b2_pi));
}
~GameObject()
{
if(physicalBody != nullptr || physicalBody->GetWorld() != nullptr)
physicalBody->GetWorld()->DestroyBody(physicalBody);
}
void move(float speed)
{
b2Vec2 force(std::cos(physicalBody->GetAngle()) * speed, std::sin(physicalBody->GetAngle()) * speed);
physicalBody->ApplyForceToCenter(force);
}
void IncrementAngularVelocity(float vel)
{
if((physicalBody->GetAngularVelocity() + vel) < 3.f )
physicalBody->SetAngularVelocity(physicalBody->GetAngularVelocity() + vel);
else
physicalBody->SetAngularVelocity(3.f);
}
b2Vec2 getBodyCenter()
{
return physicalBody->GetLocalCenter();
}
const sf::Vector2f& getPosition() const
{
return renderShape.getPosition();
}
float getBodyAngle() const
{
return physicalBody->GetAngle() * (180.f/b2_pi);
}
float getShapeAngle() const
{
return renderShape.getRotation();
}
float getAngularVelocity() const
{
return physicalBody->GetAngularVelocity();
}
const b2Vec2& getLinearVelocity() const
{
return physicalBody->GetLinearVelocity();
}
void update()
{
renderShape.setPosition(physicalBody->GetPosition().x * SCALE, physicalBody->GetPosition().y * SCALE);
renderShape.setRotation((physicalBody->GetAngle() * (180.0f/b2_pi)));
}
void render(sf::RenderWindow& renderWindow)
{
renderWindow.draw(renderShape);
}
};
int main()
{
/* Create window and limit the framerate */
sf::RenderWindow window(sf::VideoMode(1024,768, 32), "Test");
//window.setFramerateLimit(60); //When FPS is limited things get a bit choppy
//window.setVerticalSyncEnabled(true); //Doesn't help against choppyness
/* Initialize font */
sf::Font mainFont;
if(!mainFont.loadFromFile("LeagueGothic-Regular.otf"))
{
return 1;
}
/* Initialize debug text */
sf::Text fpsCounter;
fpsCounter.setFont(mainFont);
fpsCounter.setColor(sf::Color::White);
sf::Text debugInfo;
debugInfo.setFont(mainFont);
debugInfo.setColor(sf::Color::White);
debugInfo.setScale(0.5f, 0.5f);
debugInfo.setPosition(0.f, static_cast<float>(window.getSize().y) - static_cast<float>(window.getSize().y/6) );
/* Initialize background texture */
sf::Texture starsTexture;
if(!starsTexture.loadFromFile("stars.png"))
{
return 1;
}
starsTexture.setSmooth(true);
starsTexture.setRepeated(true);
/* Initialize background sprite */
sf::Sprite stars;
stars.setTexture(starsTexture, true);
stars.setScale(2,2);
stars.setOrigin(stars.getTextureRect().width / 2.0f, stars.getTextureRect().height / 2.0f);
/* Create a stringstream for conversion purposes */
std::stringstream sstream;
/* Create physical world and set it's gravity */
b2World world(b2Vec2(0.f, 0.f)); // SPAAAAAAACE
world.SetAllowSleeping(true);
/* constants for time step and physics accuracy */
const float timeStep = 1.0f / 60.0f;
const int velocityIterations = 6;
const int positionIterations = 2;
/* Create some objects */
GameObject player(world, GameObject::EqulateralTriangle, sf::Color::Red, static_cast<float>(window.getSize().x / 2), static_cast<float>(window.getSize().y / 2));
GameObject square(world, GameObject::Square, sf::Color::Green, static_cast<float>(window.getSize().x / 2) + 70, static_cast<float>(window.getSize().y / 2)+ 70);
/* Static body to test collisions and proper box2D/SFML alignment */
b2BodyDef testFloor;
testFloor.type = b2_staticBody;
float floorX = (window.getSize().x / 2.f) / SCALE;
float floorY = (window.getSize().y - (window.getSize().y / 10)) / SCALE;
testFloor.position.Set(floorX, floorY);
b2Body* floorBody = world.CreateBody(&testFloor);
float halfHeight = 20.f;
float halfWidth = 400.f;
b2PolygonShape floorShape;
floorShape.SetAsBox(halfWidth / SCALE, halfHeight / SCALE);
b2FixtureDef floorFixture;
floorFixture.density = 0.f;
floorFixture.shape = &floorShape;
floorBody->CreateFixture(&floorFixture);
sf::RectangleShape floorSprite(sf::Vector2f(halfWidth * 2 , halfHeight * 2));
floorSprite.setFillColor(sf::Color::White);
floorSprite.setOrigin(halfWidth, halfHeight);
floorSprite.setPosition(floorBody->GetPosition().x * SCALE, floorBody->GetPosition().y * SCALE);
/* initialize the camera */
sf::View camera;
camera.reset(sf::FloatRect(0.f, 0.f, window.getSize().x, window.getSize().y));
camera.setCenter(sf::Vector2f(player.getPosition().x, player.getPosition().y));
/* Set the sprite position to camera */
stars.setPosition(camera.getCenter());
sf::Clock deltaClock;
while(window.isOpen())
{
sf::Time deltaTime = deltaClock.restart();
sf::Event event;
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed || (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape))
window.close();
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
float speedConst = 300.0f;
player.move(speedConst * deltaTime.asSeconds());
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
float speedConst = -300.0f;
player.move(speedConst * deltaTime.asSeconds());
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
player.IncrementAngularVelocity(-1.5f * deltaTime.asSeconds());
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
player.IncrementAngularVelocity(1.5f * deltaTime.asSeconds());
}
world.Step(timeStep,velocityIterations,positionIterations);
player.update();
square.update();
camera.setCenter(sf::Vector2f(player.getPosition().x, player.getPosition().y));
window.clear(sf::Color::Color(40,0,70));
//First attempt at creating some sort of parallax scrolling
{
float xPos = camera.getCenter().x;
float yPos = camera.getCenter().y;
float xVel = player.getLinearVelocity().x * SCALE;
float yVel = player.getLinearVelocity().y * SCALE;
stars.setTextureRect(sf::IntRect((xPos + xVel / 2.f) , (yPos + yVel / 2.f) , starsTexture.getSize().x, starsTexture.getSize().y));
}
window.draw(stars);
window.setView(camera);
sstream.precision(0);
sstream << std::fixed << "FPS: " << 1.f / deltaTime.asSeconds();
fpsCounter.setString(sstream.str());
window.draw(floorSprite);
player.render(window);
square.render(window);
window.setView(window.getDefaultView());
window.draw(fpsCounter);
sstream.str("");
sstream.precision(2);
sstream << std::fixed
<< "AngularVel: " << player.getAngularVelocity()
<< "\n Vel: x= " << player.getLinearVelocity().x
<< " y= " << player.getLinearVelocity().y
<< "\n BodyAngle: " << player.getBodyAngle()
<< " , ShapeAngle: " << player.getShapeAngle()
<< "\n Pos: x = " << player.getPosition().x
<< " , y= " << player.getPosition().y
<< "\n View Pos: x= " << camera.getCenter().x
<< " , y= " << camera.getCenter().y
<< "\nLocal Center: " << square.getBodyCenter().x << " , " << square.getBodyCenter().y;
debugInfo.setString(sstream.str());
window.draw(debugInfo);
sstream.str("");
window.display();
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment