Created
November 10, 2020 20:00
-
-
Save sojohnnysaid/efdb2872efff13eb491abde31205b8c7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 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