球拍:在帧%窗口中使用事件

时间:2011-09-03 15:48:52

标签: events scheme racket

我正在学习球拍(以前的 PLT Scheme ,一种LISP方言)并试图发现如何处理不同于paint-callback的事件(可能不是甚至一个。)

我希望从this part of the doc获得很多,但on-charon-event似乎没有做任何我感兴趣的事情(或根本没有任何事情)。

另外,我不了解事件空间,队列回调及其用途。一个例子是一件很酷的事情!我会感谢能给我写一个的好男人:)。

这是我的代码:

(define game (new frame%))

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

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

我想使用“on-mouse-click-left”(不存在)之类的东西,我使用“paint-callback”,但我想我需要添加步骤(我读过有关事件空间等的内容) )。 我知道它不起作用,但这是我正在寻找的假设代码:

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

1 个答案:

答案 0 :(得分:12)

这是一个使用画布和键盘事件的小程序。按下箭头键后,画布会显示您按下的最后一个键。

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

每个帧都有一个管理事件分派的事件空间。 on-char方法是一个事件处理程序;它在事件空间处理程序线程中运行。在on-char方法完成之前,不会再处理任何事件。因此,如果您想要做一些复杂的事情,您可能想要创建一个单独的线程并在那里进行计算。一种简单的方法是创建另一个事件空间,一个不处理任何帧事件的事件空间,但处理使用queue-callback发送它的“事件”。例如,将上面on-char的定义替换为:

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

赋予queue-callback的函数在一个单独的线程中运行。您可以插入一些打印输出,延迟或其他任何内容来说服自己,主事件空间仍然可以处理事件,而另一个处理回调。