Próbuję napisać menu do mojej symulacji Układu Słonecznego przy użyciu biblioteki allegro. Napisałem procedurę ReadNumber, która działa w trybie graficznym analogicznie do procedury readln z trybu tekstowego. Wczytuje ona symbole (cyfry, znak -, oraz .) i wypisuje je w czasie rzeczywistym na ekranie, dopóki nie naciśnie się klawisza enter, a potem przekonwertowuje to do typu real. Procedura działa dobrze, gdy jest w oddzielnym programie, a nawet gdy jest na samym początku poniższego programu, ale gdy próbuję ją umieścić "w menu", aby uruchamiała się po wybraniu odpowiedniej opcji (konkretnie: "zmień promień Slonca"), to nie działa prawidłowo. Wyświetla mi tylko napis "Podaj liczbe". Oto kod programu:
Program MenuUkladu;
uses
allegro, graphics;
type
wektor = array[1..100] of integer;
var
i,j: integer;
promien, masa: real;
procedure KeysOff();
begin
al_key[AL_KEY_DOWN]:=0; //wylaczam sobie wszystkie klawisze
al_key[AL_KEY_UP]:=0;
al_key[AL_KEY_ENTER]:=0;
end;
procedure WriteMenu(i: integer); //procedura wyswietlajaca Glowne Menu i podswietlajaca ktoras z opcji w zaleznosci od parametru i
begin
if i=1 then
begin
al_clear_to_color(AL_SCREEN, black);
al_textout_ex(AL_SCREEN, al_font, 'Menu:', 200, 200, red, black);
al_textout_ex(AL_SCREEN, al_font, 'START', 200, 210, black, red); //podswietlony zostanie START
al_textout_ex(AL_SCREEN, al_font, 'Zmien predkosc Ziemi', 200, 220, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zmien promien Slonca', 200, 230, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zmien mase Jowisza', 200, 240, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zakoncz', 200, 250, red, black);
end;
if i=2 then
begin
al_clear_to_color(AL_SCREEN, black);
al_textout_ex(AL_SCREEN, al_font, 'Menu:', 200, 200, red, black);
al_textout_ex(AL_SCREEN, al_font, 'START', 200, 210, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zmien predkosc Ziemi', 200, 220, black, red); //podswietlona zostanie druga opcja
al_textout_ex(AL_SCREEN, al_font, 'Zmien promien Slonca', 200, 230, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zmien mase Jowisza', 200, 240, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zakoncz', 200, 250, red, black);
end;
if i=3 then
begin
al_clear_to_color(AL_SCREEN, black);
al_textout_ex(AL_SCREEN, al_font, 'Menu:', 200, 200, red, black);
al_textout_ex(AL_SCREEN, al_font, 'START', 200, 210, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zmien predkosc Ziemi', 200, 220, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zmien promien Slonca', 200, 230, black, red); //itd. itd.
al_textout_ex(AL_SCREEN, al_font, 'Zmien mase Jowisza', 200, 240, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zakoncz', 200, 250, red, black);
end;
if i=4 then
begin
al_clear_to_color(AL_SCREEN, black);
al_textout_ex(AL_SCREEN, al_font, 'Menu:', 200, 200, red, black);
al_textout_ex(AL_SCREEN, al_font, 'START', 200, 210, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zmien predkosc Ziemi', 200, 220, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zmien promien Slonca', 200, 230, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zmien mase Jowisza', 200, 240, black, red);
al_textout_ex(AL_SCREEN, al_font, 'Zakoncz', 200, 250, red, black);
end;
if i=5 then
begin
al_clear_to_color(AL_SCREEN, black);
al_textout_ex(AL_SCREEN, al_font, 'Menu:', 200, 200, red, black);
al_textout_ex(AL_SCREEN, al_font, 'START', 200, 210, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zmien predkosc Ziemi', 200, 220, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zmien promien Slonca', 200, 230, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zmien mase Jowisza', 200, 240, red, black);
al_textout_ex(AL_SCREEN, al_font, 'Zakoncz', 200, 250, black, red);
end;
end;
function String2Real(var x: wektor; wymiar: integer): real; //funkcja przekonwertowuje liczbe wprowadzona jako tablice na liczbe typu real
var
i,j,k: integer;
n, licznik: real;
//w funkcji zakladamy rozsadek uzytkownika, tzn ze minus moze wystapic tylko raz i tylko na poczatku tablicy, a kropka moze wystapic tylko raz i w srodku liczby
begin
k:=wymiar+1; //zakladam ze liczba jest calkowita
j:=1;
while (k=wymiar+1) and (j<>wymiar+1) do //petla sie zakonczy jak znajdzie kropke, lub "przebiegnie" cala tablice
begin
if x[j]=46 then
k:=j;
j:=j+1;
end;
n:=0;
licznik:=1;
for j:=k-1 downto 2 do //ta petla "wyluskuje" czesc calkowita liczby
begin
n:=n+x[j]*licznik;
licznik:=licznik*10;
end;
if x[1]=45 then //jak pierwszy element tablicy to minus, to wtedy mnoze liczbe przez -1
n:=-n
else
n:=n+x[1]*licznik; //a jak nie, to normalnie zwiekszam liczbe n
if k<>wymiar+1 then //ten warunek sprawdza czy liczba jest calkowita czy nie
begin
if x[1]<>45 then //jak liczba jest nieujemna
begin
licznik:=0.1;
for j:=k+1 to wymiar do //jak liczba nie jest calkowita, to ta petla "wyluskuje" czesc ulamkowa
begin
n:=n+x[j]*licznik;
licznik:=licznik/10;
end;
end
else //gdy liczba jest ujemna
//if liczba[1]=45 then //jak liczba jest ujemna
begin
licznik:=0.1;
for j:=k+1 to wymiar do
begin
n:=n-x[j]*licznik;
licznik:=licznik/10;
end;
end;
end;
String2Real:=n;
end;
procedure ReadNumber(var x: real); //procedura analogiczna do readln, ktora wczytuje liczbe rzeczywista w trybie graficznym
var
i, klawisz: integer;
tablica: array[1..100] of integer;
begin
KeysOff;
al_clear_to_color(AL_SCREEN, black);
al_textout_ex(AL_SCREEN, al_font, 'Podaj liczbe: ', 200, 200, red, black);
i:=1;
repeat
klawisz:=al_readkey;
case klawisz of
6960:
begin
tablica[i]:=0;
al_textout_ex(AL_SCREEN, al_font, '0', 300+7*i, 200, red, black);
i:=i+1;
end;
7217:
begin
tablica[i]:=1;
al_textout_ex(AL_SCREEN, al_font, '1', 300+7*i, 200, red, black);
i:=i+1;
end;
7474:
begin
tablica[i]:=2;
al_textout_ex(AL_SCREEN, al_font, '2', 300+7*i, 200, red, black);
i:=i+1;
end;
7731:
begin
tablica[i]:=3;
al_textout_ex(AL_SCREEN, al_font, '3', 300+7*i, 200, red, black);
i:=i+1;
end;
7988:
begin
tablica[i]:=4;
al_textout_ex(AL_SCREEN, al_font, '4', 300+7*i, 200, red, black);
i:=i+1;
end;
8245:
begin
tablica[i]:=5;
al_textout_ex(AL_SCREEN, al_font, '5', 300+7*i, 200, red, black);
i:=i+1;
end;
8502:
begin
tablica[i]:=6;
al_textout_ex(AL_SCREEN, al_font, '6', 300+7*i, 200, red, black);
i:=i+1;
end;
8759:
begin
tablica[i]:=7;
al_textout_ex(AL_SCREEN, al_font, '7', 300+7*i, 200, red, black);
i:=i+1;
end;
9016:
begin
tablica[i]:=8;
al_textout_ex(AL_SCREEN, al_font, '8', 300+7*i, 200, red, black);
i:=i+1;
end;
9273:
begin
tablica[i]:=9;
al_textout_ex(AL_SCREEN, al_font, '9', 300+7*i, 200, red, black);
i:=i+1;
end;
18734: //gdy zostanie wcisnieta kropka
begin
tablica[i]:=46; //kod kropki w ASCII
al_textout_ex(AL_SCREEN, al_font, '.', 300+7*i, 200, red, black);
i:=i+1;
end;
15661: //gdy zostanie wcisniety znak minus
begin
tablica[i]:=45;
al_textout_ex(AL_SCREEN, al_font, '-', 300+7*i, 200, red, black);
i:=i+1;
end;
16136: //gdy wcisniety zostanie back space
begin
i:=i-1; //cofamy sie o jeden
al_textout_ex(AL_SCREEN, al_font, ' ', 300+7*i, 200, black, black); //zamazuje niechciana cyfre
end;
end;
until klawisz=17165; //jak wcisniemy enter, to petla sie zakonczy
x:=String2Real(tablica, i-1);
end;
begin
inicjalizuj;
i:=0;
al_key[AL_KEY_DOWN]:=1; //to dlatego, ze warunkiem pierwszego ifa jest wcisniecie UP lub DOWN
while (i<>5) or (al_key[AL_KEY_ENTER]=0) do //program ma sie zakonczyc, gdy (i=5) and (al_key[AL_KEY_ENTER]<>0) w while musi byc warunek dzialania, a wiec nalezy tu wstawic zaprzeczenie tego wyrazenie
begin
//al_key[AL_KEY_DOWN]:=1;
if (al_key[AL_KEY_DOWN]<>0) or (al_key[AL_KEY_UP]<>0) then //gdy zostanie wcisniety DOWN albo UP...
begin
if al_key[AL_KEY_DOWN]<>0 then
if i>5 then //dodawanie (modulo 5) gdy zostanie wcisniety klawisz down
i:=1
else
i:=i+1;
if al_key[AL_KEY_UP]<>0 then
if i<1 then
i:=5
else
i:=i-1;
if i=1 then
begin
KeysOff;
WriteMenu(i);
while (al_key[AL_KEY_DOWN]=0) and (al_key[AL_KEY_UP]=0) and (al_key[AL_KEY_ENTER]=0) do; //czeka na wcisniecie DOWN, UP, albo enter
end;
if i=2 then //zmiana predkosci Ziemi
begin
KeysOff;
WriteMenu(i);
while (al_key[AL_KEY_DOWN]=0) and (al_key[AL_KEY_UP]=0) do;
end;
if i=3 then //zmiana promienia Slonca
begin
KeysOff;
WriteMenu(i);
while (al_key[AL_KEY_DOWN]=0) and (al_key[AL_KEY_UP]=0) and (al_key[AL_KEY_ENTER]=0) do;
if al_key[AL_KEY_ENTER]<>0 then //gdy zostanie wcisniety klawisz enter
ReadNumber(promien);
end;
if i=4 then //zmiana masy Jowisza
begin
KeysOff;
WriteMenu(i);
while (al_key[AL_KEY_DOWN]=0) and (al_key[AL_KEY_UP]=0) do;
end;
if i=5 then //wylaczenie programu
begin
KeysOff;
WriteMenu(i);
while (al_key[AL_KEY_DOWN]=0) and (al_key[AL_KEY_ENTER]=0) and (al_key[AL_KEY_UP]=0) do; //tu czekna na nacisniecie klawisza down, up, albo enter
end;
end;
end;
al_exit;
end.
"Graphics" to mój moduł, w którym umieściłem procedurę inicjalizującą bibliotekę allegro, oraz funkcje red, green, blue, black. Czy możecie rzucić na to okiem i powiedzieć mi co jest nie tak?