readkey + bool = Opening inventary
jaime barrachina

void teclado()
{
val = readkey();
if (val != old_val)
{
if ((val >> 8) == KEY_SPACE)
{
modo = 1 - modo;
pillartecla();
}
}
old_val=val;
}
END_OF_FUNCTION(teclado);

bool pillartecla()
{

if (modo == 1)
{ return true; }
else
{ return false; }



}
END_OF_FUNCTION(pillartecla);

Looks fine and nice, suposedly, theres a function something like

if (pillartecla == true)
{openinventary()}
else {closeinventary}

What all thaht is suposed to do is open the inventary when the player presses sapce_bar and closes it when he prees it again. As im only groping arround in the dark here, i'd apreciate any and all help you can give me, as it's not working. Especially if someone could tell me how yo use the readkey() properly and were to call the teclado(). I get a feeling inneed to call it in a while or a for but im not shure.
Any help for a beginer?

Cheers

ReyBrujo
First, use code tags, putting <code> and </code> surrounding your code so that it is "codified".

Second, you don't need to use END_OF_FUNCTION in all functions, only in those functions that are going to be called from inside a timer.

Third, the game should look something like this (this may not compile!):

#include <allegro.h>

int main() {
    int quit = 0;

    allegro_init();
    install_keyboard();

    while (!quit) {
        teclado();
        dibujo();
    }

    allegro_exit();
}
END_OF_MAIN()

You call teclado to poll the keyboard, and then call dibujo to draw on screen.

GullRaDriel

And using global variables isn't that good.
Make function with arguments.

Ceagon Xylas

I know that using globals isn't a good thing, and I dont use them because people have told me to make functions with arguments... But why exactly is it bad?

HoHo
Quote:

But why exactly is it bad?

Couple of reasons can be red from here:
http://www.bic.mni.mcgill.ca/~david/volume_io/section2_4_1.html
http://en.wikipedia.org/wiki/Global_variable

The thing about multithreading will become more and more important as multicore CPU's are becoming more widespread

Rick
Quote:

What all thaht is suposed to do is open the inventary when the player presses sapce_bar and closes it when he prees it again.

This is how I usually handle a situation like that.

bool key_space=false;
void input()
{
   if(key[KEY_SPACE] && !key_space)
   {
      openInventory();
      key_space = true;
   }
   else if(!key[KEY_SPACE] && key_space)
   {
      closeInventory();
      key_space = false;
   }
}

jaime barrachina

1000 thanks to everyone who's replied and excuse me for my lousy gramar, please, i was half asleep when i wrote the first post.
I was wondering if anyone could explain Rick's code in a "for idiots" kind of way, because it looks just like what i was looking for but somehow i dont seem able to cram it into my own code and make it work...

Thanks again everyone.
Cheers :D

Jeff Bernard

Hopefully this'll clear it up for you:

1// make key_space false so pressing space will open the inventory and not close it
2bool key_space=false;
3void input()
4{
5 // if the space bar is pressed and key_space is false (meaning inventory will be closed)
6 if(key[KEY_SPACE] && !key_space)
7 {
8 openInventory(); // open the inventory
9 key_space = true; // toggle key_space to true so you could close inventory
10 }
11 // else if the space bar is pressed and key_space is true (meaning inventory will be open)
12 else if(key[KEY_SPACE] && key_space)
13 {
14 closeInventory(); // close inventory
15 key_space = false; // toggle key_space to false so you could open the inventory
16 }
17}

Rick

Basically if you just use key[KEY_SPACE] to open the inventory it will run the code inside it on every loop, since if you hold it down it evaluates to true. Since we want a toggle of sorts, that is why we add the boolean value.

So I push the space bar, it goes in and opens the inventory, now if I hold the space bar it won't keep going in and opening the inventory. But actually thinking about it, you might not want what I posted. With that code if you let go on space the inventory closes. If you want to toggle it with the space bar you will have to put something inside the first if statement to see if it's open or closed and act on it that way.

1bool key_space=false;
2void input()
3{
4 // if the space bar is pressed and key_space is false (meaning inventory will be closed)
5 if(key[KEY_SPACE] && !key_space)
6 {
7 if(inventoryIsOpen())
8 closeInventory()
9 else
10 openInventory(); // open the inventory
11 
12 key_space = true; // toggle key_space to true so you could close inventory
13 }
14 // else if the space bar is pressed and key_space is true (meaning inventory will be open)
15 else if(key[KEY_SPACE] && key_space)
16 {
17 key_space = false; // toggle key_space to false so you could open the inventory
18 }
19}

That will toggle inventory based on open or closed.

Indeterminatus

Goin' a little off-topic.

In C++ (don't know if that'd work in C as well), a way to easily remove the global variable would be the following:

1void input()
2{
3 static bool key_space=false;
4 
5 if(key[KEY_SPACE] && !key_space)
6 {
7 openInventory();
8 key_space = true;
9 }
10 else if(!key[KEY_SPACE] && key_space)
11 {
12 closeInventory();
13 key_space = false;
14 }
15}

Rick

Good point, although if I was doing this, input() would be in a Game class and key_space would be a member variable.

Jeff Bernard

Rick, I believe the second code you posted would do just what the code I posted would do. I changed your original just a bit:

// I changed this line:
else if(!key[KEY_SPACE] && key_space)

// to this:
else if(key[KEY_SPACE] && key_space)

That way you don't need another function to determine if inventory is open, you can just use the boolean.

Or, since the input() function will most likely be looped, to make sure it doesn't run closeInventory() right away, you could just add this in: while (key[KEY_SPACE]) { rest(1); }
like so: (see the edit, I rewrote it better)

EDIT-- I'm bored, have another version of the code. This one's the best (and conforms to not using a global):

1// in your main or whatever, declare the inventory's open/closed status:
2bool inventoryStatus = false;
3//.. this uses false as closed and true as open
4 
5// in game loop somewheres:
6if (key[KEY_SPACE])
7 inventoryStatus = input(inventoryStatus);
8//..
9 
10bool input(bool invOpen)
11{
12 while (key[KEY_SPACE]) { rest(1); } // wait until space bar is let up
13 if (invOpen) // if the inventory is open
14 closeInventory(); // close it
15 else // otherwise, it is closed
16 openInventory(); // so open it!
17 return !invOpen; // toggle inventoryStatus
18}

Rick

That would actually freeze the entire game if I held the space bar. I don't like that solution.

Tobias Dammers

The core of the problem is that you need to convert states into state changes over time. To do this, you need to keep a copy of the previous state around, and compare the current one. I prefer doing this for the entire key array, so I only have to implement it once:

1// in the input class, or the game class, you choose
2int old_key[KEY_MAX]; // initialize this to all-zeroes
3int delta_key[KEY_MAX];
4 
5void tick_keyboard() {
6 poll_keyboard(); // may or may not need this
7 for (int i = 0; i < KEY_MAX; ++i) {
8 if (key<i> && !old_key<i>)
9 delta_key<i> = 1; // press
10 else
11 if (!key<i> && old_key<i>)
12 delta_key<i> = -1; // release
13 else
14 delta_key<i> = 0;
15 old_key<i> = key<i>;
16 }
17}

Call tick_keyboard() once at the start of the input function. If delta_key[KEY_SPACE] is 1, toggle the inventory state (inv_open = !inv_open).

jaime barrachina

Txs everyone for their help, really apreciate it people :) Problem is more or less solved now. Cheers

Thread #560357. Printed from Allegro.cc