Skip to content

Instantly share code, notes, and snippets.

@sojohnnysaid
Created November 10, 2020 20:00
Show Gist options
  • Save sojohnnysaid/efdb2872efff13eb491abde31205b8c7 to your computer and use it in GitHub Desktop.
Save sojohnnysaid/efdb2872efff13eb491abde31205b8c7 to your computer and use it in GitHub Desktop.
;; CMPU 101 Assignment 3
;; <YOUR NAME>
;;
;; Description: Uses a list of bouncing balls to animate many balls
;; of different sizes and colors, all moving in the same scene at
;; different speeds.
(require 2htdp/image)
(require 2htdp/universe)
(define RADIUS 25)
;; Scene dimensions
(define WIDTH 500)
(define HEIGHT 300)
;; Create the background scene image
(define BACKGROUND
(place-image (rectangle WIDTH HEIGHT "solid" "lightblue")
(/ WIDTH 2) (/ HEIGHT 2)
(empty-scene WIDTH HEIGHT)))
;;
;; Data Definitions
;;
(define-struct ball [im x y dx dy])
;; A Ball is a (make-ball im p dx dy) where
;; - im is an image (of the ball),
;; - x and y are numbers giving the position of the center of the ball, and
;; - dx and dy are numbers giving the ball's horizontal and vertical velocity
;; A ListOfBalls is either:
;; - '(), or
;; - (cons b lob), where b is a ball and lob is a ListOfBalls
;;;;;;
;; Define four (4) example Ball constants
;; One touching each edge of the scene (top, bottom, left, right)
;; These will help you test bounce conditions.
;; Here's one of my ball constants, which you may use or modify if you like
;; to define the rest.
(define TEALBALL (circle RADIUS "solid" "teal"))
(define TOP-BOUNDARY (- HEIGHT RADIUS))
(define BOTTOM-BOUNDARY RADIUS)
(define RIGHT-BOUNDARY (- WIDTH RADIUS))
(define LEFT-BOUNDARY RADIUS)
(define CENTER-Y (/ HEIGHT 2))
(define CENTER-X (/ WIDTH 2))
(define VELOCITY-UP -4)
(define VELOCITY-DOWN 4)
(define VELOCITY-RIGHT -4)
(define VELOCITY-LEFT 4)
(define BALL-AT-LEFT
(make-ball TEALBALL LEFT-BOUNDARY CENTER-Y VELOCITY-RIGHT VELOCITY-DOWN))
(define BALL-AT-RIGHT
(make-ball TEALBALL RIGHT-BOUNDARY CENTER-Y VELOCITY-LEFT VELOCITY-UP))
(define BALL-AT-TOP
(make-ball TEALBALL CENTER-X TOP-BOUNDARY VELOCITY-LEFT VELOCITY-DOWN))
(define BALL-AT-BOTTOM
(make-ball TEALBALL CENTER-X BOTTOM-BOUNDARY VELOCITY-RIGHT VELOCITY-UP))
;;;;;;
;; Define INIT-LOB to be a ListOfBalls:
;; You will use this to be the initial state of the world.
;; I've defined it to be the empty list, but you should define it
;; to contain the four example ball constants you just defined.
;;(define INIT-LOB '())
(define INIT-LOB
(list BALL-AT-BOTTOM BALL-AT-TOP BALL-AT-RIGHT BALL-AT-LEFT))
;;
;; Templates for a Ball and a ListOfBalls
;; Use these to help you get started with the functions below.
;;
;; Ball -> ???
;; Template for a function that consumes a Ball
(define (fun-for-ball b)
(... (ball-im b) ...
(ball-x b) ... (ball-y b) ...
(ball-dx b) ... (ball-dy b) ...))
;; ListOfBalls -> ???
;; Template for a function that consumes a ListOfBalls
(define (fun-for-list-of-balls lob)
(cond [(empty? lob) ...]
[(cons? lob)
(... (fun-for-ball (first lob)) ...
(fun-for-list-of-balls (rest lob)) ...)]))
;;;;;;
;; Design the functions below, in order. I've supplied the
;; signature, purpose statement, and header for each function.
;;
;; You provide the check-expect examples, and using the appropriate
;; template, complete the function bodies.
;;
;; I recommend you proceed in order, and complete each function,
;; with passing tests, before going on to the next.
;;
;; The reason for completing the functions in the order they appear
;; is earlier functions can be used as helper functions for the
;; later functions.
;; Ball -> Number
;; Compute the radius of the given Ball
;;(define (ball-radius b) 0)
;; helper
(define (get-ball-diameter b)(image-height (ball-im b)))
(define (ball-radius b)
(/ (get-ball-diameter b) 2))
;; A Ball is a (make-ball im p dx dy) where
;; - im is an image (of the ball),
;; - x and y are numbers giving the position of the center of the ball, and
;; - dx and dy are numbers giving the ball's horizontal and vertical velocity
;; Ball -> Boolean
;; Determine whether the Ball reached the top edge of the scene
(define (top-edge? b) (>= (ball-y b) TOP-BOUNDARY ))
(check-expect (top-edge? BALL-AT-TOP) #true)
(check-expect (top-edge? BALL-AT-BOTTOM) #false)
;; Ball -> Boolean
;; Determine whether the Ball reached the bottom edge of the scene
(define (bottom-edge? b) (<= (ball-y b) BOTTOM-BOUNDARY ))
(check-expect (bottom-edge? BALL-AT-TOP) #false)
(check-expect (bottom-edge? BALL-AT-BOTTOM) #true)
;; Ball -> Boolean
;; Determine whether the Ball reached the left edge of the scene
(define (left-edge? b) (<= (ball-x b) LEFT-BOUNDARY ))
(check-expect (left-edge? BALL-AT-LEFT) #true)
(check-expect (left-edge? BALL-AT-RIGHT) #false)
;; Ball -> Boolean
;; Determine whether the Ball reached the right edge of the scene
(define (right-edge? b) (>= (ball-x b) RIGHT-BOUNDARY ))
(check-expect (right-edge? BALL-AT-RIGHT) #true)
(check-expect (right-edge? BALL-AT-LEFT) #false)
;; Ball -> Ball
;; Reverse the Ball's up-down direction
(define (reverse-up-down b)
(make-ball (ball-im b)
(ball-x b)
(ball-y b)
(ball-dx b)
(* (ball-dy b) -1)))
;; Ball -> Ball
;; Reverse the ball's left-right direction
(define (reverse-left-right b)
(make-ball (ball-im b)
(ball-x b)
(ball-y b)
(* (ball-dx b) -1)
(ball-dy b)))
;; Ball -> Ball
;; Change the direction of the given Ball if it hit the top or bottom edge
(define (bounce-up-down b)
(cond [(top-edge? b)(reverse-up-down b)]
[(bottom-edge? b)(reverse-up-down b)]
[else b]))
;; Ball -> Ball
;; Change the direction of the given Ball if it hit the left or right edge
(define (bounce-left-right b)
(cond [(left-edge? b)(reverse-left-right b)]
[(right-edge? b)(reverse-left-right b)]
[else b]))
;; Ball -> Ball
;; Move the given ball by its dx and dy amounts
(define (move-ball b)
(make-ball (ball-im b)
(+ (ball-x b) (ball-dx b))
(+ (ball-y b) (ball-dy b))
(ball-dx b)
(ball-dy b)))
;; ListOfBalls -> ListOfBalls
;; Move (and possibly bounce) each Ball in the given list
(define (move-list-of-balls lob)
(map (lambda (item)
(move-ball(bounce-left-right(bounce-up-down item))))
lob))
;; Ball Image -> Image
;; Render the given Ball b on the given background bg
(define (render-ball b bg)
(place-image
(ball-im b)
(ball-x b)
(ball-y b)
bg
)
)
;; ListOfBalls -> Image
;; Produces image of each Ball at each given current position on background
;; (Yes, I provided this function for you! You shouldn't have to
;; touch it if you've correctly implemented the functions above.)
(define (render-balls lob)
(cond [(empty? lob) BACKGROUND]
[(cons? lob)
(render-ball (first lob)
(render-balls (rest lob)))]))
;; Here's the main function with the big-bang expression!
;; Once you've implemented move-list-of-balls, uncomment on-tick below.
(define (main w)
(big-bang w
[on-tick move-list-of-balls]
[to-draw render-balls]))
;; Run program automatically, or type this in Interactions Pane:
;; Use INIT-LOB as the initial state of the world...
(main INIT-LOB)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment