Rozdział 18


Ruch

 

Podsumowanie

Dosyć często będziesz chciał sprawić, aby program wykonywał się przez określony okres czasu, a do tego celu przydatnym będzie polecenie PAUSE.

 

PAUSE n

 

zatrzymuje obliczenia i wyświetla obraz przez n ramek telewizyjnych (w Europie występują one 50 razy na sekundę a w Ameryce 60 razy na sekundę). Wartość n może być do 65535, co daje ci nieco mniej niż 22 minuty; jeśli n=0, to oznacza to "wieczną pauzę".

Pauzę zawsze można przerwać przez naciśnięcie jakiegoś klawisza (zauważ, że CAPS SHIFT i spacja również spowodują przerwanie programu). Gdy pauza się rozpocznie, musisz nacisnąć klawisz.

 

Ten program tworzy wskazówkę sekundową zegara:

 

  10 REM najpierw tarcza zegara
  20 FOR n=1 TO 12
  30 PRINT AT 10-10*COS (n/6*PI),16+10*SIN (n/6*PI);n
  40 NEXT n
  50 REM teraz uruchamiamy zegar
  60 FOR t=0 TO 200000: REM t jest czasem w sekundach
  70 LET a=t/30*PI : REM a jest katem wskazowki sekundowej w radianach
  80 LET sx=80*SIN a: LET sy=80*COS a
200 PLOT 128,88: DRAW OVER 1;sx,sy: REM rysujemy wskazowke sekundowa
210 PAUSE 42
220 PLOT 128,88: DRAW OVER 1;sx,sy: REM wymazujemy wskazowke sekundowa
400 NEXT t

 

 

Ten zegar zatrzyma się po około 55,5 godzinach z powodu wiersza 60, lecz z łatwością możesz zmusić go do dłuższej pracy. Teraz jak odmierzanie czasu jest kontrolowane przez wiersz 210. Mógłbyś oczekiwać, że PAUSE 50 sprawi, że będzie tykał co sekundę, lecz obliczenia również zajmują nieco czasu i muszą być wykonywane. Najlepiej to zrobić metodą prób i błędów, sprawdzając czas zegara komputerowego z rzeczywistym zegarem i regulując wiersz 210 aż do momentu, gdy będą zgodne. (Nie uda ci się tego dokonać dokładnie; zmiana liczby ramek w jednej sekundzie daje dokładność 2%, czyli pół godziny na dzień.)

 

Istnieje dużo precyzyjniejszy sposób odmierzania czasu. Korzysta on z zawartości pewnych komórek pamięci. Przechowywane dane są pobierane za pomocą PEEK. W Rozdziale 25 znajdziesz dokładny opis tych komórek. Używane wyrażenia ma postać

 

(65536*PEEK 23674+256*PEEK 23673+PEEK 23672)/50

 

Daje to liczbę sekund od momentu uruchomienia komputera (do około 3 dni i 21 godzin, zanim się przewinie do zera).

 

Oto zmieniony program zegara, który wykorzystuje tą opcję:

 

  10 REM najpierw tarcza zegara
  20 FOR n=1 TO 12
  30 PRINT AT 10-10*COS (n/6*PI),16+10*SIN (n/6*PI);n
  40 NEXT n
  50 DEF FN t()=INT((65536*PEEK 23674+256*PEEK 23673+PEEK 23672)/50): REM liczba sekund od startu
100 REM teraz uruchamiamy zegar
110 LET t1=FN t()
120 LET a=t1/30*PI: REM a jest katem wskazowki sekundowej w radianach
130 LET sx=72*SIN a: LET sy=72*COS a
140 PLOT 131,91: DRAW OVER 1;sx,sy: REM rysuj wskazowke
200 LET t=FN t()
210 IF t<=t1 THEN GO TO 200: REM czekaj az nadejdzie czas na ruch wskazowki
220 PLOT 131,91: DRAW OVER 1;sx,sy: REM wymazujemy stara wskazowke
230 LET t1=t: GO TO 120

 

Wewnętrzny zegar wykorzystywany w tej metodzie powinien posiadać dokładność około 0,01%, gdy komputer wykonuje tylko program, co daje 10 sekund na dobę; lecz czasowo zatrzymuje się, gdy wykonywane jest polecenie BEEP, operacja na taśmie magnetofonowej, wykorzystywana jest drukarka lub inne dodatkowe wyposażenie, które możesz używać z tym komputerem. Wszystko to będzie powodowało utratę czasu.

Liczby PEEK 23674, PEEK 23673 i PEEK 23672 są przechowywane wewnątrz komputera i wykorzystywane do zliczania 50-tych części sekundy. Każda z nich ma wartość od 0 do 255 i są one stopniowo zwiększane przez wszystkie wartości kolejno od 0 do 255; po 255 znów przyjmują wartość 0.

Najczęściej zmienia się PEEK 23672. Co każdą 1/50 część sekundy zwiększa się o 1. Gdy dojdzie do 255, to kolejne zwiększenie przenosi ją na 0, a w tym samym czasie zwiększa się o 1 PEEK 23673. Gdy (co każde 256/50 sekund) PEEK 23673 przewinie się z 255 na 0, to z kolei PEEK 23674 jest zwiększane o 1. Powinno to wystarczać do wyjaśnienia, dlaczego powyższe wyrażenie działa.

Teraz, rozważmy dokładnie: załóżmy, że nasze 3 liczby mają wartość 0 (dla PEEK 23674), 255 (dla PEEK 23673) i 255 (dla PEEK 23672). Oznacza to, że minęło około 21 minut od włączenia — nasze wyrażenie powinno dać w wyniku

 

(65536*0+256*255+255)/50=1310.7

 

Lecz istnieje ukryte niebezpieczeństwo. Gdy pojawi się kolejne zliczenie 1/50 sekundy, te trzy liczby zmienią się na 1, 0 i 0. Gdy stanie się to w połowie wyliczania wartości wyrażenia, to komputer obliczy PEEK 23674 jako 0 (jeszcze stara wartość sprzed zmiany), lecz pozostałe dwie jako 0 (nowe wartości po zmianie). Wtedy wyrażenie przyjmie wartość:

 

(65536*0+256*0+0)/50=0

 

co jest całkiem źle.

W celu uniknięcia tego problemu stosujemy prostą regułę: wyrażenie jest kolejno obliczane dwukrotnie i za wynik przyjmujemy wartość większą.

Jeśli przyjrzysz się dokładnie powyższemu programowi, to zobaczysz, że faktycznie on to robi, lecz niejawnie.

Oto pewna sztuczka do zastosowania tej reguły. Zdefiniuj funkcje

 

10 DEF FN m(x,y)=(x+y+ABS (x-y))/2: REM wieksza z x i y
20 DEF FN u()=(65536*PEEK 23674+256*PEEK 23673+PEEK 23672)/50: REM czas, moze byc zly
30 DEF FN t()=FN m(FN u(), FN u()): REM czas, dobry

 

Możesz zmienić te trzy liczniki tak, aby podawały rzeczywisty czas zamiast czasu od włączenia komputera. Na przykład, aby ustawić czas na 10:00 rano, wyliczasz, że jest to 10*60*60*50=1800000 pięćdziesiątych części sekundy, a to dalej jest równe:

 

1800000=65536*27+256*119+64

 

Aby ustawić te trzy liczby na 27, 119 i 64, wykonujesz

 

POKE 23672,64: POKE 23673,119: POKE 23674,27

 

Kolejność jest ważna, ponieważ znów może dojść do zwiększenia o 1 ustawionej wartości, jeśli w trakcie wpisywania nadejdzie zmiana liczników.

 

W krajach z częstotliwością sieci 60 Hz w tych programach musisz zamienić 50 przez 60 wszędzie tam, gdzie trzeba.

 

Funkcja INKEY$ (nie posiadająca argumentu) odczytuje klawiaturę. Jeśli naciskasz dokładnie jeden klawisz (lub klawisz SHIFT i dokładnie jeden inny klawisz), to wynikiem jest znak, który ten klawisz daje w trybie L; w przeciwnym razie wynikiem jest pusty łańcuch.

Wypróbuj ten program, który działa jak maszyna do pisania.

 

10 IF INKEY$ <>"" THEN GO TO 10
20 IF INKEY$ ="" THEN GO TO 20
30 PRINT INKEY$;
40 GO TO 10

 

Tutaj wiersz 10 czeka, aż podniesiesz palec z klawiatury, a wiersz 20 czeka, aż naciśniesz nowy klawisz.

Pamiętaj, że w przeciwieństwie do INPUT, INKEY$ nie czeka na ciebie. Więc nie musisz wpisywać na końcu ENTER, lecz z drugiej strony, jeśli zupełnie nic nie wpiszesz, to przegapisz swoją szansę.

 

Ćwiczenia

1. Co się stanie, gdy pominiesz wiersz 10 w programie maszyny do pisania?

 

2. Innym sposobem używania INKEY$ jest połączenie z PAUSE, jak w tym alternatywnym programie maszyny do pisania.

 

10 PAUSE 0
20 PRINT INKEY$;
30 GO TO 10

 

Aby to działało, dlaczego jest istotne, aby pauza nie kończyła się, gdy stwierdzi naciśnięty klawisz w momencie swojego startu?

 

3. Przerób drugi program ze wskazówką sekundową tak, aby pokazywał również wskazówkę minutową i godzinną, rysując je co każdą minutę. Jeśli sądzisz, że jesteś ambitny, to zrób tak, aby co kwadrans pojawiał się jakiś pokaz — może uda ci się wygrać jakąś melodię za pomocą poleceń BEEP. (Patrz kolejny rozdział.)

 

4. (Dla sadystów.) Wypróbuj to:

 

10 IF INKEY$ ="" THEN GO TO 10
20 PRINT AT 11,14;"OJ!"
30 IF INKEY$ <>"" THEN GO TO 30
40 PRINT AT 11,14;"     "
50 GO TO 10

 

 


   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2018 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.

Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl

W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe