• Advertisement
Sign in to follow this  

How to Fire bullet continuosly

This topic is 2358 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'm a bit new to SDL programming iv'e learnt all the basic concepts and almost everything.. I made a simple bullet testing program which shoots only one bullet at one time.. I cant figure out how to shoot many bullets at one time.. IVe tried something but i failed, anyone has an idea about what to do to fire bullets fastly??..

Heres my code for 1 bullet per time :

//Libraries
#include <sdl.h>
#include <sdl_image.h>
#include <string>

//Screen attbts
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

//Fps
const int FRAMES_PER_SECOND = 20;

//Square attbs
const int SQUARE_WIDTH = 40;
const int SQUARE_HEIGHT = 40;

//Bullet attbs
const int BULLET_WIDTH = 20;
const int BULLET_HEIGHT = 10;

//Surfaces
SDL_Surface *screen = NULL;
SDL_Surface *bullet = NULL;
SDL_Surface *square = NULL;

SDL_Event event;

int x, y;
int xVel1 = 0;
int yVel1 = 5;

class Square
{
private:
int xVel, yVel;

public:
Square();

//Handle input
void handle_input();

//Move and show the dot
void move();
void show();
};

class Timer
{
private:
int startTicks;
int pausedTicks;

bool paused;
bool started;

public:
//Constructor
Timer();

//various actions
void start();
void stop();
void pause();
void unpause();

//Get ticks time
int get_ticks();

bool is_started();
bool is_paused();
};

SDL_Surface *load_image( std::string filename )
{
//The images
SDL_Surface* loadedImage = NULL;
SDL_Surface* optimizedImage = NULL;

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

if( loadedImage != NULL )
{
//Get optimizedimage
optimizedImage = SDL_DisplayFormat( loadedImage );

//Free surface
SDL_FreeSurface( loadedImage );

if( optimizedImage != NULL )
{
//Set color key
SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0, 0xFF ) );
}
}

//Return
return optimizedImage;
}

void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{
//Hold offset
SDL_Rect offset;

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

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

bool init()
{
//Init everything
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
return false;
}
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

if( screen == NULL )
{
return false;
}

//Set caption
SDL_WM_SetCaption( "Bullet test", NULL );

return true;
}

bool load_files()
{
//Load the square
square = load_image( "Square.png" );

if(square == NULL )
{
return false;
}

//Load bullet
bullet = load_image( "bullet.png" );

if( bullet == NULL )
{
return false;
}

//Everything loaded
return true;
}

void clean_up()
{
//Free surfaces
SDL_FreeSurface( square );
SDL_FreeSurface( bullet );

//Quit SDL
SDL_Quit();
}

Square::Square()
{
x = 1;
y = 420;

xVel = 0;
yVel = 0;
}

void Square::handle_input()
{
if( event.type == SDL_KEYDOWN )
{
switch( event.key.keysym.sym )
{
case SDLK_LEFT: xVel -= SQUARE_WIDTH / 3; break;
case SDLK_RIGHT: xVel += SQUARE_WIDTH / 3; break;
}
}
else if( event.type == SDL_KEYUP )
{
switch( event.key.keysym.sym )
{
case SDLK_LEFT: xVel += SQUARE_WIDTH / 3; break;
case SDLK_RIGHT: xVel -= SQUARE_WIDTH / 3; break;
}
}
}

void Square::move()
{
x += xVel;

//Keep the square in bounds
if( ( x < 0 ) || ( x + SQUARE_WIDTH > SCREEN_WIDTH ) )
{
x -= xVel;
}

y += yVel;
//keep square in bounds
if( ( y < 0 ) || ( y + SQUARE_HEIGHT > SCREEN_HEIGHT ) )
{
y -= yVel;
}
}

void Square::show()
{
apply_surface( x, y, square, screen );
}

Timer::Timer()
{
startTicks = 0;
pausedTicks = 0;
paused = false;
started = false;
}

void Timer::start()
{
started = true;

paused = false;

startTicks = SDL_GetTicks();
}

void Timer::stop()
{
started = false;
paused = false;
}

void Timer::pause()
{
if( ( started == true ) && ( paused == false ) )
{
paused = true;

pausedTicks = SDL_GetTicks() - startTicks;
}
}

void Timer::unpause()
{
if( paused == true )
{
paused = false;

startTicks = SDL_GetTicks() - pausedTicks;

pausedTicks = 0;
}
}

int Timer::get_ticks()
{
if( started == true )
{
if( paused == true )
{
return pausedTicks;
}
else
{
return SDL_GetTicks() - startTicks;
}
}

return 0;
}

bool Timer::is_started()
{
return started;
}

bool Timer::is_paused()
{
return paused;
}

class Bullet
{
private:
//Offsets
int x1, y1;
//Velocity
int xVel1, yVel1;

public:
Bullet();

//Handle input
void handle_input1();

//Move
void move1();

//Show
void show1();

bool isFired;
};

Bullet::Bullet()
{
//Position and velocity
x1 = 20;
y1 = 400;

xVel1 = 0;
yVel1 = 5;

isFired = false;
}

void Bullet::handle_input1()
{
if( event.type == SDL_KEYDOWN )
{
switch( event.key.keysym.sym )
{
case SDLK_SPACE:
if( isFired )
{
yVel1 = BULLET_WIDTH / 3; break;
}


else
{
//move bullet to position of dot
x1 = x;
y1 = y;

yVel1 = 5;
isFired = true;
}
break;

default:
break;

}
}
//IF key was released
else if( event.type == SDL_KEYUP )
{
switch( event.key.keysym.sym )
{
case SDLK_SPACE:
if( isFired )
{
yVel1 = 5;
}
break;
default:
break;
}
}
}

void Bullet::move1()
{
//Move if bullet is fired
if( isFired )
{
y1 -= yVel1;
}
}

void Bullet::show1()
{
//Show only if bullet is on screen
if( isFired && y1+BULLET_HEIGHT > 0 )
{
apply_surface( x1, y1, bullet, screen );
}
else
{
isFired = false;
}
}

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

Square mySquare;
Bullet myBullet;

Timer fps;

if( init() == false )
{
return 1;
}
if( load_files() == false )
{
return 1;
}

//When user has not quit
while( quit == false )
{
fps.start();

while( SDL_PollEvent( &event ) )
{
mySquare.handle_input();
myBullet.handle_input1();

//If users has Xed out
if( event.type == SDL_QUIT )
{
quit = true;
}
}

//Fil screen white
SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0, 0xFF, 0xFF ) );

mySquare.show();
myBullet.show1();

//Move square and bullet
mySquare.move();
myBullet.move1();

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

//Frames
if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND )
{
SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() );
}
}

//Clean up
clean_up();

return 0;
}

( I know its a bit big ) But please help me
Thank you.

Share this post


Link to post
Share on other sites
Advertisement
You need to create an array/std::vector of multiple Bullets, and call show(), etc for every bullet in the array

Share this post


Link to post
Share on other sites

You need to create an array/std::vector of multiple Bullets, and call show(), etc for every bullet in the array

Thanks, But is there any other way to do it..?

Share this post


Link to post
Share on other sites

[quote name='zacaj' timestamp='1315756960' post='4860359']
You need to create an array/std::vector of multiple Bullets, and call show(), etc for every bullet in the array

Thanks, But is there any other way to do it..?
[/quote]

No. Since you'll be firing multiple bullets, each bullet must keep track of its own position and velocity.
You should also try implementing a particle system to learn about pooling objects to make it more efficient.

Welcome to programming, where it's all hard work and sweat.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement