Thread: Using a particle engine to create a laser projectile? [C/SDL]

  1. #1
    Registered User HelpfulPerson's Avatar
    Join Date
    Jun 2013
    Location
    Over the rainbow
    Posts
    288

    Using a particle engine to create a laser projectile? [C/SDL]

    Hello, as some of you are aware of, I have been learning to use SDL recently. I have been making a game where a space fighter will shoot at some type of enemy ( similar to Galaga ). Currently, I have the movement for the user's space ship and an introduction screen done. The ship only moves left and right. I have been stuck on the issue of getting it to fire a "laser" by using C in SDL. I have seen particle engines being used on Lazy Foo's tutorial( http://lazyfoo.net/SDL_tutorials/lesson28/index.php ) and suggested on StackOverflow for this, but they were in primarily C++ code. It would be daunting for me to try to translate it, and I don't know how else to do it in C other than brute force loading images and data every time the user fires the weapon. In the future, I will also need it to "kill" enemies with collisions, so I was hoping someone here could give me tips on how to add such a system. Here is the code I wrote so far :

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    
    #include <SDL/SDL.h>
    
    
    #define MAX_SPACE_IMAGES 3
    #define SCREEN_WIDTH 920
    #define SCREEN_HEIGHT 518
    
    
    void SDL_errorexit( const char * error_message )
    {
        char buffer[BUFSIZ];
        sprintf(buffer, "%s : %s", error_message, SDL_GetError());
        fprintf(stderr, "%s", buffer);
    
    
        exit(1);
    }
    
    
    void init_SDL( )
    {
        if ( SDL_Init( SDL_INIT_EVERYTHING ) < 0 )
            SDL_errorexit("SDL_Init");
    
    
        return;
    }
    
    
    SDL_Surface * load_image_opt( char * image_path, int is_transparent )
    {
        SDL_Surface * image = NULL;
        SDL_Surface * temp_image = SDL_LoadBMP(image_path);
    
    
        if ( !temp_image )
            SDL_errorexit("SDL_LoadBMP");
    
    
        if ( is_transparent )
            SDL_SetColorKey( temp_image, SDL_SRCCOLORKEY, SDL_MapRGB(temp_image->format, 255, 255, 255) );
    
    
        image = SDL_DisplayFormat( temp_image );
        SDL_FreeSurface( temp_image );
    
    
        return image;
    }
    
    
    SDL_Surface * set_video_mode( const char * window_title )
    {
        SDL_Surface * console = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 24, SDL_HWSURFACE | SDL_DOUBLEBUF );
        SDL_WM_SetCaption( window_title, "N/A" );
    
    
        if (!console)
            SDL_errorexit("SDL_SetVideoMode");
    
    
        return console;
    }
    
    
    void game_intro( SDL_Surface ** space, SDL_Surface * title, SDL_Surface * console )
    {
        SDL_Rect title_rect;
    
    
        int offset = 0;
        int iteration;
    
    
        title_rect.x = (console->w - title->w) / 2;
        title_rect.y = (console->h - title->h) / 2;
        title_rect.h = title->h;
        title_rect.w = title->w;
    
    
        for ( iteration = 0; iteration < 9; iteration++ )
        {
            offset = (offset > MAX_SPACE_IMAGES - 1 ? 0 : offset + 1);
    
    
            SDL_FillRect(console, 0, SDL_MapRGB(console->format, 0, 0, 0)); /* Clear the screen */
    
    
            SDL_BlitSurface(space[offset], 0, console, NULL );
            SDL_BlitSurface(title, 0, console, &title_rect);
            SDL_Flip(console); /* Update the screen */
    
    
            SDL_Delay(250); /* Delay the loop */
        }
    
    
        return;
    }
    
    
    void game_start( SDL_Surface ** space, SDL_Surface * space_fighter, SDL_Surface * console )
    {
        SDL_Event event;
        SDL_Rect fighter;
    
    
        const int SPACE_UPDATE_FRAME = 60;
        int frame = 0;
        int offset = 0;
        int quit = 0;
        int x = 0;
    
    
        fighter.x = (console->w - space_fighter->w ) / 2;
        fighter.y = console->h - 100;
        fighter.h = 75;
        fighter.w = 75;
    
    
        while ( !quit )
        {
            if ( frame == SPACE_UPDATE_FRAME )
                offset = (offset > MAX_SPACE_IMAGES - 1 ? 0 : offset + 1);
    
    
            /* While-loop was from SDL documentation : http://www.libsdl.org/release/SDL-1.2.15/docs/html/guideinputkeyboard.html */
    
    
            while( SDL_PollEvent( &event ) )
            {
                switch( event.type )
                {
                    case SDL_QUIT :
                        quit = 1;
                    break;
    
    
                    /* Keydown event */
                    case SDL_KEYDOWN :
                        switch( event.key.keysym.sym )
                        {
                            case SDLK_LEFT :
                                x = -1;
                            break;
    
    
                            case SDLK_RIGHT :
                                x = 1;
                            break;
    
    
                            case SDLK_ESCAPE :
                                quit = 1;
                            break;
    
    
                            default : break;
                        }
    
    
                    break;
                    /* End keydown event */
    
    
                    /* Keyup event */
                    case SDL_KEYUP:
                        switch( event.key.keysym.sym )
                        {
                            case SDLK_LEFT :
                                if( x < 0 )
                                    x = 0;
                            break;
    
    
                            case SDLK_RIGHT :
                                if( x > 0 )
                                    x = 0;
                            break;
    
    
                            default : break;
                        }
                    /* End keyup event */
                    break;
    
    
                    default : break;
                }
            }
    
    
            if ( fighter.x >= console->w - 75 )
            {
                x = 0;
                fighter.x = console->w - 76;
            }
    
    
            fighter.x += x;
    
    
            SDL_FillRect(console, 0, SDL_MapRGB(console->format, 0, 0, 0)); /* Clear the screen */
    
    
            SDL_BlitSurface(space[offset], 0, console, NULL );
            SDL_BlitSurface(space_fighter, 0, console, &fighter);
            SDL_Flip(console); /* Update the screen */
    
    
            frame = frame == SPACE_UPDATE_FRAME ? 0 : frame + 1;
        }
    
    
        return;
    }
    
    
    int main( int argc, char * argv[] )
    {
        /* Variable declarations */
    
    
        SDL_Surface * space[MAX_SPACE_IMAGES] = {NULL};
        SDL_Surface * title = NULL;
        SDL_Surface * space_fighter = NULL;
        SDL_Surface * console = NULL;
    
    
        int offset;
    
    
        /* Initializing SDL... */
    
    
        init_SDL();
    
    
        if (atexit(SDL_Quit))
        {
            perror("atexit");
            exit(1);
        }
    
    
        /* Screen configurations */
    
    
        console = set_video_mode( "Space Fighter" );
    
    
        /* Image loading */
    
    
        space[0] = load_image_opt( "space_dark.bmp", 0 );
        space[1] = load_image_opt( "space_lighter.bmp",  0 );
        space[2] = load_image_opt( "space_light.bmp", 0 );
        title = load_image_opt( "space_fighter_intro.bmp", 1 );
        space_fighter = load_image_opt( "space_fighter.bmp", 1 );
    
    
        /* Start the game introduction */
    
    
        game_intro( space, title, console );
    
    
        SDL_FreeSurface(title); /* We no longer need the introduction title */
    
    
        /* Start the game */
    
    
        game_start( space, space_fighter, console );
    
    
        /* Free allocated memory */
    
    
        for (offset = 0; offset < MAX_SPACE_IMAGES - 1; offset++ )
            SDL_FreeSurface(space[offset]);
    
    
        SDL_FreeSurface(space_fighter);
    
    
        return 0;
    }
    If someone needs me to include the bitmaps for testing purposes I can. Also, feel free to add suggestions for anything wrong in my code currently.
    Last edited by HelpfulPerson; 08-25-2013 at 07:12 PM.
    "Some people think they can outsmart me, maybe. Maybe. I've yet to meet one that can outsmart bullet" - Meet the Heavy, Team Fortress 2

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,667
    Do you understand this C++ to C transformation?

    Code:
    class foo {
      public:
        int bar;
        void func ( int a );
    };
    void foo::func ( int a ) {
        bar = a;
    }
    int main ( ) {
        foo x;
        x.func(42);
    }
    Becomes
    Code:
    struct foo {
    //  public:
        int bar;
    //    void func ( int a );
    };
    void foo_func ( foo *p, int a ) {
        p->bar = a;
    }
    int main ( ) {
        foo x;
        foo_func(&x,42);
    }
    A simple C++ class is just name decoration, and an implicit 'this' pointer to an instance variable.
    You can easily fake this by doing your own name decoration, and passing an explicit pointer to the instance you want to work on.

    > space[0] = load_image_opt( "space_dark.bmp", 0 );
    For our purposes (and yours), you could just generate solid colour bitmaps using inline code.
    Like say a red square is your ship, and the blue triangle is the enemy 'boss' and the green circles are the enemy 'cannon fodder'.

    We're much more likely to run code we can copy/paste, than run around trying to imagine what half a dozen image files might contain.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User HelpfulPerson's Avatar
    Join Date
    Jun 2013
    Location
    Over the rainbow
    Posts
    288
    Quote Originally Posted by Salem View Post
    Do you understand this C++ to C transformation?

    Code:
    class foo {
      public:
        int bar;
        void func ( int a );
    };
    void foo::func ( int a ) {
        bar = a;
    }
    int main ( ) {
        foo x;
        x.func(42);
    }
    Becomes
    Code:
    struct foo {
    //  public:
        int bar;
    //    void func ( int a );
    };
    void foo_func ( foo *p, int a ) {
        p->bar = a;
    }
    int main ( ) {
        foo x;
        foo_func(&x,42);
    }
    A simple C++ class is just name decoration, and an implicit 'this' pointer to an instance variable.
    You can easily fake this by doing your own name decoration, and passing an explicit pointer to the instance you want to work on.

    > space[0] = load_image_opt( "space_dark.bmp", 0 );
    For our purposes (and yours), you could just generate solid colour bitmaps using inline code.
    Like say a red square is your ship, and the blue triangle is the enemy 'boss' and the green circles are the enemy 'cannon fodder'.

    We're much more likely to run code we can copy/paste, than run around trying to imagine what half a dozen image files might contain.
    I understand that transformation. I'm guessing the foo::func part signifies a method contained in a class? That doesn't seem too difficult to translate.

    Can you explain what you mean more by solid color bitmaps with inline code, or include a code example? I've never heard of it and can only guess what you mean.

    As for the files, I can't upload the original .bmp's, but for your imagination, I will attach and post the pictures.

    space_dark.bmp
    Using a particle engine to create a laser projectile? [C/SDL]-space_dark-png
    space_fighter.bmp
    Using a particle engine to create a laser projectile? [C/SDL]-space_fighter-png
    space_fighter_intro.bmp
    Using a particle engine to create a laser projectile? [C/SDL]-space_fighter_intro_2-png
    space_light.bmp
    Using a particle engine to create a laser projectile? [C/SDL]-space_light-png
    space_lighter.bmp
    Using a particle engine to create a laser projectile? [C/SDL]-space_lighter-png
    "Some people think they can outsmart me, maybe. Maybe. I've yet to meet one that can outsmart bullet" - Meet the Heavy, Team Fortress 2

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,667
    I mean you use things like SDL_FillRect - SDL Documentation Wiki to create very simple bitmaps which are just sufficient to demonstrate the problem to us.

    We (and you) don't actually need finished artwork to fully understand the nature of the problem.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Possibility to create a good game engine
    By sarah22 in forum Tech Board
    Replies: 8
    Last Post: 06-13-2009, 01:04 AM
  2. OpenGL Particle Engine Demo
    By frenchfry164 in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 11-25-2003, 09:10 AM
  3. problem with laser gun!
    By actionbasti in forum Game Programming
    Replies: 3
    Last Post: 11-24-2003, 12:56 AM