[C++]Rilevare la pressione di un tasto

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
carru93
Prode Principiante
Messaggi: 7
Iscrizione: giovedì 2 giugno 2016, 11:40
Desktop: ubuntu
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile

[C++]Rilevare la pressione di un tasto

Messaggio da carru93 »

Salve, sono un autodidatta di c++, ultimamente ho avuto il bisogno di rilevare la pressione di un tasto(penso si faccia con degli eventi), in particolare avrei bisogno di aiuto con questo programma:

Codice: Seleziona tutto

#include <iostream>
#include <cstdlib>
#ifdef _win32_
#define cls "cls"
#else
#define cls "clear"
#endif
#define rows 5
#define columns 6
using namespace std;

int main(){
	int y=4,x=1;
	char moveChar;
	char griglia [rows][columns]={/*0° riga*/{'x','x','x','x','x',},/*1° riga*/{'x','x','x','x','x'},{'x','x','x','x','x'},{'x','x','x','x','x'},{'x','x','x','x','x'}};
	griglia[y][x]='0';
	while(true){
		system(cls);
		cout << griglia[0] << endl;
		cout << griglia[1] << endl;
		cout << griglia[2] << endl;
		cout << griglia[3] << endl;
		cout << griglia[4] << endl;
		cin >> moveChar;
		switch(moveChar){
			case 'w':
				if(y>0){
					griglia[y][x]='x';
					y--;
					griglia[y][x]='0';
					break;
				}else{
				break;	
				}
			case 's':
				if(y<4){
					griglia[y][x]='x';
					y++;
					griglia[y][x]='0';
					break;
				}else{
				break;
				}
			case 'a':
				if(x>0){
				griglia[y][x]='x';
				x--;
				griglia[y][x]='0';
				break;
				}else{
				break;	
				}
			case 'd':
				if(x<4){
				griglia[y][x]='x';
				x++;
				griglia[y][x]='0';
				break;
				}else{
				break;	
				}
			default:
				cout << "grazie per aver giocato!"<<endl;
				return 0;
				break;
			}
		}
	return 1;
	}
è un programma molto semplice che utilizzando i tasti wasd permette all'utente di far "spostare" lo 0, il problema è che ogni volta che voglio far "muovere" lo zero, devo premere il tasto invio.
Sapreste dirmi come fare in modo che ogni volta che premo un tasto esegua l'azione, senza il bisogno di premere invio? (come in un videogioco)
Grazie in anticipo
Avatar utente
crap0101
Rampante Reduce
Rampante Reduce
Messaggi: 8242
Iscrizione: martedì 30 ottobre 2007, 6:33
Desktop: LXDE
Distribuzione: Ubuntu 18.04.1 LTS
Sesso: Maschile
Località: TO
Contatti:

Re: [C++]Rilevare la pressione di un tasto

Messaggio da crap0101 »

termios, ncurses
http://www.gnu.org/ http://boinc.berkeley.edu/ http://www.python-it.org/
- Ricorda le ultime parole di suo padre: «Sta' alla larga dalle chiese, figlio. La sola cosa per cui hanno la chiave è il merdaio. E giurami che non porterai mai un distintivo della legge» - W.S. Burroughs
carru93
Prode Principiante
Messaggi: 7
Iscrizione: giovedì 2 giugno 2016, 11:40
Desktop: ubuntu
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile

Re: [C++]Rilevare la pressione di un tasto

Messaggio da carru93 »

Avatar utente
SuperStep
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 2037
Iscrizione: lunedì 19 dicembre 2011, 16:26
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile
Località: Somma Vesuviana (NA)

Re: [C++]Rilevare la pressione di un tasto

Messaggio da SuperStep »

sono librerie che puoi utilizzare per la lettura di input da stdin:
termios: http://linux.die.net/man/3/termios
ncurses: http://linux.die.net/man/3/ncurses

p.s. Messaggio numero 2k :D
ubuntu 16.04 LTS 64-bit - Memoria: 31,3 Gib - Processore: Intel Core i7-5960X CPU @ 3.00 GHz × 16 - Grafica: AMD Radeon HD 7800 Series - Disco: SSD 256 GB x 4 (RAID 01)
carru93
Prode Principiante
Messaggi: 7
Iscrizione: giovedì 2 giugno 2016, 11:40
Desktop: ubuntu
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile

Re: [C++]Rilevare la pressione di un tasto

Messaggio da carru93 »

ok, grazie, non è che riuscireste a spiegarmi meglio come funzionano e cosa dovrei usare? :shy:
sbam
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 305
Iscrizione: giovedì 11 dicembre 2014, 20:31

Re: [C++]Rilevare la pressione di un tasto

Messaggio da sbam »

Termios ti serve per disabilitare l'input bufferizzato. Guarda per esempio qui. _getch() e _getche() fanno lo stesso lavoro su Windows e sono incluse nella libreria conio.h.
Avatar utente
SuperStep
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 2037
Iscrizione: lunedì 19 dicembre 2011, 16:26
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile
Località: Somma Vesuviana (NA)

Re: [C++]Rilevare la pressione di un tasto

Messaggio da SuperStep »

mi correggo, la seconda (ncurses) e' una libreria per la gestione "video" del terminale.

In particolare ti permette di trattare il terminale come una griglia XY e ti permette di "dipingerci" sopra. Contiene anche funzioni per la temporizzazione dell'input ed altre utility.
ubuntu 16.04 LTS 64-bit - Memoria: 31,3 Gib - Processore: Intel Core i7-5960X CPU @ 3.00 GHz × 16 - Grafica: AMD Radeon HD 7800 Series - Disco: SSD 256 GB x 4 (RAID 01)
Avatar utente
vbextreme
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1214
Iscrizione: domenica 12 gennaio 2014, 14:06
Desktop: lxde
Distribuzione: xubuntu 14.10

Re: [C++]Rilevare la pressione di un tasto

Messaggio da vbextreme »

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>

static struct termios initial_settings, new_settings;

void async(int enable)
{
    if (enable)
    {
        tcgetattr(0,&initial_settings);
        new_settings = initial_settings;
        new_settings.c_lflag &= ~ICANON;
        new_settings.c_lflag &= ~ECHO;
        new_settings.c_lflag &= ~ISIG;
        new_settings.c_lflag &= ~IXON;
        new_settings.c_cc[VMIN] = 1;
        new_settings.c_cc[VTIME] = 0;
        tcsetattr(0, TCSANOW, &new_settings);
    }
    else
    {
        tcsetattr(0, TCSANOW, &initial_settings);
    }
}

int getch()
{
    char ch;
	if ( read(0, &ch, 1) < 1 ) return EOF;
    return ch;
}

unsigned int kbhit(void)
{	
	unsigned int toread;
	ioctl(0, FIONREAD, &toread);
    return toread;
}

per usarla

Codice: Seleziona tutto

...
async(1); // abilito input asincrono
printf("press any key");
int c = getch();
async(0);//disabilito
...
la kbhit() invece ritorna quanti caratteri sono nel buffer
Easy framework per il linguaggio C.
vbextreme hack your life
carru93
Prode Principiante
Messaggi: 7
Iscrizione: giovedì 2 giugno 2016, 11:40
Desktop: ubuntu
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile

Re: [C++]Rilevare la pressione di un tasto

Messaggio da carru93 »

vbextreme [url=http://forum.ubuntu-it.org/viewtopic.php?p=4888906#p4888906][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>

static struct termios initial_settings, new_settings;

void async(int enable)
{
    if (enable)
    {
        tcgetattr(0,&initial_settings);
        new_settings = initial_settings;
        new_settings.c_lflag &= ~ICANON;
        new_settings.c_lflag &= ~ECHO;
        new_settings.c_lflag &= ~ISIG;
        new_settings.c_lflag &= ~IXON;
        new_settings.c_cc[VMIN] = 1;
        new_settings.c_cc[VTIME] = 0;
        tcsetattr(0, TCSANOW, &new_settings);
    }
    else
    {
        tcsetattr(0, TCSANOW, &initial_settings);
    }
}

int getch()
{
    char ch;
	if ( read(0, &ch, 1) < 1 ) return EOF;
    return ch;
}

unsigned int kbhit(void)
{	
	unsigned int toread;
	ioctl(0, FIONREAD, &toread);
    return toread;
}

per usarla

Codice: Seleziona tutto

...
async(1); // abilito input asincrono
printf("press any key");
int c = getch();
async(0);//disabilito
...
la kbhit() invece ritorna quanti caratteri sono nel buffer
Ok, purtroppo è più complicato di quanto immaginassi, speravo in qualcosa tipo:

Codice: Seleziona tutto

onPress(w){//cose}
Esiste?
sbam
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 305
Iscrizione: giovedì 11 dicembre 2014, 20:31

Re: [C++]Rilevare la pressione di un tasto

Messaggio da sbam »

Disabiliti l'input bufferizzato e, poi, puoi per esempio utilizzare if(getchar() == 'w'){...}
Avatar utente
SuperStep
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 2037
Iscrizione: lunedì 19 dicembre 2011, 16:26
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile
Località: Somma Vesuviana (NA)

Re: [C++]Rilevare la pressione di un tasto

Messaggio da SuperStep »

no, da come leggo, l'utente cerca una signature che gli permetta di passare un handler per poi gestire l'evento.
Io non ne ho mai viste. Voi invece?
ubuntu 16.04 LTS 64-bit - Memoria: 31,3 Gib - Processore: Intel Core i7-5960X CPU @ 3.00 GHz × 16 - Grafica: AMD Radeon HD 7800 Series - Disco: SSD 256 GB x 4 (RAID 01)
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 4 ospiti