Exit game from another class (Input)

Started by
50 comments, last by rip-off 12 years, 8 months ago
If you don't mask out the bits, you may erroneously treat a just-released key as a pressed key for a frame. This may or may not be noticeable, depending on what you do when a key is released.
Advertisement
Ok, i've added the 0x8000 mask. Below is my current code in Input.cpp. Is there anything you think isn't correct here or is it ok?

[source lang="cpp"]
#include <Windows.h>
#include "Input.h"
#include "Main.h"


Input::Input()
{
}


Input::~Input(void)
{
}


// --------------------------------------------------------------------------------
// Name: ButtonDown
// Desc: Checks if a specific keyboard/mouse button is pressed
// Rtrn: Returns true if the button is pressed
// --------------------------------------------------------------------------------
bool Input::ButtonDown(USHORT key)
{
if (GetAsyncKeyState(key)&0x8000)
{
return true;
}

return false;
}


// --------------------------------------------------------------------------------
// Name: ButtonDownOnce
// Desc: Checks if a specific keyboard/mouse button is pressed
// Rtrn: Only returns true once per click
// --------------------------------------------------------------------------------
bool Input::ButtonDownOnce(USHORT key)
{
if (ButtonDown(key))
{
if (pressed_keys.empty())
{
pressed_keys.push_back(key);
return true;
}

else
{
for (std::list<USHORT>::const_iterator current = pressed_keys.begin(); current != pressed_keys.end(); current++)
{
if (*current == key)
{
return false;
}
}

return true;
}
}

if (ButtonUp(key))
{
pressed_keys.remove(key);
}

return false;
}


// --------------------------------------------------------------------------------
// Name: ButtonUp
// Desc: Checks if a specific keyboard/mouse button is up
// Rtrn: Returns true if the button is up
// --------------------------------------------------------------------------------
bool Input::ButtonUp(USHORT key)
{
if (!GetAsyncKeyState(key)&0x8000)
{
return true;
}

return false;
}
[/source]

That looks ok, but I'm skeptical about you ButtonDown logic. It only adds buttons when the list is empty, which means it only works when you care about testing a single button.

I'd write it like so:

#include <algorithm>

bool Input::ButtonDown(USHORT key)
{
return (GetAsyncKeyState(key) & 0x8000);
}

bool Input::ButtonUp(USHORT key)
{
return !ButtonDown(key);
}

bool Input::ButtonDownOnce(USHORT key)
{
std::vector<USHORT>::const_iterator it = std::find(pressed_keys.begin(), pressed_keys.end(), key);
if (ButtonDown(key))
{
if(it == pressed_keys.end())
{
pressed_keys.push_back(key);
return true;
}
return false;
}
else // Button is up
{
if(it != pressed_keys.end())
{
pressed_keys.erase(it);
}
return false;
}
}

Note I'm using std::vector<> rather than std::list<>. While std::list is theoretically better for removing items in the middle of the list, for a small list like this std::vector<> will likely be the best choice. std::list involves allocation, which can fragment the heap and trash your cache, whereas std::vector provides roughly the same interface without incurring these costs.

Another would be to have a 256 length array of boolean values, which you can use to test if a key is moving from released to pressed.

However, you are not likely to be calling this many times a frame, so I wouldn't worry too much about it.

This topic is closed to new replies.

Advertisement