Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » readkey + bool = Opening inventary

Credits go to Ceagon Xylas, GullRaDriel, HoHo, Indeterminatus, Jeff Bernard, ReyBrujo, Rick, and Tobias Dammers for helping out!
This thread is locked; no one can reply to it. rss feed Print
readkey + bool = Opening inventary
jaime barrachina
Member #6,780
January 2006
avatar

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

"Under the sword lifted high There is hell making you tremble: But go ahead, And you have the land of bliss. - Miyamoto Musahshi"
"When all else fails, read the manual - Dad"

ReyBrujo
Moderator
January 2001
avatar

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.

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

GullRaDriel
Member #3,861
September 2003
avatar

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

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Ceagon Xylas
Member #5,495
February 2005
avatar

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
Member #4,534
April 2004
avatar

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

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

Rick
Member #3,572
June 2003
avatar

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;
   }
}

========================================================
Actually I think I'm a tad ugly, but some women disagree, mostly Asians for some reason.

jaime barrachina
Member #6,780
January 2006
avatar

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

"Under the sword lifted high There is hell making you tremble: But go ahead, And you have the land of bliss. - Miyamoto Musahshi"
"When all else fails, read the manual - Dad"

Jeff Bernard
Member #6,698
December 2005
avatar

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}

--
I thought I was wrong once, but I was mistaken.

Rick
Member #3,572
June 2003
avatar

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.

========================================================
Actually I think I'm a tad ugly, but some women disagree, mostly Asians for some reason.

Indeterminatus
Member #737
November 2000
avatar

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}

_______________________________
Indeterminatus. [Atomic Butcher]
si tacuisses, philosophus mansisses

Rick
Member #3,572
June 2003
avatar

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

========================================================
Actually I think I'm a tad ugly, but some women disagree, mostly Asians for some reason.

Jeff Bernard
Member #6,698
December 2005
avatar

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}

--
I thought I was wrong once, but I was mistaken.

Rick
Member #3,572
June 2003
avatar

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

========================================================
Actually I think I'm a tad ugly, but some women disagree, mostly Asians for some reason.

Tobias Dammers
Member #2,604
August 2002
avatar

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).

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

jaime barrachina
Member #6,780
January 2006
avatar

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

"Under the sword lifted high There is hell making you tremble: But go ahead, And you have the land of bliss. - Miyamoto Musahshi"
"When all else fails, read the manual - Dad"

Go to: