Sign in to follow this  

simple physics class in sdl going wrong

This topic is 3736 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys I have been trying to pick up a little physics here and there to be able to play around with it in a gui. I'm sure that much of the physics is wrong A: because it's not working and B: because physics is hard to apply to games for me(since I have to teach myself). For some reason it moves backwards and won't respond to keydowns. Here's the code
//The headers
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <string>
#include <vector>

using namespace std;
//Screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

vector <float> force;
//The surfaces
SDL_Surface *background = NULL;
SDL_Surface *ball = NULL;
SDL_Surface *screen = NULL;

//The event structure
SDL_Event event;

SDL_Surface *load_image( std::string filename )
{
    //The image that's loaded
    SDL_Surface* loadedImage = NULL;

    //The optimized image that will be used
    SDL_Surface* optimizedImage = NULL;

    //Load the image
    loadedImage = IMG_Load( filename.c_str() );

    //If the image loaded
    if( loadedImage != NULL )
    {
        //Create an optimized image
        optimizedImage = SDL_DisplayFormat( loadedImage );

        //Free the old image
        SDL_FreeSurface( loadedImage );

        //If the image was optimized just fine
        if( optimizedImage != NULL )
        {
            //Map the color key
            Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 255, 255, 255 );

            //Set all pixels of color R 0, G 0xFF, B 0xFF to be transparent
            SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey );
        }
    }

    //Return the optimized image
    return optimizedImage;
}

void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{
    //Temporary rectangle to hold the offsets
    SDL_Rect offset;

    //Get the offsets
    offset.x = x;
    offset.y = y;

    //Blit the surface
    SDL_BlitSurface( source, NULL, destination, &offset );
}

bool init()
{
    //Initialize all SDL subsystems
    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
    {
        return 1;
    }

    //Set up the screen
    screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

    //If there was an error in setting up the screen
    if( screen == NULL )
    {
        return 1;
    }

    //Set the window caption
    SDL_WM_SetCaption( "Foo says \"Hello!\"", NULL );

    //If everything initialized fine
    return true;
}

bool load_files()
{
    //Load the background image
    background = load_image( "background.png" );

    //If the background didn't load
    if( background == NULL )
    {
        return false;
    }

    //Load the stick figure
    ball = load_image( "ball.png" );

    //If the stick figure didn't load
    if( ball == NULL )
    {
        return false;
    }

    return true;
}

void clean_up()
{
    //Free the surfaces
    SDL_FreeSurface( background );
    SDL_FreeSurface( ball );

    //Quit SDL
    SDL_Quit();
}



class object
{
    public:

    object(int height, int width, double x_f, double y_f);
    std::vector <double> handle_events();
    void show(std::vector <double>  cords);

    private:
    SDL_Rect entity;
    vector <double> force;
    double x_force, y_force;
    Uint8 *keystates;
};

object::object(int height, int width, double x_f, double y_f)
{
    entity.h = height;
    entity.w = width;
    entity.x = 0;
    entity.y = 0;
    x_force = x_f;
    y_force = y_f;
    force.push_back(x_force);
    force.push_back(y_force);

}

std::vector <double>  object::handle_events()
{
    Uint8 *keystates = SDL_GetKeyState( NULL );

    if(keystates[SDLK_UP])
    {
        force[0] = 1 * x_force;
    }
    if(keystates[SDLK_DOWN])
    {
      force[0] = -1 * x_force;
    }
    if(keystates[SDLK_LEFT])
    {
      force[1] = -1 * y_force;
    }
    if(keystates[SDLK_RIGHT])
    {
       force[1] = 1 * y_force;
    }

    return force;
}



void object::show(std::vector <double>  cords)
{
    apply_surface( cords[0], cords[1], ball, screen );
}

class physics
{
    public:
    physics(double x, double y, double h, double w, double top_speed, double density, double friction_co, double g_force);

    void apply_force(vector <double> force);
    std::vector <double>  get_cords();
    private:
    double x, y, h, w, top_speed, density, friction_level, mass, wieght, volume, friction, friction_coe, x_accell, y_accell;
    vector <double> cords;

};
physics::physics(double x_cord, double y_cord, double height, double width, double top_speed_given, double density_given, double friction_co, double g_force)
{
    //set up main vars
    x = x_cord;
    y = y_cord;
    h = height;
    w = width;
    top_speed = top_speed_given;
    density = density_given;
    friction_coe = friction_co;
    cords.push_back(x);
    cords.push_back(y);



    // find volume and mass
    // first we will find volume = h * w
    volume = w * h;

    // now lets find mass = V * D
    mass = volume * density;

    // now we are going to find the gravity of the object using force = mass * 9.8(earth grav)
    wieght = mass * (g_force * 9.8);

    // find friction
    friction = friction_coe * wieght;

    // now lets set the accel to zero


}

void physics::apply_force(vector <double> force)
{
    // acceleration = force/ mass    * for both x and y
    // also note that we subtract friction from it
    if(force[0]/ mass > 0)
    {
        x_accell = (force[0] - friction )/mass ;
    }
    if(force[0]/ mass <= 0)
    {
        x_accell = (force[0] - friction) / mass ;
    }

    if(force[1]/ mass > 0)
    {
        y_accell = (force[1] - friction) / mass;
    }

    if(force[1]/ mass <= 0)
    {
        y_accell = (force[1] - friction) / mass;
    }

    x += x_accell;
    y += y_accell;

}

std::vector <double>   physics::get_cords()
{
    cords[0] = x;
    cords[1] = y;
    return cords;
}




int main( int argc, char* args[] )
{
    //Quit flag
    bool quit = false;

    //Initialize
    if( init() == false )
    {
        return 1;
    }

    //Load the files
    if( load_files() == false )
    {
        return 1;
    }


    physics ball_physics(0, 0, 25, 25, 10, 4, 0.25, 1);
    object ball(50, 50, 40, 40);

    //While the user hasn't quit
    while( quit == false )
    {
        SDL_Delay( 0 );
        ball_physics.apply_force(ball.handle_events());
        //While there's events to handle
        while( SDL_PollEvent( &event ) )
        {
            //If the user has Xed out the window
            if( event.type == SDL_QUIT )
            {
                //Quit the program
                quit = true;
            }
        }
        //Apply the surfaces to the screen
        apply_surface( 0, 0, background, screen );
        ball.show(ball_physics.get_cords());


        //Update the screen
        if( SDL_Flip( screen ) == -1 )
        {
            return 1;
        }

    }

    //Free the surfaces and quit SDL
    clean_up();

    return 0;
}

Thanks for any help, be it on the physics, or programming aspect of the code, Joe

Share this post


Link to post
Share on other sites

This topic is 3736 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this