//Basiques #include #include #include //SDL #include #include #include #undef main //Box2D #include 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 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; }