# include "imgui.h"
# include "imgui-SFML.h"
# define _USE_MATH_DEFINES
# include <math.h>
# include <fmt/core.h>
# include <box2d/box2d.h>
# include <SFML/Graphics/Sprite.hpp>
# include <SFML/Graphics/Texture.hpp>
# include <SFML/Graphics/RenderWindow.hpp>
# include <SFML/System.hpp>
# include <SFML/Audio.hpp>
# include <SFML/Window/Event.hpp>
void ImGui_setup ( sf : : RenderWindow & window ) {
ImGui : : SFML : : Init ( window ) ;
}
void ImGui_update ( sf : : RenderWindow & window , sf : : Clock & deltaClock , sf : : Time & tick ) {
ImGui : : SFML : : Update ( window , deltaClock . restart ( ) ) ;
// ImGui::ShowDemoWindow();
ImGui : : Begin ( " Clock " ) ;
sf : : Vector2u size = window . getSize ( ) ;
ImGui : : SetWindowPos ( ImVec2 ( size . x - 150 , 0 ) ) ;
ImGui : : SetWindowSize ( ImVec2 ( 150 , 50 ) ) ;
std : : string msg = fmt : : format ( " Time: {} \n " , tick . asSeconds ( ) ) ;
ImGui : : Button ( msg . c_str ( ) ) ;
ImGui : : End ( ) ;
}
void Window_update ( sf : : RenderWindow & window , sf : : Sprite & player ) {
window . clear ( ) ;
window . draw ( player ) ;
ImGui : : SFML : : Render ( window ) ;
window . display ( ) ;
}
struct BoxTest {
b2Body * groundBody ;
b2Body * body ;
} ;
struct BoxTest Box2d_setup ( b2World & world ) {
b2BodyDef groundBodyDef ;
groundBodyDef . position . Set ( 0.0f , - 10.0f ) ;
b2Body * groundBody = world . CreateBody ( & groundBodyDef ) ;
b2PolygonShape groundBox ;
groundBox . SetAsBox ( 50.0f , 10.0f ) ;
groundBody - > CreateFixture ( & groundBox , 0.0f ) ;
b2BodyDef bodyDef ;
bodyDef . type = b2_dynamicBody ;
bodyDef . position . Set ( 3.0f , 4.0f ) ;
b2Body * body = world . CreateBody ( & bodyDef ) ;
b2PolygonShape dynamicBox ;
dynamicBox . SetAsBox ( 1.0f , 1.0f ) ;
b2FixtureDef fixtureDef ;
fixtureDef . shape = & dynamicBox ;
fixtureDef . density = 1.0f ;
fixtureDef . friction = 0.3f ;
body - > CreateFixture ( & fixtureDef ) ;
BoxTest box { groundBody , body } ;
return box ;
}
void Handle_events ( sf : : RenderWindow & window , BoxTest & box , sf : : Sound & click ) {
sf : : Event event ;
// is this a main event loop
while ( window . pollEvent ( event ) ) {
ImGui : : SFML : : ProcessEvent ( window , event ) ;
switch ( event . type ) {
case sf : : Event : : Closed :
fmt : : print ( " Exiting... \n " ) ;
window . close ( ) ;
break ;
case sf : : Event : : KeyPressed :
if ( sf : : Keyboard : : isKeyPressed ( sf : : Keyboard : : Left ) ) {
b2Vec2 force ( - 200 , 1000 ) ;
box . body - > ApplyForceToCenter ( force , true ) ;
box . body - > ApplyTorque ( 100.0f , true ) ;
click . play ( ) ;
} else if ( sf : : Keyboard : : isKeyPressed ( sf : : Keyboard : : Right ) ) {
b2Vec2 force ( 200 , 1000 ) ;
box . body - > ApplyForceToCenter ( force , true ) ;
box . body - > ApplyTorque ( - 100.0f , true ) ;
click . play ( ) ;
}
break ;
case sf : : Event : : MouseButtonPressed :
if ( sf : : Mouse : : isButtonPressed ( sf : : Mouse : : Left ) ) {
b2Vec2 force ( - 200 , 1000 ) ;
box . body - > ApplyForceToCenter ( force , true ) ;
box . body - > ApplyTorque ( 100.0f , true ) ;
click . play ( ) ;
} else if ( sf : : Mouse : : isButtonPressed ( sf : : Mouse : : Right ) ) {
b2Vec2 force ( 200 , 1000 ) ;
box . body - > ApplyForceToCenter ( force , true ) ;
box . body - > ApplyTorque ( - 100.0f , true ) ;
click . play ( ) ;
}
break ;
}
}
}
sf : : Time Update_entities ( sf : : RenderWindow & window , b2World & world , sf : : Clock & clock , sf : : Clock & deltaClock , sf : : Time & tick , BoxTest & box , sf : : Sprite & player ) {
sf : : Vector2u winSize = window . getSize ( ) ;
float timeStep = 1.0f / 60.0f ;
int velocityIterations = 6 ;
int positionIterations = 2 ;
sf : : Time since = clock . getElapsedTime ( ) ;
sf : : Time nextTick = since - tick > sf : : seconds ( 1 ) ? since : tick ;
world . Step ( timeStep , velocityIterations , positionIterations ) ;
b2Vec2 position = box . body - > GetPosition ( ) ;
float angle = box . body - > GetAngle ( ) ;
player . setPosition ( position . x * 100.0f , winSize . y - position . y * 100.0f ) ;
player . setRotation ( angle * 180.0f / M_PI ) ;
ImGui_update ( window , deltaClock , tick ) ;
Window_update ( window , player ) ;
return nextTick ;
}
void Create_player ( sf : : RenderWindow & window , sf : : Sprite & player , sf : : Texture & texture ) {
if ( ! texture . loadFromFile ( " sprite.png " ) ) {
fmt : : print ( " Error loading sprite! " ) ;
}
texture . setSmooth ( true ) ;
player . setTexture ( texture ) ;
// position the prite
sf : : Vector2u winSize = window . getSize ( ) ;
player . setPosition ( winSize . x / 2 , winSize . y / 2 ) ;
player . setOrigin ( 50.f , 50.f ) ;
}
int main ( ) {
fmt : : print ( " Setting up a window for you... \n " ) ;
sf : : ContextSettings settings ;
settings . antialiasingLevel = 8 ;
sf : : RenderWindow window ( sf : : VideoMode ( 1920 , 1080 ) , " Simple Game Demo " , sf : : Style : : Default , settings ) ;
window . setFramerateLimit ( 60 ) ;
window . setVerticalSyncEnabled ( true ) ;
ImGui_setup ( window ) ;
sf : : SoundBuffer buffer ;
if ( ! buffer . loadFromFile ( " click.mp3 " ) ) {
fmt : : print ( " Failed to load click.ogg! \n " ) ;
}
sf : : Sound click ;
click . setBuffer ( buffer ) ;
sf : : Clock deltaClock ;
sf : : Clock clock ;
sf : : Time tick = clock . getElapsedTime ( ) ;
sf : : Sprite player ;
sf : : Texture texture ;
Create_player ( window , player , texture ) ;
b2Vec2 gravity ( 0.0f , - 10.0f ) ;
b2World world ( gravity ) ;
BoxTest box = Box2d_setup ( world ) ;
while ( window . isOpen ( ) ) {
Handle_events ( window , box , click ) ;
// preparing for refactoring this into a class or struct for everything
tick = Update_entities ( window , world , clock , deltaClock , tick , box , player ) ;
}
ImGui : : SFML : : Shutdown ( ) ;
}