Sign in to follow this  

Keyboard buffer Allegro

This topic is 4661 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

so here's my gameloop:
    while(!key[KEY_ESC])
    {
         if(key[KEY_ENTER]){ PlaceBet();}    
    }
    
    allegro_exit();    
}     

END_OF_MAIN();

and here's the function PlaceBet:
void PlaceBet()
{
    //Clear text and redraw border
    rectfill(buffer,0,140,WIDTH,HEIGHT,BGCOL);
    rect(buffer, 0, 0, WIDTH-1, HEIGHT-11, YELLOW);
    rect(buffer, 1, 1, WIDTH-2, HEIGHT-12, YELLOW);
    
    textout_centre(buffer,maintext,"Press + and - on keypad to change by $10",WIDTH/2,150,TXTCOL);
    textout_centre(buffer,maintext,"Press up and down arrows to change by $100",WIDTH/2,190,TXTCOL);
    //clear_keybuf();
    
    while(!key[KEY_ENTER])
    {
         if(key[KEY_PLUS_PAD])  {bet += 10;}
         if(key[KEY_MINUS_PAD]) {bet -= 10;}
         if(key[KEY_UP])    {bet += 100;}
         if(key[KEY_DOWN])  {bet -= 100;}
         if(bet<10)     { bet = 10;}
         if(bet>money) { bet = money;}
         rectfill(buffer,0,300,WIDTH,HEIGHT,BGCOL);
         rect(buffer, 0, 0, WIDTH-1, HEIGHT-11, YELLOW);
         rect(buffer, 1, 1, WIDTH-2, HEIGHT-12, YELLOW);
         textprintf_centre(buffer,maintext, 390,350,TXTCOL,"Money: $ %i",money);
         textprintf_centre(buffer,maintext, 390,380,TXTCOL,"Bet:   $ %i",bet);
         blit(buffer,screen,0,0,0,10,WIDTH,HEIGHT);
    }
}

Here's what happens...when I press enter at the main screen, it goes into the PlaceBet function, and updates the bet according to the keys pressed (so I know it's entering the while loop in PlaceBet). One thing is that it updates the keys TOO fast, so if I press + it goes up at least $50. But the big problem is that pressing ENTER doesn't end the while loop. When I press enter, it doesn't do anything at all actually. According to my code, it should exit the while loop and go back to main. Then, I should still be in the main while loop. So if I press ESC it should quit. But it doesn't do anything. I suspect I need to clear_keybuf() somewhere but I don't know where...any ideaS?

Share this post


Link to post
Share on other sites
It's probably a better idea to use a gamestate rather than waiting for enter to be pressed:



while(!key[KEY_ESC])
{

if(key[KEY_ENTER]) Betting = true;

if(Betting)
PlaceBet();

}



Share this post


Link to post
Share on other sites
Well for one thing, you can draw the screen outside of the PlaceBet function. Have you tried the code I suggested? I think it will fix the problem.

By the way, make sure to install_timer() and call rest() to slow down the program. This way, your keys won't respond too quickly.

Share this post


Link to post
Share on other sites
I put your code in and it responds the same way...but I think I see that using gamestates sort of helps with the sensitive keyboard issue.
The problem is that I want ENTER to call the PlaceBet function from the while loop in main(), but once I'm in the while loop in PlaceBet, I use ENTER to exit that loop. I added a line for ESC in the PlaceBet function to quit the placeBet, and it works, but the same line for ENTER doesn't work.
did that make any sense

Share this post


Link to post
Share on other sites
Oh I forgot! you need to also change your PlaceBet() function:



void PlaceBet()
{
//Clear text and redraw border
rectfill(buffer,0,140,WIDTH,HEIGHT,BGCOL);
rect(buffer, 0, 0, WIDTH-1, HEIGHT-11, YELLOW);
rect(buffer, 1, 1, WIDTH-2, HEIGHT-12, YELLOW);

textout_centre(buffer,maintext,"Press + and - on keypad to change by $10",WIDTH/2,150,TXTCOL);
textout_centre(buffer,maintext,"Press up and down arrows to change by $100",WIDTH/2,190,TXTCOL);
//clear_keybuf();

if(key[KEY_PLUS_PAD]) {bet += 10;}
if(key[KEY_MINUS_PAD]) {bet -= 10;}
if(key[KEY_UP]) {bet += 100;}
if(key[KEY_DOWN]) {bet -= 100;}
if(bet<10) { bet = 10;}
if(bet>money) { bet = money;}
rectfill(buffer,0,300,WIDTH,HEIGHT,BGCOL);
rect(buffer, 0, 0, WIDTH-1, HEIGHT-11, YELLOW);
rect(buffer, 1, 1, WIDTH-2, HEIGHT-12, YELLOW);
textprintf_centre(buffer,maintext, 390,350,TXTCOL,"Money: $ %i",money);
textprintf_centre(buffer,maintext, 390,380,TXTCOL,"Bet: $ %i",bet);
blit(buffer,screen,0,0,0,10,WIDTH,HEIGHT);

}




and change your loop:


while(!key[KEY_ESC])
{

if(key[KEY_ENTER]) Betting = true;

if(Betting)
{
PlaceBet();
if(key[KEY_ENTER]) Betting = false;
}

}





}


Share this post


Link to post
Share on other sites

Hi, ok, i think i know what your problem is and how to fix it without making a lot of changes in your code.

It's not that when you hit ENTER nothing happens, it's just that it happens way too fast for you to notice it. Supouse that you are in your PlaceBet loop and:

- you hit enter
- the loop exits
- PlaceBet returns to main.
- The while(!key KEY_ESC) repeats (you are not pressing esc)
- and then if(key KEY_ENTER) is TRUE!! (Why? the computer did it too fast for you to have enough time to take out your finger, and it thinks that your are still pressing it =) )...
- so you go in your PlaceBet loop again...

something interesting is that i bet that you will still be pressing enter so you come out and in from PlaceBet a lot of time before you finally lift your finger up, and chances are that you will be inside the PlaceBet function (its larger than your main)...


How to solve this? I suggest instead of wainting for a key in a continuos loop, you use readkey(), wich it STOPS the program until a key is hitted...

Just change your while(!key KEY_ENTER ) {} loop for a
do {
...
} while ((readkey() >> 8) != KEY_ENTER);
while(key[KEY_ENTER]); // this will wait until you lift your finger.


It will repeat your loop until you hit enter... if you hit another key it will go up again and do your if(key KEY-PLUS_PAD) ...etc...

hope that helps!! =) (i can't test the code here, so i cant be 100% sure it will work)

also, using the do {} while(); you wont be readrawing everything every single milisecond... only when necesary ;)

Share this post


Link to post
Share on other sites
If you're going to use readkey(), you don't need to bother with all that jazz. It'll return keys at the same rate as if you were typing in a text box.

Otherwise, you could probably write a helper function (not tested):

/* Example usage:

if(testKey(KEY_ESC))
{
// Do something. . .
}
*/


bool testKey(int code)
{
if(code < 0 || code >= 256)
return false;

static bool was_pressed[256];

if(key[code])
{
if(was_pressed[code])
return false;

was_pressed[code] = true;
return true;
}
else
{
was_pressed[code] = false;
return false;
}
}

Share this post


Link to post
Share on other sites
Quote:
while(key[KEY_ENTER]); // this will wait until you lift your finger.


Where should I put this?
I've switched to using a do-while loop so it now reads as such:

while(!key[KEY_ESC])
{
if(key[KEY_ENTER]) PlaceBet();
}



and then :

void PlaceBet()
{
//...drawing stuff

do{
if(key[KEY_PLUS_PAD]) bet += 10;
if(key[KEY_MINUS_PAD]) bet -= 10;
if(key[KEY_UP]) bet += 100;
if(key[KEY_DOWN]) bet -= 100;
if(bet<10) bet = 10;
if(bet>money) bet = money;
rectfill(buffer,0,300,WIDTH,HEIGHT,BGCOL);
rect(buffer, 0, 0, WIDTH-1, HEIGHT-11, YELLOW);
rect(buffer, 1, 1, WIDTH-2, HEIGHT-12, YELLOW);
textprintf_centre(buffer,maintext, 390,350,TXTCOL,"Money: $ %i",money);
textprintf_centre(buffer,maintext, 390,380,TXTCOL,"Bet: $ %i",bet);
blit(buffer,screen,0,0,0,10,WIDTH,HEIGHT);
}while((readkey() >> 8) != KEY_ENTER);
while(key[KEY_ENTER]);
}



If I leave that last while(key[KEY_ENTER]) in there, it doesn't let me update the bet. If I take it out, I can update my bet just fine but it doesn't register
ENTER or ESC as leaving the PlaceBet function.

Share this post


Link to post
Share on other sites
don't use rest, that's bad advice.

The way to prevent keys from being registered as down more than once is to declare a second key array:
char last_key[KEY_MAX] = {0};


your game loop (from above) then looks something like:
while(!key[KEY_ESC]) {
// if enter has just been pressed
if( key[KEY_ENTER] && ! last_key[KEY_ENTER] ) {
// place a bet
PlaceBet();
// and remember that enter has been pressed
last_key[KEY_ENTER] = 1;

// if enter isn't down, remember it
} else if ( !key[KEY_ENTER] ) {
last_key[KEY_ENTER] = 0;
}
}

edit: oops, I didn't read smart_idiot's post, which is basically the same thing...

Share this post


Link to post
Share on other sites
Quote:
don't use rest, that's bad advice.


Well, most of the time, yes it is. However, I see no problem with using it to slightly slow down the program so the keys won't respond too fast.

Share this post


Link to post
Share on other sites
Quote:
Original post by Stompy9999
Quote:
don't use rest, that's bad advice.


Well, most of the time, yes it is. However, I see no problem with using it to slightly slow down the program so the keys won't respond too fast.
that's just a ridiculous hack. You don't need to slow down your program to do that, you just have to detect and track key transitions properly.

Share this post


Link to post
Share on other sites
I probably should have read your origional code, which tracks the last key pressed. This is a far better method.

One probably I see though is that the screen is blitted alot per second. This might cause some flicker even with double buffer.

Share this post


Link to post
Share on other sites

This topic is 4661 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this