|
@@ -0,0 +1,424 @@
|
|
|
+//Basiques
|
|
|
+#include <iostream>
|
|
|
+#include <cmath>
|
|
|
+#include <vector>
|
|
|
+
|
|
|
+//SDL
|
|
|
+#include <SDL/SDL.h>
|
|
|
+#include <SDL/SDL_rotozoom.h>
|
|
|
+#include <SDL/SDL_gfxPrimitives.h>
|
|
|
+#undef main
|
|
|
+
|
|
|
+//Box2D
|
|
|
+#include <box2d/box2d.h>
|
|
|
+
|
|
|
+int main(int argc, char** argv)
|
|
|
+{
|
|
|
+ /// [0] Box2D
|
|
|
+ // Trucs
|
|
|
+ B2_NOT_USED(argc);
|
|
|
+ B2_NOT_USED(argv);
|
|
|
+
|
|
|
+ // Define the gravity vector.
|
|
|
+ b2Vec2 gravity(0.0f, 10.0f);
|
|
|
+
|
|
|
+ // Construct a world object, which will hold and simulate the rigid bodies.
|
|
|
+ b2World world(gravity);
|
|
|
+ float multi( 100.0f ); // Pour passer de Box2D à pixels
|
|
|
+ int incr( 0 );
|
|
|
+
|
|
|
+ // Define the ground body.
|
|
|
+ /*b2BodyDef solDef;
|
|
|
+ solDef.position.Set(0.0f, 6.0f);
|
|
|
+ b2Body* solBody = world.CreateBody(&solDef);
|
|
|
+ b2PolygonShape solBox;
|
|
|
+ solBox.SetAsBox(50.0f, 1.0f);
|
|
|
+ solBody->CreateFixture(&solBox, 0.0f);*/
|
|
|
+
|
|
|
+ // Define the dynamic body. We set its position and call the body factory.
|
|
|
+ std::vector<b2Body*> tbody;
|
|
|
+ float xstart( 3.0f );
|
|
|
+ float zoom( 2.0f );
|
|
|
+ b2BodyDef bodyDef;
|
|
|
+ bodyDef.type = b2_dynamicBody;
|
|
|
+
|
|
|
+ // Define another box shape for our dynamic body.
|
|
|
+ b2PolygonShape dynamicBox;
|
|
|
+ b2FixtureDef fixtureDef;
|
|
|
+ fixtureDef.shape = &dynamicBox;
|
|
|
+ fixtureDef.density = 1.0f;
|
|
|
+ fixtureDef.friction = 0.3f;
|
|
|
+
|
|
|
+ // Prepare for simulation
|
|
|
+ float timeStep = 1.0f / 60.0f;
|
|
|
+ int32 velocityIterations = 8;
|
|
|
+ int32 positionIterations = 3;
|
|
|
+
|
|
|
+ // Variables
|
|
|
+ b2Vec2 position;
|
|
|
+ float angle;
|
|
|
+ bool pause( false );
|
|
|
+ bool enable_rotation( true );
|
|
|
+ std::string msg("Victor");
|
|
|
+
|
|
|
+ /// [1] Démarrage
|
|
|
+ // [1.1] Démarrages SDL
|
|
|
+ if ( SDL_Init( SDL_INIT_VIDEO ) < 0)
|
|
|
+ {
|
|
|
+ std::cout << "Impossible d'initialiser la SDL: " << SDL_GetError() << std::endl;
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // [1.2] Préparation de fermeture
|
|
|
+ atexit(SDL_Quit);
|
|
|
+
|
|
|
+ // [1.3] Para-fenêtre
|
|
|
+ SDL_WM_SetCaption("Box2DTests", 0);
|
|
|
+
|
|
|
+ /// [2] Préparation des composants
|
|
|
+ // [2.1] Préparation de la fenêtre
|
|
|
+ SDL_Surface* screen = SDL_SetVideoMode(600, 600, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
|
|
|
+ if ( !screen )
|
|
|
+ {
|
|
|
+ std::cout << "Bug à l'initialisation: " << SDL_GetError() << std::endl;
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // [2.2] Préparation variables
|
|
|
+ SDL_Rect mouse({ 400, 200, 0, 0 });
|
|
|
+ SDL_Rect pxpos({ 400, 200, 0, 0 });
|
|
|
+
|
|
|
+ std::vector< SDL_Surface* > trot ;
|
|
|
+ std::vector< SDL_Surface* > timg ;
|
|
|
+
|
|
|
+ // [2.3] Préparation surfaces
|
|
|
+ SDL_Surface* blc = 0x0;
|
|
|
+ SDL_Surface* bar = 0x0;
|
|
|
+ SDL_Surface* ice = 0x0;
|
|
|
+ SDL_Surface* heavy = 0x0;
|
|
|
+ SDL_Surface* slim = 0x0;
|
|
|
+ SDL_Surface* megaSlim = 0x0;
|
|
|
+ SDL_Surface* zero = 0x0;
|
|
|
+ SDL_Surface* anti = 0x0;
|
|
|
+
|
|
|
+ blc = SDL_LoadBMP("Mur.bmp");
|
|
|
+ bar = SDL_LoadBMP("Bar.bmp");
|
|
|
+ ice = SDL_LoadBMP("Glace.bmp");
|
|
|
+ heavy = SDL_LoadBMP("Heavy.bmp");
|
|
|
+ slim = SDL_LoadBMP("Slim.bmp");
|
|
|
+ megaSlim = SDL_LoadBMP("MegaSlim.bmp");
|
|
|
+ zero = SDL_LoadBMP("Zero.bmp");
|
|
|
+ anti = SDL_LoadBMP("Anti.bmp");
|
|
|
+
|
|
|
+ if ( !blc || !bar || !ice || !heavy || !slim || !megaSlim || !zero || !anti )
|
|
|
+ std::cout << "Pb avec la texture." << std::endl;
|
|
|
+
|
|
|
+ // [2.4] Préparation du temps
|
|
|
+ Uint32 tprev(0), twait( timeStep * 1000.0f );
|
|
|
+ std::cout << twait << std::endl ;
|
|
|
+
|
|
|
+ // Define the edge body
|
|
|
+ b2BodyDef areaDef;
|
|
|
+ areaDef.position.Set(0.0f, 0.0f);
|
|
|
+ b2Body* areaBody = world.CreateBody(&areaDef);
|
|
|
+
|
|
|
+ b2Vec2 vs[4];
|
|
|
+ float areah( (float)screen->h / multi );
|
|
|
+ float areaw( (float)screen->w / multi );
|
|
|
+ vs[0].Set( 0.0f, 0.0f );
|
|
|
+ vs[1].Set( 0.0f, areah );
|
|
|
+ vs[2].Set( areaw, areah );
|
|
|
+ vs[3].Set( areaw, 0.0f );
|
|
|
+ b2ChainShape chain;
|
|
|
+ chain.CreateLoop(vs, 4);
|
|
|
+ areaBody->CreateFixture(&chain, 0.0f);
|
|
|
+
|
|
|
+ /// [3] Boucle principale
|
|
|
+ bool done = false;
|
|
|
+ SDL_Event event;
|
|
|
+ while (!done)
|
|
|
+ {
|
|
|
+ // [3.1] Gestion évènements
|
|
|
+ while (SDL_PollEvent(&event))
|
|
|
+ {
|
|
|
+ switch (event.type)
|
|
|
+ {
|
|
|
+ case SDL_QUIT:
|
|
|
+ done = true;
|
|
|
+ break;
|
|
|
+ case SDL_KEYDOWN:
|
|
|
+ switch( event.key.keysym.sym )
|
|
|
+ {
|
|
|
+ case SDLK_ESCAPE :
|
|
|
+ done = true;
|
|
|
+ break;
|
|
|
+ case SDLK_BACKSPACE :
|
|
|
+ for ( unsigned int i(0); i < tbody.size(); i ++ )
|
|
|
+ {
|
|
|
+ world.DestroyBody( tbody[i] );
|
|
|
+ tbody[i] = 0x0 ;
|
|
|
+ }
|
|
|
+ tbody.clear();
|
|
|
+
|
|
|
+ for ( unsigned int i(0); i < trot.size(); i ++ )
|
|
|
+ {
|
|
|
+ SDL_FreeSurface( trot[i] ) ;
|
|
|
+ }
|
|
|
+ trot.clear();
|
|
|
+
|
|
|
+ timg.clear();
|
|
|
+ std::cout << std::endl << "Deleting all blocks." << std::endl << std::endl;
|
|
|
+
|
|
|
+ break;
|
|
|
+ case SDLK_SPACE :
|
|
|
+ pause = !pause ;
|
|
|
+ break;
|
|
|
+ case SDLK_LEFT :
|
|
|
+ enable_rotation = !enable_rotation ;
|
|
|
+ break;
|
|
|
+ case SDLK_UP :
|
|
|
+ std::cout << "SDLK_UP" << std::endl;
|
|
|
+ break;
|
|
|
+ case SDLK_a :
|
|
|
+ dynamicBox.SetAsBox( (float)blc->w * zoom / multi / 2 , (float)blc->h * zoom / multi / 2 );
|
|
|
+
|
|
|
+ bodyDef.position.Set( (float)mouse.x / multi, (float)mouse.y / multi );
|
|
|
+ bodyDef.gravityScale = 1.0f;
|
|
|
+
|
|
|
+ fixtureDef.density = 1.0f;
|
|
|
+ fixtureDef.friction = 0.3f;
|
|
|
+ fixtureDef.restitution = 0.0f;
|
|
|
+
|
|
|
+ tbody.push_back( 0x0 );
|
|
|
+ tbody.back() = world.CreateBody(&bodyDef);
|
|
|
+ tbody.back()->CreateFixture(&fixtureDef);
|
|
|
+
|
|
|
+ timg.push_back( blc );
|
|
|
+ trot.push_back( rotozoomSurface( blc, 0.0f, 2.0f, 0 ) ) ;
|
|
|
+
|
|
|
+ std::cout << "Standard bloc number " << tbody.size() << "." << std::endl;
|
|
|
+ break;
|
|
|
+ case SDLK_q :
|
|
|
+ dynamicBox.SetAsBox( (float)bar->w * zoom / multi / 2 , (float)bar->h * zoom / multi / 2 );
|
|
|
+
|
|
|
+ bodyDef.position.Set( (float)mouse.x / multi, (float)mouse.y / multi );
|
|
|
+ bodyDef.gravityScale = 1.0f;
|
|
|
+
|
|
|
+ fixtureDef.density = 1.0f;
|
|
|
+ fixtureDef.friction = 0.3f;
|
|
|
+ fixtureDef.restitution = 0.0f;
|
|
|
+
|
|
|
+ tbody.push_back( 0x0 );
|
|
|
+ tbody.back() = world.CreateBody(&bodyDef);
|
|
|
+ tbody.back()->CreateFixture(&fixtureDef);
|
|
|
+
|
|
|
+ timg.push_back( bar );
|
|
|
+ trot.push_back( rotozoomSurface( bar, 0.0f, 2.0f, 0 ) ) ;
|
|
|
+
|
|
|
+ std::cout << "Standard bar number " << tbody.size() << "." << std::endl;
|
|
|
+ break;
|
|
|
+ case SDLK_z :
|
|
|
+ case SDLK_w :
|
|
|
+ dynamicBox.SetAsBox( (float)ice->w * zoom / multi / 2 , (float)ice->h * zoom / multi / 2 );
|
|
|
+
|
|
|
+ bodyDef.position.Set( (float)mouse.x / multi, (float)mouse.y / multi );
|
|
|
+ bodyDef.gravityScale = 1.0f;
|
|
|
+
|
|
|
+ fixtureDef.density = 0.5f;
|
|
|
+ fixtureDef.friction = 0.005f;
|
|
|
+ fixtureDef.restitution = 0.0f;
|
|
|
+
|
|
|
+ tbody.push_back( 0x0 );
|
|
|
+ tbody.back() = world.CreateBody(&bodyDef);
|
|
|
+ tbody.back()->CreateFixture(&fixtureDef);
|
|
|
+
|
|
|
+ timg.push_back( ice );
|
|
|
+ trot.push_back( rotozoomSurface( ice, 0.0f, 2.0f, 0 ) ) ;
|
|
|
+
|
|
|
+ std::cout << "Bloc of ice " << tbody.size() <<" : able to slide !" << std::endl;
|
|
|
+ break;
|
|
|
+ case SDLK_e :
|
|
|
+ dynamicBox.SetAsBox( (float)heavy->w * zoom / multi / 2 , (float)heavy->h * zoom / multi / 2 );
|
|
|
+
|
|
|
+ bodyDef.position.Set( (float)mouse.x / multi, (float)mouse.y / multi );
|
|
|
+ bodyDef.gravityScale = 1.0f;
|
|
|
+
|
|
|
+ fixtureDef.density = 100.0f;
|
|
|
+ fixtureDef.friction = 0.3f;
|
|
|
+ fixtureDef.restitution = 0.0f;
|
|
|
+
|
|
|
+ tbody.push_back( 0x0 );
|
|
|
+ tbody.back() = world.CreateBody(&bodyDef);
|
|
|
+ tbody.back()->CreateFixture(&fixtureDef);
|
|
|
+
|
|
|
+ timg.push_back( heavy );
|
|
|
+ trot.push_back( rotozoomSurface( heavy, 0.0f, 2.0f, 0 ) ) ;
|
|
|
+
|
|
|
+ std::cout << "Heavy bloc " << tbody.size() << " : very massive bloc." << std::endl;
|
|
|
+ break;
|
|
|
+ case SDLK_r :
|
|
|
+ dynamicBox.SetAsBox( (float)slim->w * zoom / multi / 2 , (float)slim->h * zoom / multi / 2 );
|
|
|
+
|
|
|
+ bodyDef.position.Set( (float)mouse.x / multi, (float)mouse.y / multi );
|
|
|
+ bodyDef.gravityScale = 1.0f;
|
|
|
+
|
|
|
+ fixtureDef.density = 1.0f;
|
|
|
+ fixtureDef.friction = 0.3f;
|
|
|
+ fixtureDef.restitution = 0.95f;
|
|
|
+
|
|
|
+ tbody.push_back( 0x0 );
|
|
|
+ tbody.back() = world.CreateBody(&bodyDef);
|
|
|
+ tbody.back()->CreateFixture(&fixtureDef);
|
|
|
+
|
|
|
+ timg.push_back( slim );
|
|
|
+ trot.push_back( rotozoomSurface( slim, 0.0f, 2.0f, 0 ) ) ;
|
|
|
+
|
|
|
+ std::cout << "Slim bloc " << tbody.size() << " : able to bounce !" << std::endl;
|
|
|
+ break;
|
|
|
+ case SDLK_t :
|
|
|
+ dynamicBox.SetAsBox( (float)megaSlim->w * zoom / multi / 2 , (float)megaSlim->h * zoom / multi / 2 );
|
|
|
+
|
|
|
+ bodyDef.position.Set( (float)mouse.x / multi, (float)mouse.y / multi );
|
|
|
+ bodyDef.gravityScale = 1.0f;
|
|
|
+
|
|
|
+ fixtureDef.density = 1.0f;
|
|
|
+ fixtureDef.friction = 0.3f;
|
|
|
+ fixtureDef.restitution = 1.4f;
|
|
|
+
|
|
|
+ tbody.push_back( 0x0 );
|
|
|
+ tbody.back() = world.CreateBody(&bodyDef);
|
|
|
+ tbody.back()->CreateFixture(&fixtureDef);
|
|
|
+
|
|
|
+ timg.push_back( megaSlim );
|
|
|
+ trot.push_back( rotozoomSurface( megaSlim, 0.0f, 2.0f, 0 ) ) ;
|
|
|
+
|
|
|
+ std::cout << "MegaSlim bloc " << tbody.size() << " : able to bounce over physic limits !" << std::endl;
|
|
|
+ break;
|
|
|
+ case SDLK_y :
|
|
|
+ dynamicBox.SetAsBox( (float)zero->w * zoom / multi / 2 , (float)zero->h * zoom / multi / 2 );
|
|
|
+
|
|
|
+ bodyDef.position.Set( (float)mouse.x / multi, (float)mouse.y / multi );
|
|
|
+ bodyDef.gravityScale = 0.0f;
|
|
|
+
|
|
|
+ fixtureDef.density = 1.0f;
|
|
|
+ fixtureDef.friction = 0.3f;
|
|
|
+ fixtureDef.restitution = 0.0f;
|
|
|
+
|
|
|
+ tbody.push_back( 0x0 );
|
|
|
+ tbody.back() = world.CreateBody(&bodyDef);
|
|
|
+ tbody.back()->CreateFixture(&fixtureDef);
|
|
|
+
|
|
|
+ timg.push_back( zero );
|
|
|
+ trot.push_back( rotozoomSurface( zero, 0.0f, 2.0f, 0 ) ) ;
|
|
|
+
|
|
|
+ std::cout << "Zero gravity bloc " << tbody.size() << " : able to bypass gravity !" << std::endl;
|
|
|
+ break;
|
|
|
+ case SDLK_u :
|
|
|
+ dynamicBox.SetAsBox( (float)anti->w * zoom / multi / 2 , (float)anti->h * zoom / multi / 2 );
|
|
|
+
|
|
|
+ bodyDef.position.Set( (float)mouse.x / multi, (float)mouse.y / multi );
|
|
|
+ bodyDef.gravityScale = -1.0f;
|
|
|
+
|
|
|
+ fixtureDef.density = 1.0f;
|
|
|
+ fixtureDef.friction = 0.3f;
|
|
|
+ fixtureDef.restitution = 0.0f;
|
|
|
+
|
|
|
+ tbody.push_back( 0x0 );
|
|
|
+ tbody.back() = world.CreateBody(&bodyDef);
|
|
|
+ tbody.back()->CreateFixture(&fixtureDef);
|
|
|
+
|
|
|
+ timg.push_back( anti );
|
|
|
+ trot.push_back( rotozoomSurface( anti, 0.0f, 2.0f, 0 ) ) ;
|
|
|
+
|
|
|
+ std::cout << "Anti gravity bloc number " << tbody.size() << " : counter gravity !" << std::endl;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case SDL_MOUSEMOTION:
|
|
|
+ mouse.x = event.motion.x ;
|
|
|
+ mouse.y = event.motion.y ;
|
|
|
+ break;
|
|
|
+ case SDL_MOUSEBUTTONDOWN:
|
|
|
+ std::cout << "SDL_MOUSEBUTTONDOWN" << std::endl;
|
|
|
+ break;
|
|
|
+ case SDL_MOUSEBUTTONUP:
|
|
|
+ std::cout << "SDL_MOUSEBUTTONUP" << std::endl;
|
|
|
+ break;
|
|
|
+ } // end switch event type
|
|
|
+ } // end of message processing
|
|
|
+
|
|
|
+ // [3.2] Calculs
|
|
|
+ // It is generally best to keep the time step and iterations fixed.
|
|
|
+ if ( !pause )
|
|
|
+ world.Step(timeStep, velocityIterations, positionIterations);
|
|
|
+
|
|
|
+ // [3.3] Dessin des composants
|
|
|
+ SDL_FillRect(screen, 0, 0x000000);
|
|
|
+
|
|
|
+ for ( unsigned int i(0); i < tbody.size(); i ++ )
|
|
|
+ {
|
|
|
+ position = tbody[i]->GetPosition();
|
|
|
+ angle = tbody[i]->GetAngle();
|
|
|
+
|
|
|
+ if ( /*tbody[i]->IsAwake() &&*/ enable_rotation )
|
|
|
+ {
|
|
|
+ SDL_FreeSurface( trot[i] ) ;
|
|
|
+ trot[i] = rotozoomSurface( timg[i], -angle * 180.0f / b2_pi, zoom + 0.15f, 0 );
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ pxpos.x = position.x * multi - trot[i]->w / 2 ;
|
|
|
+ pxpos.y = position.y * multi - trot[i]->h / 2 ;
|
|
|
+ SDL_BlitSurface( trot[i], 0x0, screen, &pxpos);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Messages
|
|
|
+ msg = "Ratio CPU : " ;
|
|
|
+ msg += std::to_string( ((float)SDL_GetTicks() - tprev) * 100 / twait ) ;
|
|
|
+ msg += " pourcents." ;
|
|
|
+ stringRGBA( screen, 16, 16, msg.c_str(), 0, 255, 0, 255 );
|
|
|
+
|
|
|
+ msg = "Nombre de blocs : " ;
|
|
|
+ msg += std::to_string( trot.size() ) ;
|
|
|
+ msg += "." ;
|
|
|
+ stringRGBA( screen, 16, 25, msg.c_str(), 0, 255, 0, 255 );
|
|
|
+
|
|
|
+ msg = "Nombre de décès : " ;
|
|
|
+ msg += std::to_string( incr ) ;
|
|
|
+ msg += "." ;
|
|
|
+ stringRGBA( screen, 16, 34, msg.c_str(), 0, 255, 0, 255 );
|
|
|
+
|
|
|
+ msg = "Rotations : " ;
|
|
|
+ msg += std::to_string( enable_rotation ) ;
|
|
|
+ msg += "." ;
|
|
|
+ stringRGBA( screen, 16, 43, msg.c_str(), 0, 255, 0, 255 );
|
|
|
+
|
|
|
+ SDL_Flip(screen);
|
|
|
+
|
|
|
+ // [3.4] Temps
|
|
|
+ if ( SDL_GetTicks() - tprev > twait )
|
|
|
+ {
|
|
|
+ incr ++;
|
|
|
+ }
|
|
|
+ while( SDL_GetTicks() - tprev < twait )
|
|
|
+ {
|
|
|
+ if ( SDL_GetTicks() - tprev < twait/2 )
|
|
|
+ SDL_Delay( twait/3 );
|
|
|
+ }
|
|
|
+ tprev = SDL_GetTicks();
|
|
|
+
|
|
|
+ } //fin bcl principale
|
|
|
+
|
|
|
+ ///[4] Destruction des composants
|
|
|
+ SDL_FreeSurface(screen);
|
|
|
+ SDL_FreeSurface(blc);
|
|
|
+ SDL_FreeSurface(bar);
|
|
|
+ SDL_FreeSurface(ice);
|
|
|
+ SDL_FreeSurface(heavy);
|
|
|
+ SDL_FreeSurface(slim);
|
|
|
+ SDL_FreeSurface(megaSlim);
|
|
|
+ SDL_FreeSurface(zero);
|
|
|
+ SDL_FreeSurface(anti);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|