使用线程在多个位置动画一系列图像

时间:2017-02-26 04:08:19

标签: image animation scheme racket

我正在尝试以下代码:

#lang racket/gui
(require 2htdp/image)

; list of images to be animated: 
(define images (list (circle 30 "outline" "red")
                     (circle 20 "outline" "red")
                     (circle 10 "outline" "red")
                     (circle  5 "outline" "red")))

(define (image->bitmap image)   ;from: https://lists.racket-lang.org/users/archive/2014-December/065110.html
  (let* ([width (image-width image)]
         [height (image-height image)]
         [bm (make-bitmap width height)]
         [dc (send bm make-dc)])
    (send dc clear)
    (send image draw dc 0 0 0 0 width height 0 0 #f)
    bm))

(define frame (new frame% [label "Frame"] [width 300] [height 300]))
(define canvas (new canvas% [parent frame]))
(define a-dc (send canvas get-dc))

(send frame show #t)
(sleep/yield 1)


(define x 20)
(define y 20)

(define (thunk)
  (let loop ()  ; endless loop
    (for ((i images))
      (send a-dc draw-bitmap (image->bitmap i) x y)
      (sleep 0.5)) 
    (loop)))

(thread thunk) 

(set! x 100)
(set! y 100)
(thread thunk)

(set! x 200)
(set! y 200)
(thread thunk)

然而,只有第三个动画运行,而其他动画只显示最大的圆圈(第一个图像)。显然,先前的线程也采用新的x和y值。我怎样才能让它们保留最初发送的x和y值?我不能在thunk函数中有任何参数,因为它必须被发送到需要无参数函数参数的线程函数! (我希望我的复杂陈述/论证在功能上是正确的。)

问题出在哪里?

2 个答案:

答案 0 :(得分:1)

每个线程都指的是相同的x和y坐标。这意味着所有线程都在同一个地方绘制。

这是一个示例,显示有两组不同的x和y变量可用。

#lang racket/gui
(require 2htdp/image)

; list of images to be animated: 
(define images (list (circle 30 "outline" "red")
                     (circle 20 "outline" "red")
                     (circle 10 "outline" "red")
                     (circle  5 "outline" "red")))

(define (image->bitmap image)   ;from: https://lists.racket-lang.org/users/archive/2014-December/065110.html
  (let* ([width (image-width image)]
         [height (image-height image)]
         [bm (make-bitmap width height)]
         [dc (send bm make-dc)])
    (send dc clear)
    (send image draw dc 0 0 0 0 width height 0 0 #f)
    bm))

(define frame (new frame% [label "Frame"] [width 300] [height 300]))
(define canvas (new canvas% [parent frame]))
(define a-dc (send canvas get-dc))

(send frame show #t)
(sleep/yield 1)


(define x 20)
(define y 20)

(define (thunk)
  (let loop ()  ; endless loop
    (for ((i images))
      (send a-dc draw-bitmap (image->bitmap i) x y)
      (sleep 0.5)) 
    (loop)))

(thread thunk) 

(define X 100)
(define Y 100)

(define (thunk2)
  (let loop ()  ; endless loop
    (for ((i images))
      (send a-dc draw-bitmap (image->bitmap i) X Y)
      (sleep 0.5)) 
    (loop)))

(thread thunk2) 

不要为每个坐标设置变量,而应考虑将它们存储在数据结构中(例如散列表),并让线程从数据结构中读取坐标。

使用单个绘图功能一次绘制所有对象会更简单。

但是如果你想要多个线程,那么使用一个函数来创建thunk:

(define (make-thunk n) 
   (lambda () 
     (let loop () ... )))

使用n选出第n个对象的坐标...))然后用(thread (make-thunk 0)) (thread (make-thunk 1))

创建线程

答案 1 :(得分:0)

根据@soegaard的回答,我发现以下<div id="list"> </div> fn非常便于在多个地方以不同的速度显示图像列表:

animateImageList

输出:

enter image description here

相关问题