Sign in to follow this  
FGFS

user input key store in array

Recommended Posts

Hi

any ideas on how to catch only one input keyboard key and store in a char array? If I try like below I get multiple, for ex. if L is pressed, L keys.

Thanks

 

--------

    if (hasDownFlag == 1 ){
    strcat (&ApEntrystr[airportcode], description.c_str());
    hasDownFlag = 0;
    }
//    if (hasUpFlag == 1 ){
//    airportcode += 1;
//    }
    if(hasOptAltFlag == 1){
        airportcode = 0;
        ApEntrystr[0] = 0;
    }

Share this post


Link to post
Share on other sites

Can you just iterate through the array and ensure that it isn't already in there?

 

Also, if your are using C++ (as opposed to C), you might find std::vector<char> to be much easier for this task. I tend to have two vectors, one for pressed keys this frame (cleared at the beginning of a new frame) and one for keys that are down (they get removed from the array when the up signal is obtained).

Edited by Karsten_

Share this post


Link to post
Share on other sites

Hopefully this will better explain what I mean smile.png

Input.h

class Input
{
...
  static std::vector<int> keys;
  static std::vector<int> upKeys;
  static std::vector<int> downKeys;
...
}

Application.cpp

    ....
    else if(event.type == SDL_KEYDOWN)
    {
      bool found = false;

      for(int i = 0; i < Input::keys.size(); i++)
      {
        if(Input::keys.at(i) == event.key.keysym.sym)
        {
          found = true;
          break;
        }
      }

      if(found == true)
      {
        // go onto the next SDL_Event
        continue;
      }
 
      Input::keys.push_back(event.key.keysym.sym);
      Input::downKeys.push_back(event.key.keysym.sym);
    }
    else if(event.type == SDL_KEYUP)
    {
      for(int i = 0; i < Input::keys.size(); i++)
      {
        if(Input::keys.at(i) == event.key.keysym.sym)
        {
          Input::keys.erase(Input::keys.begin() + i);
          i--;
        }
      }
 
      Input::upKeys.push_back(event.key.keysym.sym);
    }
    ...

from https://github.com/osen/mutiny/blob/master/src/mutiny/Application.cpp

Edited by Karsten_

Share this post


Link to post
Share on other sites


Thanks, but still no luck as I cannot use sdl (init_video).

Just substitute the SDL parts for whatever library you are using. The general idea of using vectors to hold the current key state should work with anything.

 

If glut, then do this on the glutKeyboard(Up) callbacks

if X11 (via glx), use XNextEvent and if(xev.type == KeyPress)

etc...

Edited by Karsten_

Share this post


Link to post
Share on other sites

I get back from x-plane a char: gChar with the pressed key. So while pressed it loops all the time hence resulting in a huge amount of returned chars.

Any help/ideas for that? I don't want to use glut. Thanks

Share this post


Link to post
Share on other sites

Why not just store them all? When you press key, it sends like ~30 events per second so, for example, std::vector<key>(1000) can hold it easily and iterate through all of the key presses very fast.

The most important about this approach is that you won't loose any analog key events so your character movements won't become discontinuous.

Edited by GuardianX

Share this post


Link to post
Share on other sites

I think its not a good idea to translate key events into an array just to one moment later iterate over the whole array to find which keys are pressed and possibly loosing data when a key gets pressed and released or gets pressed repeatedly before searching the array again. Sometimes its also useful to only react when a key gets pressed or only when a key is released and not the whole time its down.

Why don't you just use the event and directly react to it?

Share this post


Link to post
Share on other sites

I need the last 4 user key inputs. Later on I want to compare this and show all airports beginning with the user input, first letter, second etc..

So I get all into a vector then delete all except the first 4 values? Well I try that then. But seems complicated it the user typed for ex. LL...

Edited by FGFS

Share this post


Link to post
Share on other sites

Why don't you just use the event and directly react to it?

Depending on the requirements, this could be ideal. However in many cases at this point in the program you don't know which entities / gameobjects / nodes need to react to the control so it is required to store a "snapshot" of keys which can be polled during the individual objects update / control events.

 

In the system I presented above, the last keys pressed this frame are stored in Input::downKeys.

The keys released during last frame are stored in Input::upKeys

and the current keys held down are stored in Input::keys

 

(This is mimicking the same API that Unity 3D provides (as is the nature of this project ;))).

 

So to get the last 4 keys pressed, just iterate through the last 4 keys in the Input::downKeys array.

This approach is pretty much platform agnostic so for x-plane, just substitute event.key.keysym.sym with gChar in whatever bit of code you get the key down event.

Edited by Karsten_

Share this post


Link to post
Share on other sites

Hmm if I do:

 

static std::vector<char> keys;
static std::vector<int> upKeys;
static std::vector<int> downKeys;

 

 

    hasControlFlag = gFlags & xplm_ControlFlag;
    hasDownFlag = gFlags & xplm_DownFlag;

      if (hasOptAltFlag == 1)
      {
          keys.pop_back();
      }

if (hasControlFlag == 1)
{
    if (hasDownFlag == 1)
    {
    keys.push_back(gChar);
}
for (std::vector<char>::iterator it = keys.begin() ; it != keys.end(); ++it)
//for (std::vector<char>::iterator it = 0; it != 5; ++it)
{
      std::copy(keys.begin(), keys.end(), ApEntrystr);
}

    RenderText(font, 1, 1, 1, PanelLeft1 + 550, PanelTop1 - 320, test.displayAirport(ApEntrystr));
        }

 

pusing ctrl and a key not only fills the vector but it displays also lots of rubbish and it crashes after a while.

Thanks again.

Edited by FGFS

Share this post


Link to post
Share on other sites

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