Autoshooter on this game
AleX-G Squadron

I am trying to add an autoshooter to this game i was building from scratch but it seems unclear this concept to me. (It is based on mike geig shooter)
I have already opened a thread about the autoshooter, but i don't get the logic and how do i apply to codes like the game i am trying to build?
Also, pls add comments in each line you have added and explain step by step.
Anyone pls help! :'(
Here is all the game's code so far:
source.cpp

#SelectExpand
1#include <allegro5\allegro.h> 2#include <allegro5\allegro_primitives.h> 3#include <allegro5\allegro_image.h> 4#include <allegro5\allegro_ttf.h> 5#include <allegro5\allegro_font.h> 6#include "objects.h" 7 8// Buttons 9enum BUTON{A,S,D,W,SPACE}; 10bool buton[5] = {false,false,false,false,false}; 11 12// Globals 13const int FPS = 80, width = 800, height = 600; 14const int NUM_BULLETS = 5; 15 16// Protorypes 17void InitShip(SpaceShip &ship); 18void DrawShip(SpaceShip &ship); 19void MoveShipUp(SpaceShip &ship); 20void MoveShipDown(SpaceShip &ship); 21void MoveShipLeft(SpaceShip &ship); 22void MoveShipRight(SpaceShip &ship); 23 24void InitBullet(Bullet bullet[], int size); 25void DrawBullet(Bullet bullet[], int size); 26void FireBullet(Bullet bullet[], int size, SpaceShip &ship); 27void UpdateBullet(Bullet bullet[], int size); 28 29int main() 30{ 31 // Initialization 32 al_init(); 33 al_init_primitives_addon(); 34 al_init_image_addon(); 35 al_init_font_addon(); 36 al_init_ttf_addon(); 37 38 // Installations 39 al_install_keyboard(); 40 al_install_mouse(); 41 42 // Variables 43 SpaceShip ship; 44 Bullet bullets[5]; 45 int fireCooldown = 0; 46 47 int x = width / 2; 48 int y = height / 2; 49 50 bool quit = false; 51 bool draw = true; 52 53 // ALLEGRO variables 54 ALLEGRO_DISPLAY *window = al_create_display(width, height); 55 ALLEGRO_BITMAP *icon = al_load_bitmap("image/1.png"); 56 ALLEGRO_FONT *font16 = al_load_ttf_font("fonts/1.ttf", 80, ALLEGRO_ALIGN_CENTRE); 57 ALLEGRO_TIMER *timer = NULL; 58 ALLEGRO_EVENT_QUEUE *event = NULL; 59 60 event = al_create_event_queue(); 61 timer = al_create_timer(1.0 / FPS); 62 63 // Events 64 al_register_event_source(event, al_get_keyboard_event_source()); 65 al_register_event_source(event, al_get_mouse_event_source()); 66 al_register_event_source(event, al_get_display_event_source(window)); 67 al_register_event_source(event, al_get_timer_event_source(timer)); 68 69 // Window title, icon and mouse hide 70 al_set_window_title(window, "Game programming"); 71 al_set_display_icon(window, icon); 72 al_hide_mouse_cursor(window); 73 74 // Player initializations 75 InitShip(ship); 76 InitBullet(bullets, NUM_BULLETS); 77 78 // Start timer 79 al_start_timer(timer); 80 81 82 // The drawing 83 while(!quit) 84 { 85 // Call of the event 86 ALLEGRO_EVENT e; 87 al_wait_for_event(event, &e); 88 89 // Drawing 90 if(e.type == ALLEGRO_EVENT_TIMER) 91 { 92 draw = true; 93 94 if(buton[A]) 95 MoveShipLeft(ship); 96 if(buton[D]) 97 MoveShipRight(ship); 98 if(buton[S]) 99 MoveShipDown(ship); 100 if(buton[W]) 101 MoveShipUp(ship); 102 103 UpdateBullet(bullets, NUM_BULLETS); 104 } 105 106 // Key down or up 107 switch(e.type) 108 { 109 case ALLEGRO_EVENT_KEY_DOWN: 110 switch(e.keyboard.keycode) 111 { 112 case ALLEGRO_KEY_A: 113 buton[A] = true; 114 break; 115 116 case ALLEGRO_KEY_S: 117 buton[S] = true; 118 break; 119 120 case ALLEGRO_KEY_D: 121 buton[D] = true; 122 break; 123 124 case ALLEGRO_KEY_W: 125 buton[W] = true; 126 break; 127 128 case ALLEGRO_KEY_SPACE: 129 buton[SPACE] = true; 130 FireBullet(bullets, NUM_BULLETS, ship); 131 break; 132 133 case ALLEGRO_KEY_ESCAPE: 134 quit = true; 135 break; 136 } 137 } 138 139 switch(e.type) 140 { 141 case ALLEGRO_EVENT_KEY_UP: 142 switch(e.keyboard.keycode) 143 { 144 case ALLEGRO_KEY_A: 145 buton[A] = false; 146 break; 147 148 case ALLEGRO_KEY_S: 149 buton[S] = false; 150 break; 151 152 case ALLEGRO_KEY_D: 153 buton[D] = false; 154 break; 155 156 case ALLEGRO_KEY_W: 157 buton[W] = false; 158 break; 159 160 case ALLEGRO_KEY_SPACE: 161 buton[SPACE] = false; 162 break; 163 } 164 } 165 166 167 // Close display when X is pressed 168 if(e.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 169 { 170 quit = true; 171 } 172 173 // Mouse movement 174 else if(e.type == ALLEGRO_EVENT_MOUSE_AXES) 175 { 176 ship.y = e.mouse.y; 177 } 178 179 else if(e.mouse.button & 1) 180 { 181 FireBullet(bullets, NUM_BULLETS, ship); 182 } 183 184 if(draw && al_event_queue_is_empty(event)) 185 { 186 draw = false; 187 DrawShip(ship); 188 DrawBullet(bullets, NUM_BULLETS); 189 190 al_flip_display(); 191 al_clear_to_color(al_map_rgb(0,0,0)); 192 } 193 194 } 195 196 // Destroy 197 al_destroy_event_queue(event); 198 al_destroy_bitmap(icon); 199 al_destroy_display(window); 200} 201 202void InitShip(SpaceShip &ship) 203{ 204 ship.x = 20; 205 ship.y = height / 2; 206 ship.ID = PLAYER; 207 ship.lives = 3; 208 ship.speed = 7; 209 ship.boundx = 6; 210 ship.boundy = 7; 211 ship.score = 0; 212} 213 214void DrawShip(SpaceShip &ship) 215{ 216 al_draw_filled_rectangle(ship.x - 10, ship.y-15, ship.x + 35, ship.y, al_map_rgb(255,128,0)); 217 al_draw_filled_rectangle(ship.x + 35, ship.y-15, ship.x + 130, ship.y, al_map_rgb(255,255,255)); 218} 219 220void MoveShipUp(SpaceShip &ship) 221{ 222 ship.y -= ship.speed; 223 if(ship.y < 15) 224 ship.y = 15; 225} 226 227void MoveShipDown(SpaceShip &ship) 228{ 229 ship.y += ship.speed; 230 if(ship.y > height) 231 ship.y = height; 232} 233 234void MoveShipLeft(SpaceShip &ship) 235{ 236 ship.x -= ship.speed; 237 if(ship.x < 10) 238 ship.x = 10; 239} 240 241void MoveShipRight(SpaceShip &ship) 242{ 243 ship.x += ship.speed; 244 if(ship.x > 100) 245 ship.x = 100; 246} 247 248void InitBullet(Bullet bullet[], int size) 249{ 250 for(int i = 0; i < size; i++) 251 { 252 bullet[i].ID = BULLET; 253 bullet[i].speed = 10; 254 bullet[i].live = false; 255 } 256} 257 258void DrawBullet(Bullet bullet[], int size) 259{ 260 for(int i = 0; i < size; i++) 261 { 262 if(bullet[i].live) 263 al_draw_filled_circle(bullet[i].x, bullet[i].y, 5, al_map_rgb(128,128,128)); 264 } 265} 266 267void FireBullet(Bullet bullet[], int size, SpaceShip &ship) 268{ 269 for(int i = 0; i < size; i++) 270 { 271 if(!bullet[i].live) 272 { 273 bullet[i].x = ship.x + 120; 274 bullet[i].y = ship.y - 7; 275 bullet[i].live = true; 276 break; 277 } 278 } 279} 280 281void UpdateBullet(Bullet bullet[], int size) 282{ 283 for(int i = 0; i < size; i++) 284 { 285 if(bullet[i].live) 286 { 287 bullet[i].x += bullet[i].speed; 288 if(bullet[i].x > width) 289 { 290 bullet[i].live = false; 291 break; 292 } 293 } 294 } 295}

objects.h

#SelectExpand
1// Objects IDs 2enum ID{PLAYER, BULLET, ENEMY}; 3 4// The player 5struct SpaceShip 6{ 7 int ID; 8 int x; 9 int y; 10 int lives; 11 int speed; 12 int boundx; 13 int boundy; 14 int score; 15}; 16 17struct Bullet 18{ 19 int ID; 20 int x; 21 int y; 22 bool live; 23 int speed; 24};

taronĀ 
#SelectExpand
1#include <allegro5\allegro.h> 2#include <allegro5\allegro_primitives.h> 3#include <allegro5\allegro_image.h> 4#include <allegro5\allegro_ttf.h> 5#include <allegro5\allegro_font.h> 6#include "objects.h" 7 8// Buttons 9enum BUTON{A,S,D,W,SPACE}; 10bool buton[5] = {false,false,false,false,false}; 11 12// Globals 13const int FPS = 80, width = 800, height = 600; 14const int NUM_BULLETS = 5; 15 16// Protorypes 17void InitShip(SpaceShip &ship); 18void DrawShip(SpaceShip &ship); 19void MoveShipUp(SpaceShip &ship); 20void MoveShipDown(SpaceShip &ship); 21void MoveShipLeft(SpaceShip &ship); 22void MoveShipRight(SpaceShip &ship); 23 24void InitBullet(Bullet bullet[], int size); 25void DrawBullet(Bullet bullet[], int size); 26void FireBullet(Bullet bullet[], int size, SpaceShip &ship); 27void UpdateBullet(Bullet bullet[], int size); 28 29int main() 30{ 31 // Initialization 32 al_init(); 33 al_init_primitives_addon(); 34 al_init_image_addon(); 35 al_init_font_addon(); 36 al_init_ttf_addon(); 37 38 // Installations 39 al_install_keyboard(); 40 al_install_mouse(); 41 42 // Variables 43 SpaceShip ship; 44 Bullet bullets[5]; 45 // I don't think you are actually using this variable 46 int fireCooldown = 0; 47 48 int x = width / 2; 49 int y = height / 2; 50 51 bool quit = false; 52 bool draw = true; 53 54 // ALLEGRO variables 55 ALLEGRO_DISPLAY *window = al_create_display(width, height); 56 ALLEGRO_BITMAP *icon = al_load_bitmap("image/1.png"); 57 ALLEGRO_FONT *font16 = al_load_ttf_font("fonts/1.ttf", 80, ALLEGRO_ALIGN_CENTRE); 58 ALLEGRO_TIMER *timer = NULL; 59 ALLEGRO_EVENT_QUEUE *event = NULL; 60 61 event = al_create_event_queue(); 62 timer = al_create_timer(1.0 / FPS); 63 64 // Events 65 al_register_event_source(event, al_get_keyboard_event_source()); 66 al_register_event_source(event, al_get_mouse_event_source()); 67 al_register_event_source(event, al_get_display_event_source(window)); 68 al_register_event_source(event, al_get_timer_event_source(timer)); 69 70 // Window title, icon and mouse hide 71 al_set_window_title(window, "Game programming"); 72 al_set_display_icon(window, icon); 73 al_hide_mouse_cursor(window); 74 75 // Player initializations 76 InitShip(ship); 77 InitBullet(bullets, NUM_BULLETS); 78 79 // Start timer 80 al_start_timer(timer); 81 82 83 // The drawing 84 while(!quit) 85 { 86 // Call of the event 87 ALLEGRO_EVENT e; 88 al_wait_for_event(event, &e); 89 90 // Drawing 91 if(e.type == ALLEGRO_EVENT_TIMER) 92 { 93 draw = true; 94 95 if(buton[A]) 96 MoveShipLeft(ship); 97 if(buton[D]) 98 MoveShipRight(ship); 99 if(buton[S]) 100 MoveShipDown(ship); 101 if(buton[W]) 102 MoveShipUp(ship); 103 // Why didn't you apply the same logic to firing your bullets? 104 if(buton[SPACE]) 105 { 106 // also it's button, you got it right in the comments though. 107 // Or is this a different language? 108 if(fireCooldown == 0) 109 { 110 // We'll decrement this variable later 111 // This block will only get executed if fireCooldown equals 0 112 fireCooldown = 10; 113 // Now that we've assigned 10 to fireCooldown we can be sure the next bullet is not going to be fired for a couple of frames 114 FireBullet(bullets, NUM_BULLETS, ship); 115 } 116 } 117 118 // Let's get the ship ready for the next shot 119 if(fireCooldown > 0) 120 fireCooldown--; 121 122 123 UpdateBullet(bullets, NUM_BULLETS); 124 } 125 126 // Key down or up 127 switch(e.type) 128 { 129 case ALLEGRO_EVENT_KEY_DOWN: 130 switch(e.keyboard.keycode) 131 { 132 case ALLEGRO_KEY_A: 133 buton[A] = true; 134 break; 135 136 case ALLEGRO_KEY_S: 137 buton[S] = true; 138 break; 139 140 case ALLEGRO_KEY_D: 141 buton[D] = true; 142 break; 143 144 case ALLEGRO_KEY_W: 145 buton[W] = true; 146 break; 147 148 case ALLEGRO_KEY_SPACE: 149 buton[SPACE] = true; 150 // Now you are going to fire a bullet each time you press your spacebar, so let's move this out of here 151 //FireBullet(bullets, NUM_BULLETS, ship); 152 153 break; 154 155 case ALLEGRO_KEY_ESCAPE: 156 quit = true; 157 break; 158 } 159 } 160 161 switch(e.type) 162 { 163 case ALLEGRO_EVENT_KEY_UP: 164 switch(e.keyboard.keycode) 165 { 166 case ALLEGRO_KEY_A: 167 buton[A] = false; 168 break; 169 170 case ALLEGRO_KEY_S: 171 buton[S] = false; 172 break; 173 174 case ALLEGRO_KEY_D: 175 buton[D] = false; 176 break; 177 178 case ALLEGRO_KEY_W: 179 buton[W] = false; 180 break; 181 182 case ALLEGRO_KEY_SPACE: 183 buton[SPACE] = false; 184 break; 185 } 186 } 187 188 189 // Close display when X is pressed 190 if(e.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 191 { 192 quit = true; 193 } 194 195 // Mouse movement 196 else if(e.type == ALLEGRO_EVENT_MOUSE_AXES) 197 { 198 ship.y = e.mouse.y; 199 } 200 201 // Bad idea, an ALLEGRO_EVENT is an union 202 // Meaning that multiple different members can take the same place in memory 203 // Other events might 'overwrite' e.mouse.button, causing it to falsely evaluate to true and this is more likely than you might think as it caused the firing to seem irregular with this not being commented 204 /*else if(e.mouse.button & 1) 205 { 206 FireBullet(bullets, NUM_BULLETS, ship); 207 }*/ 208 if(e.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) 209 { 210 if(e.mouse.button & 1) 211 { 212 buton[SPACE] = true; // Ugly hack but it works 213 } 214 } 215 else if(e.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) 216 { 217 if(e.mouse.button & 1) 218 { 219 buton[SPACE] = false; 220 } 221 } 222 223 if(draw && al_event_queue_is_empty(event)) 224 { 225 draw = false; 226 DrawShip(ship); 227 DrawBullet(bullets, NUM_BULLETS); 228 229 al_flip_display(); 230 al_clear_to_color(al_map_rgb(0,0,0)); 231 } 232 233 } 234 235 // Destroy 236 al_destroy_event_queue(event); 237 al_destroy_bitmap(icon); 238 al_destroy_display(window); 239} 240 241void InitShip(SpaceShip &ship) 242{ 243 ship.x = 20; 244 ship.y = height / 2; 245 ship.ID = PLAYER; 246 ship.lives = 3; 247 ship.speed = 7; 248 ship.boundx = 6; 249 ship.boundy = 7; 250 ship.score = 0; 251} 252 253void DrawShip(SpaceShip &ship) 254{ 255 al_draw_filled_rectangle(ship.x - 10, ship.y-15, ship.x + 35, ship.y, al_map_rgb(255,128,0)); 256 al_draw_filled_rectangle(ship.x + 35, ship.y-15, ship.x + 130, ship.y, al_map_rgb(255,255,255)); 257} 258 259void MoveShipUp(SpaceShip &ship) 260{ 261 ship.y -= ship.speed; 262 if(ship.y < 15) 263 ship.y = 15; 264} 265 266void MoveShipDown(SpaceShip &ship) 267{ 268 ship.y += ship.speed; 269 if(ship.y > height) 270 ship.y = height; 271} 272 273void MoveShipLeft(SpaceShip &ship) 274{ 275 ship.x -= ship.speed; 276 if(ship.x < 10) 277 ship.x = 10; 278} 279 280void MoveShipRight(SpaceShip &ship) 281{ 282 ship.x += ship.speed; 283 if(ship.x > 100) 284 ship.x = 100; 285} 286 287void InitBullet(Bullet bullet[], int size) 288{ 289 for(int i = 0; i < size; i++) 290 { 291 bullet[i].ID = BULLET; 292 bullet[i].speed = 10; 293 bullet[i].live = false; 294 } 295} 296 297void DrawBullet(Bullet bullet[], int size) 298{ 299 for(int i = 0; i < size; i++) 300 { 301 if(bullet[i].live) 302 al_draw_filled_circle(bullet[i].x, bullet[i].y, 5, al_map_rgb(128,128,128)); 303 } 304} 305 306void FireBullet(Bullet bullet[], int size, SpaceShip &ship) 307{ 308 for(int i = 0; i < size; i++) 309 { 310 if(!bullet[i].live) 311 { 312 bullet[i].x = ship.x + 120; 313 bullet[i].y = ship.y - 7; 314 bullet[i].live = true; 315 break; 316 } 317 } 318} 319 320void UpdateBullet(Bullet bullet[], int size) 321{ 322 for(int i = 0; i < size; i++) 323 { 324 if(bullet[i].live) 325 { 326 bullet[i].x += bullet[i].speed; 327 if(bullet[i].x > width) 328 { 329 bullet[i].live = false; 330 break; 331 } 332 } 333 } 334}

Well most of your code worked, I just don't understand why you decided to handle your shooting so different in comparison to the movement of the ship.

AleX-G Squadron

So you mean this is the code block which makes the autoshooting?

#SelectExpand
1 // Why didn't you apply the same logic to firing your bullets? 2 if(buton[SPACE]) 3 { 4 // also it's button, you got it right in the comments though. 5 // Or is this a different language? 6 if(fireCooldown == 0) 7 { 8 // We'll decrement this variable later 9 // This block will only get executed if fireCooldown equals 0 10 fireCooldown = 10; 11 // Now that we've assigned 10 to fireCooldown we can be sure the next bullet is not going to be fired for a couple of frames 12 FireBullet(bullets, NUM_BULLETS, ship); 13 } 14 } 15 16 17 // Let's get the ship ready for the next shot 18 if(fireCooldown > 0) 19 fireCooldown--;

And than i can apply int firecooldown to all games i will create?

Also, i didnt understand why did you put firecooldown = 10. What is the logic?
It decrements 10 loops and than shoots a bullet?

J-Gamer

That code fires every 10 ticks. You can increase it to lower the rate of fire, or decrease it to make it fire faster.

AleX-G Squadron

Just did that :)
It works perfect, i don't get one last thing.
The same block of code is used to make the autoshooting?

taronĀ 

Yes, every time you fire a bullet the counter will get increased. As long as this counter is not zero the next bullet won't be fired.
Every frame(timer event) this counter gets decreased so it can become 0 again.

AleX-G Squadron

Ok, thank you very much!

Thread #610957. Printed from Allegro.cc