Sfml Text Entered arrow keys - c++

I am making console style game in sfml. It's graphical interface but game itself contains console. I'm using Text Entered event for writing things in console but i also want to move the cursor (console cursor not mouse) with arrow keys. To be more specific in text entered event i am using event.text.unicode for key value. But arrow keys unicode values not working in my pc. I used 37 for left arrow, 39 for right arrow but it doesn't work. This is my console's key process function.
void Console::update(int unicode) {
if(unicode == 8) { // Backspace
deleteLast();
} else if(unicode == 13) { // Enter
newLine();
} else if(unicode == 37) { // Left arrow key
currentX--;
std::cout << "Left arrow" << std::endl;
} else if(unicode == 39) { // Right arrow key
currentX++;
std::cout << "Right arrow" << std::endl;
} else { // Normal characters
buffer[(currentY == 0) ? currentX : (currentY * maxColumn) + currentX] = (char)unicode;
currentX++;
if(currentX == maxColumn - 1) {
newLine();
}
std::cout << "[KEY TYPED] X: " << currentX << " Y: " << currentY << std::endl;
}
}
Thanks in advance :)
Edit: I think i solved. I used KeyPressed event for handling special keys. And TextEntered for handling normal characters.

For those having the same problem:
From an Event type variable, first check if its a keyboard event
if(event.type == sf::Event::KeyPressed)
Then check if its an arrow:
if(event.key.code == sf::Keyboard::Up)
//do stuff
if(event.key.code == sf::Keyboard::Down)
//do stuff

Related

How do i detect Key release C++

So i am making a software to help me with an arduino project, it is supossed to be like PUTTY. I programed the arduino to play different notes from Q-I(C4-C5) and the software is supossed to play thoes notes but i need to make it detect when the Key is pressed and released, how do i do that? I searched and found something but it is not working like it's supposed to here is the code:
int main(){
int KeyGet;
while(1)
{
KeyGet = getch();
if (GetKeyState(0x51) & 0x8000)
{
cout<<"key is pressed"<< endl;
}
else if(GetKeyState(0x51)& 0x0001)
{
cout<<"key is released"<< endl;
}
}
return 0;
The program just prints "key is pressed" when i press Q(0x51) and not "key released" as it should, insted it prints "key released" when i press something else other the Q. And i tried GetAsyncKeyState and tried
If (GetKeyState(0x51) != 0)
it still doesent work.
GetKeyState() requires a window and a message loop to keep the state machine updated. But you do not have a message loop. Also, getch() would swallow any key press+release anyway.
Also, GetKeyState(0x51) & 0x0001 is not the right way to detect a key release. That bit is meant for detecting the toggle state of togglable keys like CapsLock, etc.
In your example, you would need to get rid of getch() and use GetAsyncKeyState() instead, eg:
int main(){
bool down = false;
while (1) {
if (GetAsyncKeyState(0x51) < 0) {
if (!down) {
down = true;
cout << "key is pressed" << endl;
}
}
else {
if (down) {
down = false;
cout << "key is released"<< endl;
}
}
Sleep(0);
}
return 0;
}
Otherwise, you can use a WH_KEYBOARD[_LL] hook via SetWindowsHookEx() instead, so you can receive actual key down/up notifications in real-time.

How to implement input without enter in C++ console game

I am stuck with the input with no enter input.
I tried to use kbhit() + getch() from conio.h and it doesn't work on my system (Win10 and Ubuntu - unistd.h and termios.h). Program just skips block with these functions.
Then I used GetAsynkKeyState from windows.h. It works in the game (Level) though buggy, but doesn't in a Menu. Program as well skips (or something) block with input dispatch.
Menu input:
// The menu interface
bool Menu::SelectLevel() {
cout << "Select the level:" << endl;
size_t arrow_pos = 0;
// Prints level's names and char to exit the game
for (size_t i = 0; i <= _levels.size(); ++i) {
// Draw arrow before selected level
if (i == arrow_pos) {
cout << '>' << i + 1 << " - " << _levels[i].first[0] << endl;;
}
// Draw arrow before the exit select
else if (i == _levels.size() && i == arrow_pos) {
cout << '>' << "Exit" << endl;
}
// Draw the exit option
else if (i == _levels.size()) {
cout << ' ' << "Exit" << arrow_pos << endl;
}
// Draw levels list
else {
cout << ' ' << i + 1 << " - " << _levels[i].first[0] << endl;
}
}
// Input from keyboard TODO DOESN'T WORK!:
// If 's' pressed move arrow down
PoollingDelay(1);
if (GetAsyncKeyState(0x53) & 0x8000) {
++arrow_pos;
// If arrow reached top it goes to the bottom
if (arrow_pos == _levels.size() + 1) {
arrow_pos = 0;
}
}
// If 'w' pressed move arrow up
else if (GetAsyncKeyState(0x57) & 0x8000) {
--arrow_pos;
// If arrow reached bottom it goes to the top
if (arrow_pos == 65535) {
arrow_pos = _levels.size() + 1;
}
}
// If Return pressed
else if (GetAsyncKeyState(VK_RETURN) & 0x8000) {
// Don't think it would be worthy
if (arrow_pos < 1 || arrow_pos > _levels.size() - 1) {
throw runtime_error("Wrong select: " + to_string(arrow_pos));
}
// If player tired of this shit
if (arrow_pos == _levels.size() - 1) {
ClearTerminal();
return false;
}
// Play
PlayLevel(arrow_pos);
}
ClearTerminal();
return true;
}
Level input:
// TO DO DOESN'T WORK!:
void Level::ReadCommand() {
PoollingDelay(100);
if (GetAsyncKeyState(0x57)) {
Move(_NORTH);
}
else if (GetAsyncKeyState(0x41)) {
Move(_WEST);
}
else if (GetAsyncKeyState(0x53)) {
Move(_SOUTH);
}
else if (GetAsyncKeyState(0x44)) {
Move(_EAST);
}
else if (GetAsyncKeyState(0x45)) {
throw runtime_error(exit_the_lvl);
}
}
Short answer: you can't using only C++ and its standard library.
This is because the language is not designed to handle low-level hardware events. To do this, you need to rely on a separate library, dedicated to handle I/O. Lots of them, some are more or less easy to integrate. For simple games, SDL is nice.

Scrolling Menu is Not Working in c++

This is the code for my scrolling menu where it display different values based on the 3 vectors, welcomeMenuVector, menuOptionsVector and menuActionVector:
welcomeMenuVector - Save function of title
menuOptionsVector - Save menu options of scrolling menu
menuActionsVector - Save the functions to perform after the menu option is selected
vector<string> menuOptionsVector;
vector<function<void()>> menuActionsVector;
vector<function<void()>> welcomeMenuVector;
void scrollingMenu(){
ShowConsoleCursor(false);
int pointer = 0;
while (true){
system("cls");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
welcomeMenuVector[0]();
for (unsigned int i = 0; i < menuOptionsVector.size(); ++i){
if (i == pointer){
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 14);
cout << center("> " + menuOptionsVector[i] + " <" ,getWindowWidth()) <<endl;
}
else{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
cout << center(" " + menuOptionsVector[i] + " ", getWindowWidth()) << endl;
}
}
while (true){
if (GetAsyncKeyState(VK_UP) != 0){
pointer -= 1;
if (pointer == -1){
pointer = menuOptionsVector.size() - 1;
}
break;
}
else if (GetAsyncKeyState(VK_DOWN) != 0){
pointer += 1;
if (pointer == menuOptionsVector.size()){
pointer = 0;
}
break;
}
else if (GetAsyncKeyState(VK_RETURN) != 0){ //when enter key is pressed
menuActionsVector[pointer]();
}
}
Sleep(100);
}
}
I will need to enter menu title, menu options and menu functions into vector before I need to call the scrollingMenu(). Hence, I will have to clear all the 3 vectors before entering values into vectors because there will be values inside as it might be used by another menu earlier.
This is my main page, user page and add user page:
void mainPage(){
clearMenuVectors();
welcomeMenuVector = { [](){mainPageWelcome(); } };
menuOptionsVector = { "Login", "Exit" };
menuActionsVector = {
[](){ userPage(); },
[](){ exit(0); }
};
scrollingMenu();
}
void userPage(){
clearMenuVectors();
welcomeMenuVector = { [](){userPageWelcome(); } };
menuOptionsVector = { "Add User", "Update User", "Delete User", "Exit" };
menuActionsVector = {
[](){ addUsers(); },
[](){ updateUsers(); },
[](){ deleteUsers(); },
[](){ exit(0); }
};
scrollingMenu();
}
void addUsers(){
clearMenuVectors();
welcomeMenuVector = { [](){cout << center("Which type of user would you like to add?", getWindowWidth()) << endl;; } };
menuOptionsVector = { "Add Admin", "Add Scheduler", "Add Professional", "Exit" };
menuActionsVector = {
[](){ /*addUser();*/ },
[](){ /*updateUsers();*/ },
[](){ /*deleteUsers();*/ },
[](){ exit(0); }
};
}
My main page works fine at first, I'm able to move up & down, after hitting enter on the Login menu option, it goes to the userPage, but here comes the problem, when I'm in the userPage, I can still see the menu options of userPage, but when I just move up/down it will then changed the menu options of addUsers (I haven't even hit the enter), even if I dont move up/down I hit enter on Add User option, nothing happens, I'm not sure what is the problem here.
If you change
[](){ /*addUser();*/ },
to
{ cout << "add user option 1" << endl; },
and it writes it continuously then the key is pressed.
GetAsyncKeyState
whether the key is currently up or down. If the most significant bit
is set, the key is down, and if the least significant bit is set, the
key was pressed after the previous call to GetAsyncKeyState.
So you need to check the least significant bit. In this case
if (GetAsyncKeyState(VK_RETURN) != 0)
should be
if (GetAsyncKeyState(VK_RETURN) & 0x1)

How can I detect when a key has been released (SDL 2.0)

I'm having issues detecting when a key has been released. If I were to call:
csdl_setup->GetMainEvent()->key.keysym.sym == SDLK_UP
SDLK_UP would not be true for around 2-3s which is inefficient for a keyboard driven menu. I want to be able to scroll through my menu easily in SDL.
Can anybody help me?
SDL_Event event;
while (SDL_PollEvent(&event) && event.key.repeat == 0 && some_sprite->GetY() == coords[1] && event.type == SDL_KEYDOWN)
{
some_sprite->SetY(coords[1] + 20);
}
SDL_PollEvent(&event);
if (event.key.repeat == 0 && some_sprite->GetY() == coords[3])
{
if(some_sprite->GetY() == coords[3] && event.type == SDL_KEYDOWN)
{
some_sprite->SetY(coords[3] + 20);
}
cout << "Event Key Repeat = " << event.key.repeat << endl;
}
You should be handling events as they come. Your code uses multiple calls to SDL_PollEvent() and even short-circuits the polling in some cases.
Move all of your event handling code into the while loop. Remove the additional checks on the while loop so you stay in the loop until all events are processed.
A quick modification of your code might look something like this:
SDL_Event event;
while (SDL_PollEvent(&event))
{
if(event.type == SDL_KEYDOWN)
{
if(event.key.repeat == 0)
{
if(some_sprite->GetY() == coords[1])
some_sprite->SetY(coords[1] + 20);
else if(some_sprite->GetY() == coords[3])
some_sprite->SetY(coords[3] + 20);
}
cout << "Event Key Repeat = " << event.key.repeat << endl;
}
}

destroyWindow (from opencv) closes all windows and stops c++ program

I'm writing an live video processing program in c++, and want to be able to toggle three windows with the same mjpeg stream, in color, grayscale, and monochrome. I have all the image feeds running, but, since my screen is small, I want to be able to toggle them on and off individually. To do this, I have written the code below, but calling destroyWindow("[windowname]"); stops the whole program, instead. I've already read the documentation, and putting void in front of it doesn't help. Can anybody tell me what I'm doing wrong?
Here's the code (it's in an infinite loop, until the break you see below is called):
imshow("Color", imageColor);
imshow("Monochrome", imageMonochrome);
imshow("Grayscale", imageGrayscale);
int keyPressed = waitKey(0);
if (keyPressed > 0)
{
cout << keyPressed;
cout << "key was pressed\n";
// Press C to toggle color window
if (99 == keyPressed)
{
if (colorOpen)
{
cout << "Color window closed\n";
void destroyWindow("Color");
colorOpen = false;
}
if (!colorOpen)
{
cout << "Color window opened\n";
imshow("Color", imageColor);
colorOpen = true;
}
}
// Press M to toggle monochrome window
if (109 == keyPressed)
{
if (monochromeOpen)
{
cout << "Monochrome window closed\n";
void destroyWindow("Monochrome");
monochromeOpen = false;
}
if (!monochromeOpen)
{
cout << "Monochrome window opened\n";
imshow("Monochrome", imagebw);
monochromeOpen = true;
}
}
// Press G to toggle grayscale window
if (103 == keyPressed)
{
if (grayscaleOpen)
{
cout << "Grayscale window closed\n";
void destroyWindow("Grayscale");
grayscaleOpen = false;
}
if (!grayscaleOpen)
{
cout << "Grayscale window opened\n";
imshow("Grayscale", image);
grayscaleOpen = true;
}
}
// Break out of infinite loop when [ESC] is pressed:
if (27 == keyPressed)
{
cout << "Escape Pressed\n";
break;
}
}
The code you pasted terminates after calling destroyWindow (by running off the end of main). If that's not what you want to happen, write code that does something else after calling destroyWindow. Perhaps you want a loop?