Procházet zdrojové kódy

Import first car project

DricomDragon před 4 roky
rodič
revize
835444d846
12 změnil soubory, kde provedl 535 přidání a 0 odebrání
  1. binární
      carTest/Bar.bmp
  2. 4 0
      carTest/CMakeLists.txt
  3. 148 0
      carTest/Car.cpp
  4. 60 0
      carTest/Car.h
  5. 1 0
      carTest/Compile.sh
  6. binární
      carTest/Mur.bmp
  7. 49 0
      carTest/Terrain.cpp
  8. 38 0
      carTest/Terrain.h
  9. binární
      carTest/Truck.bmp
  10. binární
      carTest/Wheel.bmp
  11. 235 0
      carTest/main.cpp
  12. binární
      carTest/pierres.bmp

binární
carTest/Bar.bmp


+ 4 - 0
carTest/CMakeLists.txt

@@ -0,0 +1,4 @@
+# Hello World examples
+include_directories (${Box2D_SOURCE_DIR})
+add_executable(HelloWorld HelloWorld.cpp)
+target_link_libraries (HelloWorld Box2D)

+ 148 - 0
carTest/Car.cpp

@@ -0,0 +1,148 @@
+# include "Car.h"
+
+Car::Car()
+: m_bodyCar( 0x0 ), m_bodyWheelFwd( 0x0 ), m_bodyWheelBack( 0x0 ),
+m_motorAxe( 0x0 ), m_fwdAxe( 0x0 ),
+m_imgCar( 0x0 ), m_imgWheel( 0x0 ),
+m_cmd( FREE ),
+m_currentTorque( 0.0f ), m_currentSpeed( 0.0f ),
+m_goTorque( 0.7f ), m_minTorque( 0.0025f ), m_maxSpeed( 60.0f )
+{
+	// Constructeur
+	m_currentTorque = m_minTorque ;
+	m_currentSpeed = 0.0f ;
+}
+
+Car::~Car()
+{
+	if ( !m_imgCar )
+		SDL_FreeSurface( m_imgCar );
+
+	if ( !m_imgWheel )
+		SDL_FreeSurface( m_imgWheel );
+}
+
+void Car::init( b2World &world, float32 x, float32 y, float32 angle )
+{
+	// Images
+	m_imgCar = SDL_LoadBMP("Truck.bmp");
+    m_imgWheel = SDL_LoadBMP("Wheel.bmp");
+
+    SDL_SetColorKey( m_imgCar, SDL_SRCCOLORKEY, SDL_MapRGBA( m_imgCar->format, 0, 0, 0, 255 ) );
+    SDL_SetColorKey( m_imgWheel, SDL_SRCCOLORKEY, SDL_MapRGBA( m_imgWheel->format, 0, 0, 0, 255 ) );
+
+    // Dimensions
+    float32 wtruck, htruck, rwheel;
+    wtruck = (float32)m_imgCar->w / MULTI / 2 ;
+    htruck = (float32)m_imgCar->h / MULTI / 2 ;
+    rwheel = (float32)m_imgWheel->h / MULTI / 2 ;
+
+    // Définition body
+    b2BodyDef bodyDef;
+    b2PolygonShape dynamicBox;
+    b2FixtureDef fixtureDef;
+    bodyDef.type = b2_dynamicBody;
+
+	// Roue arrière
+	bodyDef.userData = m_imgWheel ;
+    bodyDef.position.Set( x - wtruck + rwheel, y + htruck + rwheel );
+
+    b2CircleShape dynamicCircle;
+    dynamicCircle.m_radius = rwheel ;
+
+    fixtureDef.shape = &dynamicCircle;
+    fixtureDef.density = 0.24f;
+    fixtureDef.friction = 15.0f;
+
+    m_bodyWheelBack = world.CreateBody(&bodyDef);
+    m_bodyWheelBack->CreateFixture(&fixtureDef);
+
+    // Roue avant
+    bodyDef.position.Set( x + wtruck - rwheel, y + htruck + rwheel );
+
+    dynamicCircle.m_radius = rwheel ;
+
+    fixtureDef.shape = &dynamicCircle;
+    fixtureDef.density = 0.24f;
+    fixtureDef.friction = 15.0f;
+
+    m_bodyWheelFwd = world.CreateBody(&bodyDef);
+    m_bodyWheelFwd->CreateFixture(&fixtureDef);
+
+    // Carrosserie
+    bodyDef.userData = m_imgCar ;
+    bodyDef.position.Set( x, y );
+
+    dynamicBox.SetAsBox( wtruck, htruck );
+
+    fixtureDef.shape = &dynamicBox;
+    fixtureDef.density = 1.0f;
+    fixtureDef.friction = 0.2f;
+
+	m_bodyCar = world.CreateBody( &bodyDef );
+	m_bodyCar->CreateFixture( &fixtureDef );
+
+    // Création pivot avant
+    b2RevoluteJointDef myJointDef;
+    myJointDef.collideConnected = false ;
+
+    myJointDef.Initialize( m_bodyWheelFwd, m_bodyCar, m_bodyWheelFwd->GetPosition() );
+
+    m_fwdAxe = (b2RevoluteJoint*)world.CreateJoint(&myJointDef);
+
+    // Création pivot arrière
+    myJointDef.collideConnected = false ;
+
+    myJointDef.Initialize( m_bodyWheelBack, m_bodyCar, m_bodyWheelBack->GetPosition() );
+
+    myJointDef.maxMotorTorque = 0.05f;
+    myJointDef.motorSpeed = 0.0f;
+    myJointDef.enableMotor = true;
+
+    m_motorAxe = (b2RevoluteJoint*)world.CreateJoint(&myJointDef);
+
+    // Fin
+    return ;
+}
+
+void Car::drive( command cmd )
+{
+	m_cmd = cmd ;
+}
+
+void Car::update()
+{
+	// Update state
+	if ( m_cmd == FREE )
+	{
+		m_currentSpeed = 0.0f ;
+		m_currentTorque = m_minTorque ;
+	}
+
+	else if ( m_cmd == BREAK )
+	{
+		m_currentSpeed = 0.0f ;
+		m_currentTorque = m_goTorque ;
+	}
+
+	else if ( m_cmd == GO )
+	{
+		m_currentSpeed = -m_maxSpeed ;
+		m_currentTorque = m_goTorque ;
+	}
+
+	else if ( m_cmd == REVERSE )
+	{
+		m_currentSpeed = m_maxSpeed ;
+		m_currentTorque = m_goTorque ;
+	}
+
+	// Update motor
+	m_motorAxe->SetMotorSpeed( m_currentSpeed );
+    m_motorAxe->SetMaxMotorTorque( m_currentTorque );
+}
+
+b2Vec2 Car::GetPosition()
+{
+	return m_bodyCar->GetPosition();
+}

+ 60 - 0
carTest/Car.h

@@ -0,0 +1,60 @@
+# ifndef CAR_HEADER_FILE
+# define CAR_HEADER_FILE
+
+// Basiques
+# include <iostream>
+# include <cmath>
+# include <vector>
+
+// Random
+# include <ctime>
+# include <cstdlib>
+
+// SDL
+# include <SDL/SDL.h>
+# undef main
+# include <SDL/SDL_rotozoom.h>
+# include <SDL/SDL_gfxPrimitives.h>
+
+// bBox2D
+# include <Box2D/Box2D.h>
+# define MULTI 100.0f
+
+enum command { FREE, BREAK, GO, REVERSE };
+
+class Car
+{
+public:
+	Car();
+	virtual ~Car();
+
+	void init( b2World &world, float32 x, float32 y, float32 angle = 0.0f );
+
+	void drive( command cmd );
+	void update();
+
+	b2Vec2 GetPosition();
+
+protected:
+	b2Body* m_bodyCar ;
+	b2Body* m_bodyWheelFwd ;
+	b2Body* m_bodyWheelBack ;
+
+	b2RevoluteJoint* m_motorAxe ;
+	b2RevoluteJoint* m_fwdAxe ;
+	
+	SDL_Surface* m_imgCar ;
+	SDL_Surface* m_imgWheel ;
+
+	command m_cmd ;
+
+	float32 m_currentTorque ;
+	float32 m_currentSpeed ;
+
+	float32 m_goTorque ;
+	float32 m_minTorque ;
+	float32 m_maxSpeed ;
+};
+
+
+# endif // CAR_HEADER_FILE

+ 1 - 0
carTest/Compile.sh

@@ -0,0 +1 @@
+g++ main.cpp Car.cpp Terrain.cpp -l Box2D -Wl,-rpath=/usr/local/lib/ -l SDL -l SDL_gfx -std=c++11

binární
carTest/Mur.bmp


+ 49 - 0
carTest/Terrain.cpp

@@ -0,0 +1,49 @@
+#include "Terrain.h"
+
+Terrain::Terrain( const unsigned int size )
+: m_size( size ), m_nextAdd( 0 ), m_plot( 0x0 )
+{
+	m_plot = new b2Vec2[ size ];
+}
+
+Terrain::~Terrain()
+{
+	delete[] m_plot ;
+	m_plot = 0x0 ;
+}
+	
+void Terrain::addPlot( float32 x, float32 y )
+{
+	if ( m_nextAdd == m_size )
+		return ;
+
+	m_plot[ m_nextAdd ].Set( x, y );
+
+	m_nextAdd ++;
+}
+
+void Terrain::build( b2World &world )
+{
+	b2BodyDef areaDef;
+	areaDef.position.Set(0.0f, 0.0f);
+	b2Body* areaBody = world.CreateBody(&areaDef);
+
+	b2ChainShape chain;
+	chain.CreateChain( m_plot, m_nextAdd );
+	areaBody->CreateFixture( &chain, 0.0f );
+}
+
+void Terrain::draw( SDL_Surface* screen, b2Vec2 origin )
+{
+	int x1, y1, x2, y2 ;
+	for ( unsigned int i(0); i < m_nextAdd - 1 ; i++ )
+	{
+		x1 = ( m_plot[i].x - origin.x ) * MULTI ;
+		y1 = ( m_plot[i].y - origin.y ) * MULTI ;
+		x2 = ( m_plot[i + 1].x - origin.x ) * MULTI ;
+		y2 = ( m_plot[i + 1].y - origin.y ) * MULTI ;
+
+
+		lineRGBA (screen, x1, y1, x2, y2, 255, 0, 0, 255);
+	}
+}

+ 38 - 0
carTest/Terrain.h

@@ -0,0 +1,38 @@
+# ifndef TERRAIN_HEADER_FILE
+# define TERRAIN_HEADER_FILE
+
+// Basiques
+# include <iostream>
+# include <vector>
+
+// Random
+# include <ctime>
+# include <cstdlib>
+
+// SDL
+# include <SDL/SDL.h>
+# undef main
+# include <SDL/SDL_gfxPrimitives.h>
+
+// bBox2D
+# include <Box2D/Box2D.h>
+# define MULTI 100.0f
+
+class Terrain
+{
+public:
+	Terrain( const unsigned int size );
+	~Terrain();
+	
+	void addPlot( float32 x, float32 y );
+	void build( b2World &world );
+
+	void draw( SDL_Surface* screen, b2Vec2 origin );
+
+protected :
+	const unsigned int m_size ;
+	unsigned int m_nextAdd ;
+	b2Vec2* m_plot; // Static array
+};
+
+# endif // TERRAIN_HEADER_FILE

binární
carTest/Truck.bmp


binární
carTest/Wheel.bmp


+ 235 - 0
carTest/main.cpp

@@ -0,0 +1,235 @@
+// Basiques
+# include <iostream>
+# include <cmath>
+# include <vector>
+
+// Random
+# include <ctime>
+# include <cstdlib>
+
+// SDL
+# include <SDL/SDL.h>
+# undef main
+# include <SDL/SDL_rotozoom.h>
+# include <SDL/SDL_gfxPrimitives.h>
+
+// bBox2D
+# include <Box2D/Box2D.h>
+# define MULTI 100.0f
+
+// Local
+# include "Car.h"
+#include "Terrain.h"
+
+int main(int argc, char** argv)
+{
+	/// [1] Démarrage
+    // [1.0] Démarrage aléatoire
+    srand( time(0) );
+
+    // [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 SDL
+    // [2.1] Préparation de la fenêtre
+    SDL_Surface* screen = SDL_SetVideoMode(1200, 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 });
+
+    // [2.3] Préparation surfaces
+    SDL_Surface* tempo( 0x0 );
+
+    // [2.4] Préparation du temps
+    Uint32 frameRate( 60 );
+    Uint32 tprev(0), twait( 1000 / frameRate );
+    bool pause( false );
+
+    // [2.5] Préparation des messages
+    std::string msg("Victor");
+
+    /// [3] Box2D
+    // Trucs
+    B2_NOT_USED(argc);
+    B2_NOT_USED(argv);
+
+    // Construct a world object
+    b2Vec2 gravity( 0.0f, 10.0f );
+    b2World world(gravity);
+
+    // Simulation settings
+    float32 timeStep = 1.0f / frameRate;
+    int32 velocityIterations = 8;
+    int32 positionIterations = 3;
+    float32 angle ;
+    b2Vec2 position, ref ;
+
+	// Define the edge body
+	float32 areah( (float32)screen->h / MULTI );
+	float32 areaw( (float32)screen->w / MULTI );
+
+    # define NB_PLOT 400
+    Terrain myTerrain( NB_PLOT );
+    myTerrain.addPlot( 0.0f, 0.0f );
+    myTerrain.addPlot( 0.0f, areah );
+
+    for ( unsigned int i(2); i < NB_PLOT ; i ++ )
+    {
+        myTerrain.addPlot( 1.0f * i, areah + 0.03f * i * sin( 0.35f * i ) ) ;
+    }
+
+    myTerrain.build( world );
+
+    // Voiture
+    Car myCar;
+    myCar.init( world, 3.0f, 1.0f );
+
+    /// [4] Boucle principale
+    bool done = false;
+    SDL_Event event;
+    while (!done)
+    {
+        // [4.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 :
+                    // Destroy joints first of all
+
+                    std::cout << std::endl << "Deleting all entities." << std::endl << std::endl;
+
+                    break;
+                case SDLK_SPACE :
+                    pause = !pause ;
+                    break;
+                case SDLK_RIGHT :
+                    myCar.drive( GO );
+                    break;
+                case SDLK_LEFT :
+                    myCar.drive( REVERSE );
+                    break;
+                case SDLK_DOWN :
+                    myCar.drive( BREAK );
+                    break;
+                }
+                break;
+            case SDL_KEYUP:
+                switch( event.key.keysym.sym )
+                {
+                case SDLK_LEFT :
+                case SDLK_RIGHT :
+                case SDLK_DOWN :
+                    myCar.drive( FREE );
+                    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
+
+        // [4.2] Calculs
+        // It is generally best to keep the time step and iterations fixed.
+        /*motor->SetMotorSpeed( speed );
+        motor->SetMaxMotorTorque( torque );*/
+
+        if ( !pause )
+        {
+			world.Step(timeStep, velocityIterations, positionIterations);
+            myCar.update();
+        }
+
+        ref = myCar.GetPosition();
+        ref.Set( ref.x - areaw / 4.0f , ref.y - areah / 2.0f );
+
+        // [4.3] Dessin des composants
+        SDL_FillRect(screen, 0, 0x444444);
+
+        myTerrain.draw( screen, ref );
+
+        for ( b2Body* b = world.GetBodyList(); b; b = b->GetNext() )
+        {
+            position = b->GetPosition() - ref ;
+            angle = b->GetAngle();
+
+            tempo = (SDL_Surface*)b->GetUserData();
+            if ( tempo == 0x0 )
+                continue ;
+
+            tempo = rotozoomSurface( tempo, -angle * 180.0f / b2_pi, 1.0f, 0 );
+
+
+            pxpos.x = position.x * MULTI - tempo->w / 2 ;
+            pxpos.y = position.y * MULTI - tempo->h / 2 ;
+            SDL_BlitSurface( tempo, 0x0, screen, &pxpos);
+
+            SDL_FreeSurface( tempo );
+            tempo = 0x0 ;
+        }
+
+        // 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 = "Position : " ;
+        msg += std::to_string( ref.x ) ;
+        msg += " m." ;
+        stringRGBA( screen, 16, 25, msg.c_str(), 0, 255, 0, 255 );
+
+        /*msg = "Torque : " ;
+        msg += std::to_string( torque ) ;
+        msg += " N.m." ;
+        stringRGBA( screen, 16, 34, msg.c_str(), 0, 255, 0, 255 );*/
+
+        SDL_Flip(screen);
+
+        // [4.4] Temps
+        while( SDL_GetTicks() - tprev < twait )
+        {
+        	if ( SDL_GetTicks() - tprev < twait/2 )
+        		SDL_Delay( twait/3 );
+        }
+        tprev = SDL_GetTicks();
+
+    } //fin bcl principale
+
+    ///[5] Destruction des composants
+
+	return 0;
+}

binární
carTest/pierres.bmp