I am trying to build a simple tetris game within the terminal. I need to move the pieces when the player presses an arrow key. I heard about the getch() method but it doesn't seem to work with arrow keys (they were all detected with the same int code: 27). What should I do?
Here is my current code:
initscr();
int inputCode;
do
{
inputCode = getch();
// here I would put my code to move the pieces if the code is right
} while (inputCode != 113); // q to exit
endwin();
Sincerely,
Thomas
The as noted in the manual page:
Most programs would additionally use the sequence:
intrflush(stdscr, FALSE);
keypad(stdscr, TRUE);
That is, your program should turn on keypad mode to get KEY_UP, etc:
The keypad option enables the keypad of the user's terminal. If enabled (bf is TRUE), the user can press a function key (such as an arrow
key) and wgetch(3x) returns a single value representing the function
key, as in KEY_LEFT. If disabled (bf is FALSE), curses does not treat
function keys specially and the program has to interpret the escape sequences itself. If the keypad in the terminal can be turned on (made
to transmit) and off (made to work locally), turning on this option
causes the terminal keypad to be turned on when wgetch(3x) is called.
The default value for keypad is FALSE.
Related
After typing
int func(){
And pressing enter I'm getting like this , since I have enabled auto close plugin
int func(){
//cursor stays here }
But what i need is
int func(){
//cursor stays here
}
I'm able to achieve the required indentation by changing snippets.conf, but I have to press c and Tab, where
c=%brace_open%%cursor%%brace_close%
brace_open={\n\t
brace_close=\n}\n
Auto-close plugin settings:
is there any other way of achieving ?? Thanks in advance.
I haven't been able to figure out how to get exactly what you've indicated, but the Autoclose plugin can get close. Typing int func(){ and pressing Enter gives the following, where the | character represents the cursor location:
int func(){
|
}
EDIT:
My Autoclose settings are as shown below. But that turns out not to be the whole story. See after the image for more.
While looking into this some more, I discovered some strange behavior. I don't know if it's at the root of your problem or not, but it's maybe something to consider.
Autoclose worked as I described when pressing Enter on the main keyboard, but not when pressing Enter on the keypad, with or without NumLock enabled. In the latter case, I got the same result you did.
I normally use an antique IBM Model M keyboard, so to eliminate any chance of the problem being caused by the keyboard itself, I tried a modern USB keyboard with keypad. The results were exactly the same.
Having a suspicion as to what was happening, and since it's open source, I pulled down the Autoclose source code and took a look. And found...
static gboolean
auto_close_chars(
AutocloseUserData *data,
GdkEventKey *event)
{
...
else if (ch == GDK_Return)
{
return improve_indent(sci, editor, pos);
}
...
}
A general search for GDK_Return turned up gdkkeysyms.h that defines all of the GDK key codes. In that, there's GDK_Return and also GDK_KP_Enter, where "KP" means "keypad". Since Autoclose doesn't recognize GDK_KP_Enter, it'll fail to respond to pressing Enter on the keypad.
So, if you're using a full keyboard with keypad, it should work ok so long as Enter on the main keyboard is being used. On the other hand, If you're using a laptop where there's only one Enter key, all bets are off.
Check out https://plugins.geany.org/autoclose.html for autoclose plugin. This will solve your problem.
In Linux you can directly install it by
sudo apt-get install geany-plugin-autoclose
I'm making an console application. It starts with a menu where if I press the key; 1. The menu changes into another menu screen. But note, without me pressing 'Enter'. This means that my 1 still remains, which is obviously bad when stepping down further in the menus.
How do I clear the input command line?
The function im using.
if(GetAsyncKeyState('1'))
{
IEventDataPtr gameState(GCC_NEW EvtData_Set_Game_State("PREGAMESTATE"));
em->VTriggerEvent(gameState);
//Enter line clearing code.
}
The function GetAsyncKeyState gives you "the current state of a key". So it will return true between the point when the keyboard driver has received the "key for 1 has been pressed" until the keyboard driver receives "key for 1 has been released".
I would seriously suggest that you use ReadConsoleInput instead if you want to get one keypress at a time.
The alternative is to use something like this:
while(GetAsyncKeyState('1'))
{
// Do nothing.
}
to wait for that key to be released.
I want to write a command line shell for a background program, and in witch I can type some commands. I want to add a feature like the bash (or other shell-like) ---'UP' key to get the historic input. How can I capture the 'UP' key was pressed?
If I just use std::getline(std::cin, line) I can't get the 'UP' key or other function key, ie. Ctrl+w to delete a word of the input line.
There is a readline function that supports history and line editing, etc.
In basic mode it does reading of line, etc. If you want to add hooks, you can make it expand commands when pressing tab or similar.
This is what your typical shell in Linux uses.
Documentation here:
http://web.mit.edu/gnu/doc/html/rlman_2.html
An example here:
http://www.delorie.com/gnu/docs/readline/rlman_48.html
Main project page:
http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html
Use kbhit() to get Keyboard Arrow Keys
Use ncurses library, see sample program:
#include<ncurses.h>
#include<iostream>
int main()
{
int ch;
initscr(); //initialize the ncurses data structures
keypad(stdscr,TRUE); //enable special keys capturing
ch=getch();
if(ch==KEY_UP)
std::cout << "Key up pressed!" << std::endl;
}
I have a section of code as such:
while (true) {
if(_kbhit()) {
cout << "keypressed";
exit(1);
}
for testing purposes to get the _kbhit() section working
The program takes arrow key input using GetAsyncKeyState() and in the case that the Shift key is pressed it runs this portion of code.
If i DONT press any arrow keys before i press shift to call this portion of code, then _kbhit evaluates to false as expected.
The problem is this, if i press an arrow key before i press shift to call this portion of code, "keypressed" is output even though no keys have been pressed since calling this portion of code.
Is kbhit somehow picking up the previous arrow key strokes? Do i need to clear an input buffer or something?
I am making Pacman in C++ with the Ncurses library. I am able to move Pacman with my code, but I want to move it so that pacman keeps moving even when I am not pressing any key and when I press another direction key, it changes direction. Right now, the pacman only takes one step when I press a key. Also I have to press a key 2 or 3 times before pacman moves in that direction.
if (ch==KEY_LEFT)
{
int b,row,column;
getyx(stdscr,row,column);
int h;
do // do-whileloop to move the pacman left until it hits the wall
{
column-=1;
mvprintw(row,column,">"); //print the ">" symbol
refresh();
waitf(0.1); //this pauses the game for 0.1sec
attron(COLOR_PAIR(1));
mvprintw(row,column,">");
attroff(COLOR_PAIR(1));
refresh();
waitf(0.1);
mvprintw(row,(b),"O"); //showing the open mouth of pacman
refresh();
waitf(0.1);
attron(COLOR_PAIR(1));a
mvprintw(row,column,"O");
attroff(COLOR_PAIR(1));
h = getch();
}
while(h == KEY_LEFT);
}
right = getch();
loop to move right in an if condition
up = getch();
loop to move up in an if condition
down = getch();
oop for moving down in an if condition.
The standard solution to this is the finite-state machine. The character has six or so possible states: standing, moving up, moving right, moving down, moving left, dead. Rather than a keypress directly moving the character, the keypress should change the character's state.
In such a small application, rather than implementing an incredibly flexible finite-state machine, you may use a very simple implementation as such:
enum PlayerState {
Standing,
MovingUp,
MovingRight,
MovingDown,
MovingLeft,
Dead
};
Then, inside your game loop you can add a very simple state check which then takes the appropriate action for the frame.
switch(state) {
case Standing:
break;
case MovingUp:
player.PositionY += 1;
break;
// ...
}
The last step is to hook input, which depends on your method of retrieving input. Using callbacks, an example is:
void KeyDown(Key k) {
switch(k) {
case UpArrow:
if(state != Dead)
state = MovingUp;
break;
case RightArrow:
if(state != Dead)
state = MovingRight;
// ...
}
}
You can see why in a larger project it would be important to implement a more flexible finite-state machine, but hopefully this example has given you an easy-to-understand idea.
You need an equivalent of kbhit, ie. a non-blocking getch. Which really gives the solution, set O_NONBLOCK on the input. See an example here. Once you have this, simply loop contiguously and just check for the key hit, w/o waiting on actual key press.
Function getch is blocked until some key is pressed. If you don't want to be blocked then call _kbhit before getch too make sure that there is something in input buffer.
EDIT: Take a look at ncurses functions nodelay and cbreak. They enable asynchronous input.
I suggest you take a look at the model-view-controller model, it will help you with this problems and all the other problems that you will have if you continue your program like this.
Edit: shortcut
To move your pacman continuously you will need a separate thread to control it and make it move. Take a look at pthreads for that.
If you keep only the user input in the main run loop of your program, the problem that you have to press the keys a few times will go away too (the problem here is that the processor has to be on the getch() line when you press the key, otherwise it will not be detected.
It is pretty easy
for each direction make 4 function
and inside the function,put in the other 3 direction function which get activated by kbhit.
and put a else statement in which it keeps moving forward if you do not hit a button i.e (!kbhit());
and then put all this in a loop.
If you do this for all the direction functions you should be able to get the desirable outcome.