Programming
C++
Turbo Pascal
Delphi
Ver. 1.0 Beta, Don't have a compiler? Now you can write simple scripts ONLINE! This is a basic version -does not include all the Pascal statements. Only to learn basics
Data i Czas w Turbo Pascalu -jak pobierać datę, jak wyświetlić godzinę w swoim programie, Jak napisać zegar wskazówkowy
Data i czas
Moduł 'Dos' Turbo Pascal'a udostępnia funkcje, za pomocą których możesz uzyskać wiadomości o bieżącej godzinie a także dacie. Pascal umożliwia również sprawdzenie ile milisekund jest włączony komputer bez użycia dodatkowych modułów. Ponieważ część operacji opisanych w tym rozdziale będzie operawała na module Dos, musimy go zadeklarować, czyli wpisać na początku programu: uses Dos; Badanie czasuprocedure GetTime(var Hour, Minute, Second, Sec100 : Word); procedura GetTime zwraca aktualny czas komputerowy. Zapisuje go do Twoich zmiennych, które wstawisz do procedury. Można uzyskać czas choćby w taki sposób: uses Dos; var h, m, s, ss : Word; begin GetTime(h, m, s, ss); WriteLn('Jest godzina: ', h, ':', m); end. Można korzystać ze zmiennych o dowolnej nazwie, ale zadeklarowanych jako Word. Badanie datyprocedure GetDate(var Year, Month, Day, DayOfWeek : Word); procedura GetDate zwraca aktualną datę. Zapisuje ją także do Twoich zmiennych, które wstawisz do procedury. Jeśli chodzi o dni tygodnia, gdy program zwróci 0 będzie to niedziela Można uzyskać datę choćby w taki sposób: uses Dos; var y, m, d, dw : Word; begin GetDate(y, m, d, dw); WriteLn('Dzisiaj jest: ', y, '-', m, '-', d); end. W trybie graficznymZadanie wyświetlania godziny i daty w trybie graficznym jest nieco trudniejsze, ale także proste. Jeśli pierwszy raz próbujesz w grafice wyświetlić czas lub datę, pewnie spotka Cię niemiłe zaskoczenie i błąd: „Type Mismatch”. Najprawdopodobniej będziesz chciał tak samo jak to robiłeś we WriteLn, użyć OutText, lub OutTextXY. To normalne dla człowieka, niestety nie dla komputera. Niestety nie wolno napisać tak: Dlaczego? Twoje zadanie polega więc na zbudowaniu jednej zmiennej tekstowej, która będzie zawierała całą informację łącznie z godziną -czyli zmienną liczbową. Kolejna trudność powstaje z tym, że nie wolno łączyć zmiennej tekstowej z liczbową. Są one całkiem inaczej zapisywane w pamięci komputera. Dzięki temu liczby zajmują mniej miejsca w pamięci i komputerowi jest znacznie łatwiej robić na nich operacje matematyczne. Zamiana zmiennej liczbowej na tekstową Str(Liczba : LongInt; var Tekst : string); Służy do tego procedura Str var i : Integer; s : string; begin i := 10; Str(i, s); WriteLn(s); end; Przygotowanie zmiennej tekstowej zawierającej aktualną datę: uses Dos; var y, m, d, dw : Word; temp, s : string; begin GetDate(y, m, d, dw); Str(y, temp); s := 'Dzisiaj jest: ' + temp; Str(m, temp); s := s + '-' + temp; Str(d, temp); s := s + '-' + temp; WriteLn(s); end. Zegar wskazówkowy*Do stworzenia zegara wskazówkowego będzie potrzebna lekka umiejętność matematyki. Naszym zadaniem będzie obliczenie kątów jakie wskazówka pokonała od godziny 0:00. Będziemy zamieniali liczbę minut, które minęły od początku godziny na stopnie, a stopnie na radiany. Podobna operacja czeka nas z godziną i sekundami. Kolejna uwaga, Twoja karta grafiki musi być zgodna ze standardem VESA. Niestety, coraz więcej firm produkujących karty graficzne, zrezygnowało z podtrzymywania tego standardu. Być może będziesz musiał programować na VirtualPC -program, na którym można emulować inny komputer. Niżej opisany jest ogólny schemat budowy i rozwoju programu. Pomoże Ci ustalić jak w rzeczywistości powstaje bardziej skomplikowany kod. W rzeczywistości trzeba go podzielić na mniejsze punkty, co chwilę je testować i dodawać kolejne. Warto regularnie zapisywać program (F2) – przed każdym jego uruchomieniem, a nawet co napisanie kilku linii programu. Uruchomienie grafiki Wyłączenie grafiki Najpierw zajmujemy się najprostszymi operacjami, w dodatku tymi, bez których dalszy kod programu nie ruszy. W tym wypadku włączeniem grafiki. Uruchomienie grafiki Narysowanie tarczy zegara Wyłączenie grafiki Później warto narysować tarczę, czyli zobaczyć pierwsze efekty swojej pracy. Tarcza będzie jeszcze bez wskazówek, ale da Tobie dużo satysfakcji... w końcu coś zaczyna się dziać. Następnie dobrze narysować krótkie linie, ułatwiające odczytanie z tarczy minuty. Będzie ich 60, najlepiej zrobić to w pętli i pierwszy raz skorzystać w poważnej matematyki (Sinus, Cosinus). Jest 360 stopni w pełnym kole, więc co 6 stopni powinna być kolejna linia. Ale jak za pomocą stopni ustalić pozycje 60 linii? Będziemy potrzebowali wyliczyć współrzędne x i y dla każdego punktu. Każda linia potrzebuje 2 punktów. Trzeba przypomnieć więc kilka informacji z matematyki: Długość odcinka "a", czyli oddalenie wyliczanego punktu od środka liczymy ze wzoru: a = r cos ?. Długość odcinka c = r sin ?. Teraz do środka współrzędnych tarczy musimy dodać: w poziomie odcinek a, a w pionie odjąć odcinek c. Manipulując promieniem -dodając jeden odrobinę dłuższy od drugiego otrzymamy dwie współrzędne dla dwóch punktów. Możemy połączyć już je linią. W Pascalu funkcje sinus i cosinus potrzebują wartości w radianach by wyliczyć żądaną wartość. W pełnym kole jest 360 stopni co odpowiada wartości 2? (w radianach). Z tego wynika, że 360° = 2? (rad), 1° = 2? / 360 (rad), 1° = ? / 180 (rad), x° odpowiada x * (? / 180) (rad), Aby więc wyliczyć sin 30° wpiszemy: WriteLn Sin(30 * (PI / 180)); Co piąta minuta powinna być grubsza. FOR i:=1 TO 60 DO BEGIN IF (i MOD 5<>0) THEN SetLineStyle(0, $FF, 1) ELSE SetLineStyle(0, $FF, 3); SetColor(7); Line(Sx+Round(Sin((540-i*6)*(PI/180))*(DlM+12)), Sy+Round(Cos((540-i*6)*(PI/180))*(DlM+12)), Sx+Round(Sin((540-i*6)*(PI/180))*(DlM+18)), Sy+Round(Cos((540-i*6)*(PI/180))*(DlM+18))); END; Potrzebny jest nam promień tarczy zegara a także kąt jaki pokonała wskazówka. W matematyce kąty liczymy od poziomu w górę, w zegarze interesują nas kąty od godziny dwunastej w dół. Przy rysowaniu poruszającej się wskazówki trzeba więc uwzględnić, że ruch wskazówek zegara jest przeciwny do zwiększającego się kąta w matematyce a w dodatku nie zaczyna się od tego samego miejsca. To jednak nie jest dla nas problemem. Wskazówka minutowa matematycznie pokonuje drogę od kąta 90 stopni, potem 84, 78, 72 aż do 0 a następnie 354, 348 itd.. aż do 90 stopni. Zamiast zwiększać kąty, będziemy je odejmować od 90. (Wskazówka minutowa porusza się kątowo wg wzoru: ? = 90 – m * 6, gdzie zmienna m to kolejna minuta od 0 do 59) Godzina dwunasta ma kąt 90 stopni, trzecia ma kąt 0 stopni, szósta 270 a dziewiąta 180. Czyli wskazówka godzinowa występuje co 30 stopni. Z tego wzór na obliczenie kąta godziny to: ? = 90 – g * 30, gdzie g to numer godziny (od 0 do 11) Z wartościami kątów nie będzie problemów, bo przecież rysujemy 60 razy linię co 6 stopni. Korzystając z pętli ze zmienną i od 1 do 60, będziemy po prostu mnożyli zmienną "i" przez 6. Orzymamy w wyniku 6, 12, 18, 24... 354, 360 Narysowanie tarczy zmobiluzuje Cię do dalszej pracy. Trzeba pamiętać, by dodać pętlę czekającą na naciśnięcie klawisza, żeby wogóle cokolwiek zauważyć. Uruchomienie grafiki Dodanie pętli aż do momentu naciśnięcia klawisza Narysowanie tarczy zegara Koniec pętli Wyłączenie grafiki Pętla spowoduje, że program będzie się wykonywał w kółko. Zacznie od początku, dojdzie do końca i znowu zacznie od początku. while (PORT[$60]<>1) do begin {...} end Tarczę zegara i wskazówki rysujemy tylko wtedy, gdy jest to potrzebne, czyli co sekundę -gdy pozycja wskazówek ulegnie zmianie. Nie ma potrzeby, żeby tarcza się cały czas rysowała, bo będzie to obciążało procesor komputera a poza tym będzie bardzo mocno migało. Dlatego właśnie w programie jest warunek: GetTime(h, m, s, ss); if (s<>sse) then begin {...} sse := s; end; W tym wypadku zmienna sse przechowuje starą wartość sekund a zmienna 's' aktualną. Jeśli aktualna ilość sekund jest różna od starej, wtedy... rysujemy cały zegar. Oczywiście trzeba po sprawdzeniu warunku do zmiennej 'sse' przypisać wartość 's', bo teraz starą sekundą będzie ta, właśnie narysowana. A jak narysować wskazówki? To jest znacznie prostsze od narysowania tarczy. Jeden koniec wskazówki będzie w środku koła, drugi koniec będzie ruchomy, będzie przesuwał się dookoła tarczy. Uruchomienie grafiki Dodanie pętli aż do momentu naciśnięcia klawisza Dodanie warunku -jeśli zmieniła się sekunda Narysowanie tarczy zegara Narysowanie wskazówek Koniec pętli Wyłączenie grafiki Już wiemy jak obliczyć współrzędne X i Y punktu znajdującego się na okręgu o podanym promieniu, dla dowolnego kąta. Teraz wystarczy zamienić ilość minut, sekund i godzin na odpowiedni kąt i wszystko gotowe. Rysujemy trzy linie, każdą o jej własnym stylu graficznym. Line(Sx, Sy, Sx+Round(Sin((540-m*6)*(PI/180))*DlM), Sy+Round(Cos((540-m*6)*(PI/180))*DlM)); Zmienna Sx, Sy oznacza tu środek tarczy zegara. 'm' to ilość minut. (540-m*6) to zamieniona ilość minut na kąt. (540-m*6)*(PI/180) to obliczenie wartości radianowej z kątowej -bo tego właśnie wymaga funkcja Sin(). Na koniec mnożymy otrzymany wynik przez DlM, czyli długość wskazówki minutowej. Jeśli zmienisz wartość DlM na mniejszą, wskazówka będzie krótsza, jeśli ułożysz nieprawidłowo obliczanie kąta, wskazówka będzie się cofać, albo zaczynać nie od minuty :00 tylko od innego miejsca. Poniżej znajduje się całkowity kod źródłowy zegara wskazówkowego w Turbo Pascalu. Poeksperymentuj trochę z zegarem a dużo się z tego nauczysz. Będziesz wtedy dobrze wiedzieć co odpowiada za jakie właściwości i przede wszystkim łatwiej Ci będzie zrozumieć ideę tworzenia podobnych kodów. uses Graph, Dos; const Sx : Integer = 320; Sy : Integer = 240; DlM = 100; DlH = 80; DlS = 90; GM = 1; GH = 3; GS = 1; var h, m, s, ss : Word; sse : Word; i : Integer; grDriver: Integer; grMode: Integer; ErrCode: Integer; function IntToStr(i:Integer):string; var s:string; begin Str(i, s); if (i<10) then s:='0'+s; IntToStr:=s; end; begin grDriver :=Detect; InitGraph(grDriver, grMode,' '); ErrCode := GraphResult; if ErrCode = grOk then begin { Do graphics } while (PORT[$60]<>1) do begin GetTime(h, m, s, ss); if (s<>sse) then begin ClearDevice; SetColor(10); OutTextXY(560, 460, IntToStr(h)+':'+IntToStr(m)+':'+IntToStr(s)); SetColor(7); SetFillStyle(1, 8); FillEllipse(Sx, Sy, DlM+20, DlM+20); for i:=1 to 60 do begin if (i mod 5<>0) then SetLineStyle(0, $FF, 1) else SetLineStyle(0, $FF, 3); SetColor(7); Line(Sx+Round(Sin((540-i*6)*(PI/180))*(DlM+12)), Sy+Round(Cos((540-i*6)*(PI/180))*(DlM+12)), Sx+Round(Sin((540-i*6)*(PI/180))*(DlM+18)), Sy+Round(Cos((540-i*6)*(PI/180))*(DlM+18))); end; sse := s; SetColor(15); SetLineStyle(0, $FF, GH); Line(Sx, Sy, Sx+Round(Sin((540-h*30)*(PI/180))*DlH), Sy+Round(Cos((540-h*30)*(PI/180))*DlH)); SetColor(9); SetLineStyle(0, $FF, GM); Line(Sx, Sy, Sx+Round(Sin((540-m*6)*(PI/180))*DlM), Sy+Round(Cos((540-m*6)*(PI/180))*DlM)); SetColor(12); SetLineStyle(0, $FF, GS); Line(Sx, Sy, Sx+Round(Sin((540-s*6)*(PI/180))*DlS), Sy+Round(Cos((540-s*6)*(PI/180))*DlS)); end; end; CloseGraph; end else Writeln('Graphics error:', GraphErrorMsg(ErrCode)); end. |
ON-LINE scripts!