Can't Get Bullets to Shoot

Started by
6 comments, last by unicoder 7 years, 9 months ago

Hello, I am trying to make a simple shooter. However whenever I try to make it, so that you shoot a bullet, the bullet does not appear correctly, or it does not move. I'm using C++ and SDL2. I can post more code if it is needed.


	//Init values, X and Y and X_Vel and Y_Vel are declared as floats. 
gBullet.Img = IMG_Load("bullet.png");
	gBullet.Tex = SDL_CreateTextureFromSurface(GameRen, gBullet.Img);
	//gBullet.X = 0.0f;
	gBullet.Y = gPlayer.Y;
	//gBullet.X_Vel = 0.0f;
	gBullet.Y_Vel = 0.0f;
	gBullet.Width = 32;
	gBullet.Height = 32;
	gBullet.isAlive = false;
	//gBullet.Rect.x = (int)gBullet.X;
	gBullet.Rect.y = (int)gBullet.Y;
	gBullet.Rect.w = gBullet.Width;
	gBullet.Rect.h = gBullet.Height;
	gBullet.Timer = 0.05f;

//Supposed to fire bullet when space is pressed
if (event.key.keysym.sym == SDLK_SPACE)
				{
					gBullet.isAlive = true;
					gBullet.Y_Vel = 0.05f;
					gBullet.Y -= gBullet.Y_Vel;
					gBullet.Rect.y = (int)gBullet.Y;
				}

//Draw bullet	
if (gBullet.isAlive)
	{
		SDL_RenderCopy(GameRen, gBullet.Tex, NULL, &gBullet.Rect);
	}
Advertisement

You don't appear to be doing anything to it's x-coordinate. Can you say more about the game, is it 2D, top down, left/right scroller etc? Does the player move?

See if you can put the bullet at a known position (centre of the screen perhaps) with 0 velocity first, just to make sure it renders. Once you have tried that you can then try positioning it dynamically on (or in front of) the player. You will need to do that when the space button is pressed if the player can move.

Another thing to consider is if the bullet is colliding with the player when they shoot and destroying itself.

It might be helpful if you show the declaration for the bullet class/struct and maybe the constructor so we can get a better idea of default values. What units is bullet.timer measured in, seconds? The value you give it looks very small, is it possible the bullet's timer runs out almost instantly?

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

The game is meant to be a vertical shooter, so I don't think I need to mess with the X coord. It is 2D. The player does move.



int ThisTime,LastTime;
float DeltaTime;

struct BULLET
{
    SDL_Surface* Img;
    SDL_Texture* Tex;
    SDL_Rect Rect;

    bool isAlive;
    float X, Y;
    float X_Vel, Y_Vel;
    int Width, Height;
    float Timer;
};

Here is the struct for the bullet.

    ThisTime = SDL_GetTicks();
    DeltaTime = (float)(ThisTime - LastTime) / MAX_TICKS;
    LastTime = ThisTime;

if (event.key.keysym.sym == SDLK_SPACE)
                {
                    gBullet.isAlive = true;
                    gBullet.Y_Vel = 0.05f;
                    gBullet.Y -= gBullet.Y_Vel * DeltaTime;
                    gBullet.Rect.y = (int)gBullet.Y;
                }
Here is some more code.

Try doing something like this:


if (event.key.keysym.sym == SDLK_SPACE)
                {
                    gBullet.isAlive = true;
                    gBullet.Y_Vel = 0.05f;
                    gBullet.Y -= gBullet.Y_Vel * DeltaTime;
                    gBullet.Rect.y = (int)gBullet.Y;
                    printf("gBullet.Rect.y = %d\ngBullet.Y = %f\nDeltaTime = %f\n", gBullet.Rect.y, gBullet.y, DeltaTime);
                }

Presumably, one of those three values isn't what you think it is. I can't tell at a glance what the problem is, but that should illuminate what it is pretty quickly (and kill your framerate, so don't keep it around of course).

if (event.key.keysym.sym == SDLK_SPACE)
{
    gBullet.isAlive = true;
    gBullet.Y_Vel = 0.05f;                  // (2)
    gBullet.Y -= gBullet.Y_Vel * DeltaTime; // (1)
    gBullet.Rect.y = (int)gBullet.Y;
}


This code only moves the bullet (1) a single step, but only after pressing the space bar. Additionally, if these units are in pixels, then the bullet will take 20 seconds to move a single pixel (2). Obviously, the bullet should move regardless of whether of not the space bar was pressed, so it should be updated independently:

// Update time
ThisTime = SDL_GetTicks();
DeltaTime = (float)(ThisTime - LastTime) / MAX_TICKS;
LastTime = ThisTime;

// Process events
SDL_Event ev;
while ( SDL_GetEvent(&ev) )
{
    // ...

    if (event.key.keysym.sym == SDLK_SPACE)
    {
        gBullet.isAlive = true;
        gBullet.Y_Vel = 300.0f;  // pixels per second
    }
}

// Update entities
if ( gBullet.isAlive )
{
    gBullet.Y -= gBullet.Y_Vel * DeltaTime;  
    gBullet.Rect.y = (int)gBullet.Y;
}    

Thanks, I got it. Here is the updated code.


	if (event.key.keysym.sym == SDLK_SPACE)
				{
					gBullet.isAlive = true;
					gBullet.Y_Vel = 25.0f;
					gBullet.Timer = 50.0f;
				}
			}
		}

		if (gBullet.isAlive)
		{
			gBullet.Timer--;
			gBullet.Y -= gBullet.Y_Vel * DeltaTime;
			gBullet.Rect.y = (int)gBullet.Y;

			if (gBullet.Timer == 0)
			{
				gBullet.isAlive = false;
				gBullet.Y = gPlayer.Y;
			}
		}

Now I just need to make it so that the bullet fires from the player and not from the left side of the screen.

Now I just need to make it so that the bullet fires from the player and not from the left side of the screen.

You'll want to set the bullet's rectangle X to the player's X position on initial creation.

I'd also suggest removing the X, Y, Width, and Height variables in the Bullet struct since all of those values are repeated in the Rect Variable.

Also, you might want to look into creating a vector of bullets, so you can have more than 1 bullet at a time, but that's obviously gameplay specific. And, instead of using a timer to kill the bullet, remove it when it either leaves the view-able screen, or it has collided with an enemy.

Good luck and have fun!

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

Not related I know, but are you only allowing one bullet on screen at a time? Or did I misread this?

This topic is closed to new replies.

Advertisement