以 60fps 运行球拍/GUI

问题描述 投票:0回答:1

我正在 Racket 中开展我的第一个项目。我认为该语言包含一个跨平台 GUI 工具包真是太棒了,我想集中精力思考如何让它表现良好。

我尝试制作一个小画布,绘制白色和黑色方块的网格,每一帧都会随机化。当您运行下面的程序并按下键盘上的某个键时,它会退出并转储出总体测量的 FPS。

在当前状态下,它在我的 MacBook M1 上以约 20fps 的速度运行。我真的希望能够以至少 60 fps 的速度运行。有人有一些建议可以帮助我到达那里吗?

#lang racket

(require racket/gui)
(require racket/random)

(define *width* 64)
(define *height* 32)
(define *scale* 10)
(define *counted-frames* 0)
(define *start-time* 0)
(define *end-time* 0)

(define *timer*
  (new timer%
       [notify-callback
        (lambda ()
          (update-grid!)
          (send *canvas* refresh-now)
          (flush-output))]))

(define *grid*
  (for/vector ([i (in-range (* *height* *width*))])
    #f))

(define (update-grid!)
  (for ([i (vector-length *grid*)])
    (if (zero? (random 2))
        (vector-set! *grid* i #f)
        (vector-set! *grid* i #t))))

(define (sample-grid)
  (for ([i (in-range 10)])
    (println (vector-ref *grid* i))))

(define (get-element x y)
  (vector-ref *grid* (+ (* y *width*) x)))

(define *frame*
  (new frame% [label "Checkboard Grid"]
       [width (* *scale* *width*)]
       [height (* *scale* *height*)]))

(define rect-canvas%
  (class canvas%
    (inherit get-dc)
    (super-new)
    (define/override (on-char event)
      (begin
             (fprintf (current-error-port)
                      "Received key event: ~a, quitting\n" event)
             (set! *end-time* (current-inexact-milliseconds))
             (println (format "FPS: ~a"
                              (/ (* 1000 *counted-frames*)
                                 (- *end-time* *start-time*))))
             (exit)))
    (define/override (on-paint)
      (set! *counted-frames* (+ 1 *counted-frames*))
      (let ((dc (get-dc)))
        (for* ([x (in-range *width*)] [y (in-range *height*)])
          (if (get-element x y)
              (begin
                (send dc set-pen "black" 1 'solid)
                (send dc set-brush "black" 'solid))
              (begin
                (send dc set-pen "white" 1 'solid)
                (send dc set-brush "white" 'solid)))
          (send dc draw-rectangle (* x 10) (* y 10) 10 10))))))

(define *canvas* (new rect-canvas% [parent *frame*]))

(define (run)
  (set! *start-time* (current-inexact-milliseconds))
  (send *frame* show #t)
  (send *timer* start 1))

(run)
performance lisp racket
1个回答
0
投票

球拍话语上回答过,引用如下:

“我不认为,在不做更少的绘制工作的情况下,你会看到更高的 fps。

这可能会给你带来一点收获:

   (define black-pen   (new pen%   [color "black"] [width 1] [style 'solid]))
    (define white-pen   (new pen%   [color "white"] [width 1] [style 'solid]))
    (define black-brush (new brush% [color "black"]           [style 'solid]))
    (define white-brush (new brush% [color "white"]           [style 'solid]))
    (define dc (get-dc))
    (define/override (on-paint)
      (set! *counted-frames* (+ 1 *counted-frames*))
      (for* ([x (in-range *width*)] [y (in-range *height*)])
        (if (get-element x y)
            (begin
              (send dc set-pen   black-pen)
              (send dc set-brush black-brush))
            (begin
              (send dc set-pen   white-pen)
              (send dc set-brush white-brush)))
        (send dc draw-rectangle (* x 10) (* y 10) 10 10)))

如果您的游戏是具有 10x10“像素”的复古游戏,那么您可以获得加速 通过使用低分辨率的位图,例如 100x80,然后 通过在屏幕上绘制位图的缩放副本来进行绘制完成。

这里使用了这个技术:

https://github.com/soegaard/sketching/blob/main/sketching-examples/examples/pacman/maze-game.rkt

[虽然不是 60 fps。]

如果这还不够快,您需要了解如何使用 GPU - 要么 直接或使用可用的库之一。”

© www.soinside.com 2019 - 2024. All rights reserved.