Racket 如何使用球拍控制时钟速度?

Racket 如何使用球拍控制时钟速度?,racket,Racket,我试着用Racket写一个从10倒数到0的程序。它起作用了,但是计数速度太快了,有没有办法实现一个设定的时间,每转一秒计数?我一直在努力,但还是找不到。谢谢你抽出时间。以下是我目前的代码: ;; Functions: ;; countdown -> countdown ;; start the world with main at CTR-X CTR-Y ;; (define (main cd) (big-bang cd

我试着用Racket写一个从10倒数到0的程序。它起作用了,但是计数速度太快了,有没有办法实现一个设定的时间,每转一秒计数?我一直在努力,但还是找不到。谢谢你抽出时间。以下是我目前的代码:

;; Functions:

;; countdown -> countdown
;; start the world with main at CTR-X CTR-Y 
;; 
  (define (main cd)
    (big-bang cd                              ; countdown
              (on-tick advance-countdown)     ; countdown -> countdown
              (to-draw render)                ; countdown -> Image
              (on-key handle-key)             ; countdown KeyEvent ->
                                                countdown
              (on-mouse handle-mouse)))       ; Integer Integer MouseEvent 
                                              ; -> countdown

;; countdown -> countdown
;; produce the next number by decrease by 1 from the previous number 
   (check-expect (advance-countdown 5) 4)
   (check-expect (advance-countdown 0) 0)

;(define (advance-countdown cd) 0)  ; stub
;;<use template from Countdown>
  (define (advance-countdown cd)
    (if (= cd 0)
        0
        (- cd 1)))

;; countdown -> Image
;; render ... 
  (check-expect (render 4) (place-image (text (number->string 4) TEXTSIZE 
                                         TEXT-COLOR) CTR-X CTR-Y MTS))
;(define (render cd) MTS) ; stub

  (define (render cd) 
    (place-image (text (number->string cd) TEXTSIZE TEXT-COLOR)
                 CTR-X
               CTR-Y
               MTS))

;; countdown KeyEvent -> countdown
;; reset countdown to 10
   (check-expect (handle-key 10 " ") 10)
   (check-expect (handle-key 10 "a") 10) 
;(define (handle-key cd ke) 0) ; stub

   (define (handle-key cd ke)
     (cond [(key=? ke " ") 10]
           [else cd]))
;;功能:
;; 倒计时->倒计时
;; 在CTR-X CTR-Y以main开始世界之旅
;; 
(定义(主cd)
(大爆炸cd;倒计时)
(勾选前进倒计时);倒计时->倒计时
(绘制渲染);倒计时->图像
(按键手柄键);倒计时键事件->
倒计时
(在鼠标柄上);整数MouseEvent
; -> 倒计时
;; 倒计时->倒计时
;; 在上一个数字的基础上减少1,生成下一个数字
(检查预期(提前倒计时5)4)
(检查预期(提前倒计时0)0)
;(定义(提前倒计时cd)0);树桩
;;
(定义(提前倒计时cd)
(如果(=cd 0)
0
(-cd1)))
;; 倒计时->图像
;; 提供。。。
(选中expect(render 4)(放置图像(文本(数字->字符串4))TEXTSIZE
文本颜色)CTR-X CTR-Y MTS)
;(定义(呈现cd)MTS);树桩
(定义(渲染cd)
(放置图像(文本(数字->字符串cd)文本大小文本颜色)
CTR-X
CTR-Y
MTS)
;; 倒计时键事件->倒计时
;; 将倒计时重置为10
(检查expect(手柄键10“)10)
(检查expect(手柄键10“a”)10)
;(定义(手柄键cd ke)0);树桩
(定义(手柄键cd-ke)
(条件[(键=?ke“”)10]
[光盘])

您正在寻找的是一个“计时器”。球拍内置了一些不同的计时器概念,你们甚至可以自己制作。但其中两个更为突出的内置功能是:

  • -从
    racket/gui/base
    库中,以及
  • -来自web服务器库
或者你也可以自己使用和制作。(您也可以使用更多的“低级”原语制作自己的计时器,但我不建议这样做,因为它很容易犯微妙的错误并获得错误的时间

由于看起来您已经在使用gui(虽然是
HTDP2
gui而不是
racket/gui
),因此允许用户
timer%
。只需创建一个使计时器递减的回调,并在计时器达到0时停止

#lang racket
(require racket/gui/base)
(define count 10)
(displayln count)
(define the-timer
  (new timer% [notify-callback
                (lambda ()
                  (set! count (- count 1))
                  (displayln count)
                  (when (= count 0)
                    (send the-timer stop)))]
              [interval 1000]))

现在,当你运行这个程序时,它应该一次计数10到0 1秒。我们可以用这个函数来测试它。只需获取开始时间、结束时间和差值。当我在我的机器上运行这个程序时,我得到的总时间是“10138”毫秒,或10.138秒。

你要找的是一个“计时器”。Racket有一些不同的否它内置了许多定时器,你甚至可以自己制作。但其中两个更突出的内置定时器是:

  • -从
    racket/gui/base
    库中,以及
  • -来自web服务器库
或者你可以自己使用和(你也可以从更低级的原语中制作自己的计时器,但我不建议这样做,因为它很容易犯微妙的错误并得到错误的时间)

由于看起来您已经在使用gui(虽然是
HTDP2
gui而不是
racket/gui
),因此允许用户
timer%
。只需创建一个使计时器递减的回调,并在计时器达到0时停止

#lang racket
(require racket/gui/base)
(define count 10)
(displayln count)
(define the-timer
  (new timer% [notify-callback
                (lambda ()
                  (set! count (- count 1))
                  (displayln count)
                  (when (= count 0)
                    (send the-timer stop)))]
              [interval 1000]))

现在,当你运行这个程序时,它应该一次计数10到0 1秒。我们可以用这个函数来测试它。只需获取开始时间、结束时间和差值。当我在我的机器上运行这个程序时,我得到的总时间是'10138'毫秒,或10.138秒。

请看,我在Racket中写这篇文章已经有一段时间了,但有什么原因吗不要从
racket/base
使用
sleep
?你可以这样做。如果你想避免使用racket/gui/base,这是一个很好的方法。(尽管在这种情况下,我仍然建议使用
alarm evt
sync
。真正的gatcha是,每次线程醒来后,它必须对其当前时间进行采样,以查看它“实际”睡眠的时间,并相应地设置下一个警报。这是因为睡眠只能保证线程“至少”睡眠的时间你要求它睡觉,但它可以(而且经常会)睡得更久。我在Racket中写过一段时间了,但是有没有理由不使用
Racket/base中的
sleep
?你可以这样做。如果你想避免使用Racket/gui/base,这是一个很好的方法。(尽管在这种情况下,我仍然建议使用
alarm evt
sync
。真正的gatcha是,每次线程醒来后,它必须对其当前时间进行采样,以查看它“实际”睡眠的时间,并相应地设置下一个警报。这是因为睡眠只能保证线程“至少”睡眠的时间你让它睡,但它可以(而且经常会)睡得更多。