Autoshooter
AleX-G Squadron

Hi!
1)I want to make an autoshooter for a space shooting game i made long ago, so the ship will shoot every 1.2 seconds if the space button is being pressed.

2)I want to pause the game, but there is no command to do that. I have tried al_rest(1.2) but that was a stupid idea.

EDIT: I accidentally found how to pause the game.

GullRaDriel

1) then start a timer and trigger a new bullet shot each time it reach 1.2 seconds.

Pseudo code:

time = start_timer();
reset_timer( &time );
while( !done )
{
    if( timer.msec > 1200 )
    {
        launch_a_bullet();
        reset_timer( &time );
    }
}

AleX-G Squadron

I tried something like this

#SelectExpand
1case ALLEGRO_KEY_SPACE: 2 count++; 3 while(count % 3000 == 0) 4 { 5 ShipShot(bullet, BULLET_NUMBER, ship); 6 count=0; 7 } 8 break;

The game launches but no bullet launch.

I tried this one and i get problems

#SelectExpand
1case ALLEGRO_KEY_SPACE: 2ALLEGRO_TIMER *spaceshoot = NULL; 3spaceshoot = al_create_timer(1.0); 4al_start_timer(spaceshoot); 5if(spaceshoot > 1000.0) 6{ 7GjuajPlumb(plumb, NUMRI_PLUMBAVE, anija); 8} 9break;

l j

Try pressing space 3000 times it will work.
Also that while will never loop, it will only be true once, so why no if?

J-Gamer

It won't be true even once, since he increments count before it.(assuming count started at 0)

AleX-G Squadron

Looks like i got it to work somehow, but it doesnt work as needed.
I have to press it each time.
I added a timer, created it outside my while(!done)
Inside the Space button i have put this,
but i cannot make any differences with the if statement,
because the timer, is not an integer!

#SelectExpand
1case ALLEGRO_KEY_SPACE: 2al_start_timer(spaceshoot); 3if(spaceshoot) 4{ 5SpaceShoot(bullet, BULLET_NUMBER, ship); 6} 7break;

@taron
Actually it doesnt work well! :o

Dizzy Egg
int bulletTimer = 0;

while(game_running){
  if(key_space && bulletTimer == 0){
    fire_bullet();
    bulletTimer = 20;
  }

  if(bulletTimer > 0){
    bulletTimer -= 1;
  }
}

AleX-G Squadron

I wrote your idea, but the timer is not an int.
I mean it has to be a second. If I use an int it wont work.
And it didn't.

EDIT: I actually modified the counter = 20 to counter = 0 and it worked launching infinite bullets.
When i try to add something > 0 it doesnt shoot.
Any idea?

Temia Eszteri

If your code editor has debugging support, drop a breakpoint on the line of code that's decrementing the timer and run it in the debugger to see if it breaks. If it doesn't, something's wrong with the block.

AleX-G Squadron

After dropping a breakpoint with F9 on visual studio 2012, the program went on and the game started like always. The ship could not use any bullets. This is the REAL coding i made for the autoshooting piece.

#SelectExpand
1else if (ev.type == ALLEGRO_EVENT_KEY_DOWN && counter == 0) 2 { 3 GjuajPlumb(plumb, NUMRI_PLUMBAVE, anija); 4 counter = 0; 5 } 6 else if (counter > 0) 7 { 8 counter -= 1; 9 }

I have searched everywhere on the internet and i only got a reply from someone who has made autoshooter telling me i have to make a % 5 with the counter. I did that myself because that is the basic logic at first, but it doesnt happen.
Normally the counter increases, but the game FREEZES!
If i try to make it % 5000 it doesnt shoot at all.

I learned one thing though. How to freeze the ship when i press space!

l j

else if (counter > 0)

Move that code to your timer event and remove the else too.

AleX-G Squadron

Did it like you said, it only shoots one time. If i keep the button pressed, it wont shoot anymore.

#SelectExpand
1else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) 2 { 3 if(ev.keyboard.keycode == ALLEGRO_KEY_SPACE) 4 GjuajPlumb(plumb, NUMRI_PLUMBAVE, anija); 5 counter = 20; 6 if (counter > 0) 7 counter -= 1; 8 }

Actually i created a kind of debugging. I added text and used it to show the counter.
Using this piece of code, if i press space, the counter value went always to 20.
If i delete counter = 20 it removes by one. That is not quite logical, because what i want is to shoot every 5 frames for example.
And not removing the counter value.

After some other research i found this piece of code

#SelectExpand
1 else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) 2 { 3 if(ev.keyboard.keycode == ALLEGRO_KEY_SPACE) 4 if(counter % 5 == 0) 5 { 6 GjuajPlumb(plumb, NUMRI_PLUMBAVE, anija); 7 } 8 if (counter > 0) 9 counter -= 1; 10 }

But this is even worse. The ship shoots only when the space is pressed and the frame is % 5 == 0. So you have to press it several times for the ship to shoot!

After many attempts i found out something else even more amazing

#SelectExpand
1else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) 2 { 3 if(ev.keyboard.keycode == ALLEGRO_KEY_SPACE) 4 if(counter = counter + 15000) 5 { 6 GjuajPlumb(plumb, NUMRI_PLUMBAVE, anija); 7 } 8 if (counter > 0) 9 counter -= 1; 10 }

It raises the frames by 15000! :o

I found a minimized version when the ships shoots every time the frames % 5 == 0, but the problem is that you have to press the key!
How can i make it without pressing the key?

#SelectExpand
1else if (ev.type == ALLEGRO_EVENT_KEY_DOWN && ev.keyboard.keycode == ALLEGRO_KEY_SPACE) 2 { 3 if(counter % 5 == 0) 4 GjuajPlumb(plumb, NUMRI_PLUMBAVE, anija); 5 }

I tried the while cycle but that crashes the whole game! :o:o:o

l j
#SelectExpand
1// Initialize stuff 2// Code assumes your event queue is simply called queue 3bool isFiring = false; 4 5ALLEGRO_TIMER *timer = al_create_timer(1.0 / 60.0); // 60 ticks per second 6al_register_event_source(queue, timer); 7 8while (true) // Begin of gameloop, statement can differ 9{ 10 al_wait_for_event(queue, &ev); // Or your preffered way to poll the events 11 if (ev.type == ALLEGRO_EVENT_KEY_DOWN) 12 { 13 if (ev.keyboard.keycode == ALLEGRO_KEY_SPACE) 14 { 15 isFiring = true; 16 } 17 } 18 else if (ev.type == ALLEGRO_EVENT_KEY_UP) 19 { 20 if (ev.keyboard.keycode == ALLEGRO_KEY_SPACE) 21 { 22 isFiring = false; 23 } 24 } 25 else if (ev.type == ALLEGRO_EVENT_TIMER) // executes 60 times per second 26 { 27 if (counter > 0) 28 { 29 counter--; // Subtract one from your counter 30 } 31 if (isFiring && counter == 0) 32 { 33 counter = 5; // Now you'll shoot every 5 frames 34 // since the game runs at 60 ticks/frames per second 35 // you'll have a fire rate of 720 bullets per minute 36 // Fire bullet 37 GjuajPlumb(plumb, NUMRI_PLUMBAVE, anija); // I guess 38 39 } 40 } 41 42 // I'm pretty sure you can do the drawing yourself. 43}

This code is completely untested.
May or may not work 'out of the box', but it should get the idea across.

Also you can use a switch statement for your event handling instead of all those if statements, whatever you prefer.

EDIT:
if(counter = counter + 15000)

It raises the frames by 15000!

there is nothing surprising about this.
you assign counter + 15000 to counter. "==" != "="
And because this value will (most likely) never be 0 it will always evaluate to true.

AleX-G Squadron

I get only an error with the timer.
I deleted my timer and added yours.
My timer was a bit different, because it was:
const FPS = 80;
timer = al_create_timer(1.0, FPS);

I added mine and deleted yours and still on both cases the timer is labeled with red
in this piece of code:

al_register_event_source(event_queue, timer);

My event is event_queue so no problem there, only timer is red.
It says after compiling and getting the error:

IntelliSense: argument of type "ALLEGRO_TIMER *" is incompatible with parameter of type "ALLEGRO_EVENT_SOURCE *"

l j

oops, forgot something.
that should be:

AleX-G Squadron

The game freezes :(
Can you try your code with one of your projects and prove it?
Maybe it is my fault.

EDIT: After entering the code again, i got it shooting only 1 time!

l j
#SelectExpand
1#include <allegro5/allegro.h> 2#include <cstdlib> 3 4const int MAX_BULLETS = 200, 5 SCREEN_WIDTH = 800, 6 SCREEN_HEIGHT = 600; 7 8const float PLAYER_X_VELOCITY = 1.5f; 9const float PLAYER_Y_VELOCITY = 1.5f; 10 11const float BULLET_Y_VELOCITY = 3; 12 13class Player 14{ 15 16public: 17 float x, y; 18 bool movingUp, 19 movingDown, 20 movingRight, 21 movingLeft; 22 bool isFiring; 23 24 Player() 25 { 26 movingUp = 27 movingDown = 28 movingRight = 29 movingLeft = false; 30 31 isFiring = false; 32 } 33 34 void Update() 35 { 36 if (movingUp) 37 { 38 y -= PLAYER_Y_VELOCITY; 39 } 40 else if (movingDown) 41 { 42 y += PLAYER_Y_VELOCITY; 43 } 44 45 if (movingRight) 46 { 47 x += PLAYER_X_VELOCITY; 48 } 49 else if (movingLeft) 50 { 51 x -= PLAYER_X_VELOCITY; 52 } 53 } 54 55}; 56 57class Bullet 58{ 59public: 60 float x, y; 61 bool alive; 62}; 63 64void HandleInput(Player &player, int keyCode, bool keyDown) 65{ 66 switch (keyCode) 67 { 68 case ALLEGRO_KEY_Z: 69 player.isFiring = keyDown; 70 break; 71 case ALLEGRO_KEY_LEFT: 72 player.movingLeft = keyDown; 73 break; 74 case ALLEGRO_KEY_UP: 75 player.movingUp = keyDown; 76 break; 77 case ALLEGRO_KEY_RIGHT: 78 player.movingRight = keyDown; 79 break; 80 case ALLEGRO_KEY_DOWN: 81 player.movingDown = keyDown; 82 break; 83 } 84} 85 86int main(int argc, char *argv[]) 87{ 88 al_init(); 89 al_install_keyboard(); 90 ALLEGRO_DISPLAY *display = al_create_display(SCREEN_WIDTH, SCREEN_HEIGHT); 91 ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue(); 92 ALLEGRO_TIMER *timer = al_create_timer(1.0 / 60.0); 93 94 al_register_event_source(queue, al_get_display_event_source(display)); 95 al_register_event_source(queue, al_get_keyboard_event_source()); 96 al_register_event_source(queue, al_get_timer_event_source(timer)); 97 98 ALLEGRO_EVENT event; 99 100 // Bullet stuff 101 int fireCooldown = 0; 102 int bulletsAlive = 0; 103 Bullet bulletArray[MAX_BULLETS]; 104 memset(bulletArray, 0, sizeof(Bullet) * MAX_BULLETS); // Initialize bullet memory to 0 105 106 // Player stuff 107 Player player; 108 player.x = SCREEN_WIDTH / 2; 109 player.y = SCREEN_HEIGHT - 20; 110 111 bool invalidated = false; 112 al_start_timer(timer); 113 while (true) 114 { 115 bool keyDown = false; 116 al_wait_for_event(queue, &event); 117 switch (event.type) 118 { 119 case ALLEGRO_EVENT_DISPLAY_CLOSE: 120 return 0; 121 122 case ALLEGRO_EVENT_KEY_DOWN: 123 HandleInput(player, event.keyboard.keycode, true); 124 break; 125 126 case ALLEGRO_EVENT_KEY_UP: 127 HandleInput(player, event.keyboard.keycode, false); 128 129 case ALLEGRO_EVENT_TIMER: 130 invalidated = true; 131 if (fireCooldown > 0) 132 { 133 fireCooldown--; 134 } 135 136 player.Update(); 137 138 if (player.isFiring && fireCooldown == 0) 139 { 140 // Replace first dead bullet with a 'living' one 141 for (int i = 0; i < MAX_BULLETS; i++) 142 { 143 if (!bulletArray[i].alive) 144 { 145 bulletArray[i].alive = true; 146 bulletArray[i].x = player.x; 147 bulletArray[i].y = player.y; 148 break; 149 } 150 } 151 fireCooldown = 5; 152 } 153 154 // Update all living bullets 155 for (int i = 0; i < MAX_BULLETS; i++) 156 { 157 if (bulletArray[i].alive) 158 { 159 bulletArray[i].y -= BULLET_Y_VELOCITY; 160 // Kill bullet if it has gone off the screen 161 if (bulletArray[i].y < 0) 162 { 163 bulletArray[i].alive = false; 164 } 165 } 166 } 167 break; 168 } 169 if (invalidated && al_is_event_queue_empty(queue)) // Redraw 170 { 171 al_clear_to_color(al_map_rgb(0, 0, 0)); 172 al_draw_pixel(player.x, player.y, al_map_rgb(0,255, 0)); // player is a green dot 173 174 for (int i = 0; i < MAX_BULLETS; i++) 175 { 176 if (bulletArray[i].alive) 177 { 178 al_draw_pixel(bulletArray[i].x, bulletArray[i].y, al_map_rgb(255, 0, 0)); 179 } 180 } 181 182 al_flip_display(); 183 invalidated = false; 184 } 185 } 186 return 0; 187}

if this code freezes, it's your computer.
Tested 100% this time.
Didn't bother making proper error checking or clean up though.

AleX-G Squadron

FINALLY IT WORKED!!!!
I will replace your code with my game and if i encounter any error i will ask again!
Thank you very much :)

l j

You should try to understand how and why the code works, otherwise you'll run into problems again real fast.

AleX-G Squadron

You are totally right.
I will try to create the game from the start this time to get more knowledge!

EDIT: I am trying to understand your code, but that seems to me a bit strange.
Can you add comments to the code line?

Thread #610903. Printed from Allegro.cc