# Can't make my ship shoot bullet

This topic is 3085 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi everyone.I'we been writing my own space invaders like game in C . And everything was ok till now. I write the code for the bullet too,but when i compile it and when i try to shoot(i press SPACE) and then everything freezes :S and it wont continue. So i tried to change it somehow.the code for the bullet. And now i got it to not freeze, BUT the bullet is in the corner of my screen and its not moving from my ship to the top,slowly. :( I really don't know how to try next. It would be good if someone can find my bug and help me. Herre is my code :
#include <allegro.h>
#include <stdlib.h>
#include <stdio.h>

void init();
void deinit();
int Enemy_Animacio(int x,int y,int frame_counter,BITMAP* buffer,BITMAP* Enemy01,BITMAP* Enemy02,BITMAP* Enemy03);
void increment_speed_counter();
void wait (int sec);

volatile long speed_counter = 0;

int main() {
init();
set_color_depth(16);

//-----------BITMAPOK letrehozasa-----------------------------------------------
BITMAP *Battle_Ship=NULL;
BITMAP *Enemy01=NULL;
BITMAP *Enemy02=NULL;
BITMAP *Enemy03=NULL;
BITMAP *buffer=NULL;
BITMAP *golyo=NULL;

//------------------------------------------------------------------------------

//-------------BITMAPOK beolvasasa----------------------------------------------
buffer = create_bitmap(640,480);
if(buffer == NULL)
{
set_gfx_mode(GFX_TEXT,0,0,0,0);
allegro_message("Could not create buffer!");
exit(EXIT_FAILURE);
}

//------------------------------------------------------------------------------

//-----------------Kulonbozo Deklaralasok---------------------------------------
LOCK_VARIABLE(speed_counter);
LOCK_FUNCTION(increment_speed_counter);

install_int_ex(increment_speed_counter, BPS_TO_TIMER(130)); //Set our BPS

int BS_x = 270;// Battleship X coorinataja
int BS_y = 400;// Battleship Y coordinataja
int frame_counter=0;

int buffer_bb_left=640;  //bb=bounding box :)
int buffer_bb_top=480;
int buffer_bb_right=(buffer_bb_left + buffer->w);
int buffer_bb_bottom=(buffer_bb_top + buffer->h);
int golyo_left=BS_x+10;
int golyo_top=BS_y-10;
int golyo_right=(golyo_left + golyo->w);
int golyo_bottom=(golyo_top + golyo->h);

int show_bbox=FALSE;
int collision=FALSE;
int collision_b=FALSE; //utkozese a bufferal.(ha ki akar lepni a kepernyorol)
int fire_golyo=FALSE;
int y;
int x;

//------------------------------------------------------------------------------
//-----------------------Egyszeru kezdoszoveg kiirasa---------------------------
textout_ex(buffer,font,"Az iranyitashoz hasznald a le,fol,jobra,balra gombokat :):)",0,0,30,0);
textout_ex(buffer,font,"ha ki szeretnel lepni akkor nyomd meg az ESC gombot ",0,10,30,0);
textout_ex(buffer,font,"nyomj meg egy gombot a tovabblepesre :D.... :)",0,20,30,0);
blit(buffer,screen,0,0,0,0,640,480);

clear_bitmap(buffer);
//------------------------------------------------------------------------------
//------------------Maga a jatek menete-----------------------------------------
while (!key[KEY_ESC]) {

while(speed_counter > 0)
{
//----------------------Az iranyitas,es(vagy)mas gombok  meghatarozasa -----------------------------
if(key[KEY_RIGHT])
BS_x ++;
if(key[KEY_LEFT])
BS_x --;
if(key[KEY_UP])
BS_y --;
if(key[KEY_DOWN])
BS_y ++;
//------------------------------------------------------------------------------
/*    if(key[KEY_B])
show_bbox=TRUE;
else if(!key[KEY_B])
show_bbox=FALSE;
*/
if(key[KEY_SPACE])
fire_golyo=TRUE;
else if(!key[KEY_SPACE])
fire_golyo=FALSE;
if(fire_golyo==TRUE)
for(x=BS_x,y=BS_y;y>10;y--)
{
blit(golyo,buffer,0,0,0,0,x,y);

}

//---------------------------Azert kell hpgy updatelje a bb-t-------------------
/* int buffer_bb_left=640;  //bb=bounding box :)
int buffer_bb_top=480;
int buffer_bb_right=(buffer_bb_left + buffer->w);
int buffer_bb_bottom=(buffer_bb_top + buffer->h);       */
//------------------------------------------------------------------------------
/*      collision_b=TRUE;
if(<)
collision_b=FALSE;
else if(>)
collision_b=FALSE;
else if(<)
collision_b=FALSE;
else if(>)
collision_b=FALSE;
*///----------------------------------------------------------------------------

speed_counter --;
frame_counter ++;

if(frame_counter > 520) // 130 * 4 = 520 (When frame counter = 130, 1 second has passed)
{
frame_counter = 0;
}

}  //END OF WHILE (speed_counter > 0)
//------------------------------------------------------------------------------

//-----------------A Spriteok kirajzolasa---------------------------------------
draw_sprite(buffer, Battle_Ship, BS_x, BS_y);
Enemy_Animacio(80,100,frame_counter,buffer,Enemy01,Enemy02,Enemy03);
Enemy_Animacio(160,100,frame_counter,buffer,Enemy01,Enemy02,Enemy03);
Enemy_Animacio(240,100,frame_counter,buffer,Enemy01,Enemy02,Enemy03);
Enemy_Animacio(320,100,frame_counter,buffer,Enemy01,Enemy02,Enemy03);
Enemy_Animacio(400,100,frame_counter,buffer,Enemy01,Enemy02,Enemy03);
Enemy_Animacio(480,100,frame_counter,buffer,Enemy01,Enemy02,Enemy03);

blit(buffer, screen, 0,0,0,0,640,480);
clear_bitmap(buffer);

//------------------------------------------------------------------------------

}
//-----------------A bitmapok torlese,hogy nehogy valami szemet maradjon a memoriaban
destroy_bitmap(buffer);
destroy_bitmap(Battle_Ship);
destroy_bitmap(Enemy01);
destroy_bitmap(Enemy02);
destroy_bitmap(Enemy03);
destroy_bitmap(golyo);

deinit();
return 0;
}
END_OF_MAIN()

void init() {
int depth, res;
allegro_init();
depth = desktop_color_depth();
if (depth == 0) depth = 32;
set_color_depth(depth);
res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
if (res != 0) {
allegro_message(allegro_error);
exit(-1);
}

install_timer();
install_keyboard();
install_mouse();
/* add other initializations here */
}

void deinit() {
clear_keybuf();
/* add other deinitializations here */
}

void increment_speed_counter() //A function to increment the speed counter
{
speed_counter++; // This will just increment the speed counter by one. :)
}
END_OF_FUNCTION(increment_speed_counter); //Make sure you tell it that it's the end of the
//function

int Enemy_Animacio(int x,int y,int frame_counter,BITMAP* buffer,BITMAP* Enemy01,BITMAP* Enemy02,BITMAP* Enemy03)
{
if(frame_counter < 130) // Less than a full second
{
draw_sprite(buffer, Enemy01, x,y);//Draw the first frame
}
else if(frame_counter >= 130 && frame_counter < 260)//Between 1 and 2 seconds
{
draw_sprite(buffer, Enemy02, x, y);//Draw the second frame
}
else if(frame_counter >= 260 && frame_counter < 390)//If we are between 2 and 3 seconds
{
draw_sprite(buffer, Enemy01, x, y);//Draw the first frame again,
//to acheive better effect
}
else // If we are over 3 seconds
{
draw_sprite(buffer, Enemy03, x, y); //Draw the last frame.
}
}

//------------------------------------------------------------------------------

void wait ( int sec )
{
clock_t end_wait;
end_wait = clock () + sec * CLK_TCK ;

while (clock() < end_wait) {}
}

//------------------------------------------------------------------------------


EDIT: In the code the "golyo" is the name for my bullet. Thanks for Everything Ronel

##### Share on other sites
I'm not sure, but it seems to me that there is code to actually make the bullet and display it (hence it appearing).

But to my knowledge there doesnt seem to be any code for making it move across the screen perhaps you should start there?

If there is code for moving the bullet then i apologise for my idiocy and you can disregard this comment.

##### Share on other sites

Well,

I might ask why are you blitting instead of drawing a sprite when you are shooting?

Also, the logic of shooting looks strange. In another words:

While space is being pressed, you call blit function in a loop with y being the loop counter.

This code doesn't add a bullet to the screen. It just draws (if blitting is the right function) a line of sprites from the location of the ship to the upper part of the screen, while space is being pressed.

You have to think a differently. ie.

- when space is pressed, add a bullet to a list of bullets.
- every time you update your logic, move your bullets and check for collisions
- if bullet hits something or has flown enough, remove it from the list
- when drawing, loop through your list of bullets and draw them.

Good luck!

##### Share on other sites
Hi,

The problem is in the bullet drawing method. Now, when you press the space then it begins to draw many bullets on the current frame because of the for loop. More over I think the parameters of the blit function are wrong too, because you draw a the bullets with changeing their size and not their position.

You need to draw the bullet in the main loop and change its position there.

Sok szerencsét :),
fenor

##### Share on other sites
Hi. Wow how fast you guys reply ed. thanks :)

@Xeogen
Hi.The For is moving my bullet from the ship to the top.(i think)

@Kauna
Hi. I replaced the Blit func. with draw_sprite(buffer,golyo, x, y);
And now it does what you sayd.: "a line of sprites from the location of the ship to the upper part of the screen, while space is being pressed." it looks like a beam,while i press SPACE. (but it's still better than the Blit)

and
- when space is pressed, add a bullet to a list of bullets. Im sorry but i don't understand this. How should i make a list of bullets,and how should i make it work? this is my first game and i'm writing it alone. I learned allegro from the net tutorials. and i didn't see something like that in the tutorials.
I don't know how to make list for bullets and how to add bullets to the list
- when drawing, loop through your list of bullets and draw them. << How should i do this too??
Sorry im so noob with this things :(

I first want to make the bullet work. After that i will try to make collison detection whit boundig box.

@fenor
Hi. How to draw bullet with changing its size?not the position. And why?
So i need to draw the bullet in while (!key[KEY_ESC]) { } and not in while(speed_counter > 0){} ???

Thanks for everything guys.
Ronel

##### Share on other sites
Hi,

here is some very very simple code for adding bullets to your game.

call InitBullets() in the initialization part of the program.
call AddBullet(int x,int y) when space is pressed with your ships position as parameters

call DrawBullets() at the location where you draw your things (not in the place where you check for space being pressed)

class ProcessBullets() every frame in your main loop.

struct MyBullet{	int PositionX,PositionY;	bool IsActive;};#define MAXBULLETS 32MyBullet BulletArray[MAXBULLETS];void InitBullets(){for(int i=0;i<MAXBULLETS;++i)BulletArray.IsActive = false; //set all bullets to false}void AddBullet(int x,int y){	for(int i=0;i<MAXBULLETS;++i)	if(BulletArray.IsActive == false) //look for inactive slot	{		BulletArray.IsActive = true; //mark the slot active		BulletArray.PositionX = x;		BulletArray.PositionY = y;		return;		}}void ProcessBullets(){	for(int i=0;i<MAXBULLETS;++i)	if(BulletArray.IsActive == true)	{		BulletArray.PositionY--;	//bullet movement here		if(BulletArray.PositionY < 10)BulletArray.IsActive = false; //check for bullet reaching upper part of the screen//add your bullet/enemy collision detection here	}}void DrawBullets(){	for(int i=0;i<MAXBULLETS;++i)	if(BulletArray.IsActive == true)	{		DrawSprite(BulletArray.PositionX,BulletArray.PositionY); // Fix this line to work with your drawing routines	}}

##### Share on other sites
Hi,

I think you misunderstood me. You use to draw the bullet:

blit(golyo,buffer,0,0,0,0,x,y);

The last two parameter of blit gives the size and not the position of the destination rect. That's why your bullet is in the corner.

You need a bit more change to draw your bullets.

for(x=BS_x,y=BS_y;y>10;y--)
{
blit(golyo,buffer,0,0,0,0,x,y);

}
That draws all the bullets on the current frame and that is not what you need. If you just write:

if(fire_golyo==TRUE)
blit(golyo,buffer,0,0,0,0,x,y);

is wrong too, because your bullet would be drawn as long as you press the space.
You need a solution in which the bullet will be drawn independent of the space and thats why you need to store the fired bullets in a list how Kouna said and will explain in datails I think.

##### Share on other sites
S(z)o(val):

just the idea, have to work with it.

List of bullets means a list of bullets, not just one bullet:
golyo[MAX_BULLETS];

If you hit the spacebar, you add a bullet to the list.
The simplest way to do it:
readkey();if(key[KEY_SPACE]){  Space_bar_hit=true;//We hit spacebar   key[KEY_SPACE] = false; //clear it !! I'm not sure about this one,                            //because I don't know how readkey works.}if( Space_bar_hit==true ){  for(i = 0; i < MAX_BULLETS; i++)   {   if( fire_golyo == false ) // we've found and "empty" bullet so we use it.       {   fire_golyo = true;           golyo_x = BS_x;       // the golyo is flying, and the start                                     // position=BS position           golyo_y = BS_y;           break;                   // we exit from the loop, because we want only                                     // one element to be filled.       }   }   Space_bar_hit=false;//so only one bullet fires, if you hit the spacebar (no                        //"machinegun effect")}// Move all flying bullets:for(i = 0; i < MAX_BULLETS; i++){   if( fire_golyo == true )    {    golyo_y = golyo_y+increment_value;         draw_golyo(i);    }    for( k = 0; k < enemies_count; k++ )    {   if( collision_with_enemy(i,k) )        {    fire_golyo = false;   // so it won't fly anymore             destroy_enemy(k);             draw_explosion(); // robbanás        }    }}

You have to fill all the elements of fire_golyo with false at the very beginning of your program.

I hope that helps, and your naming convention is very cute :P

##### Share on other sites
Hi again.
Now everything is a mess herre T_T.

First i tried to implement what Kauna wrote. But when i tyd to compile it i had a lot of errors. I think it was cuz he/she wrote it in C++. Cuz i think that Bool type is not in C. or i don't know.
This didnt work :( ,so i tryd what szecs sayd.
I changed the code herre:
        if(key[KEY_SPACE])                 Space_bar_hit=TRUE;        else if(!key[KEY_SPACE])                  Space_bar_hit=FALSE;

And in the game loop i write the code he gave and needed to change it a little. herre it is:
 if( Space_bar_hit==TRUE )     {       for(i = 0; i < MAX_BULLETS; i++)       {         if( fire_golyo == FALSE ) // we've found and "empty" bullet so we use it.              {                 fire_golyo = TRUE;               golyo_x = BS_x+18;       // the golyo is flying, and the start                                           // position=BS position               golyo_y = BS_y-20;               break;                   // we exit from the loop, because we want only                                         // one element to be filled.               }                                  }          Space_bar_hit=FALSE;//so only one bullet fires, if you hit the spacebar (no                        //"machinegun effect")     }               for(i = 0; i < MAX_BULLETS; i++)     {            if( fire_golyo == TRUE )          {              golyo_y = golyo_y--;          draw_sprite(buffer,golyo,golyo_x,golyo_y);          }     }

    int Space_bar_hit=FALSE;    int fire_golyo[MAX_BULLETS];    int i;    int golyo_x[MAX_BULLETS];    int golyo_y[MAX_BULLETS];

And in the beginning i defined the MAX_BULLETS :#define MAX_BULLETS 32

And now when i try to compile it im getting these errors :(:( :
210 E:\my stuffz\PROGRAMOZAS SAJAT\C programming\Allegro\sajat\Pelda_08\main.c [Warning] parameter names (without types) in function declaration
210 E:\my stuffz\PROGRAMOZAS SAJAT\C programming\Allegro\sajat\Pelda_08\main.c conflicting types for 'destroy_bitmap'
411 C:\Dev-Cpp\include\allegro\gfx.h previous declaration of 'destroy_bitmap' was here
210 E:\my stuffz\PROGRAMOZAS SAJAT\C programming\Allegro\sajat\Pelda_08\main.c conflicting types for 'destroy_bitmap'
411 C:\Dev-Cpp\include\allegro\gfx.h previous declaration of 'destroy_bitmap' was here
210 E:\my stuffz\PROGRAMOZAS SAJAT\C programming\Allegro\sajat\Pelda_08\main.c [Warning] data definition has no type or storage class
211 E:\my stuffz\PROGRAMOZAS SAJAT\C programming\Allegro\sajat\Pelda_08\main.c [Warning] parameter names (without types) in function declaration
211 E:\my stuffz\PROGRAMOZAS SAJAT\C programming\Allegro\sajat\Pelda_08\main.c [Warning] data definition has no type or storage class
212 E:\my stuffz\PROGRAMOZAS SAJAT\C programming\Allegro\sajat\Pelda_08\main.c [Warning] parameter names (without types) in function declaration

And i get these errors the first time at :
destroy_bitmap(buffer);

BUT its the same the destroy_bitmap.its the same as the first time.i didnt even touch it :(. I totally dont understand this thing now.

Thanks for everything
Ronel

##### Share on other sites

I've just realized Kauna told the same things as me before my post. I should actually read the other posts before posting. NWM.

• 10
• 16
• 14
• 18
• 15