2011-09-03 7 views
6

sto imparando Racket (ex PLT Scheme, un dialetto LISP) e cercare di scoprire come gestire gli eventi differenti rispetto paint-callback (forse non è nemmeno uno).Racket: utilizzando gli eventi in una finestra% telaio

Spero molto da this part of the doc ma on-char e on-event sembrano non fare nulla che possa interessarmi (o niente del tutto).

Inoltre, non capisco gli spazi degli eventi, la richiamata della coda e i loro usi. Un esempio sarebbe una cosa interessante! Sarò grato all'uomo gentile che me ne scriverà uno :).

Ecco il mio codice:

(define game (new frame%)) 

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

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

voglio usare qualcosa come "on-mouse-click-sinistra" (che non esiste) il modo in cui io uso "paint-callback" ma credo di è necessario aggiungere passaggi (ho letto su spazi eventi ecc.). So che non funziona, ma qui è il codice ipotetica che sto cercando:

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

Penso che un esempio di ciò che vuoi fare sia di grande aiuto nel mostrare come è fatto. – Svante

+0

Ecco il mio codice: '(definire gioco (nuovo telaio%)) (definire gameLay (tela classe% (super-nuovo))) (nuova gameLay [gioco genitore] [vernice-callback (λ (canvas dc) ; disegnare cose )]})) ' Voglio usare qualcosa come" on-mouse-click-sinistro "(che non esiste) il modo in cui uso" paint-callback " ma penso di aver bisogno di aggiungere dei passaggi (ho letto degli spazi degli eventi ecc.). – L01man

+0

Ho inserito queste informazioni nella tua domanda. Si prega di correggere il codice; ci sono parentesi e parentesi non corrispondenti alla fine, quindi potrebbe non essere quello che intendevi. Per rendere l'esempio più chiaro, basta mettere l'ipotetico "clic sul mouse" nell'esempio proprio come si vorrebbe usarlo. – Svante

risposta

10

Ecco un piccolo programma che utilizza tele e gli eventi di tastiera. Dopo aver premuto un tasto freccia, la tela mostra l'ultimo premuto.

#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) 

Ogni frame ha uno spazio eventi che gestisce l'invio di eventi. Il metodo on-char è un gestore di eventi; viene eseguito nel thread del gestore eventi. Non verranno elaborati altri eventi fino al completamento del metodo on-char. Quindi se vuoi fare qualcosa di complicato, potresti voler creare un thread separato e fare il calcolo laggiù. Un modo semplice per farlo è creare un altro spazio eventi, uno che non gestisca eventi per qualsiasi frame, ma che gestisca gli "eventi" che lo invii usando queue-callback. Ad esempio, sostituire la definizione di on-char sopra con questo:

(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))))))) 

La funzione attribuita ad queue-callback viene eseguito in un thread separato. È possibile inserire alcune stampe, ritardi o altro per convincersi che lo spazio eventi principale può ancora elaborare gli eventi mentre l'altro gestisce la richiamata.

+0

Ooooh, grazie mille. Quando ho [link] (http://docs.racket-lang.org/search/index.html?q=key&q=get-key-code&q=refresh) ho cercato "chiave" nella barra di ricerca [/ link] non ho trovo niente Grazie al tuo codice sarò in grado di finire il mio piccolo progetto (felice)! – L01man

+0

Se una risposta funziona per te, devi cliccare su "accetta" per indicare agli altri che ha funzionato. –

+0

Hai ragione, ho appena trovato questo pulsante (il tick che si trova a sinistra delle risposte). Grazie Ryan, funziona perfettamente. Davvero, davvero, fantastico! – L01man

Problemi correlati