I'm new to C++. Have decided to do my own game. And i want to make a starting screen for it. And the problem is that i havent found the way to make an "Press any key to continue" function while dots continue. I made the loop for the programm to wait till any would be pressed but dots dont want to display in.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <stdlib.h>
#include <windows.h>
using namespace std;
int pressCheck(){
char c = 0;
c = getchar();
if (c == 0)
return 1;
return 0;
}
int main()
{
cout << "\t\t\t\t Hello" << endl;
Sleep(300);
cout << "\t\t Welcome to my new game BITHCES!" << endl << endl;
Sleep(700);
cout << "\t\t\tPress any key to proceed";
while(!pressCheck()){
Sleep(300);
cout << ".";
Sleep(300);
cout << ".";
Sleep(300);
cout << ".";
}
getchar();
system("cls");
Sleep(100);
return 0;
}
If you are creating a text based game I would recommend using ncurses (or pdcurses for windows):
[...] a toolkit for developing "GUI-like" application software that runs
under a terminal emulator.
Implementing what you have above would be something like
#include <string>
#include <ncurses.h> // This header might be different on windows
#include <unistd.h> // for usleep, replace with Windows.h (?)
void DisplayCentre(int yy, const std::string& str)
{
// Get the screen size
int y, x;
getmaxyx(stdscr, y, x);
// Compute starting location for string (centre)
x = (x - str.size())/2;
// Write the string to the window
mvwprintw(stdscr, yy, x, str.c_str());
// Make sure the screen is updated
refresh();
}
void PromptForKey(void)
{
// Get the screen size
int y, x;
getmaxyx(stdscr, y, x);
// Write a message at the bottom left of the screen
mvwprintw(stdscr, y-1, 0, "Press any key to continue");
// Set a time-out for wgetch
wtimeout(stdscr, 300);
// While the user hasn't entered a character
while (wgetch(stdscr) == ERR)
{
// Add another dot to the screen
waddch(stdscr, '.');
refresh();
}
// Clear time-out
notimeout(stdscr, true);
}
int main(int argc, char** argv)
{
initscr(); // Initialize curses
cbreak(); // Make typed characters immediately available
noecho(); // Don't automatically print typed characters
curs_set(0); // Make the cursor invisible (where supported)
// Display `Hello' (at line 10)
DisplayCentre(10, "Hello");
// Delay (you might want to use Sleep())
sleep(1);
// Display `Welcome to my new game' (at line 15)
DisplayCentre(15, "Welcome to my new game");
sleep(1);
// Prompt user for key
PromptForKey();
// Close down curses
endwin();
return 0;
}
To compile this program on Linux I use g++ test.cpp -lncurses. On windows you will probaly need to replace sleep with the windows Sleep function and use the appropriate header. You may also need to use an alternative to ncurses.
However, if you are just learning to program I would suggest you try using ncurses in Python. Python has the benefit of being an interpreted language so you don't need to worry too much about compiling or linking executables. Python is also mostly cross platform. The above implemented in Python:
#!/usr/bin/python
from curses import *
from time import sleep
def promptForKey(win):
""" Ask the user to press any key to continue. """
# Get screen size
y,x = win.getmaxyx()
# Display prompt
win.addstr(y-1, 0, "Press any key to continue")
win.refresh()
# Set time-out
win.timeout(300)
while (win.getch() == ERR):
win.addch('.')
# Disable time-out
win.notimeout(True)
def dispCentre(win, yy, string, delay):
""" Display string at line yy and wait for delay milliseconds. """
# Get screen size
y,x = win.getmaxyx()
# Display string in centre
x = (x - len(string))/2
win.addstr(yy, x, string)
win.refresh()
# Delay
sleep(delay)
if __name__ == '__main__':
# Initialize curses
win = initscr()
cbreak()
noecho()
curs_set(0)
# Display some stuff
dispCentre(win, 10, "Hello", 0.3)
dispCentre(win, 15, "Welcome to my new game", 0.7)
promptForKey(win)
# Close down curses
endwin()
i know i am late but i think maybe you wanted to do this? (Run the attached code)
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <stdlib.h>
#include <windows.h>
#include<conio.h>
using namespace std;
bool pressCheck(){
if (getch())
return 1;
return 0;
}
int main()
{
cout << "\t\t\t\t Hello" << endl;
Sleep(300);
cout << "\t\t Welcome to my new game BITHCES!" << endl << endl;
Sleep(700);
cout << "\t\t\tPress any key to proceed";
while(!pressCheck()){
Sleep(300);
cout << ".";
Sleep(300);
cout << ".";
Sleep(300);
cout << ".";
}
system("cls");
Sleep(100);
return 0;
}
Related
I've been searching for a while, and I don't achieve to find any way to get the input keys of my keyboard, to use them in my program...
Context : I'm starting on robotics, and C++, and I'd simply like to command a motor.
The idea is that "if I press the up arrow, the motor turns, if I press the down arrow, the motor stops" and that's it, no need to validate something or anything like that...
I am with raspbian, through VNC (controlling from my real computer), and the actual code is executed in the terminal.
I'll see later on to make that more complex.
I went through 20 or more pages and didn't find anything helpful... Isn't there an easy way to do something that seems so basically useful?
Some spoke about conio library, but apparently it's outdated, curses/ncurses took its place,but I didn't achieve to find/have anything working...
http://www.cplusplus.com/forum/general/74211/
Create a function to check for key press in unix using ncurses
Capture characters from standard input without waiting for enter to be pressed
This is apparently C code, and not C++, moreover, I don't really understand that...
How to detect key presses in a Linux C GUI program without prompting the user?
This, maybe? But it makes no sense to me (beginner in C++)
How can I get the keyboard state in Linux?
here they speak of "allegro", but apparently, it don't work on the PI 45 yet... and no idea how to install that anyway
http://www.cplusplus.com/forum/general/47357/
Does someone knows a simple little code that I can copy-past to do that, or any way? I'm quite shocked to not have something similar to windows C++ programming where it seems so simple
I mean something like "Keyboard.GetKeyStates(Key)"
I'll continue my research anyway, but please, help !
EDIT :
Apparently, the library SDL (SDL2) can help me do this...
I tried to implement it, it doesn't give any result...
Here is the code I got up to now (I deleted a good part that is useless in here), basically, it's a copy-past from internet SDL official web page :
#include <iostream>
#include <wiringPi.h> //Raspberry pi GPIO Library
#include <cstdio>
#include <csignal>
#include <ctime>
#include <chrono> //library for counting time
#include <thread> //for "this thread sleep"
#include <SDL2/SDL.h> //for getting the keyboard buttons events
bool RUNNING = true; // global flag used to exit from the main loop
/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
GPIO Pins definition
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
int SPser = 13, SPclk = 19, SPrclk = 26; //Define the output pins used
int Optocoupler = 17; //define the input pins used
/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
SDL definition
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
//void PrintKeyInfo( SDL_KeyboardEvent *key );
//void PrintModifiers( SDLMod mod );
//SOME CODE
// Callback handler if CTRL-C signal is detected
void my_handler(int s) {
std::cout << "Detected CTRL-C signal no. " << s << '\n';
RUNNING = false;
}
//###################################################################################
int main(int argc, char *args[]) {
// Initialize wiringPi and allow the use of BCM pin numbering
wiringPiSetupGpio();
//Initialize SDL
if (SDL_Init(SDL_INIT_EVENTS) != 0) {
SDL_Log("Unable to initialize SDL: %s", SDL_GetError());
return 1;
}
else
{
SDL_Log("SDL initialized");
}
SDL_Event event;
// Register a callback function to be called if the user presses CTRL-C
std::signal(SIGINT, my_handler);
while(RUNNING)
{
while( SDL_PollEvent( &event ) )
{
std::cout << "SDL While \n" << '\n';
//When the user presses a key
switch( event.type )
{
case SDL_KEYDOWN:
std::cout << "Key press detected \n" << '\n';
//printf( "Key press detected\n" );
break;
case SDL_KEYUP:
std::cout << "Key release detected \n" << '\n';
//printf( "Key release detected\n" );
break;
default:
break;
}
}
//std::cout << "Works??" << '\n';
/*for( i = 0; i <= 15; i++ )
{
//std::cout << "data input i =" << i << '\n';
if (i==0){
//std::cout << "if array " << i << '\n';
DataArr[i]=1;
DataArr[15]=0;
}
else{
j=i-1;
DataArr[j]=0;
DataArr[i]=1;
//std::cout << "in else i" << i << " and j " << j << '\n';
}
SendData(DataArr);
}*/
}
std::cout << "Program ended ...\n";
}
As I followed "dumbly" the tutorial, this should work, but the while loop is never entered as the "std::cout << "SDL While \n" << '\n';" is never shown...
But, as it achieve to compile, I guess the SDL library was installed correctly and things work...
When executing the code, it writes "SDL initialized", then, nothing... pressing keys do nothing
I'm still not sure how to check if the library is installed correctly, but when I type in de command prompt "sudo apt-get install libsdl2-dev", it shows a few lines and says "0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded"
If you are on linux, you should use termios to stop the buffering
#include <termios.h>
void set_no_buffer()
{
struct termios term;
tcgetattr(0, &term);
term.c_lflag &= ~ICANON;
tcsetattr(0, TCSANOW, &term);
}
and then getchar() to get a character without entering
I have installed the ncurses.h lib and started experimenting with the getch() function.When I built and run this code which seems alright to me at first, the console printed out a weird character: '�'(if it doesn't show and shows as a space here is a screen shot: https://prnt.sc/gbrp7b) The console starts spamming it but if I type a character, it shows up in the output but still the '�' spams. Here is the code:
#include <iostream>
#include <fstream>
#include <ncurses.h>
using namespace std;
int main(){
char input;
while(true){
input = getch();
cout << "You entered : " << input << endl;
//break;
}
return 0;
}
So I thought of trying to use an if statement to try and stop it spamming but the code doesn't recognise the character:
It gives this error:
error: character too large for enclosing character literal type
For this code:
#include <iostream>
#include <fstream>
#include <ncurses.h>
using namespace std;
int main(){
char input;
while(true){
input = getch();
if(input!='�'){
cout << "YOu entered : " << input << endl;
}
}
return 0;
}
I am on OSX Sierra 10.12.5 and using eclipse Oxygen
You need to initialize ncurses with initscr() and close it with endwin() functions:
#include <iostream>
#include <fstream>
#include <ncurses.h>
using namespace std;
int main(){
char input;
initscr();
while (true) {
input = getch();
cout << "YOu entered : " << input << endl;
}
endwin();
return 0;
}
FLTK is a callback based GUI system but there are times that I need a user to input an acceptable answer into a Fl_Input widget before a function can return.
This seems to require updating the widget, collecting the answer then returning the answer if it is valid.
So, in essence let's say I have a function called int get_int(Fl_Input i). This function needs to continually update the Fl_Input, validate the contents by attempting to cast the value() to an int, clear Fl_Input if the validation fails, and finally return the cast int from the function. This validation should happen on the press of enter key. (I plan to also have functions to return cast strings and floats but they'll work the same way)
This is actually part of a scripting system and FLTK is the GUI. The embedded language is waiting to get a proper int from my Fl_Input but FLTK can't update and process events because it has not completed the main loop. I can't easily do this via normal FLTK callbacks it seems because they must return void and I'll have many types of casting and validation on my single input depending on the context of the object reading from it.
Thanks to anyone who can help me!
EDIT here is some rough example code of what I need.
Embeddable Common Lisp needs to wrap the get_int function but I'm not sure how to update all widgets with an interrupt and also break the loop with a callback which can't affect the loop directly. (boolean flag maybe?)
#include <iostream>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <Fl/Fl_Input.H>
#include <Fl/Fl_Button.H>
#include <stdexcept>
int get_int(Fl_Input* i)
{
int temp = 0;
while(True)
{
// not sure how to update here
// at this point, button and field need to update
// also somehow validate needs to be done on Enter button press
// but callbacks can't interact with this part of the code directly
// to validate and end the loop here
try
{
temp = std::stoi(i->value());
}
catch(...)
{
std::cout << "Invalid conversion to int" << i->value() << std::endl;
i->value("");
}
}
return temp;
}
void field_callback(Fl_Widget * w, void *d)
{
// This callback simulates Embeddable Common Lisp calling wrapped get_int
// Once a number is valid, it is converted and passed to back to Lisp
int something = get_int((Fl_Input*)w);
std::cout << something << std::endl;
}
int main()
{
Fl_Window *w = new Fl_Window(200, 32);
Fl_Input *i = new Fl_Input(0, 0, 128, 24, "");
Fl_Button *b = new Fl_Button(128, 0, 32, 24, "Simulate Request");
b->callback(field_callback);
w->show();
return(Fl::run());
}
Well after some help on FLTK's mailing list I've composed an example for those looking to do a similar thing. This was just off the cuff and might be buggy for production use. Be sure to debug and not copy/paste directly.
#include <FL/Fl.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
#include <string>
#include <iostream>
Fl_Window* win = new Fl_Window(240, 128, "Loop n Prompt");
Fl_Button* button = new Fl_Button(5, 5, 128, 24, "Simulate Prompt");
Fl_Input* input = new Fl_Input(5, 96, 230, 24, "");
Fl_Box* prompt_msg = new Fl_Box(5, 48, 230, 24, "");
std::string get_input(const char* prompt, Fl_Input *input)
{
// Lock all widgets not pertaining to field here
button->deactivate();
prompt_msg->label(prompt);
// Open up the input for value entry
input->readonly(false);
input->activate();
while(! input->readonly())
{
Fl::wait();
}
// other groups activate here
button->activate();
// Have a funny feeling about c -> std::string conversion double check...
std::string return_string = input->value();
// Reset input and prompt to ""
input->value("");
prompt_msg->label("");
return return_string;
}
void input_CB(Fl_Widget *w, void* data)
{
Fl_Input* ptr = (Fl_Input*)w;
ptr->readonly(true);
}
void button_CB(Fl_Widget *w, void* data)
{
// Simulate something needing these values RIGHT NOW
std::cout << "Got " << get_input("Please enter name", input) << std::endl;
std::cout << "Got " << get_input("Please enter mother's name", input) << std::endl;
std::cout << "Got " << get_input("Please enter father's name", input) << std::endl;
// Now try a standard loop until thing
std::string password = "";
while(password != "password")
{
password = get_input("You must enter 'password'", input);
}
std::cout << "Nice job you answered correctly to exit the loop!" << std::endl;
}
int main()
{
// Callback setup
input->callback((Fl_Callback*)input_CB);
button->callback((Fl_Callback*)button_CB);
// Entry field does callback when enter key pressed
input->when(FL_WHEN_ENTER_KEY_ALWAYS);
// Show the window and all children
win->show();
return(Fl::run());
}
How would I effectively cancel a call for user input if there is no input within a certain time? (I'm programming a game for a terminal/cmd window with Mac OS X).
I have tried turning off canonical buffering and using a timer thread that joins after the call for user input. I also tried implementing the call to pthread_join() within the parameters of the while loop. Still nothing. The problem is that even though canonical buffering is off, the call for user input is still held up when there is no input. It works fine if there is input though.
It would be great if I could do this without fiddling around with downloading and installing ncurses, but I'll do it if I have to.
Edit: Source code:
//Most headers only pertain to my main program.
#include <iostream>
#include <termios.h>
#include <pthread.h>
#include <time.h>
#include <cstring>
#include <stdio.h>
#include <string.h>
using namespace std;
//Timer function.
void *Timer(void*) {
time_t time1, time2;
time1 = time(NULL);
while (time2 - time1 < 1) {
time2 = time(NULL);
}
pthread_exit(NULL);
}
int main() {
//Remove canonical buffering.
struct termios t_old, t_new;
tcgetattr(STDIN_FILENO, &t_old);
t_new = t_old;
t_new.c_lflag &= ~ICANON;
tcsetattr(STDIN_FILENO, TCSANOW, &t_new);
cout << "Press any key to continue." << endl;
string szInput;
int control = 0;
do {
pthread_t inputTimer;
pthread_create(&inputTimer, NULL, Timer, NULL);
szInput = "";
while (szInput == "") {
szInput = cin.get();
//Handle keypresses instantly.
if (szInput == "a") {
cout << endl << "Instant keypress." << endl;
}
}
pthread_join(inputTimer, NULL);
cout << endl << "One second interval." << endl;
control ++;
} while (control < 25);
cout << "Game Over." << endl;
return 0;
}
See if this works!
char ch; //Input character
int time = 0; //Time iterator
int TIMER = 5000; //5 seconds
while(time<TIMER)
{
if(!kbhit())
{
time = 0;
ch = getch();
//Do your processing on keypress
}
time++;
delay(1);
}
kbhit() detects if any keystroke has occurred. If yes, then get the key character in ch.
One way of checking if there is input is to poll the file descriptor STDIN_FILENO using e.g. the select system call. If STDIN_FILENO is readable, then you can read at at least one character. You can also pass a timeout to the select call.
Thanks Shashwat, it works with the below modifications:
1) Changing if(!kbhit()) to if(kbhit())
2) Changing delay(1); to Sleep(1);
I do not have enough rep to post a comment, hence adding as an answer.
I'm trying to display a video file at 25fps smoothly without any lag. The code below does this, but only achieves about 10fps, taking about 0.1ms to execute. With cvWaitKey(1) I get around 0.03 to 0.04ms, which would be perfect, but the named window just stays grey and doesn't show the video!
Is this because cvShowImage() is too slow? Is there any other way to speed up the code and output the video smoothly?
See my code below.
Thanks a lot in advance,
Adrian
#include <cv.h>
#include <iostream>
#include <highgui.h>
#include <cxcore.h>
#include <cvaux.h>
#include <sstream>
#include <time.h>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
CvCapture* vid = 0;
IplImage* input; //Input image
int fps;
int i=0;
clock_t start, end;
/*Creates the GUI to output the processed images*/
cvNamedWindow("Video input", 0);
/*Open input video*/
if (argc!=2)
{
cout << "Please specify an input video." << endl;
return -1;
}
else
{
vid=cvCreateFileCapture(argv[1]);
if (!vid)
{
cout << "Could not extract frame." << endl;
return -1;
}
}
input = cvQueryFrame(vid);
fps = (int)cvGetCaptureProperty(vid, CV_CAP_PROP_FPS);
cout << fps << endl;
cout << "Video found." << endl;
/*Extraction loop */
while (input)
{
start = clock();
cout << flush;
cout << i << "\r";
i++;
/*Show image*/
cvShowImage("Video input", input);
cvWaitKey(2); //Wait is needed or else we see a grey box
input = cvQueryFrame(vid); //Read next frame from video
end = clock();
cout << (double)(end-start)/CLOCKS_PER_SEC << " s" << endl;
};
/*Release the allocated memory for the frames */
cvReleaseImage(&input);
cvDestroyWindow("Video input");
return 1;
}
Have you tried this without all the cout stuff?
The debug build of the Microsoft STL has cout handling which is almost unbelievably slow.
Try calling cvWaitKey with 1000 / fps wanted, in your case :
cvWaitKey(1000/25)
You could try something like:
char key = cvWaitKey(10); //waits 10 milliseconds
if (key == 27) //and if ESC is pressed, get out of the loop
break;