SDL Bullet Movement

Grey
  • SDL Bullet Movement Grey

    I'm currently working on my first space shooter, and I'm in the process of making my ship shoot some bullets/lasers. Unfortunately, I'm having a hard time getting the bullets to fly vertically. I'm a total noob when it comes to this so you might have a hard time understanding my code :/

        // Position Bullet Function
        projectilex = x + 17;
        projectiley = y + -20;
        if(keystates[SDLK_SPACE])
        {
            alive = true;
        }
    

    And here's my show function

        if(alive)
        {
    
            if(frame == 2)
            {
                frame = 0;
            }
            apply_surface(projectilex,projectiley,ShootStuff,screen,&lazers[frame]);
            frame++;
            projectiley + 1;
        }
    

    I'm trying to get the bullet to fly vertically... and I have no clue how to do that. I've tried messing with the y coordinate but that makes things worse. The laser/bullet just follows the ship :(

    How would I get it to fire at the starting position and keep going in a vertical line without it following the ship?

    int main( int argc, char* args[] )
    {
    Player p;
    Timer fps;
    bool quit = false;
    if( init() == false )
    {
        return 1;
    }
    
    //Load the files
    if( load_files() == false )
    {
        return 1;
    }
    
    clip[ 0 ].x = 0;
    clip[ 0 ].y = 0;
    clip[ 0 ].w = 30;
    clip[ 0 ].h = 36;
    
    clip[ 1 ].x = 31;
    clip[ 1 ].y = 0;
    clip[ 1 ].w = 39;
    clip[ 1 ].h = 36;
    
    clip[ 2 ].x = 71;
    clip[ 2 ].y = 0;
    clip[ 2 ].w = 29;
    clip[ 2 ].h = 36;
    
    lazers [ 0 ].x = 0;
    lazers [ 0 ].y = 0;
    lazers [ 0 ].w = 3;
    lazers [ 0 ].h = 9;
    
        lazers [ 1 ].x = 5;
    lazers [ 1 ].y = 0;
    lazers [ 1 ].w = 3;
    lazers [ 1 ].h = 7;
    
    
    while( quit == false )
    {
        fps.start();
        //While there's an event to handle
        while( SDL_PollEvent( &event ) )
        {
            p.handle_input();
            //If a key was pressed
    
    
            //If the user has Xed out the window
            if( event.type == SDL_QUIT )
            {
                //Quit the program
        quit = true;
        }
    
        }
    
        //Scroll background
        bgX -= 8;
    
        //If the background has gone too far
        if( bgX <= -GameBackground->w )
        {
        //Reset the offset
        bgX = 0;
        }
        p.move();
        apply_surface( bgX, bgY,GameBackground, screen );
        apply_surface( bgX + GameBackground->w, bgY, GameBackground, screen );
    
        apply_surface(0,0, FullHealthBar,screen);
    
        p.shoot();
        p.show();
        //Apply the message
        //Update the screen
        if( SDL_Flip( screen ) == -1 )
        {
        return 1;
        }
        SDL_Flip(GameBackground);
        if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND )
        {
        SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() );
        }
        }
        //Clean up
        clean_up();
        return 0;
        } 
    

  • Well i was about to write a formerly answer, but seeing your code, it appears that you dont have any Entity system. So it may complicate you, but lets try to solve this.

    We need a class to follow what are those bullets, and where are they, dont we?

    So lets create something!

    class Bullet
    {
        Vector2 position;
        Vector2 speed;
    };
    

    If you have entities, probably you already had something like this. So just adapt yourself (:

    What must we do? Lets try to describe in plain english what will the code do to shoot bullets.

    Every frame, check if the space bar is pressed. If it is pressed, and wasnt before, create a new bullet, going to where the player is faced. If the bullet hits something, delete it, make some nice explode animation and take hp of the object that took the hit. If the bullet just goes after the screen boundaries, just delete it.

    Lets try to pass it to C++.

    First of all, you have to have some kind of container to storage your bullets. Of course you'll have more than one, so thats why.

    Some kind like this on your initialization should do:

    std::list<Bullet*> bullets;
    

    I dont recommend lists for a game, but they're easier to deal for now.

    Now, the code to shoot:

    if(event.type == SDL_KEYDOWN)
    {
        if(event.key == SDLK_SPACE)
        {
            Bullet* toShoot = new Bullet();
            toShoot.speed = player.direction * 5;
            toShoot.position = player.position + toShoot.speed;
            bullets.add(toShoot);
        }
    
    }
    

    Adapt it to your needs and current usages.

    The most tricky part here is the player.direction * 5; Well, probably, you have a vector pointing where the player is facing, if you dont have, you SHOULD! When you multiply a vector by a number, you can get a nice speed direction going to that direction! so you'll have a 5px going into that direction. That may not be too right, but should work as a basis for you. Study distance and the pitagoras's formula d = sqrt(x^2 + y^2); If you just want the bullet to go up, change toShoot.speed = player.direction * 5;with toShoot.speed = Vector(0, 5);

    To update your code, try:

    for(list<Bullet*>::iterator it = bullets.begin(); it != bullets.end();)
    {
        (*it)->position += (*it)->speed;
        if(isOutOfBound((*it)->position))
        {
            delete (*it);
            bullets.erase(it++); //remove from the list and take next
        }
        else if(collideWithSomething((*it)->position))
        {
            Entity collisor = getCollisor((*it)->position);
            collisor.takeHit();
            playSound(Explosion);
            makeAnimation(Explosion);
            delete (*it);
            bullets.erase(it++);
        }
        else
        {
            ++it; //take next object
        }
    }
    

    This should do :D

    Remembering, the most of these classes you maybe dont have, but you should think about creating something similar.

Tags
c++ sdl projectile-physics
Related questions and answers
  • (); missile-&gt;Init(true, s-&gt;X, s-&gt;Y); bullets-&gt;push_back(missile); } } void CleanUp() { for(unsigned int index = 0; index &lt; bullets-&gt;size(); index...)-&gt;Alive == true) { bullets-&gt;at(index)-&gt;Draw(buffer, sprite); } } } //Entry point of the application int main(void) { Ship* s = new Ship(); int x = (WIDTH / 2) - 64; allegro_message("Initialzing ship class"); s-&gt;Init(x); int frame = 0; BITMAP* buffer = NULL; BITMAP* background = NULL; BITMAP* ship = NULL; SceCtrlData

  • //////////// bool move(int X, int Y) { location[0] += X; location[1] += Y; return true;}; };// end of sprite...{ // cwall is negative swall--; cwall++;}} for(int w= 0; w &lt;swall; w++) buff[buff.size()-1].push_back('X'); // cspace...--; cspace++;}} for(int s= 0; s &lt;sspace; s++) buff[buff.size()-1].push_back(' '); // cwall2 //if(cwall2!= 0){ // if(cwall2&gt;0

  • ; pTransform-&gt;SetMatrix(&amp;matFinal._11); pPass-&gt;Apply(0); device-&gt;DrawIndexed(36, 0, 0); // display the rendered frame swapchain-&gt;Present(0, 0); } // this function sets up... the basic windows header files and the Direct3D header files #include &lt;d3d10.h&gt; #include &lt;d3dx10.h&gt; #include "direct3D.h" #include "Globals.h" // this function initializes and prepares...); UINT offset = 0; device-&gt;IASetVertexBuffers(0, 1, &amp;pBuffer, &amp;stride, &amp;offset); device-&gt;IASetIndexBuffer(iBuffer, DXGI_FORMAT_R32_UINT, 0); D3DXMATRIX matRotate, matView

  • i think i just found the solution. 1) the problem is that backbuffer surface and source surface are of different formats - that is why exception was thrown. 2) the image path needed double slash "C\\......." ;) ================================= I have been googling for a while but still cant come up with a solution to the problem - D3DXGetImageInfoFromFile function just doesn't load any images...(D3D_SDK_VERSION))) return false; std::wstring wsPath = L"C:\wood.bmp"; // path to the image D3DXIMAGE_INFO Info; if (FAILED(D3DXGetImageInfoFromFile(wsPath.c_str(), &amp;Info

  • &lt; numTriangles; i++) { MD2Triangle* triangle = triangles + i; for(int j = 0; j &lt; 3; j++) { MD2Vertex* v1 = frame1-&gt;vertices + triangle-&gt;vertices[j... = triangles + i; for(int j = 0; j &lt; 3; j++) { MD2Vertex* v1 = frame1-&gt;vertices + triangle-&gt;vertices[j]; MD2Vertex* v2 = frame2-&gt;vertices + triangle-&gt;vertices[j...? Something unnecessary that maybe you guys could spot? Both MD2 and 3DS loader have an InitToon() function called upon creation to load the shader initToon(){ int i

  • ; float current_time, old_time, interpol; int type, current_frame, next_frame; }; struct md2_glcmd_t { float s; float t; int index; }; #define MD2_IDENT (('2'&lt;&lt;24) + ('P'&lt;&lt;16..._Commands, m_MD2Header.num_glcommands * sizeof(int)); // Read all the data. for(int i = 0; i &lt; m_MD2Header.num_frames; ++i) { md2_frame_t* Frame = (md2_frame_t*)&amp;Buffer...I'm trying to load MD2 models (stolen from Cube) and my loader seems to be loading the models fine, but I can't say the same for the drawing of the model. Here's my code: typedef float vec3_t[3

  • ; outside that space, white is drawn. Here is my OpenGL init code... SDL_SetVideoMode(windowWidth, windowHeight, 16, SDL_HWSURFACE|SDL_GL_DOUBLEBUFFER|SDL_OPENGL); glClearColor(0, 0, 0, 0...); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glLoadIdentity(); ...here is my image loading function... SDL_Surface *loadImage (const char *filename, bool alpha = true) { SDL_Surface...; glGenTextures(1, &amp;thisIsMyTexture); temporarySurface = loadImage("theimagetomytexture.png"); glBindTexture(GL_TEXTURE_2D,thisIsMyTexture); glTexImage2D(GL_TEXTURE_2D, 0, 4, temporarySurface-&gt;w

  • ) { once2 = 0; spacebar = false; } //This will eventually get better. My shoot function is horrible lol :/ } Does anyone have any ideas as to how I can accomplish this without... want it to do is keep producing bullets until the user releases their hand on the space-bar... here's the code I have so far: if(spacebar) // this bool variable is set to true once the user presses the space bar { int frame2 = 0; if(once2 == 0) { projectilex2 = x + 19; projectiley2 = y + -35; //Positions the bullet at the nose of the ship } if(frame2

  • (); playerMoveInX = true; return; } playerMoveInX = false; } } And for the frames I have a class Animation which handles the following information: Uint32 frameRate, oldTime; int frameDelay; int frameCount; And in the function that animates I do the following, much like the MoveX in Sprite: int Animation::animate() { if( oldTime + frameRate &gt; SDL_GetTicks() ) { return -1... the movement and the changes of frames. To clarify what I mean I have in my Sprite class these parameters: std::vector< Vector2f &gt; delayMovementSprite; std::vector< int &gt; frameDelayPerAnimation

Data information