【问题标题】:Programming Breakout in Racket (BSL) using big-bang. Running into an error upon placing the paddle使用 big-bang 在 Racket (BSL) 中编程 Breakout。放置桨时出错
【发布时间】:2017-12-16 17:20:22
【问题描述】:

我们的目标是制作游戏 Breakout 并逐步完成。我已经在实施桨的第一步遇到了问题。球和球的弹跳已经预先定义和给出。我希望像这样把它放在(定义(渲染球)中:

(define (render ball worldstate)
(place-image BALL-IMG
           (posn-x (ball-loc ball))
           (posn-y (ball-loc ball))
(place-image PADDLE (posn-x (world-state-paddle worldstate)) (posn-y (world-state-paddle worldstate))
           SCENE)))

但是我收到错误“to-draw:一个参数的预期函数作为第一个参数;给定 2 个参数的函数”我不确定如何使代码更好。这是我的代码到目前为止的样子。球和刻度线已经预定义。到目前为止,我什至无法将球拍放入,但球会反弹(尚未实施任何砖块)

(require 2htdp/image)
(require 2htdp/universe)

(define WIDTH 200)
(define HEIGHT 200)
(define BALL-RADIUS 10)
(define BALL-IMG (circle BALL-RADIUS "solid" "red"))
(define SCENE (empty-scene WIDTH HEIGHT))

(define PADDLE (rectangle 60 10 "solid" "green"))
(define SPEED 4)

(define-struct vel (delta-x delta-y))
; a Vel is a structure: (make-vel Number Number)
; interp. the velocity vector of a moving object

(define-struct ball (loc velocity))
; a Ball is a structure: (make-ball Posn Vel)
; interp. the position and velocity of a object 

; Posn Vel -> Posn
; applies q to p and simulates the movement in one clock tick
(check-expect (posn+vel (make-posn 5 6) (make-vel 1 2))
              (make-posn 6 8))

(define (posn+vel p q)
  (make-posn (+ (posn-x p) (vel-delta-x q))
             (+ (posn-y p) (vel-delta-y q))))


; Ball -> Ball
; computes movement of ball in one clock tick
(check-expect (move-ball (make-ball (make-posn 20 30)
                                    (make-vel 5 10)))
              (make-ball (make-posn 25 40)
                     (make-vel 5 10)))

(define (move-ball ball)
  (make-ball (posn+vel (ball-loc ball)
                       (ball-velocity ball))
         (ball-velocity ball)))


; A Collision is either
; - "top"
; - "down"
; - "left"
; - "right"
; - "none"
; interp. the location where a ball collides with a wall

; Posn -> Collision
; detects with which of the walls (if any) the ball collides
(check-expect (collision (make-posn 0 12))  "left")
(check-expect (collision (make-posn 15 HEIGHT)) "down")
(check-expect (collision (make-posn WIDTH 12))  "right")
(check-expect (collision (make-posn 15 0)) "top")
(check-expect (collision (make-posn 55 55)) "none")

(define (collision posn)
  (cond
    [(<= (posn-x posn) BALL-RADIUS) "left"]
    [(<= (posn-y posn) BALL-RADIUS)  "top"]
    [(>= (posn-x posn) (- WIDTH BALL-RADIUS)) "right"]
    [(>= (posn-y posn) (- HEIGHT BALL-RADIUS)) "down"]
    [else "none"]))

; Vel Collision -> Vel  
; computes the velocity of an object after a collision
(check-expect (bounce (make-vel 3 4) "left")
              (make-vel -3 4))
(check-expect (bounce (make-vel 3 4) "top")
              (make-vel 3 -4))
(check-expect (bounce (make-vel 3 4) "none")
              (make-vel 3 4))

(define (bounce vel collision)
  (cond [(or (string=? collision "left")
         (string=? collision "right"))
     (make-vel (- (vel-delta-x vel))
               (vel-delta-y vel))]
    [(or (string=? collision "down")
         (string=? collision "top"))
     (make-vel (vel-delta-x vel)
               (- (vel-delta-y vel)))]
    [else vel]))

; WorldState is a Ball
; interp. the current state of the ball

; WorldState -> Image
; renders ball at its position
;(check-expect (image? (render INITIAL-BALL)) #true)

(define (render ball worldstate)
  (place-image BALL-IMG
           (posn-x (ball-loc ball))
           (posn-y (ball-loc ball))
           SCENE))

; WorldState -> WorldState
; moves ball to its next location
(check-expect (tick (make-ball (make-posn 20 12) (make-vel 1 2)))
              (make-ball (make-posn 21 14) (make-vel 1 2)))

(define (tick ball)
  (move-ball (make-ball (ball-loc ball)
                    (bounce (ball-velocity ball)
                            (collision (ball-loc ball))))))


(define-struct world-state (paddle speed ball))

;WorldState is a structure (make-world-state paddle speed Ball)

(define Example-world-state (make-world-state PADDLE SPEED (make-ball (make-posn 20 12)
                                                      (make-vel 1 2))))

;mouse
;Worldstate Number Number MouseEvent -> Worldstate
;moves the paddle
(define (mouse worldstate x y mouseEvent)
  (make-world-state (world-state-speed worldstate) (world-state-ball     worldstate)
                (cond
                  [(string=? mouseEvent "move")
                   (make-posn x y)]
                  [else (world-state-paddle worldstate)])))




(define INITIAL-BALL (make-ball (make-posn 20 12)
                            (make-vel 1 2)))

(define INITIAL-WORLD-STATE INITIAL-BALL)

(define (main state)
  (big-bang state (on-tick tick 0.01) (to-draw render) (on-mouse mouse)))

(main INITIAL-WORLD-STATE)

感谢您提供的任何提示!

【问题讨论】:

    标签: scheme lisp racket breakout racket-student-languages


    【解决方案1】:

    我注意到您的“渲染”函数签名是

    世界状态 -> 图像

    但是,render 有 2 个参数:

     `(define (render ball worldstate) ...)`
    

    签名用于类型检查和更好地记录您的工作以供其他人理解,在这种情况下,它帮助我快速找到问题:)

    根据您提供的错误:

    (to-draw render)

    在函数'main'中期望渲染是一个只接收1个参数的函数,而在你的代码中它被定义为一个接受2个参数的函数:

    在此处查看渲染和绘制: to-draw@docs.racket-lang.org

    【讨论】:

    • 我明白了,所以在做 (to-draw ...) 或 (on-tick ...) 时只接受一个参数?或者如果我给它两个参数,比如 (to-draw render render2),它会接受 2 个参数吗?
    • 这些函数都是重载的,to-draw可以带1个或3个参数。从我的回答中的文档中:(to-draw render-expr)=“......调用函数render-expr......它的大小由第一个生成的图像的大小决定。”或者您可以使用: (to-draw render-expr width-expr height-expr) = "...使用 width-expr by height-expr canvas 而不是由第一个生成的图像确定的。"也请查看on-tick
    【解决方案2】:

    render函数只以世界状态为参数,不能再添加参数。
    您已经拥有该状态的桨,您可以从中取回球和桨:

    (define (render world)
        (place-image BALL-IMG
               (posn-x (ball-loc (world-state-ball world))
               (posn-y (ball-loc (world-state-ball world))
        ...
    

    您可能想为组件编写单独的渲染函数:

    (define (render-ball ball)
         ...)
    
    (define (render-paddle paddle)
         ...)
    
    (define (render-world world)
        (render-ball (world-state-ball world))
        (render-paddle (world-state-paddle world))
    

    【讨论】:

    • 因此,如果我有这些不同的渲染,然后最后将这种情况下的渲染世界放入我的(定义(主状态))中,一切都应该显示出来?:D 我理解正确吗?
    • @DelightWang 嗯,他们应该,但我不承诺任何事情 ;-) (当您想要添加多球模式时,制作单独的函数会派上用场,或两人模式。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-13
    • 1970-01-01
    • 2012-06-05
    • 2012-04-24
    • 2021-12-15
    • 2021-03-01
    • 1970-01-01
    相关资源
    最近更新 更多