使用新列表调用函数

Calling the function with new list

大家好,我想使用 Dracket 制作一个动画,其中有 4 个不同的对象以不同的方式移动,例如“左右上下”,但我遇到了问题。 所以问题是我给了这个函数一个列表,我想用另一个新的列表来调用这个“新”列表的函数,这样它就会自动递归并且形状会不停地移动

我的程序是这样的

    (define R 300)
(define L (* 2 R))
(define U (* 2.5 R))
(define MYSCN (empty-scene L U))


;Structure:
(define-struct SHAPE (type posn direction color size))
;type is a shape of the object and it can only be circle or square (Image)
;posn is the initial point of the shape is drawn (Number)
;direction can be "left right up down" and represents the direction of the shape moves (String)
;color and size are the color and size of the object (String)

;Contructors
(define pos1 (make-posn 450 50))
(define pos3 (make-posn 200 540))
(define shape1 (make-SHAPE "circle" pos1 "down" "red" 50))
(define shape2 (make-SHAPE "square" (make-posn 100 230) "right" "purple" 170))
(define shape3 (make-SHAPE "circle" pos3 "up" "green" 100))
(define shape4 (make-SHAPE "square" (make-posn 500 450) "left" "orange" 155))

(define shapelist1 (list shape1 shape2 shape3 shape4))

;Selectors
(posn-x pos1) ;400 (Number)
(posn-y (SHAPE-posn shape2)) ;200 (Number)
(SHAPE-type shape3) ;"circle" (Image)
(SHAPE-direction shape4) ;"left" (String)
(SHAPE-color shape1) ;"red" (String)

;Predicators
(SHAPE? shape1) ;true
(posn? shape2) ;false
(posn? pos1) ;true

;Purpose: Transferring all the shapes to the scene 
;alltheshapes shapelist1-->image
(define (alltheshapes f)
  (place-image (circle (SHAPE-size (first shapelist1)) "solid" (SHAPE-color (first shapelist1)))
               (posn-x (SHAPE-posn (first shapelist1))) (posn-y (SHAPE-posn (first shapelist1)))
               (place-image
                (square (SHAPE-size (first(rest shapelist1))) "solid" (SHAPE-color (first (rest shapelist1))))
                (posn-x (SHAPE-posn (first(rest shapelist1)))) (posn-y (SHAPE-posn (first(rest shapelist1))))
                (place-image
                 (circle (SHAPE-size (first (rest (rest shapelist1)))) "solid" (SHAPE-color (first (rest (rest shapelist1)))))
                 (posn-x (SHAPE-posn (first (rest (rest shapelist1))))) (posn-y (SHAPE-posn (first (rest (rest shapelist1)))))
                 (place-image
                  (square (SHAPE-size(first(rest(rest(rest shapelist1))))) "solid" (SHAPE-color(first(rest(rest(rest shapelist1))))))
                   (posn-x (SHAPE-posn (first(rest(rest(rest shapelist1)))))) (posn-y (SHAPE-posn (first(rest(rest(rest shapelist1))))))
                   MYSCN)))))


I couldn't figure out the recursive part here 

    ;Purpose: Change the position of the shape according to the current word
    ;Contract: moveshapes shapelist1-->creates a new shape
    
    (define (moveshapes shapelist1)
      (cond
        ((string=? (SHAPE-direction (first shapelist1)) "down") (append (list (make-SHAPE "circle" (make-posn 450 (+ 1 (posn-y pos1)))  "down" "red" 50)) (moveshape (rest shapelist1))))
        ((string=? (SHAPE-direction (first shapelist1)) "right") (append (list (make-SHAPE "square" (make-posn (+ 1 (posn-x (SHAPE-posn shape2))) 230) "right" "purple" 170)) (moveshape (rest shapelist1))))
        ((string=? (SHAPE-direction (first shapelist1)) "up")  (append (list(make-SHAPE "circle" (make-posn 200 (- (posn-y (SHAPE-posn shape3)) 1))  "up" "green" 100)) (moveshape (rest shapelist1))))
        ((string=? (SHAPE-direction (first shapelist1)) "left") (append (list(make-SHAPE "square" (make-posn (- (posn-x (SHAPE-posn shape4)) 1) 450) "left" "orange" 155))))
    

    (define (Project super)
          (big-bang super
            (to-draw alltheshapes) ;Takes the current word and produce an image
            (on-tick moveshapes))) ;It will take the shapes and create a new shape while moving them
        
        (Project shapelist1)

在你进入动画部分之前,我想帮助你消除上面程序中的一些痛点 -

(require 2htdp/image)

; setup my scene
(define my-scene (empty-scene 600 750))

; define structure for scene elements
(define-struct element (image posn direction))

; define my elements
(define e1 (make-element (circle 50 "solid" "red") (make-posn 450 50) "down"))
(define e2 (make-element (square 170 "solid" "purple") (make-posn 100 230) "right"))
(define e3 (make-element (circle 100 "solid" "green") (make-posn 200 540) "up"))
(define e4 (make-element (square 155 "solid" "orange") (make-posn 500 450) "left"))

(define my-elements (list e1 e2 e3 e4))

; place elements into scene
(define (place-elements scene elements)
  (if (null? elements)
      scene
      (place-image (element-image (car elements))
                   (posn-x (element-posn (car elements)))
                   (posn-y (element-posn (car elements)))
                   (place-elements scene (cdr elements)))))

(place-elements my-scene my-elements)

这会呈现以下场景 -

如果您在阅读本文后仍然卡在动画上 post,请告诉我,我会进一步帮助您。

(define R 300)
(define L (* 2 R))
(define U (* 2.5 R))
(define MYSCN (empty-scene L U))


;Structure:
(define-struct SHAPE (type posn direction color size))
;type is a shape of the object and it can only be circle or square (Image)
;posn is the initial point of the shape that drawn (Number)
;direction can be "left right up down" and represents the direction of the shape that moves (String)
;color and size are the color and size of the object (String)

;Contructors
(define pos1 (make-posn 450 60))
(define pos3 (make-posn 160 620))
(define shape1 (make-SHAPE "circle" pos1 "down" "red" 50))
(define shape2 (make-SHAPE "square" (make-posn 100 230) "right" "purple" 170))
(define shape3 (make-SHAPE "circle" pos3 "up" "green" 100))
(define shape4 (make-SHAPE "square" (make-posn 500 450) "left" "orange" 155))

(define shapelist1 (list shape1 shape2 shape3 shape4))

;Selectors
(posn-x pos1) ;450 (Number)
(posn-y (SHAPE-posn shape2)) ;230 (Number)
(SHAPE-type shape3) ;"circle" (String)
(SHAPE-direction shape4) ;"left" (String)
(SHAPE-color shape1) ;"red" (String)

;Predicators
(SHAPE? shape1) ;true
(posn? shape2) ;false
(posn? pos1) ;true


;*****************************************************************************************************************************************************************************************************
;Purpose: add all the image inside of the given list to a scene
;Contract: to-draw (alltheshapes LOS -> Images)

;Example
(check-expect (alltheshapes (list shape1)) (place-image (circle 50 "solid" "red") 450 60 MYSCN))
(check-expect (alltheshapes (list shape3)) (place-image (circle 100 "solid" "green") 160 620 MYSCN))
(check-expect (alltheshapes (list shape4)) (place-image (square 155 "solid" "orange") 500 450 MYSCN))

;Function
(define (alltheshapes a-list)
  (cond
    ((empty? a-list) MYSCN)
    ((string=? (SHAPE-type (first a-list)) "circle")
     (place-image
      (circle (SHAPE-size (first a-list)) "solid" (SHAPE-color (first a-list)))
      (posn-x (SHAPE-posn (first a-list))) (posn-y (SHAPE-posn (first a-list)))
      (alltheshapes (rest a-list))))
    
    ((string=? (SHAPE-type (first a-list)) "square")
     (place-image
     (square (SHAPE-size (first a-list)) "solid" (SHAPE-color (first a-list)))
     (posn-x (SHAPE-posn (first a-list))) (posn-y (SHAPE-posn (first a-list)))
     (alltheshapes (rest a-list))))))

;Test
(alltheshapes (list shape2 shape3))
(alltheshapes (list shape1 shape3 shape4))

;*****************************************************************************************************************************************************************************************************
;Purpose: Moves the shapes every tick
;Contract: on-tick (moveshapes LOS->LOS)

;Example
(check-expect (moveshapes (list shape2)) (cons (make-SHAPE "square" (make-posn 101 230) "right" "purple" 170) '()))
(check-expect (moveshapes (list shape1)) (cons (make-SHAPE "circle" (make-posn 450 61)  "down" "red" 50) '()))
(check-expect (moveshapes (list shape4)) (cons (make-SHAPE "square" (make-posn 499 450) "left" "orange" 155) '()))

;Function
(define (moveshapes a-list)
  (cond
    ((empty? a-list) empty)
    ((string=? (SHAPE-direction (first a-list)) "down") (cons (make-SHAPE (SHAPE-type (first a-list)) (make-posn (posn-x (SHAPE-posn (first a-list))) (+ (posn-y (SHAPE-posn (first a-list))) 1))
                                                                          "down" (SHAPE-color (first a-list)) (SHAPE-size (first a-list))) (moveshapes (rest a-list))))
    
    ((string=? (SHAPE-direction (first a-list)) "right")(cons (make-SHAPE (SHAPE-type (first a-list)) (make-posn (+ 1 (posn-x (SHAPE-posn (first a-list)))) (posn-y (SHAPE-posn (first a-list))))
                                                                          "right" (SHAPE-color (first a-list)) (SHAPE-size (first a-list))) (moveshapes (rest a-list))))
    
    ((string=? (SHAPE-direction (first a-list)) "up") (cons (make-SHAPE (SHAPE-type (first a-list)) (make-posn (posn-x (SHAPE-posn (first a-list))) (- (posn-y (SHAPE-posn (first a-list))) 1))
                                                                        "up" (SHAPE-color (first a-list)) (SHAPE-size (first a-list))) (moveshapes (rest a-list))))
    
    ((string=? (SHAPE-direction (first a-list)) "left") (cons (make-SHAPE (SHAPE-type (first a-list)) (make-posn (- (posn-x (SHAPE-posn (first a-list))) 1) (posn-y (SHAPE-posn (first a-list))))
                                                                          "left" (SHAPE-color (first a-list)) (SHAPE-size (first a-list))) (moveshapes (rest a-list))))
    
    (else a-list)))

;Test
(moveshapes (list shape2 shape1))

;*****************************************************************************************************************************************************************************************************

;----------------------------------------------------------------------------
;Purpose: Help to on-mouse command with creating all the shapes again as a list
;Contract: LOS-> (creates the original forms of the shapes)

;Examples
(check-expect (helperonmouse (list shape2 shape3)) (cons (make-SHAPE "square" (make-posn 100 230) "right" "purple" 170)
                                                         (cons (make-SHAPE "circle" (make-posn 160 620) "up" "green" 100) '())))

(define (helperonmouse shapelist1)
  (cond
    ((empty? shapelist1) empty)
    (else (cons (make-SHAPE (SHAPE-type (first shapelist1)) (make-posn (posn-x (SHAPE-posn (first shapelist1))) (posn-y (SHAPE-posn (first shapelist1))))
                            (SHAPE-direction (first shapelist1)) (SHAPE-color (first shapelist1)) (SHAPE-size (first shapelist1))) (helperonmouse (rest shapelist1))))))

;Test
(helperonmouse (list shape1 shape4))
;----------------------------------------------------------------------------

;Purpose: Every time when you hit mouse1, the animation will restart
;Contract: on-mouse LOS -> LOS 

;Examples
(check-expect (restart (list shape2) 3 5 "button-down") (cons(make-SHAPE"circle"(make-posn 450 60) "down" "red" 50) (cons (make-SHAPE "square" (make-posn 100 230) "right" "purple" 170)
                                                        (cons (make-SHAPE "circle" (make-posn 160 620) "up" "green" 100) (cons (make-SHAPE "square" (make-posn 500 450) "left" "orange" 155)'())))))

(check-expect (restart (list shape4) 6 1 "button-down") (cons (make-SHAPE "circle" (make-posn 450 60) "down" "red" 50) (cons (make-SHAPE "square" (make-posn 100 230) "right" "purple" 170)
                                                        (cons (make-SHAPE "circle" (make-posn 160 620) "up" "green" 100) (cons (make-SHAPE "square" (make-posn 500 450) "left" "orange" 155) '())))))

(check-expect (restart (list shape1) 4 2 "button-down") (cons (make-SHAPE "circle" (make-posn 450 60) "down" "red" 50) (cons (make-SHAPE "square" (make-posn 100 230) "right" "purple" 170)
                                                        (cons (make-SHAPE "circle" (make-posn 160 620) "up" "green" 100) (cons (make-SHAPE "square" (make-posn 500 450) "left" "orange" 155) '())))))


;Function
(define (restart a-list x y clack)
  (cond
    ((empty? a-list) empty)
    ((mouse=? clack "button-down") (helperonmouse shapelist1))
    (else a-list)))

;Test
(restart (list shape1) 3 4 "button-down")

;*****************************************************************************************************************************************************************************************************
;Purpose: When you press the "d" button in your keyboard, one of the images will be deleted
;Contract: on-key LOS-> (- LOS 1)

;Examples
(check-expect (delete (list shape1 shape2) "d") (cons (make-SHAPE "square" (make-posn 100 230) "right" "purple" 170) '()))
(check-expect (delete (list shape2 shape3 shape4) "d") (cons (make-SHAPE "circle" (make-posn 160 620) "up" "green" 100) (cons (make-SHAPE "square" (make-posn 500 450) "left" "orange" 155) '())))
(check-expect (delete (list shape1) "d") '())

;Function
(define (delete a-list a-key)
  (cond
    ((empty? a-list) empty)
    ((key=? a-key "d") (rest a-list))
    (else a-list)))

;Test
(delete (list shape2 shape1) "d")

;*****************************************************************************************************************************************************************************************************
(define (Project super)
  (big-bang super
    (to-draw alltheshapes) ;Takes the current word and produce an image
    (on-tick moveshapes) ;Takes the current word and everytick changes the coordinates of the shapes 
    (on-mouse restart) ;Takes the current word and create the original current word again
    (on-key delete))) ;Takes the current word and remove one element inside of it


(Project shapelist1)