gpt4 book ai didi

scheme - 如何在 Breakout 中让球与砖 block 碰撞( Racket )

转载 作者:太空宇宙 更新时间:2023-11-03 19:01:34 25 4
gpt4 key购买 nike

我一直在尝试让 Breakout 在 Racket 中工作,到目前为止,球从桨上弹起(桨由鼠标控制)并且砖 block 存在

完整代码如下:

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

(define WIDTH 400)
(define HEIGHT 400)
(define BALL-RADIUS 10)
(define BALL-IMG (circle BALL-RADIUS "solid" "red"))

(define REC-WIDTH 50)
(define REC-HEIGHT 10)
(define REC-IMG (rectangle REC-WIDTH REC-HEIGHT "solid" "grey"))

(define BRICK-IMG0 (rectangle 60 30 "solid" "blue"))
(define BRICK-IMG1 (rectangle 60 30 "solid" "green"))

(define SCENE (empty-scene WIDTH HEIGHT))

(define STARTGAME
(text "CLICK TO START" 60 "purple"))

(define GAMEOVER
(text "GAMEOVER" 60 "red"))

(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

(define-struct rec (pos))
;
;

(define-struct brick (pos))
;
;

; 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 bricks 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 ball rec)
(cond
[(<= (posn-x ball) BALL-RADIUS) "left"]
[(<= (posn-y ball) BALL-RADIUS) "top"]
[(>= (posn-x ball) (- WIDTH BALL-RADIUS)) "right"]
[(>= (posn-y ball) (- HEIGHT BALL-RADIUS)) "GAMEOVER"]
[(and (>= (posn-x ball) (- (posn-x (rec-pos rec)) (/ REC-WIDTH 2)))
(<= (posn-x ball) (+ (posn-x (rec-pos rec)) (/ REC-WIDTH 2)))
(= (posn-y ball) (posn-y (rec-pos rec)))) "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 a-world)
(draw-ball (world-ball a-world)
(draw-bricklist (world-bricks a-world)
(draw-rect (world-rec a-world)))))


(define (draw-ball ball img)
(place-image BALL-IMG
(posn-x (ball-loc ball))
(posn-y (ball-loc ball))
img))

(define (draw-rect rec)
(place-image REC-IMG
(posn-x (rec-pos rec))
(posn-y (rec-pos rec))
SCENE))


(define (draw-bricklist list img)
[cond ((empty? list) img)
((cons? list) (draw-bricklist (rest list) (draw-brick (first list) img)))])

(define (draw-brick brick image)
(place-image (choice BRICK-IMG0 BRICK-IMG1)
(posn-x (brick-pos brick))
(posn-y (brick-pos brick))
image))


(define (choice a b )
(if (zero? (random 1)) a b ))

; 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 (tick world)
(make-world (move-ball (make-ball (ball-loc (world-ball world))
(bounce (ball-velocity (world-ball world))
(collision (ball-loc (world-ball world))
(world-rec world)))))
(world-rec world)
(world-bricks world)))



(define (mouse world mouse-x mouse-y mouse-event)
(cond
[(string=? mouse-event "move") (make-world (world-ball world)
(make-rec (make-posn mouse-x REC-Y-POS))
(world-bricks world))]
[else world]))



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

(define REC-Y-POS (- HEIGHT (+ 20 REC-HEIGHT)))
(define INITIAL-REC (make-rec (make-posn 100 REC-Y-POS)))
(define INITIAL-BRICKS (list
(make-brick (make-posn 50 100))
(make-brick (make-posn 111 100))
(make-brick (make-posn 172 100))
(make-brick (make-posn 233 100))
(make-brick (make-posn 294 100))
(make-brick (make-posn 355 100))
(make-brick (make-posn 50 131))
(make-brick (make-posn 111 131))
(make-brick (make-posn 172 131))
(make-brick (make-posn 233 131))
(make-brick (make-posn 294 131))
(make-brick (make-posn 355 131))
(make-brick (make-posn 50 162))
(make-brick (make-posn 111 162))
(make-brick (make-posn 172 162))
(make-brick (make-posn 233 162))
(make-brick (make-posn 294 162))
(make-brick (make-posn 355 162))))






(define-struct world (ball rec bricks))

(define INITIAL-WORLD-STATE (make-world INITIAL-BALL INITIAL-REC INITIAL-BRICKS))

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

(main INITIAL-WORLD-STATE)

球直接穿过砖 block 。我向其中添加了以下代码:

;--------------------------------------------------------------------------------------------------
(define (overlap?
brick-one-x brick-one-y brick-one-width brick-one-height
brick-two-x brick-two-y brick-two-width brick-two-height)
(cond
[(and
(and
(>= (+ brick-one-x brick-one-width) brick-two-x); within right bounds
(<= brick-one-x (+ brick-two-x brick-two-width)); within left bounds
)
(and
(>= (+ brick-one-y brick-one-height) brick-two-y) ;within top bounds
(<= brick-one-y (+ brick-two-y brick-two-height)) ; within bottom bounds
))
#t]
[else ;not overlapping
#f]))



(define (brick-collide-ball? brick ball)
(if
(overlap?
;balls dimensions and location
(posn-x (ball-loc ball))
(posn-y (ball-loc ball))
10
10
;first brick in list
(posn-x (brick-pos brick))
(- (posn-y (brick-pos brick)) 10)
60
30)
#t
#f))

(define (delete-bricks bricklist ball)
(cond
[(empty? bricklist) empty]
((cons? bricklist)
(if (brick-collide-ball? (first bricklist) ball)
(delete-bricks (rest bricklist) ball)
(cons (first bricklist)(delete-bricks (rest bricklist) ball))))))

;--------------------------------------------------------------------------------------------------------

但似乎并没有对任何事情产生影响。我现在被困住了,如果有任何改进建议,我将不胜感激!

最佳答案

我在我的 Atari 经典版本中使用了以下内容:

(define (colliding? b1 b2)
(match-define (body x1 y1 w1 h1) b1)
(match-define (body x2 y2 w2 h2) b2)
(not (or (eq? b1 b2)
(< (+ x1 w1) x2) (> x1 (+ x2 w2))
(< (+ y1 h1) y2) (> y1 (+ y2 h2)))))

这里 Racket 和球都是一个“ body ”,是一个长方形具有 (x,y) 位置和宽度 w 以及高度 h。

(struct body (x y w h) #:transparent)

注意:如果您的球碰巧移动得非常快,它可能会“跳过” Racket 。这可以通过设置最大速度来解决。

关于scheme - 如何在 Breakout 中让球与砖 block 碰撞( Racket ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48037371/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com