PDA

View Full Version : [C++] Cerco funzione simile a getch()


MrModd
20-01-2008, 10:55
Ciao, ho bisogno di una funzione che mi catturi un carattere da tastiera come getch(), ma non deve mettere in pausa il computer:
Io tengo la funzione in ascolto per x tempo e se non è stato premuto niente va avanti.

Cosa posso usare?

cionci
20-01-2008, 11:06
Non esiste nelle funzioni standard del C e del C++
Devi usare le librerie del sistema operativo (le funzioni per la console delle Win32 API, o delle system call di Linux o qualche libreria portabile come ncurses).

MrModd
20-01-2008, 11:13
Un piccolo accenno?
Sono abbastanza niubbo, nel programma ho incluso conio2, windows, stdlib e iostream.
Cosa dovrei aggiungere e che funzione uso?

cionci
20-01-2008, 11:15
Non so cosa sia questa conio2...lì non c'è ?

MrModd
20-01-2008, 11:19
Lasciando da parte conio2 (che comunque è la versione aggiornata del conio.h) come posso fare per utilizzare una funzione simile a getch()?

#include <...>

while (gli uccelli cantano)
{
a=funzione;
}

:D

cionci
20-01-2008, 11:25
Bisogna un po' lavorarci, non è una cosa così immediata.
Prova a vedere se hai curses.h...ti dovrebbe includere già una funzione chiamata getch.

cionci
20-01-2008, 11:28
Comunque leggendo il tuo primo post...getch mette in "pausa" il computer...è kbhit della conio.h che controlla se un tasto è o meno disponibile.

MrModd
20-01-2008, 11:35
Comunque leggendo il tuo primo post...getch mette in "pausa" il computer...è kbhit della conio.h che controlla se un tasto è o meno disponibile.

E quindi? Posso evitare di metterlo in pausa?
Comunque curses.h non ce l'ho...

MrModd
20-01-2008, 12:48
Vabbeh fa niente, lo lascio così com'è.



PS. se qualcuno vuole dargli un'occhiata ho creato una versione rudimentale di Snake. QUI (http://www.megaupload.com/it/?d=C78CEKQJ) (E' lecito postare programmi nel forum?)

xblitz
20-01-2008, 13:30
NO L'INCUBO CONTINUA!!!!!!!!!!!!!!!!

scusate non ho resistito :D

mi sono trovato anche io in questa situazione solo che io non dovevo fare lo snake ma un gioco di nuova concezione elaborato dal nostro prof di laboratorio dopo anni di meditazione spirituale e purificazione, per dover di cronaca il gioco era il tiro al bersaglio :rolleyes: io ho risolto così:


do
{
do
{
//operazioni da eseguire e da stoppare quando si preme il tasto
}
while (kbhit() == 0); //ciclo che termina quando si preme UN tasto

tasto=getch(); //che tatso si è premuto?
}
while (tasto != <codice ascii tasto>);


sperando di essere stato utile

cionci
20-01-2008, 13:38
Ma kbhit l'hai preso dalla conio.h ;)

Andare a leggere lo stato del buffer di input con le API Win32 non è una cosa semplice ;)

MrModd
20-01-2008, 13:44
Ci va vicino, ma mi serve all'incontrario:
Questo esegue le operazioni e poi controlla la pressione di un tasto. Ma con uno sleep in mezzo dovrei tenerlo premuto.
A me serve che è sempre in ascolto tranne che per un breve momento in cui termina il ciclo, esegue le operazioni e ricomincia il ciclo.

Per ora l'ho lasciato senza movimento automatico (il serpente si sposta solo se pigi i tasti).

cionci
20-01-2008, 13:48
while(1)
{
If(kbhit())
c = getch();
sleep(300); //valore per regolare la velocità
if(ho_perso)
break;
}

xblitz
20-01-2008, 13:51
Ma kbhit l'hai preso dalla conio.h ;)


Andare a leggere lo stato del buffer di input con le API Wind2 non è una cosa semplice ;)[/QUOTE]

non metto in dubbio che sia una cosa complicata, io per semplice intendevo qualcosa del tipo "una funzione da mettere al volo e via"...

MrModd
20-01-2008, 13:52
kbhit() cosa fa?
Una mezza specie di getch()?

cionci
20-01-2008, 13:54
kbhit() cosa fa?
Una mezza specie di getch()?
kbhit ritorna vero se c'è un tasto da leggere nel buffer

MrModd
20-01-2008, 14:08
MITTICU!!!
Ho risolto così:

#include <time.h>

int ms=1000, delay;
delay= ms + clock();
do
{
if (kbhit()) c=getch();
}
while (delay > clock());


In questo modo controlla SEMPRE se è premuto un tasto per ms tempo

cionci
20-01-2008, 14:12
No...assolutamente no, non fa quello che dici.
Se anche un tasto viene premuto per 1 ms kbhit lo mette in coda e ritorna 1.
Non puoi gestire il tempo in cui il tasto resta premuto se non con metodi molto più complessi.

MrModd
20-01-2008, 14:17
Oo a me funziona...

Considerando che il ciclo do-while si ripete ogni ciclo di clock del processore (nanosecondi) tu premi un tasto per almeno 50ms, quindi esegui qualche migliaio di volte il ciclo, in quei momenti c assume il valore del tasto premuto.
Il ciclo continua a funzionare anche dopo che hai premuto il tasto finchè delay non è == a clock(). A quel punto esce dal ciclo ed esegue il resto.

cionci
20-01-2008, 14:23
Non funziona perché non ti misura per quanto tempo è premuto il tasto...se in quel secondo premo 20 tasti lui li legge tutti.
Il ciclo corretto per dimensionare la ripetizione dei tasti in un gioco del genere è questo:

while(1)
{
If(kbhit())
c = getch();
while(kbhit())
getch(); //scarta tutti i tasti premuti oltre al primo
sleep(300); //valore per regolare la velocità
if(ho_perso)
break;
}

MrModd
20-01-2008, 14:32
Ho capito cosa intendi: se premi a e poi b lui registra b. Ma è meglio così, lo preferisco.
Se metto uno Sleep() lui non legge nient'altro, si mette in pausa.

cionci
20-01-2008, 14:35
Legge, i caratteri rimangono nel buffer di lettura anche se sei in pausa.
Il gioco inoltre va temporizzato...ad esempio con l'aumentare dei livelli il gioco dovrà essere più veloce...per fare questa temporizzazione basta ridurre la pausa.

MrModd
20-01-2008, 14:51
Ah, capito.
Il risultato tra il tuo modo e il mio è lo stesso, però il tuo permette di ottimizzare il codice eliminando una libreria e riducendo le risorse sfruttate durante il ciclo. Ora vedrò come fare...

MrModd
20-01-2008, 15:12
Con il modo che dicevi tu non ci sono riuscito, lo Sleep non funzionava :confused:
Ho fatto a modo mio ed è venuto così ----> Snake (http://www.megaupload.com/it/?d=C9AMF0X4)

cionci
20-01-2008, 15:23
Per usare la Sleep devi includere windows.h.

MrModd
20-01-2008, 15:26
Già incluso.

cionci
20-01-2008, 15:27
Allora deve funzionare...l'hai scritto con la S maiuscola ?

MrModd
20-01-2008, 16:15
Si, forse ho invertito il kbhit e Sleep, comunque ormai ho impacchettato tutto e funziona alla grande (anche se utilizza il 15% della CPU :D)

Grazie CIAO!

cionci
20-01-2008, 16:32
(anche se utilizza il 15% della CPU :D)
Proprio perché non usi la sleep. C'è un'attesa attiva ;)
Metti una sleep, anche di un microsecondo e ti andrà a zero.

MrModd
20-01-2008, 19:12
Oki fatto come dici te:


Sleep(ms);
if (kbhit()) c=getch();
while (kbhit()) getch();


Così posso eliminare time.h

Grazie!

Passo e chiudo

PS. se volete provarlo ditemelo che lo uppo, a quanto pare è piaciuto ai miei amici, tanto che si sono messi a giocare sul serio (il lv 7 è impossibile)

Tommo
20-01-2008, 20:27
Anche se hai risolto, penso che OIS (http://sourceforge.net/projects/wgois/) ti potrebbe essere utile...

E' una libreria per l'input che gestisce di tutto, dalla tastiera al wiimote... ed è fatta apposta per i giochi :D

MrModd
21-01-2008, 09:06
Interessante, lo terrò a mente per progetti futuri ;)