[FP] Problem z ReadKey w duecie z GRAPH.

0

Witam. Na koniec stycznia muszę napisać pewien mały programik, nad którym od dzisiejszego rana męczę się. Konkretnie hodzi o kawałek kodu z ReadKey. Na początku rysuję w oknie grafikę, następnie sprawdzam klawisze strzałkowe (góra, dół) za pomocą ReadKey, na ich podstawie zmieniam wartość liczbową zmiennej a z kolei na jej podstawie "podświetlam" pozycje w menu.

Tutaj zaczynają się schody. Dlaczego? Program narysuje to co ma narysować ale dalej czeka. Nie reaguje na wciskane klawisze. Z tego, co zauważyłem, po wyłączenia okna z grafiką, konsola zaczyna dopiero "czytać" klawisze i reaguje na końcowy ENTER.

Jakieś sugestie?

Kod:

program szablon;

uses crt, graph;

const
  ster : Integer = VGA;
  tryb : Integer = VGAHI;
  Maus = $33;

procedure inicjuj_grafike;
begin
  InitGraph(ster, tryb, 'D:/Program Files/2.4.0/bin/');
end;

procedure rysuj_logo;
begin
  SetColor(Blue);
  Arc(150,100,0,330,50);
  Line(200,100,150,100);
  Line(150,100,194,125);
  Circle(165,80,7);
  SetTextStyle(4,horizdir,6);
  OutTextXY(220,100,'PatMan');
end;

function przelacz_opcje(stan:Integer):Integer;
begin
  if(stan = 0) then
   begin
    SetColor(White);
    OutTextXY(245,260, 'Nowa Gra');
    SetColor(LightBlue);
    OutTextXY(260,280,'Wyniki');
    OutTextXY(260,300,'Koniec');
   end;

  if(stan = 1) then
   begin
    SetColor(White);
    OutTextXY(260,280, 'Wyniki');
    SetColor(LightBlue);
    OutTextXY(245,260,'Nowa Gra');
    OutTextXY(260,300,'Koniec');
   end;

  if(stan = 2) then
   begin
    SetColor(White);
    OutTextXY(260,300, 'Koniec');
    SetColor(LightBlue);
    OutTextXY(245,260,'Nowa Gra');
    OutTextXY(260,280,'Wyniki');
   end;

end;

procedure rysuj_menu;
var
  stan : Integer;
  klawisz : char;

begin
  SetColor(blue);
  SetTextStyle(4,horizdir,4);
  OutTextXY(245,215,'MENU');
  Line(200,250,420,250);
  SetTextStyle(4,horizdir,2);
  SetColor(LightBlue);
  OutTextXY(245,260,'Nowa Gra');;
  OutTextXY(260,280,'Wyniki');
  OutTextXY(260,300,'Koniec');

  stan := 0;

  repeat
  klawisz := Readkey;
  case klawisz of
    #72 :
     begin
      stan := stan + 1;
      przelacz_opcje(stan);
     end;

    #80 :
     begin
      stan := stan - 1;
      przelacz_opcje(stan);
     end;

  else
    stan := stan;
  end;

  until klawisz = #13;


end;

procedure zamknij_grafike;
begin
  readln;
  CloseGraph;
end;

begin
  inicjuj_grafike;
  rysuj_logo;
  rysuj_menu;
  zamknij_grafike;
end.
0

Zrobiles kilka bledow:

  1. jak chcesz by wejscia z klawiatury odnosily sie do okna programu dajesz zamisat uses crt - wincrt
  2. po co ci w ogóle wartosc "Maus" w stalych ?
  3. FPC nie odczyta w ten sam sposob strzalki i enter-a
  4. w procedurze "rysuj_menu" zalozyles, iz nacisniecie strzalki w gore lub w dol powoduje modyfikacje zmiennej "stan" o odpowiednio +1 i -1, nastomiast w funkcji "przelacz_opcje" dales tylko rezulataty dla wartosci funkcji "stan" = 0, 1 i 2. Co jesli 10 razy z rzedu nacisne strzalke w gore ? Zmienna "stan" bedzie przechowywac wtedy wartosc 10 i co zrobi wtedy funkcja "przelacz_opcje" ?

Robisz tak:

  1. zamieniasz w uses crt - wincrt
  2. wywalasz nieptrzebna stala "Maus"
  3. procedure "rysuj_menu" zmieniasz nastepujaco:
procedure rysuj_menu;
var
  stan : Integer;
  klawisz : char;
  klawisz1: char;

begin

  SetColor(blue);
  SetTextStyle(4,horizdir,4);
  OutTextXY(245,215,'MENU');
  Line(200,250,420,250);
  SetTextStyle(4,horizdir,2);
  SetColor(LightBlue);
  OutTextXY(245,260,'Nowa Gra');;
  OutTextXY(260,280,'Wyniki');
  OutTextXY(260,300,'Koniec');
  
  stan := 0;
  przelacz_opcje(stan);
  repeat
  klawisz:=readkey;
  if ord(klawisz)=0 then
  begin
  klawisz1:=readkey;
  case ord(klawisz1) of
  72: begin if stan = 2 then begin przelacz_opcje(0); stan:=0; end else begin przelacz_opcje(stan+1); stan:=stan+1; end; end;
  80: begin if stan = 0 then begin przelacz_opcje(2); stan:=2; end else begin przelacz_opcje(stan-1); stan:=stan-1; end; end;
  end;
  end;
  until ord (klawisz) = 13;

end;

procedure zamknij_grafike;
begin
  CloseGraph;
end;
0

Co do Maus w stałch. Została z czasów, kiedy dodawałem myszkę ale po paru niepowodzeniach postanowiłem zrezygnować z niej. Stała została zapomniana :].

Co do Wincrt. Dziękuję. Nie wiedziałem o tym pliku.

Co do strzałek i wartości większej niż przewiduję. Chciałem dorobić warunki w funkcji ale najpierw zamierzałem dojść do tego, dlaczego nie działa readkey.

W każdym razie bardzo dziękuję za odpowiedź.

0

Trochę przerobiłem kod (zabezpieczenie w przelacz_opcje dojdzie później) jednak ciągle program nie wyłapuje klawiszy.

program szablon;

uses Wincrt, graph;

const
  ster : Integer = VGA;
  tryb : Integer = VGAHI;

procedure inicjuj_grafike;
begin
  InitGraph(ster, tryb, 'D:/Program Files/2.4.0/bin/');
end;

procedure rysuj_logo;
begin
  SetColor(Blue);
  Arc(150,100,0,330,50);
  Line(200,100,150,100);
  Line(150,100,194,125);
  Circle(165,80,7);
  SetTextStyle(4,horizdir,6);
  OutTextXY(220,100,'PatMan');
end;

function przelacz_opcje(stan:Integer):Integer;
begin
  if(stan = 0) then
   begin
    SetColor(White);
    OutTextXY(245,260, 'Nowa Gra');
    SetColor(LightBlue);
    OutTextXY(260,280,'Wyniki');
    OutTextXY(260,300,'Koniec');
   end;

  if(stan = 1) then
   begin
    SetColor(White);
    OutTextXY(260,280, 'Wyniki');
    SetColor(LightBlue);
    OutTextXY(245,260,'Nowa Gra');
    OutTextXY(260,300,'Koniec');
   end;

  if(stan = 2) then
   begin
    SetColor(White);
    OutTextXY(260,300, 'Koniec');
    SetColor(LightBlue);
    OutTextXY(245,260,'Nowa Gra');
    OutTextXY(260,280,'Wyniki');
   end;

end;

procedure rysuj_menu;
var
  stan     : Integer;
  klawisz  : char;
  klawiszw : char;

begin
  SetColor(blue);
  SetTextStyle(4,horizdir,4);
  OutTextXY(245,215,'MENU');
  Line(200,250,420,250);
  SetTextStyle(4,horizdir,2);
  SetColor(LightBlue);
  OutTextXY(245,260,'Nowa Gra');
  OutTextXY(260,280,'Wyniki');
  OutTextXY(260,300,'Koniec');

  stan := 0;
  przelacz_opcje(stan);

  repeat
  klawisz := Readkey;
  if ord(klawisz) = 0 then
  begin
  klawiszw := readkey;
   case ord(klawiszw) of
     72 :
      begin
       stan := stan + 1;
       przelacz_opcje(stan);
      end;

     80 :
      begin
       stan := stan - 1;
       przelacz_opcje(stan);
      end;
   end;
   end;
   until ord(klawisz) = 13;

end;

procedure zamknij_grafike;
begin
  CloseGraph;
end;

begin
  inicjuj_grafike;
  rysuj_logo;
  rysuj_menu;
  zamknij_grafike;
end.
0

Dobrze to zmodyfikowales, tylko w poprzednim poscie omylkowo zamienilem liczby w instrukcji case - zamien sobie 72 <-> 80 i bedzie dzialac. Tu masz juz gotowiec, uwzgledniajacy ilosc pozycji w menu:

repeat
  klawisz:=readkey;
  if ord(klawisz)=0 then
   begin
   klawiszw:=readkey;
   case ord(klawiszw) of
   80:
    begin if stan = 2 then
     begin
     przelacz_opcje(0);
     stan:=0;
     end
    else 
     begin 
     przelacz_opcje(stan+1); 
     stan:=stan+1;
     end;
    end;
   72:
    begin if stan = 0 then
     begin 
     przelacz_opcje(2);
     stan:=2;
     end
    else
     begin
     przelacz_opcje(stan-1);
     stan:=stan-1;
     end;
    end;
    end;
  end;
  until ord (klawisz) = 13;
0

Witam. Podmieniłem kod repeat na Twój i niestety dalej nie działa. Wiem, że kompilator robi różnicę i czuję, że Ty kompilujesz w Turbo Pascalu. Jestem bardzo ciekaw dlaczego program ciągle nie reaguje na jakiekolwiek klawisze...

0

Przed chwila jeszcze raz sprawdzilem, u mnie dziala wszystko elegancko. Kompilator FPC w najnowszej wersji 2.2.2.
Nie wiem dokladnie jaka ty masz wersje i czy ci wszystkie moduly dobrze dzialaja. Jak jeszcze nie pronowales to sproboj zainstalowac najnowsza wersje. Jesli tego nie chcesz to sprawdz czy w ogóle okno programu ci poprawnie reaguje na odczyt np. litery a.

0

Pięknie. Problem za problemem. Miałem wersję 2.0.4 więc zrobiłem upgrade do 2.2.2. Niestety po instalacji, wrzuceniu plików wincrt do katalogu fpc i skompilowaniu dostaję errory:

Illegal parametr -Opentium3
Unable to open file fp.cfg

Aktualnie szukam jakiegoś lekarstwa na to ale czuję, że zbyt szybko nie znajdę... Jakieś pomysły?

0

Pamietam, ze kiedys tez mialem ten blad. Nie pamietam juz jak go rozwiazalem, ale z tego co kojarze nie bylo to trudne.
Nie "wrzucaj" do FPC unitu wincrt, bowiem ma go w standardzie.

0

Matko, jakie to było proste...

Dla potomności. FPC w wersji 2.2.2 ma "wbudowaną" literówkę w konfiguracji. Aby naprawić błąd: "Illegal parametr -Opentium3
Unable to open file fp.cfg",

stanowczo nie należy kasować pliku fp.cfg, jak to radzą wszędzie w Sieci, bo i tak kompilator przy następnym uruchomieniu stworzy ten plik. Należy wejść do zakładki Options->Compiler a następnie w polu Additional Compiler args zamienić string "-Opentium3" na "-Oppentium3" i zatwierdzić. Uruchomić ponownie kompilator i skompilować program.

Co do rozwiązania problemu programistycznego. Wielkie dzięki, działa :).

1 użytkowników online, w tym zalogowanych: 0, gości: 1