Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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;
    } 
share|improve this question
    
Wow, kinda strange your functions. Can you add more details? Like where/when they're called/triggered? –  Gustavo Maciel Jan 19 '12 at 3:05
    
Oh sorry :(. The position bullet function is called whenever the user presses the space bar and so is the show function so it kind of looks like this: if(keystates[SDLK_SPACE]){//Position Bullet Function go here //show function go here} –  Grey Jan 19 '12 at 3:08
    
Oh, nevermind. And wow haha, now you confused myself, or yourself! if you know that the space is pressed to call the position function, why do you check inside the function if space is pressed? i dont know what you're trying, but there may be a better way! –  Gustavo Maciel Jan 19 '12 at 3:12
    
By the way, i have an answer, but i may still want to see more from your code. So i make sure that it will well integrate for you. But if you care sharing, tell me so i post it more "pseudo code" that may still work for you. And use the edit button! it's way better than adding code in the comments :) –  Gustavo Maciel Jan 19 '12 at 3:14
    
Alright. I gave you my main. Is that enough? Thanks for all your help! –  Grey Jan 19 '12 at 4:07
show 6 more comments

2 Answers

up vote 5 down vote accepted

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.

share|improve this answer
add comment
PBullet.XPos=XPos+Enterprise.LImageLength/2; //get bullet YX start ship location
PBullet.YPos=YPos+Enterprise.LImageHeight/2; //get bullet YX start ship location
PBullet.XVel= PBullet.ShipSpeed*cos(ShipFacing);  //work out angle of bullet
PBullet.YVel= PBullet.ShipSpeed*sin(ShipFacing);  //work out angle of bullet
PBullet.TimeOfEvent= SDL_GetTicks(); //start timer for duration of bullet alive

You also need somthing like

GameObject ::apply_surface(SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip)
{
    SDL_Rect sourceImage;
    sourceImage.x = ShipSpritesheetX; //position in image file left to right
    sourceImage.y = ShipSpritesheetY; //position in image file up and down
    sourceImage.w = LImageHeight; //width of sprite in image
    sourceImage.h = LImageLength; //height of sprite in image
    SDL_Rect offset; //Holds offsets
    offset.x = XPos;  //Get offsets
    offset.y = YPos;
    SDL_BlitSurface( source, &sourceImage, destination, &offset );  //Blit
}

 PBullet.apply_surfacing(PlayerBullet, screen,NULL ); //display bullet while firing
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.