Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Näppäinten lukua tekstitilassa @ curses

Heikki [07.06.2006 19:20:48]

#

Pelissä luetaan pohjassa olevat näppäimet tällä hetkellä NCursesin getch():lla, ja tässä tavassa on ongelma.

Ongelmana on se, että tällä tavalla on mahdollista selvittää vain viimeisin alas painettu näppäin, kun taas pitäisi saada selville kaikki pohjassa olevat näppäimet riippumatta siitä missä vaiheessa ne on painettu. NCursesin manuaalia lueskelin mutta siitä en löytänyt mitään sopivaa keinoa ongelman ratkaisemiseksi.

Olisiko jollain ehdotuksia siihen, miten noita näppäimiä pystyisi hyvin lukemaan? NCurses paljastanee että alustana on Linux (tosin Windows-versio tulee ehkä joskus).

Sisuaski [13.06.2006 03:56:27]

#

Kunnon yleistä vastausta en tiedä(eikä sellaista välttämättä olekaan), mutta ainakin alt-, shift- ja ctrl-näppäinten kanssa tarkistuksen voi jossain määrin suorittaa. ctrl- ja shift-näppäinten kanssa getch() palauttaa usein jonkun kokonaan uuden merkin, jota voi käyttää suoraan. Alt(ja joissain tilanteissa ctrl ja shiftkin)-näppäimen kanssa tarvitaan seuraavanlaista purkkaa:

Poista syötteen odotus käytöstä kutsumalla nodelay-funktiota tähän tyyliin:

nodelay(stdscr, true);

(Tämän seurauksena getch-funktio ei enää jää odottamaan kunnes näppäintä painetaan, vaan palauttaa ncurses.h-otsikkotiedostossa esitellyn vakion ERR mikäli mitään näppäintä ei ole painettu.)
Nyt jos pidät esim. alt-näppäintä pohjassa ja painat jotain muuta näppäintä, niin 2 perättäistä kutsua getch():lle palauttaa nämä näppäimet, kun taas jos painat 2:ta eri näppäintä peräkkäin, palauttaa getch() ainakin kerran ERR-arvon välissä (ainakin jos tarkistat viiveettä kunnes saat ERR-arvon). Seuraava ruma (C99/C++98)koodinpätkäni voi vähän valottaa tätä:

#include <ncurses.h>

int input(int* buf);

int main()
{
	initscr();	// alustetaan kiroukset
	cbreak();	// disabloidaan bufferointi
	noecho();	// disabloidaan merkkien automaattinen tulostus
	keypad(stdscr, true);	// otetaan mm. nuolinäppäimet luettavien joukkoon
	raw();		// luetaan itse myös terminaalille tarkoitetut painallukset
	nodelay(stdscr, true);	// poistetaan syötteen lukemisen odotus
	refresh();	// päivitetään ikkuna

	int buf[1024];
	// jatka kunnes käyttäjä painaa ^C
	while(input(buf)) {
		if (buf[0] != ERR) {
			printw("new buf:\n");
			for(int i=0; buf[i] != ERR; i++)
				printw("%i: %c\n", buf[i], buf[i]);
		}
	}
	endwin();
	return 0;
}

// lue kaikki nyt painetut näppäimet taulukkoon
int input(int* buf)
{
	for(int i=0; ; i++) {
		int k = getch();
		buf[i] = k;
		if (k == ERR) {
			// tarkistetaan onko ^C painettu
			return (buf[0] != 3);
		}
	}
}

Eli siis luet johonkin tauluun kaikki ennen ERRriä tulevat näppäimet ja katsot sitten mitä yhdistelmiä on tullut. Tätä tapaa käyttää ainakin Irssi.
Tämä siis ei tosiaan toimi mm. kahden kirjaimen kanssa vaan vain erikoistapauksissa, kuten alt-näppäintä pohjassa pidettäessä (jolloin getch() palauttaa ensin arvon 27 ja sitten varsinaisen merkin). Myös monet erikoismerkit tulevat getch():lta useana palana joten tämä on silti ihan hyvä tyyli käyttää.

Metabolix [13.06.2006 11:33:41]

#

Ongelma varmaankin oli siis se, että NCurses ei koskaan ilmoita, milloin näppäin nousee ylös, joten on mahdotonta tehdä peli, jossa liikutaan niin kauan, kuin näppäin on pohjassa. Enpä löytänyt tuolle ratkaisua.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta