Skocz do zawartości
aurel

Kbhit W C++

Rekomendowane odpowiedzi

oto doszłam już jako tako jak używać kbhit()

i wszystko byłoby pięknie ale pojawia się mały problemik:

 

moja pętelka działa aż kbhit()==0

 

następnie - w teorii - program idzie dalej do następnej pętelki, która też kończy się kiedy kbhit()!=0

(czyli gdy znów zostanie nacisniety jakis klawisz)

 

i tak w sumie cztery pętelki.

 

niestety po zakonczeniu pierwszej petelki kbhit!=0 i takie już zostaje do nastepnych petelek i program sie konczy :/

 

to nie tak powinno być!

 

 

podsumowując:

 

jak wyczyścić bufor klawiatury...?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

hm, wg mnie to chyba oczywiste.. skoro każda pętla ma ten sam warunek końcowy to spełnienie go w pierwszej pętli powoduje że zostają spełnione wszystkie kolejne... Nie ma siły żeby zdążyć wcisnąć klawisz zanim procesor przejdzie do obrabiania następnej instrukcji bo to są nanosekundy :)

 

może pokaż lepiej kod zamiast gdybać.. kod jest rosty i zrozumiały dla wszystkich - inaczej język polski :D

Edytowane przez PelzaK

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

main(){clrscr();textmode(C4350);x=18;	 y=20;		  //kolumna, wiersza=1;	  b=1;i=0;	  k=0;			//zmienna pomocniczaL:do{if (x>1) x=x-1;						 //pętla przesuniecia napisu w lewo		else x=80;rysuj();Sleep(100);clrscr();}while (!kbhit());k=getch();if (k=='2') goto D;if (k=='8') goto G;if (k=='4') goto L;if (k=='6') goto P;G:do{if (y>1) y=y-1;						 //pętla przesuniecia napisu w gore		else y=50;rysuj();Sleep(100);clrscr();}while (x>0);//while (!kbhit());k=getch();if (k=='2') goto D;if (k=='8') goto G;if (k=='4') goto L;if (k=='6') goto P;P:do{if (x>1) x=x+1;						 //pętla przesuniecia napisu w prawo		else x=80;rysuj();Sleep(100);clrscr();}while (x>0);//while (!kbhit());k=getch();if (k=='2') goto D;if (k=='8') goto G;if (k=='4') goto L;if (k=='6') goto P;D:do{if (y>1) y=y+1;						 //pętla przesuniecia napisu w dol		else x=50;rysuj();Sleep(100);clrscr();}while (x>0);//while (!kbhit());k=getch();if (k=='2') goto D;if (k=='8') goto G;if (k=='4') goto L;if (k=='6') goto P;getch();return 0;}

 

 

wersja, w ktorej nie wszystko dziala (celowo, sprawdzalam inne funkcje i za to sie na razie nie bralam poki nie wiem)

jak dla mnie rowniez oczywiste jest ze spelnienie warunku dla pierwszej petli spełnia go rowniez dla reszty ://

wlasnie dlatego pytałam o to jak wyczyscic bufor klawiatury, by na poczatku kazdej petli to wstawic i wtedy byloby miło.

 

 

zaraz sprobuje fflush() i zobaczymy co z tego bedzie...

 

tylko jeszcze jeden mały problem - program ma korzystać z funkcji wejścia/wyjścia tylko i wyłącznie conio.h

czy fflush() nalezy zakwalifikować jako io? tu nie jestem pewna... jeśli tak, to niestety odpada.

 

 

//edit - fflush() nie działa, albo raczej - nie mam pojęcia jak go zastosować i o jaką ścieżkę do jakiego pliku on mnie pyta :// jakoś szczegółowiej o fflush()...?

 

//ok, fflush() już działa.

Edytowane przez aurel

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

ojojoj... dwie uwagi ode mnie:

- stosuj wcięcia w kodzie... o wiele łatwiej się czyta i wierz mi, wykładowca zwróci na to uwagę

Label_L:		// użyj lepiej całej nazwy wskazujacej że to jest label, bo Ci się pomiesza potem :)  do  {	  if (x>1) x=x-1;						 //pętla przesuniecia napisu w lewo	  else x=80;	  rysuj();	  Sleep(100);	  clrscr();   }
tak od razu wizulanie masz podzielony kod na bloki...

 

- staraj się nie używać składni GOTO - to jest pierwszy gwóźdź do trumny przy większym programie...

zamiast tego użyj funkcji. Powtarzasz przez to kod pobierania klawisza... powiesz ze masz dużo pamięci.. ale teraz chcąc zmienić klawisz UP musisz zmieniać kod w 4 miejscach... to drugi gwóźdź do trumny :]

 

zamiast tego proponuję tak:

enum eDirections	// definiujesz sobie np typ enum, który rozróżnia kierunek ruchu{	goDown=1,	goUp,	goLeft,	goRight	} direction;//---------------------------------------------------// funkcja Move() zawiera kod przesuwający cośtam po obrazievoid Move(eDirections direction) {  do  {		// w zaleznosci od parametru direction (z ang. kierunek) switch ...	   // ..wybiera odpowiednie działanie zmieniając zmienne x,y	  switch(direction)  	  {		  case goDown: if (y>1) y=y+1; else y=50; break;		  case goUp: iif (y>1) y=y-1; else y=50; break;		  case goLeft: if (x>1) x=x-1; else x=80; break;		  case goRight: if (x>1) x=x+1; else x=80; break;	  }	  rysuj();	  Sleep(100);	  clrscr();  } while (!kbhit());}//---------------------------------------------------main(){	clrscr();	textmode(C4350);	x=18;	 y=20;		  //kolumna, wiersz	a=1;	  b=1;	i=0;	  k=0;			//zmienna pomocnicza  fflush(stdin);	// czyscisz bufor na początku aby pozbyć sie śmieci     while((k=getch())!=27);   // wykonuj aż uzytkownik wcisnie escape   {	if (k=='2') Move(goDown);  // w zaleznosci od klawisza z NUPADA wywołujesz funkcję...	if (k=='8') Move(goUp);	  // Move z odpowiednim parametrem, ona już wie co z nimi zrobić	if (k=='4') Move(goLeft);	if (k=='6') Move(goRight);   }}

no, oczywiscie mozna to zrobić na wiele innych sposobów. Kod może zawierac błędy, chodziło mi jedynie o pokazanie metodyki i uproszczenie kodu i zwiększenie jego niezawodności...

Edytowane przez PelzaK

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

enum eDirections	// definiujesz sobie np typ enum, który rozróżnia kierunek ruchu{	goDown=1,	goUp,	goLeft,	goRight	} direction;

tej części nie rozumiem....

znaczy jakby to - ogólnie rozwiązanie faktycznie niezłe :)

tyle że ja to bym na to nie wpadła :P

 

i w sumie ujme to tak - jeśli ta wersja zadziała i mój napis przestanie się irytująco rozjeżdzać na krawędziach (o czym pisałam w jakimś innym topicu) to za pewne wykorzystam twoje rady...

jeśli nic to nie da.... no cóż, dzięki, ale zostane przy swoim ;)

 

//które nawiasem mówiąc tak w ogóle to już działa, tylko w szczególe ma problemy ze sobą ;)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

ja Ci dobrze radzę... Twój program to jest przykład jak nie należy robić :)... Masz 8x większą szansę zrobić błąd w swoim programie niż w moim. Jak ja zaczynałem to też byłem gotów pisać programy na Twój sposób.. ale szybko polubiłem funkcje :)

 

wiec tak.. enum jest to typ enumeration - wyliczanie... w definicji podajesz jakie wartości może przyjąć zmienna direction i w programie możesz posługiwać się nazwami goDown, goUp - chodzi o ułatwienie sobie życia :)

 

Jeśli typ enum Ci się nie podoba możesz zdefiniować sobie stałe na początku programu:

#define	goDown	1#define	goUp		2#define	goLeft	   3#define	goRight	 4
choć w językach wysokiego poziomu przyjęło się pisać nazwy stałych dużymi literami (GO_DOWN) to ja użyłem oznaczeń zgodnych z programem.

 

Jeśli chodzi o rozjeżdżanie się napisu.. nie wiem dokładnie o co chodzi.. ale spróbuj zamiast x=80 wstawić x=79... W trybie 80x25 linii 80 linijka przeskakuje już do nowej linii po wypisaniu znaku :)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

czyli jednak w znakach ASCII sa zdefiniowane strzałki ? Kurde nie widze ich w tych tablicach co podales? :unsure: albo sie zle zrozumielsmy, chodzi mi o sterowanie kursorami (ta czescie klawiatury ktora ma namalowane strzalki :-P )

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

kody ascii są to kody 7bitowe od 0..127, zawierają znaki sterujące oraz standardowe litery i wszystko to co widać na klawiaturze. Do tego dobudowano kolejne 127 znaków co tworzy tzw rozszerzone kody ascii - tam są głównie znaczki typu ramki jakieś kreseczki etc... nadal jednak jets to kod 1 bajtowy

 

Do kodowania np kursorów używa się kodowania na 2 bajtach. Jeśli odpalisz program który pokazał razor1 to po naciśnieciu strzałki pojawią Ci się (chyba :) ) dwa kody, 0 i np 78, co onzacza że obsługa klawiszy typu strzałki w programie jest następujaca:

 

pobierz znakif znak = 0 then{   pobierz znak // tutaj pobieramy z bufora klawiatury drugi bajt   if znak = 78 then wcisnietoUpArrow();	  // wartosci 78, 76 przypadkowe   if znak = 76 then wcisnietoDownArrow();}else {  // obsluga zwyklych znakow, np 27-escape, 13-enter etc...}

powyższy pseudo kod mówi, iż najpierw musisz odczytać bajt, jesli jest to 0, tzn ze po nim prawdopodobnie będzie kolejny bajt charakteryzujący kody np strzałek. No i wtedy pobeirasz drugi bajt i sprawdzasz co to jest...

 

jeśli natomiast pierwszy bajt jest różny od 0 tzn ze user nacisnął zwykły klawisz :)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie


×
×
  • Dodaj nową pozycję...