2011-09-03 14 views
6

uczę Rakieta (dawniej PLT Scheme, dialekt LISP) i spróbować dowiedzieć się, jak obsługiwać zdarzenia inaczej niż paint-callback (może to nawet nie jeden).Racket: using wydarzenia w ramie okna%

Mam nadzieję, że wiele z this part of the doc, ale on-char i on-event wydaje się nie robić nic, co mogłoby mnie zainteresować (lub w ogóle nic).

Co więcej, nie rozumiem obszarów zdarzeń, kolejki-wywołania zwrotnego i ich zastosowań. Przykładem może być fajna rzecz! Będę wdzięczny miłemu człowiekowi, który mi napisze :).

Oto mój kod:

(define game (new frame%)) 

(define gameLay (class canvas% (super-new))) 

(new gameLay 
    [parent game] 
    [paint-callback (λ (canvas dc) #|draw things|#)]) 

chcę użyć czegoś w stylu „na kliknięcie myszą-left” (który nie istnieje) sposób używam „paint-zwrotnej”, ale myślę, trzeba dodać kroki (czytałem o obszarach zdarzeń itp.). wiem, że to nie działa, ale tutaj jest hipotetyczny kod Szukam:

(new gameLay 
    [parent game] 
    [paint-callback (λ (canvas dc) #|draw things|#)] 
    [on-mouse-click-left (λ (canvas dc) #|do other things|#)]) 
+1

Myślę, że przykład tego, co chcesz zrobić, naprawdę pomoże ci pokazać, jak to się robi. – Svante

+0

Oto mój kod: '(określić grę (nowa rama%)) (określić gameLay (klasa płótno% (super-nowy))) (nowa gameLay [rodzic gra] [farby zwrotna (λ (canvas dc) ; rysuj rzeczy )]})) ' Chcę użyć czegoś w rodzaju" kliknięcia lewym przyciskiem myszki "(co nie istnieje) w taki sposób, w jaki używam" wywołania funkcji malowania " ale myślę, że muszę dodać kroki (czytałem o obszarach zdarzeń itp.). – L01man

+0

Umieściłem te informacje w twoim pytaniu. Popraw kod; na końcu znajdują się niedopasowane nawiasy i klamry, więc może to nie być zamierzone. Aby uczynić przykład bardziej przejrzystym, po prostu umieść hipotetyczne "kliknięcie myszą" w przykład w taki sposób, w jaki chciałbyś go użyć. – Svante

Odpowiedz

10

Oto mały program za pomocą płótna i zdarzeń klawiaturowych. Po naciśnięciu klawisza strzałki płótno pokazuje ostatnie naciśnięcie.

#lang racket/gui 

(define game-canvas% 
    (class canvas% 
    (inherit get-width get-height refresh) 

    ;; direction : one of #f, 'left, 'right, 'up, 'down 
    (define direction #f) 

    (define/override (on-char ke) 
     (case (send ke get-key-code) 
     [(left right up down) 
     (set! direction (send ke get-key-code)) 
     (refresh)] 
     [else (void)])) 

    (define/private (my-paint-callback self dc) 
     (let ([w (get-width)] 
      [h (get-height)]) 
     (when direction 
      (let ([dir-text (format "going ~a" direction)]) 
      (let-values ([(tw th _ta _td) 
          (send dc get-text-extent dir-text)]) 
       (send dc draw-text 
        dir-text 
        (max 0 (/ (- w tw) 2)) 
        (max 0 (/ (- h th) 2)))))))) 

    (super-new (paint-callback (lambda (c dc) (my-paint-callback c dc)))))) 

(define game-frame (new frame% (label "game") (width 600) (height 400))) 
(define game-canvas (new game-canvas% (parent game-frame))) 
(send game-frame show #t) 

Każda klatka ma przestrzeń zdarzeń, która zarządza wysyłaniem zdarzeń. Metoda on-char jest procedurą obsługi zdarzeń; jest uruchamiany w wątku procedury obsługi obszaru zdarzeń. Żadne dalsze zdarzenia nie zostaną przetworzone, dopóki nie zakończy się twoja metoda on-char. Jeśli chcesz zrobić coś skomplikowanego, możesz utworzyć oddzielny wątek i wykonać obliczenia. Jednym prostym sposobem na zrobienie tego jest utworzenie innej przestrzeni zdarzeń, która nie obsługuje zdarzeń dla żadnej ramki, ale która obsługuje "zdarzenia", które wysyłasz, używając queue-callback. Na przykład, należy wymienić definicji on-char powyżej to:

(define aux-eventspace (make-eventspace)) 

(define/override (on-char ke) 
    (parameterize ((current-eventspace aux-eventspace)) 
    (queue-callback 
    (lambda() 
     (case (send ke get-key-code) 
     ((left right up down) 
      (set! direction (send ke get-key-code)) 
      (refresh)) 
     (else (void))))))) 

Funkcja uwagę na queue-callback prowadzi się w oddzielnym wątku. Możesz wstawić niektóre wydruki, opóźnienia lub cokolwiek innego, aby przekonać się, że główna przestrzeń zdarzeń może nadal przetwarzać zdarzenia, podczas gdy druga obsługuje wywołania zwrotne.

+0

Ooooh Wielkie dzięki. Kiedy [link] (http://docs.racket-lang.org/search/index.html?q=key&q=get-key-code&q=refresh) wyszukiwany "klucz" w pasku wyszukiwania [/ link] I didn niczego nie znajdziesz. Dzięki twojemu kodowi będę mógł dokończyć mój mały projekt (szczęśliwy)! – L01man

+0

Jeśli odpowiedź ci odpowiada, powinieneś kliknąć "zaakceptuj", aby wskazać innym, że zadziałało. –

+0

Masz rację, właśnie znalazłem ten przycisk (tyknięcie unoszące się po lewej stronie odpowiedzi). Dziękuję Ryan, działa perfekcyjnie. Naprawdę, naprawdę, świetnie! – L01man