[Allegro C] Multuple object and deleting object
wisien92

Hi i was trying to make tank-shooting game. I am new to proggraming so i thought it would be nice to try out allegro. I have a tank that moves, when you press space a bullet appers and fly's in the direction of tank's movment and when the bullet touches the wall it is trnasfered out of the screen.

So i have 2 questions ...
-How can i make multiple bullets at the same time?
-as for now the bullet after hitting the wall goes to x=-100 y=-100 but does not dissapear ... how do i make it dissapear as an imige?

my code:

#SelectExpand
1#include <stdio.h> 2#include <stdlib.h> 3#include <allegro.h> 4 5volatile long speed = 0; 6void increment_speed() 7{ 8 speed++; 9} 10END_OF_FUNCTION(increment_speed); 11LOCK_VARIABLE(speed); 12LOCK_FUNCTION(increment_speed); 13 14 15 16 17 18int main(int argc, char *argv[]) 19{ 20 21 allegro_init(); 22 install_keyboard(); 23 set_color_depth(16); 24 set_gfx_mode(GFX_AUTODETECT_WINDOWED,800,600,0,0); 25 clear_to_color(screen, makecol(128,128,128)); 26 install_timer(); 27 install_int_ex(increment_speed, BPS_TO_TIMER(40)); 28 29 BITMAP *bufor = NULL; 30 BITMAP *player = NULL; 31 BITMAP *background = NULL; 32 BITMAP *bullet = NULL; 33 BITMAP *wyb1 = NULL; 34 BITMAP *wyb2 = NULL; 35 36 bufor = create_bitmap(800,600); 37 background = create_bitmap(800,600); 38 39 install_timer(); // timery 40 install_int_ex(increment_speed, BPS_TO_TIMER(100)); 41 42 43 if (!bufor) 44 { 45 set_gfx_mode(GFX_TEXT,0,0,0,0); 46 allegro_message("Nie mogę utworzyć bufora !"); 47 allegro_exit(); 48 return 0; 49 } 50 51 52 player = load_bmp("player.bmp",default_palette); 53 background = load_bmp("trawa.bmp",default_palette); 54 bullet = load_bmp("pociskhorizontal.bmp",default_palette); 55 wyb1 = load_bmp("wyb1.bmp",default_palette); 56 wyb2 = load_bmp("wyb2.bmp",default_palette); 57 58 59 if (!wyb1) 60 { 61 set_gfx_mode(GFX_TEXT,0,0,0,0); 62 allegro_message("Nie mogę utworzyć wby 1 !"); 63 allegro_exit(); 64 return 0; 65 } 66 67 if (!wyb2) 68 { 69 set_gfx_mode(GFX_TEXT,0,0,0,0); 70 allegro_message("Nie mogę utworzyć wyb 2 !"); 71 allegro_exit(); 72 return 0; 73 } 74 75 if (!background) 76 { 77 set_gfx_mode(GFX_TEXT,0,0,0,0); 78 allegro_message("nie mogę załadować tlo !"); 79 allegro_exit(); 80 return 0; 81 } 82 83 if (!player) 84 { 85 set_gfx_mode(GFX_TEXT,0,0,0,0); 86 allegro_message("Blad przy wczytywaniu gracza!"); 87 allegro_exit(); 88 return 0; 89 } 90 91 92 93 int player_x = 350, player_y = 250; 94 int bullet_x , bullet_y; 95 int face = 3; 96 int counter = 0; 97 int leci; 98 int pociskleci = 0; 99 int kolizja =0; 100 101 int wyb1_x, wyb1_y, wyb2_x, wyb2_y; 102 int framewyb = 0; 103 104 int leci_lewo = 0; 105 int leci_prawo = 0; 106 int leci_gora = 0; 107 int leci_dol = 0; 108 109 while(speed > 0) 110 { 111 while( !key[KEY_ESC]) 112 113 { 114 115 if( key[KEY_LEFT]) 116 { 117 player_x--; 118 player = load_bmp("player_LEFT.bmp",default_palette); 119 face = 1; 120 } 121 122 else if( key[KEY_RIGHT]) 123 { 124 player_x++; 125 player = load_bmp("player_RIGHT.bmp",default_palette); 126 face = 2; 127 } 128 else if( key[KEY_UP]) 129 { 130 player_y--; 131 player = load_bmp("player_UP.bmp",default_palette); 132 face = 3; 133 } 134 else if( key[KEY_DOWN]) 135 { 136 player_y++; 137 player = load_bmp("player_DOWN.bmp",default_palette); 138 face = 4; 139 } 140 141 //kolizje czołgu ze ścianą 142 if(player_x>=28 && player_x<=28 && player_y>=0 && player_y<=600) {player_x=30; player_y=player_y;} //lewa sciana ekranu 143 if(player_x>=700 && player_x<=700 && player_y>=0 && player_y<=600) {player_x=699; player_y=player_y;} // prawa sciana ekranu 144 if(player_x>=0 && player_x<=800 && player_y>=33 && player_y<=33) {player_x=player_x; player_y=35;} // gorna sciana ekranu 145 if(player_x>=0 && player_x<=800 && player_y>=500 && player_y<=500) {player_x=player_x; player_y=498;} // dolna sciana ekranu 146 147 148 149 150 if( key[KEY_SPACE]) 151 { 152 if( face == 3) 153 { 154 leci_gora = 1; 155 bullet_x = player_x+25; 156 bullet_y = player_y-19; 157 bullet = load_bmp("pociskhorizontal.bmp",default_palette); 158 pociskleci=1; 159 160 } 161 162 if( face == 1) 163 { 164 leci_lewo = 1; 165 bullet_x = player_x-19; 166 bullet_y = player_y+25; 167 bullet = load_bmp("pociskvertical.bmp",default_palette); 168 pociskleci=1; 169 170 } 171 172 if( face == 2) 173 { 174 leci_prawo = 1; 175 bullet_x = player_x+52; 176 bullet_y = player_y+25; 177 bullet = load_bmp("pociskvertical.bmp",default_palette); 178 pociskleci=1; 179 180 } 181 182 if( face == 4) 183 { 184 leci_dol = 1; 185 bullet_x = player_x+25; 186 bullet_y = player_y+53; 187 bullet = load_bmp("pociskhorizontal.bmp",default_palette); 188 pociskleci=1; 189 190 191 } 192 193 194 } 195 196 197 ///* kolizje pocisk-ściana 198 if(bullet_x>=28 && bullet_x<=28 && bullet_y>=0 && bullet_y<=600) {kolizja =1; } //lewa sciana ekranu 199 if(bullet_x>=700 && bullet_x<=700 && bullet_y>=0 && bullet_y<=600) {kolizja =1;} // prawa sciana ekranu 200 if(bullet_x>=0 && bullet_x<=800 && bullet_y>=33 && bullet_y<=33) {kolizja =1;} // gorna sciana ekranu 201 if(bullet_x>=0 && bullet_x<=800 && bullet_y>=500 && bullet_y<=500) {kolizja =1;} // dolna sciana ekranu 202 //*/ 203 204 205 206 207 208 if(pociskleci == 1) 209 { 210 if(leci_lewo == 1) 211 { 212 leci_gora=0; 213 leci_dol=0; 214 leci_prawo=0; 215 bullet_x --; 216 } 217 if(leci_prawo == 1) 218 { 219 leci_gora=0; 220 leci_dol=0; 221 leci_lewo=0; 222 bullet_x ++; 223 } 224 if(leci_gora == 1) 225 { 226 leci_lewo=0; 227 leci_dol=0; 228 leci_prawo=0; 229 bullet_y --; 230 } 231 if(leci_dol == 1) 232 { 233 leci_gora=0; 234 leci_lewo=0; 235 leci_prawo=0; 236 bullet_y ++; 237 } 238 239 if(kolizja == 1) 240 { 241 pociskleci=0; 242 kolizja=0; 243 leci_dol = 0; 244 leci_gora = 0; 245 leci_lewo = 0; 246 leci_prawo = 0; 247 248 wyb1_x = bullet_x; 249 wyb1_y = bullet_y; 250 wyb2_x = bullet_x; 251 wyb2_y = bullet_y; 252 253 254 framewyb++; 255 256 if( framewyb > 40) 257 framewyb=0; 258 259 260 bullet_x = -100; // zamiast tego bede musiał usunąć obrazek 261 bullet_y = -100; 262 } 263 } 264 265 266 267 clear_to_color(bufor, makecol(150,150,150)); 268 269 if( framewyb<20) 270 draw_sprite(bufor, wyb1, wyb1_x, wyb1_y); 271 272 else if( framewyb>=20 && framewyb<40) 273 draw_sprite(bufor, wyb2, wyb2_x, wyb2_y); 274 275 blit( background, bufor,0,0, 0,0, 800,600); 276 masked_blit( player, bufor, 0,0, player_x, player_y, player->w, player->h); 277 masked_blit( bullet, bufor, 0,0, bullet_x, bullet_y, bullet->w, bullet->h); 278 blit( bufor, screen, 0,0,0,0, 800,600); 279 280 //rest(2); 281 282 } 283 speed--; 284 } 285 286 287 288 289 290remove_int( increment_speed); 291destroy_bitmap(player); 292destroy_bitmap(bufor); 293destroy_bitmap(background); 294destroy_bitmap(bullet); 295destroy_bitmap(wyb1); 296destroy_bitmap(wyb2); 297 298allegro_exit(); 299 300return 0; 301 302} 303 304END_OF_MAIN(); 305;

LennyLen
wisien92 said:

-How can i make multiple bullets at the same time?

Have an array of bullets. I's suggest you create a struct to hold info about bullets. something like this:

typedef struct {

   int active;
   int x;
   int y;
   int w;
   int h;

} BULLET;

Now you can create an array of as many bullets as you need. eg:

BULLET bullets[100];

Quote:

as for now the bullet after hitting the wall goes to x=-100 y=-100 but does not dissapear ... how do i make it dissapear as an imige?

By using the active member of the struct we just used. When a bullet is created, set active to 1. When a bullet goes off screen (or is no longer needed for some other reason), set active to 0.

Only draw or update bullets where active == 1.

One thing I noticed in your code is that you have a HUGE memory leak, as you are constantly loading bitmaps. Each time you call load_bitmap() and assign the result to an already existing pointer. Any BITMAP that pointer was already pointing to now becomes inaccessible, but is not freed from memory, so your program will take up more and more resources constantly. You need to call destroy_bitmap() for each time you call load_bitmap() in order to free the memory.

This still isn't the ideal solution however, as calling load_bitmap() constantly not only keeps allocating more memory, it is also very slow.

A better way to do this is load all the player and bullet BITMAPS you will need at the start, and then create a current player and bullet BITMAP pointer that can point to any of the bitmaps you loaded initially. Each time you need to change the BITMAP, just change where the current BITMAP pointer is pointing to.

wisien92

so in main function:

#SelectExpand
1typedef struct { 2 3 int active; //determins if bullet is "alive" 4 int x; //x coordinate 5 int y; //y cooridinate 6 7} BULLET; 8 9BULLET bullets[100]; // max number of bullets 100 10 11int a; //for use in BULLET bullets[a]

in shooting

#SelectExpand
2 3if( face == 3) 4{ 5 leci_gora = 1; 6 for(a=0;a<=100;a++) 7 { 8 bullets[a].x = player_x+25; 9 bullets[a].y = player_y-19; 10 bullet = load_bmp("pociskhorizontal.bmp",default_palette); //later pointer 11 pociskleci=1; 12 13 } 14}

and when deleting bullet a--;

something like this? i'm not sure how to use strucktures since i did not have it on my lessons ;/

Gabriel Campos

If i got it your code, when you are shooting, you are moving ALL the array, and loading each time 100 images, what will cause a great memory leak. Other thing, the struct doesnt need to be in main function, is better to be outside any function.

About the shoot, you could make this way...

#SelectExpand
1typedef struct{ 2 int x; 3 int y; 4 bool active; 5};Bullet; 6 7// in main function 8Bullet bullet[100]; // or any number you want to shoots you can shoot per time 9 10// in shoot function 11for(int i = 0; i < 100; i++) 12{ 13 if(!bullet[i].active) // here you check if the bullet is not active 14 { 15 bullet[i].active = true; // here you make it active 16 bullet[i].init(); // here you initialize his position 17 } 18} 19 20// the code when its collide or is out of the screen 21for(int i = 0; i < 100; i++) 22{ 23 if(bullet[i].x > screen_width) // check if the bullet is out of the screen 24 { 25 bullet[i].active = false; 26 bullet[i].deInit(); // here you clear the bullet position 27 } 28}

this is not the proper way... but is a little start to understand the object oriented programing

LennyLen

this is not the proper way... but is a little start to understand the object oriented programing

He's using C, not C++.

So instead:

for(int i = 0; i < 100; i++)
{
  if(!bullet[i].active) // here you check if the bullet is not active
  {
    bullet[i].active = 1; // here you make it active
    init_bullet(bullet[i]);
  }
}

The init_bullet() function will check which direction the ship is facing and set the x and y values accordingly.

A deInit() function isn't really required.

Gabriel Campos
LennyLen said:

He's using C, not C++.

Sorry, i didnt saw that... :P

wisien92

I get error

164 C:\Documents and Settings\kuba\Pulpit\Projekt Infa\main.c structure has no member named `active'

but in structure there is int active or am i missing something?

#SelectExpand
1int init_bullet() 2{ 3 4 //bullet function where we check what side is player facing etc. 5 6 7 return 0; 8}

should there be something in the () of buller ini function?

Arthur Kalliokoski
wisien92 said:

structure has no member named `active'

I get those errors all the time, due to my mixing up '.' and '->'.

bamccaig

You only need to load each bitmap one time. :) All 100 bullets can draw the same bitmap. :) For small games it is normal to load all bitmaps one time at the beginning of the program (i.e., right after initializing Allegro) and keeping them in memory for the life of the program.

#SelectExpand
1#include <allegro.h> 2#include <stdio.h> 3 4struct bullet_t 5{ 6 int active; 7 int x; 8 int y; 9}; 10 11typedef struct bullet_t bullet_t; 12 13#define NUM_BULLETS 100 14 15int main(int argc, char * argv[]) 16{
17 BITMAP * bullet_sprite = 0;
18 BITMAP * scrbuf = 0; 19 bullet_t bullets[NUM_BULLETS] = {0}; 20 int i; 21 22 // initialize Allegro, back-buffer, etc. 23
24 bullet_sprite = load_bitmap("pociskhorizontal.bmp", default_palette);
25 26 if(bullet_sprite == 0) 27 { 28 fprintf(stderr, "Failed to load bullet sprite.\n"); 29 return 1; 30 } 31 32 // ...etc... 33 34 while(!key[ESC]) 35 { 36 // logic... 37 38 for(i=0; i<NUM_BULLETS; i++) 39 { 40 bullet_t * bullet = &bullets[i]; 41 42 if(bullet->active) 43 { 44 draw_sprite( 45 scrbuf,
46 bullet_sprite,
47 bullet->x, 48 bullet->y); 49 } 50 } 51 52 blit(scrbuf, screen, 0, 0, 0, 0, scrbuf->w, scrbuf->h); 53 } 54 55 /* 56 * Clean up (technically optional at this point, but it's 57 * useful to understand anyway). 58 */
59 destroy_bitmap(bullet_sprite);
60 61 return 0; 62}

We load the bullet sprite once, use it for all 100 bullets, and we destroy it once when we're completely finished with it (i.e., when the user exits).

I'm glad to see you checking return values. :) Your indentation is a little bit sporadic though.

I'm not sure why you're using load_bmp directly. I think that's a slightly lower-level function. I think the correct front-end is load_bitmap, which does pretty much the same thing, but I think supports a few variations of formats. That said, if you're using load_bmp for a good reason then that's fine. :)

wisien92

I used load_bmp 'couse i didn't know any other functions :D as i said i am proggraming for one and a half week and learning in allegro is something that i do for myself becouse in school we have basics right now.

there is error in loading scrbuf (what it supose to do anyway?)

#SelectExpand
1 2 3#include <stdio.h> 4#include <stdlib.h> 5#include <allegro.h> 6 7#define NUM_BULLETS 100 8 9volatile long speed = 0; 10void increment_speed() 11{ 12 speed++; 13} 14END_OF_FUNCTION(increment_speed); 15LOCK_VARIABLE(speed); 16LOCK_FUNCTION(increment_speed); 17 18struct bullet_t { 19 20 int active; 21 int x; 22 int y; 23 24} ; 25typedef struct bullet_t bullet_t; 26 27int main(int argc, char *argv[]) 28{ 29 30 allegro_init(); 31 install_keyboard(); 32 set_color_depth(16); 33 set_gfx_mode(GFX_AUTODETECT_WINDOWED,800,600,0,0); 34 clear_to_color(screen, makecol(128,128,128)); 35 install_timer(); 36 install_int_ex(increment_speed, BPS_TO_TIMER(40)); 37 38 BITMAP *bufor = NULL; 39 BITMAP *player = NULL; 40 BITMAP *background = NULL; 41 BITMAP *bullet = NULL; 42 BITMAP *wyb1 = NULL; 43 BITMAP *wyb2 = NULL; 44 BITMAP * bullet_sprite = 0; 45 BITMAP * scrbuf = 0; 46 47 48 bufor = create_bitmap(800,600); 49 background = create_bitmap(800,600); 50 51 install_timer(); // timery 52 install_int_ex(increment_speed, BPS_TO_TIMER(100)); 53 54 55 56 57 if (!bufor) 58 { 59 set_gfx_mode(GFX_TEXT,0,0,0,0); 60 allegro_message("Nie mogę utworzyć bufora !"); 61 allegro_exit(); 62 return 0; 63 } 64 65 66 player = load_bmp("player.bmp",default_palette); 67 background = load_bmp("trawa.bmp",default_palette); 68 //bullet = load_bmp("pociskhorizontal.bmp",default_palette); 69 //bullet = load_bmp("pociskvertical.bmp",default_palette); 70 wyb1 = load_bmp("wyb1.bmp",default_palette); 71 wyb2 = load_bmp("wyb2.bmp",default_palette); 72 73 bullet_sprite = load_bitmap("bullet.bmp", default_palette); 74 75 76 if (!wyb1) 77 { 78 set_gfx_mode(GFX_TEXT,0,0,0,0); 79 allegro_message("Nie mogę utworzyć wby 1 !"); 80 allegro_exit(); 81 return 0; 82 } 83 84 if (!wyb2) 85 { 86 set_gfx_mode(GFX_TEXT,0,0,0,0); 87 allegro_message("Nie mogę utworzyć wyb 2 !"); 88 allegro_exit(); 89 return 0; 90 } 91 92 if (!background) 93 { 94 set_gfx_mode(GFX_TEXT,0,0,0,0); 95 allegro_message("nie mogę załadować tlo !"); 96 allegro_exit(); 97 return 0; 98 } 99 100 if (!player) 101 { 102 set_gfx_mode(GFX_TEXT,0,0,0,0); 103 allegro_message("Blad przy wczytywaniu gracza!"); 104 allegro_exit(); 105 return 0; 106 } 107 108 if (!bullet_sprite) 109 { 110 set_gfx_mode(GFX_TEXT,0,0,0,0); 111 allegro_message("Blad przy wczytywaniu gracza!"); 112 allegro_exit(); 113 return 0; 114 } 115 116 if (!scrbuf) 117 { 118 set_gfx_mode(GFX_TEXT,0,0,0,0); 119 allegro_message("Blad przy wczytywaniu scrbuf!"); 120 allegro_exit(); 121 return 0; 122 } 123 124 125 126 int player_x = 350, player_y = 250; 127 int bullet_x , bullet_y; 128 int face = 3; 129 int counter = 0; 130 int leci; 131 int pociskleci = 0; 132 int kolizja =0; 133 int i; 134 int wyb1_x, wyb1_y, wyb2_x, wyb2_y; 135 int framewyb = 0; 136 bullet_t bullets[NUM_BULLETS] = {0}; 137 int leci_lewo = 0; 138 int leci_prawo = 0; 139 int leci_gora = 0; 140 int leci_dol = 0; 141 142 while(speed > 0) 143 { 144 while( !key[KEY_ESC]) 145 146 { 147 148 if( key[KEY_LEFT]) 149 { 150 player_x--; 151 player = load_bmp("player_LEFT.bmp",default_palette); 152 face = 1; 153 } 154 155 else if( key[KEY_RIGHT]) 156 { 157 player_x++; 158 player = load_bmp("player_RIGHT.bmp",default_palette); 159 face = 2; 160 } 161 else if( key[KEY_UP]) 162 { 163 player_y--; 164 player = load_bmp("player_UP.bmp",default_palette); 165 face = 3; 166 } 167 else if( key[KEY_DOWN]) 168 { 169 player_y++; 170 player = load_bmp("player_DOWN.bmp",default_palette); 171 face = 4; 172 } 173 174 //kolizje czołgu ze ścianą 175 if(player_x>=28 && player_x<=28 && player_y>=0 && player_y<=600) {player_x=30; player_y=player_y;} //lewa sciana ekranu 176 if(player_x>=700 && player_x<=700 && player_y>=0 && player_y<=600) {player_x=699; player_y=player_y;} // prawa sciana ekranu 177 if(player_x>=0 && player_x<=800 && player_y>=33 && player_y<=33) {player_x=player_x; player_y=35;} // gorna sciana ekranu 178 if(player_x>=0 && player_x<=800 && player_y>=500 && player_y<=500) {player_x=player_x; player_y=498;} // dolna sciana ekranu 179 180 181 182 183 if( key[KEY_SPACE]) 184 { 185 for(i=0; i<NUM_BULLETS; i++) 186 { 187 bullet_t * bullet = &bullets[i]; 188 189 if(bullet->active) 190 { 191 draw_sprite( 192 bullet_sprite, 193 scrbuf, 194 bullet->x, 195 bullet->y); 196 } 197 } 198 199 200 } 201 202 203 ///* kolizje pocisk-ściana 204 if(bullet_x>=28 && bullet_x<=28 && bullet_y>=0 && bullet_y<=600) {kolizja =1; } //lewa sciana ekranu 205 if(bullet_x>=700 && bullet_x<=700 && bullet_y>=0 && bullet_y<=600) {kolizja =1;} // prawa sciana ekranu 206 if(bullet_x>=0 && bullet_x<=800 && bullet_y>=33 && bullet_y<=33) {kolizja =1;} // gorna sciana ekranu 207 if(bullet_x>=0 && bullet_x<=800 && bullet_y>=500 && bullet_y<=500) {kolizja =1;} // dolna sciana ekranu 208 //*/ 209 210 211 212 clear_to_color(bufor, makecol(150,150,150)); 213 214 215 blit( background, bufor,0,0, 0,0, 800,600); 216 masked_blit( player, bufor, 0,0, player_x, player_y, player->w, player->h); 217 blit(scrbuf, bufor, 0, 0, 0, 0, scrbuf->w, scrbuf->h); 218 //masked_blit( bullet, bufor, 0,0, bullet_x, bullet_y, bullet->w, bullet->h); 219 blit( bufor, screen, 0,0,0,0, 800,600); 220 221 //rest(2); 222 223 } 224 speed--; 225 } 226 227 228 229 230 231remove_int( increment_speed); 232 233destroy_bitmap(bullet_sprite); 234destroy_bitmap(scrbuf); 235destroy_bitmap(player); 236destroy_bitmap(bufor); 237destroy_bitmap(background); 238destroy_bitmap(bullet); 239destroy_bitmap(wyb1); 240destroy_bitmap(wyb2); 241 242allegro_exit(); 243 244return 0; 245 246} 247 248END_OF_MAIN();

Gabriel Campos
#SelectExpand
1while( !key[KEY_ESC]) 2 144 3 145 { 4 146 5 147 if( key[KEY_LEFT]) 6 148 { 7 149 player_x--; 8 150 player = load_bmp("player_LEFT.bmp",default_palette); 9 151 face = 1; 10 152 } 11 153 12 154 else if( key[KEY_RIGHT]) 13 155 { 14 156 player_x++; 15 157 player = load_bmp("player_RIGHT.bmp",default_palette); 16 158 face = 2; 17 159 } 18 160 else if( key[KEY_UP]) 19 161 { 20 162 player_y--; 21 163 player = load_bmp("player_UP.bmp",default_palette); 22 164 face = 3; 23 165 } 24 166 else if( key[KEY_DOWN]) 25 167 { 26 168 player_y++; 27 169 player = load_bmp("player_DOWN.bmp",default_palette); 28 170 face = 4; 29 171 }

It is wrong yet. Pay close attention, your are loading the bitmaps on key press. So, with you press lets say, key down 300 times, u will load 300 images. This is memory leak! Load all bitmaps you will need ONLY ONE TIME. Then use them.
For example...

int main()
{
  BITMAP *player[4];
  player[0] = load_bitmap("player_UP.bmp", default_pallete);
  player[1] = load_bitmap("player_DOWN.bmp", default_pallete);
  player[2] = load_bitmap("player_LEFT.bmp", default_pallete);
  player[3] = load_bitmap("player_RIGHT.bmp", default_pallete);

// In your draw function
  masked_blit(player[face], bufor, 0, 0 player_x, player_y, player[face]->w, player[face]->h);

There still errors in shooting bullets, but try to figure out first. Try to compile the code in your head and see what are happening.

wisien92

player[face] don't give errors but there is game error and it doesn't compile

old code without shooting to test out

#SelectExpand
1#include <stdio.h> 2#include <stdlib.h> 3#include <allegro.h> 4 5volatile long speed = 0; 6void increment_speed() 7{ 8 speed++; 9} 10END_OF_FUNCTION(increment_speed); 11LOCK_VARIABLE(speed); 12LOCK_FUNCTION(increment_speed); 13 14 15 16 17 18int main(int argc, char *argv[]) 19{ 20 21 allegro_init(); 22 install_keyboard(); 23 set_color_depth(16); 24 set_gfx_mode(GFX_AUTODETECT_WINDOWED,800,600,0,0); 25 clear_to_color(screen, makecol(128,128,128)); 26 install_timer(); 27 install_int_ex(increment_speed, BPS_TO_TIMER(40)); 28 29 BITMAP *bufor = NULL; 30 BITMAP *player[4]; 31 BITMAP *background = NULL; 32 33 34 bufor = create_bitmap(800,600); 35 background = create_bitmap(800,600); 36 37 install_timer(); // timery 38 install_int_ex(increment_speed, BPS_TO_TIMER(100)); 39 40 41 if (!bufor) 42 { 43 set_gfx_mode(GFX_TEXT,0,0,0,0); 44 allegro_message("Nie mogę utworzyć bufora !"); 45 allegro_exit(); 46 return 0; 47 } 48 49 50 //player = load_bmp("player.bmp",default_palette); 51 background = load_bmp("trawa.bmp",default_palette); 52 bullet = load_bmp("pociskhorizontal.bmp",default_palette); 53 wyb1 = load_bmp("wyb1.bmp",default_palette); 54 wyb2 = load_bmp("wyb2.bmp",default_palette); 55 56 57 player[0] = load_bmp("player_UP.bmp",default_palette); 58 player[1] = load_bmp("player_DOWN.bmp",default_palette); 59 player[2] = load_bmp("player_LEFT.bmp",default_palette); 60 player[3] = load_bmp("player_RIGHT.bmp",default_palette); 61 62 63 64 if (!background) 65 { 66 set_gfx_mode(GFX_TEXT,0,0,0,0); 67 allegro_message("nie mogę załadować tlo !"); 68 allegro_exit(); 69 return 0; 70 } 71 72 if (!player[4]) 73 { 74 set_gfx_mode(GFX_TEXT,0,0,0,0); 75 allegro_message("Blad przy wczytywaniu gracza!"); 76 allegro_exit(); 77 return 0; 78 } 79 80 81 82 int player_x = 350, player_y = 250; 83 int face = 0; 84 85 86 while(speed > 0) 87 { 88 while( !key[KEY_ESC]) 89 90 { 91 92 if( key[KEY_LEFT]) 93 { 94 player_x--; 95 face = 2; 96 } 97 98 else if( key[KEY_RIGHT]) 99 { 100 player_x++; 101 face = 3; 102 } 103 else if( key[KEY_UP]) 104 { 105 player_y--; 106 face = 0; 107 } 108 else if( key[KEY_DOWN]) 109 { 110 player_y++; 111 face = 1; 112 } 113 114 //kolizje czołgu ze ścianą 115 if(player_x>=28 && player_x<=28 && player_y>=0 && player_y<=600) {player_x=30; player_y=player_y;} //lewa sciana ekranu 116 if(player_x>=700 && player_x<=700 && player_y>=0 && player_y<=600) {player_x=699; player_y=player_y;} // prawa sciana ekranu 117 if(player_x>=0 && player_x<=800 && player_y>=33 && player_y<=33) {player_x=player_x; player_y=35;} // gorna sciana ekranu 118 if(player_x>=0 && player_x<=800 && player_y>=500 && player_y<=500) {player_x=player_x; player_y=498;} // dolna sciana ekranu 119 120 121 122 123 clear_to_color(bufor, makecol(150,150,150)); 124 125 126 blit( background, bufor,0,0, 0,0, 800,600); 127 masked_blit( player[face], bufor, 0,0, player_x, player_y, player[face]->w, player[face]->h); 128 masked_blit( bullet, bufor, 0,0, bullet_x, bullet_y, bullet->w, bullet->h); 129 blit( bufor, screen, 0,0,0,0, 800,600); 130 131 //rest(2); 132 133 } 134 speed--; 135 } 136 137 138 139 140 141remove_int( increment_speed); 142destroy_bitmap(player[4]); 143destroy_bitmap(bufor); 144destroy_bitmap(background); 145 146allegro_exit(); 147 148return 0; 149 150} 151 152END_OF_MAIN();

Gabriel Campos

scrbuf = bufor
Its just a name for buffer BITMAP. ::)

EDIT
Hint: destroy_bitmap only destroys one bitmap.

wisien92

So i deleted the scrbuf completly and in draw_sprite i put bufor and it compiles (as well with your player[4] instad of puttinig images)

so i will try to make it fire multiple times. if i fail completly i will as you guys again for help but i hope i won't need to :D

thank you all again!

bamccaig

Sorry, I didn't have the energy to write a fully working program. :) There are implicit parts missing. Also, note that I passed the two bitmaps in the wrong order to draw_sprite (it's been a while since I've written A4)... Fixed. ::)

wisien92

ok i have multiple bullets and showing them depending on face of the tank. now i work on their movment and collision with wall and i have problem of making sprite move

code:

#SelectExpand
1if(face==3) 2 { 3 bullet_t * bullet = &bullets[i]; 4 bullets[i].active = 1; 5 if(bullets[i].active ==1) 6 { 7 draw_sprite( 8 background, 9 bullet_sprite, 10 player_x, 11 player_y); 12 13 bullets[i].x ++; //shouldn't this line make bullet move as long as bullets[i].active=1? 14 } 15 16 } 17 18 //collisions bullet-walls: 19 if(bullets[i].x >=28 && bullets[i].x <=28 && bullets[i].y >=0 && bullets[i].y <=600) {bullets[i].active =0;} //lewa sciana ekranu 20 if(bullets[i].x >=700 && bullets[i].x <=700 && bullets[i].y >=0 && bullets[i].y <=600) {bullets[i].active =0;} // prawa sciana ekranu 21 if(bullets[i].x >=0 && bullets[i].x <=800 && bullets[i].y >=33 && bullets[i].y <=33) {bullets[i].active =0;} // gorna sciana ekranu 22 if(bullets[i].x >=0 && bullets[i].x <=800 && bullets[i].y >=500 && bullets[i].y <=500) {bullets[i].active =0;} // dolna sciana ekranu

LennyLen

In that code you have there, you set bullets[i].active to 1 and then in the next line check if it equals 1, which doesn't make much sense.

Also, without seeing the rest of the code you have, I'm guessing that all your bullets will move in whatever direction the ship is currently facing, while they should be moving in the direction the ship was facing when they were fired. You can fix this by either storing the direction they are traveling in the bullet struct, or store the x and y component of their velocities.

wisien92

Does this make any sense?

i have added face in bullets structure

#SelectExpand
1for(i=0;i<=NUM_BULLETS;i++) 2{ 3 if( key(KEY_SPACE)) 4 { 5 if(face==0) 6 { 7 bullets[i].face=0; 8 bullets[i]active=1: 9 } 10 //rest of face's 11 12 } 13 14 //collision if collision bullets[i].active=0 15 16 while(bullets[i].active==1) 17 { 18 drawsprite; 19 if(bullets[i].strona==0) 20 bullets[i].x --; 21 //rest of bullets faces 22 23 } 24}

bamccaig

First please specify what you are trying to do right now? The code you posted doesn't make sense (i.e., if face is 0 then set face to 0; but it already is :P). It looks like you don't understand what it is you're trying to do and if you don't know that then we can't help you. :P

I would recommend that you abstract the concept of "shooting" into a function. For [crude] example:

#SelectExpand
1void fire_bullet(int num_bullets, bullet_t * pool, int x, int y, int facing) 2{ 3 int i; 4 5 // Search for an unused bullet from the pool. 6 for(i=0; i<num_bullets; i++) 7 { 8 bullet_t * bullet = &pool[i]; 9 10 if(!bullet->active) 11 { 12 // We found one! Activate and initialize it 13 // with the player's position. 14 bullet->active = 1; 15 bullet->facing = facing; 16 bullet->x = x; 17 bullet->y = y; 18 break; 19 } 20 } 21}

Then if you want to fire a bullet when you press the space bar then you could just do something like:

if(key[KEY_SPACE])
{
    fire_bullet(NUM_BULLETS, bullets, player_x, player_y, face);
}

Of course, this only shows how you can record a newly fired bullet. You still need to write the logic to move and draw active bullets (independent of the player). Does this make sense to you? Copy/paste will get you nowhere. :)

wisien92

face was the facing of the tank and i wanted to store that variable in bullet structer so that's why there is bullet.face

but yeah making other function for shooting would be better :)

Thread #611203. Printed from Allegro.cc