- ;Aalok Kharidia
- ;Computer Science FINAL PROJECT
- ;Section C
- ;Part 1: Due: Monday April 30th, 2012
- ;Part 2: Due: Monday May 14th, 2012
- ;ULTIMATE FIELD GOAL KICKING GAME!!
- ; ;````````_____``_____``_____```_________``_____``____````____```````_`````_________``________````````
- ; ;```````|_```_||_```_||_```_|`|``_```_``||_```_||_```\``/```_|`````/`\```|``_```_``||_```__``|```````
- ; ;`````````|`|````|`|````|`|```|_/`|`|`\_|``|`|````|```\/```|``````//_\\``|_/`|`|`\_|``|`|_`\_|```````
- ; ;`````````|`'````'`|````|`|```_```|`|``````|`|````|`|\``/|`|`````/`___`\`````|`|``````|``_|`_````````
- ; ;``````````\`\__/`/````_|`|__/`|`_|`|_````_|`|_``_|`|_\/_|`|_``_/`/```\`\_``_|`|_````_|`|__/`|```````
- ; ;````````````.__.'````|________||_____|``|_____||_____||_____||____|`|____||_____|``|________|```````
- ; ;````````````````````````````````````````````````````````````````````````````````````````````````````
- ; ;`________``_____``________``_____`````______`````````````````______`````___````````_```````_____````
- ; ;|_```__``||_```_||_```__``||_```_|```|_```_``.`````````````.'`___``|``.'````.`````/`\`````|_```_|```
- ; ;``|`|_`\_|``|`|````|`|_`\_|``|`|```````|`|``.`\```````````/`.'```\_|`/``.-.``\```//_\\``````|`|`````
- ; ;``|``_|`````|`|````|``_|`_```|`|```_```|`|``|`|```````````|`|```____`|`|```|`|``/`___`\`````|`|```_`
- ; ;`_|`|_`````_|`|_``_|`|__/`|`_|`|__/`|`_|`|_.'`/```````````\``.___]``|\``'-'``/_/`/```\`\_``_|`|__/`|
- ; ;|_____|```|_____||________||________||______.'``````````````._____.'```.___.'|____|`|____||________|
- ; ;````````````````````````````````````````````````````````````````````````````````````````````````````
- ; ;````````````````___``____```_____```______``___``____```_____``____``_____```______`````````````````
- ; ;```````````````|_``||_``_|`|_```_|.'`___``||_``||_``_|`|_```_||_```\|_```_|.'`___``|````````````````
- ; ;`````````````````|`|_/`/`````|`|`/`.'```\_|``|`|_/`/`````|`|````|```\`|`|`/`.'```\_|````````````````
- ; ;`````````````````|``__'.`````|`|`|`|`````````|``__'.`````|`|````|`|\`\|`|`|`|```____````````````````
- ; ;````````````````_|`|``\`\_``_|`|_\``.___.'\`_|`|``\`\_``_|`|_``_|`|_\```|_\``.___]``|```````````````
- ; ;```````````````|____||____||_____|`.____`.'|____||____||_____||_____|\____|`._____.'````````````````
- ; ;````````````````````````````````````````````````````````````````````````````````````````````````````
- ; ;``````````````````````````______```````_```````____````____``________``_``_`````````````````````````
- ; ;````````````````````````.'`___``|`````/`\`````|_```\``/```_||_```__``||`||`|````````````````````````
- ; ;```````````````````````/`.'```\_|````//_\\``````|```\/```|````|`|_`\_||`||`|````````````````````````
- ; ;```````````````````````|`|```____```/`___`\`````|`|\``/|`|````|``_|`_`|`||`|````````````````````````
- ; ;```````````````````````\``.___]``|_/`/```\`\_``_|`|_\/_|`|_``_|`|__/`||_||_|````````````````````````
- ; ;`````````````````````````._____.'|____|`|____||_____||_____||________|(_)(_)````````````````````````
- ; ;````````````````````````````````````````````````````````````````````````````````````````````````````
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; ;
- ; GAME DESCRPTION ;
- ; ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;This game is very closely related to kicking a field goal in a normal football game online. The ;
- ;game will contain a field goal post, a ball, a kicker, and a scoreboard. The field goal post will ;
- ;be represented by two yellow squares of dimensions 25x25 pixels. These squares will be separated ;
- ;by a vertical distance of 50 pixels. The ball will be represented by a circle of radius 10. Also, ;
- ;the starting position of the ball will be at a random x-location between 50 and 100, and the y- ;
- ;location will be constant. The kicker will be a rectangle of height 50 and width 5. The scene ;
- ;will be of width 400 and height 300. The kick will be successful if the ball passes between the ;
- ;two yellow squares. The user will first use the UP and DOWN arrow keys to set the angle at ;
- ;which the kicker will kick the ball. The arrow will be in the direction of an arrow. After setting;
- ;the angle, the user will hit the SPACEBAR to verify the angle. Next, there will be a countdown ;
- ;from 3. When the countdown reaches 0, the kicker will move towards the ball at a constant ;
- ;speed. The kicker will kick the ball, and the ball will move towards the field goal post at the ;
- ;specified angle. The kick will be successful if the ball passes between the two yellow squares. ;
- ;Each kick will be worth 15 points, and the user will have 10 lives. The scoreboard will say how ;
- ;many lives remain, and how many points the user has gained. There will be acid rain. This rain ;
- ;will have the ability to make any ball disintegrate. The rain will fall down in columns in the ;
- ;middle of the scene at reasonable intervals. The intervals will not be too small. This is so that ;
- ;the ball will have the possibility of safely passing through the rain. The rain will be in a ;
- ;random number of columns. There will be 1, 2, or 3 columns of rain. The rain will begin to fall ;
- ;when the SPACEBAR is hit. ; ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;```______````_```````````````````````````_``````````````````````````````````;;;;;;;;;;;;
- ;;;;;;;;;;;;`.'`____`\``/`|_````````````````````````/`|_````````````````````````````````;;;;;;;;;;;;
- ;;;;;;;;;;;;`|`(___`\_|`|`|-'_`.--.``__```_```.---.`|`|-'__```_```_`.--.``.---.``.--.```;;;;;;;;;;;;
- ;;;;;;;;;;;;``_.____`.``|`|`[``/'`\][``|`|`|`/`/'`\]|`|`[``|`|`|`[``/'`\]/`/__\\(`(`\]``;;;;;;;;;;;;
- ;;;;;;;;;;;;`|`\____)`|`|`|,`|`|`````|`\_/`|,|`\__.`|`|,`|`\_/`|,`|`|````|`\__.,``'.'.``;;;;;;;;;;;;
- ;;;;;;;;;;;;``\______.'`\__/[___]````'.__.'_/'.___.'\__/`'.__.'_/[___]````'.__.'[\__)`)`;;;;;;;;;;;;
- ;;;;;;;;;;;;````````````````````````````````````````````````````````````````````````````;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; ;
- ; BALL ;
- ; ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;A ball is a structure. This structure
- ;will contain x location, y location
- ;speed, an angle and a color,
- ;besides yellow.
- ;(make-ball number number number number string)
- (define-struct ball (x y speed angle color))
- ; ;Template
- ; (define (ball-func ball)
- ; (... (ball-x ball)...
- ; (ball-y ball)...
- ; (ball-speed ball)...
- ; (ball-angle ball)...
- ; (ball-color ball)...))
- (make-ball 50 570 10 30 "red")
- (make-ball 70 570 13 30 "blue")
- (make-ball 80 570 15 45 "black")
- (make-ball 100 570 24 45 "brown")
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; ;
- ; POST ;
- ; ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;The post is a structure. This structure
- ;will contain x location, and y location.
- ;(make-post number number)
- (define-struct post (x y))
- ; ;Template
- ; (define (post-func post)
- ; (... (post-x post)...
- ; (post-y post)...))
- (make-post 760 60)
- (make-post 760 90)
- (make-post 760 120)
- (make-post 760 150)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; ;
- ; RAIN ;
- ; ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;A drop of rain is a structure. This
- ;structure will contain x location,
- ;y location, fall speed, and color.
- ;(make-rain number number number string)
- (define-struct rain (x y speed color))
- ; ;Template
- ; (define (rain-func rain)
- ; (... (rain-x rain)...
- ; (rain-y rain)...
- ; (rain-speed rain)...
- ; (rain-color rain)...))
- (make-rain 400 10 13 "green")
- (make-rain 420 20 12 "green")
- (make-rain 440 35 11 "green")
- (make-rain 460 55 10 "green")
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; ;
- ; LIST OF RAIN ;
- ; ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;A list of rain is a structure. This
- ;structure will contain multiple rain.
- ;list-of-rain is either:
- ;empty or
- ;(cons rain list-of-rain)
- ; ;Template
- ; (define (list-of-rain-func list)
- ; (... (rain-x (first list)...
- ; (rain-y (first list))...
- ; (rain-speed (first list))...
- ; (rain-color (first list))...))
- ; (rest list)...)
- (cons (make-rain 400 10 13 "green") empty)
- (cons (make-rain 400 10 13 "green")
- (cons (make-rain 420 20 12 "green") empty))
- (cons (make-rain 400 10 13 "green")
- (cons (make-rain 420 20 12 "green")
- (cons (make-rain 240 35 11 "green") empty)))
- (cons (make-rain 400 10 13 "green")
- (cons (make-rain 420 20 12 "green")
- (cons (make-rain 420 35 11 "green")
- (cons (make-rain 460 55 10 "green") empty))))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; ;
- ; KICKER ;
- ; ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;A kicker is a structure. This
- ;structure will contain x location,
- ;y location, run speed, and color.
- ;(make-rain number number number string)
- (define-struct kicker (x y speed color))
- ; ;Template
- ; (define (kicker-func kicker)
- ; (... (kicker-x kicker)...
- ; (kicker-y kicker)...
- ; (kicker-speed kicker)...
- ; (kicker-color kicker)...))
- (make-kicker 13 570 10 "black")
- (make-kicker 24 570 12 "black")
- (make-kicker 30 570 14 "black")
- (make-kicker 35 570 16 "black")
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; ;
- ; SCOREBOARD ;
- ; ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;A scoreboard is a structure. This
- ;structure will contain a number representing score,
- ;and a number representing the number of lives remaining
- ;(make-scoreboard number number)
- (define-struct scoreboard (score lives))
- ; ;Template
- ; (define (kicker-func scoreboard)
- ; (... (scoreboard-score scoreboard)...
- ; (scoreboard-lives scoreboard)...))
- (make-scoreboard 0 10)
- (make-scoreboard 30 10)
- (make-scoreboard 30 9)
- (make-scoreboard 60 0)
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; ;
- ; WORLD ;
- ; ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;A world is a structure. This
- ;structure will contain a ball, a post,
- ;rain and a kicker.
- ;(make-world ball post rain kicker)
- (define-struct world (ball post list-of-rain kicker scoreboard))
- ; ;Template
- ; (define (world-func world)
- ; (...(...(ball-x (world-ball world))...
- ; (ball-y (world-ball world))...
- ; (ball-speed (world-ball world))...
- ; (ball-angle (world-ball world))...
- ; (ball-color (world-ball world))...)
- ; (...(post-x (world-post world))...
- ; (post-y (world-post world))...)
- ; (...(...(rain-x (first (world-list-of-rain world))...
- ; (rain-y (first (world-list-of-rain world)))...
- ; (rain-speed (first (world-list-of-rain world)))...
- ; (rain-color (first (world-list-of-rain world)))...))
- ; (rest (world-list-of-rain world))...)
- ; (...(kicker-x (world-kicker world))...
- ; (kicker-y (world-kicker world))...
- ; (kicker-speed (world-kicker world))...
- ; (kicker-color (world-kicker world))...)
- ; (... (scoreboard-score scoreboard)...
- ; (scoreboard-lives scoreboard)...)))
- (make-world (make-ball 50 570 10 30 "red")
- (make-post 760 60)
- (list (make-rain 400 10 13 "green"))
- (make-kicker 13 570 10 "black")
- (make-scoreboard 0 10))
- (make-world (make-ball 70 570 13 30 "blue")
- (make-post 760 90)
- (list (make-rain 400 10 13 "green")
- (make-rain 420 20 12 "green"))
- (make-kicker 24 570 12 "black")
- (make-scoreboard 30 10))
- (make-world (make-ball 80 570 15 45 "orange")
- (make-post 760 120)
- (list (make-rain 400 10 13 "green")
- (make-rain 420 20 12 "green")
- (make-rain 440 35 11 "green"))
- (make-kicker 30 570 14 "black")
- (make-scoreboard 30 9))
- (make-world (make-ball 100 570 24 45 "brown")
- (make-post 760 150)
- (list (make-rain 400 10 13 "green")
- (make-rain 420 20 12 "green")
- (make-rain 440 35 11 "green")
- (make-rain 460 55 10 "green"))
- (make-kicker 35 570 16 "black")
- (make-scoreboard 60 0))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;```______``````````````````````````_```````````````````_``````````;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;`.'`___``|````````````````````````/`|_````````````````/`|_````````;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;/`.'```\_|``.--.```_`.--.```.--.``|`|-',--.```_`.--.``|`|-'.--.```;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;|`|```````/`.'`\`\[``.-.`|`(`(`\]`|`|``'_\`:`[``.-.`|`|`|`(`(`\]``;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;\``.___.'\|`\__.`|`|`|`|`|```'.'.`|`|,//`|`|,`|`|`|`|`|`|,``'.'.``;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;``.____`.'`'.__.'`[___||__][\__)`)\__/\'-;__/[___||__]\__/[\__)`)`;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;``````````````````````````````````````````````````````````````````;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (define HEIGHT 600) ;Height of SCENE
- (define WIDTH 800) ;Width of SCENE
- (define BOX-HEIGHT 125) ;POST Box Height
- (define BOX-WIDTH 50) ;POST Box Width
- (define POST-HEIGHT 25) ;POST Square Side Length
- (define POST-WIDTH 50) ;POST Square Side Length
- (define KICKER-WIDTH 5) ;Width of KICKER
- (define KICKER-HEIGHT 50) ;Height of KICKER
- (define BALL-RADIUS 10) ;Radius of BALL
- (define RAIN-WIDTH 4) ;Width of RAIN
- (define RAIN-HEIGHT 8) ;Height of RAIN
- (define BALL-Y 570) ;Starting y-location of BALL
- (define BALL-SPEED 10) ;Speed of BALL
- (define POST-X 775) ;Starting x-location of POST
- (define KICKER-X 10) ;Starting x-position of KICKER
- (define KICKER-Y 570) ;Starting y-location of KICKER
- (define KICKER-SPEED 5) ;Speed of all KICKER
- (define RAIN-X 500) ;X-Positions of all RAIN
- (define RAIN-SPEED 3) ;Speed of all RAIN
- (define SCOREBOARD-X 75) ;Starting x-position of scoreboard
- (define SCOREBOARD-Y 75) ;Starting y-position of scoreboard
- (define SCENE (rectangle WIDTH HEIGHT "solid" "darkgreen")) ;SCENE
- (define KICKER-IMAGE (rectangle KICKER-WIDTH KICKER-HEIGHT "solid" "black")) ;KICKER image
- (define BALL-IMAGE (circle BALL-RADIUS "solid" "red")) ;BALL image
- (define POST-SQUARE (rectangle POST-WIDTH POST-HEIGHT "solid" "yellow")) ;yellow square
- (define POST-IMAGE (place-image POST-SQUARE 25 12.5
- (place-image POST-SQUARE 25 112.5
- (rectangle BOX-WIDTH BOX-HEIGHT "solid" "darkgreen")))) ;POST image
- (define ARROW-IMAGE
- (place-image (rectangle 100 7.5 "solid" "darkgreen") 50 3.75
- (place-image (rectangle 100 7.5 "solid" "darkgreen") 50 16.25
- (place-image (rectangle 50 10 "solid" "darkgreen") 25 10
- (place-image (triangle/sas 10 90 10 "solid" "darkgreen") 105 3.75
- (place-image(flip-vertical
- (triangle/sas 10 90 10 "solid" "darkgreen")) 105 16.25
- (rectangle 110 20 "solid" "blue"))))))) ;ARROW image
- (define BALL-ARROW-IMAGE (place-image BALL-IMAGE 55 10 ARROW-IMAGE)) ;BALL on ARROW image
- (define RAIN (rectangle RAIN-WIDTH RAIN-HEIGHT "solid" "green")) ;RAIN
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;`________``````````````````````````_````_`````````````````````````;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;|_```__``|````````````````````````/`|_`(_)````````````````````````;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;``|`|_`\_|__```_```_`.--.```.---.`|`|-'__```.--.```_`.--.```.--.``;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;``|``_|``[``|`|`|`[``.-.`|`/`/'`\]|`|`[``|/`.'`\`\[``.-.`|`(`(`\]`;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;`_|`|_````|`\_/`|,`|`|`|`|`|`\__.`|`|,`|`||`\__.`|`|`|`|`|```'.'.`;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;|_____|```'.__.'_/[___||__]'.___.'\__/[___]'.__.'`[___||__][\__)`);;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;``````````````````````````````````````````````````````````````````;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; Convert-to-Radians Function
- ; convert-to-radians: ball -> number
- ; Takes ball with an angle in degrees, and converts the angle
- ; into radians to be used in ball-xspeed and ball-yspeed.
- ; Examples:
- (check-within (convert-to-radians (make-ball 50 270 10 30 "red")) .5235987756 .1)
- (check-within (convert-to-radians (make-ball 70 270 13 30 "blue")) .5235987756 .1)
- (check-within (convert-to-radians (make-ball 80 270 15 45 "black")) 0.7853981633974483 .1)
- (check-within (convert-to-radians (make-ball 100 270 24 45 "brown")) 0.7853981633974483 .1)
- (define (convert-to-radians ball)
- (* (ball-angle ball) (/ pi 180)))
- ; Update-Angle Function
- ; update-angle: ball number string -> ball
- ; Given a ball and a number and a string which will be either "up" or "down",
- ; Outputs a ball with an angle updated based on string and number.
- ; Examples:
- (check-expect (update-angle (make-ball 50 270 10 30 "red") 5 "up")
- (make-ball 50 270 10 35 "red"))
- (check-expect (update-angle (make-ball 50 270 10 30 "red") 5 "down")
- (make-ball 50 270 10 25 "red"))
- (check-expect (update-angle (make-ball 50 270 10 30 "red") 1 "up")
- (make-ball 50 270 10 31 "red"))
- (check-expect (update-angle (make-ball 50 270 10 30 "red") 1 "down")
- (make-ball 50 270 10 29 "red"))
- (define (update-angle ball number string)
- (cond [(string=? string "up")
- (make-ball (ball-x ball)
- (ball-y ball)
- (ball-speed ball)
- (+ (ball-angle ball) number)
- (ball-color ball))]
- [(string=? string "down")
- (make-ball (ball-x ball)
- (ball-y ball)
- (ball-speed ball)
- (- (ball-angle ball) number)
- (ball-color ball))]))
- ; Ball-X-Start-Position Function
- ; ball-x-start-position: number -> ball
- ; Given a number that is never actually used,
- ; outputs a ball with an X location that is at
- ; random between 50 and 75.
- (define (ball-x-start-position number) (+ (random 26) 50))
- ; Test Cases:
- ; Each should generate a random number between 50 and 75
- (ball-x-start-position 1)
- (ball-x-start-position 13)
- (ball-x-start-position 24)
- (ball-x-start-position 25)
- ; Ball-XSpeed Function
- ; ball-xspeed: ball -> number
- ; Given a ball with a specified speed and angle,
- ; calculates the x-speed of the ball (COSINE). Uses the
- ; convert-to-radians function.
- ; Examples:
- (check-within (ball-xspeed (make-ball 50 270 10 30 "red")) 8.660254038 .1)
- (check-within (ball-xspeed (make-ball 70 270 13 30 "blue")) 11.25833025 .1)
- (check-within (ball-xspeed (make-ball 80 270 15 45 "black")) 10.60660172 .1)
- (check-within (ball-xspeed (make-ball 100 270 24 45 "brown")) 16.97056275 .1)
- (define (ball-xspeed ball)
- (inexact->exact (* (ball-speed ball) (cos (convert-to-radians ball)))))
- ; Ball-YSpeed Function
- ; ball-yspeed: ball -> number
- ; Given a ball with a specified speed and angle,
- ; calculates the y-speed of the ball (SINE). Uses the
- ; convert-to-radians function.
- ; Examples:
- (check-within (ball-yspeed (make-ball 50 270 10 30 "red")) 5 .1)
- (check-within (ball-yspeed (make-ball 70 270 13 30 "blue")) 6.5 .1)
- (check-within (ball-yspeed (make-ball 80 270 15 45 "black")) 10.60660172 .1)
- (check-within (ball-yspeed (make-ball 100 270 24 45 "brown")) 16.97056275 .1)
- (define (ball-yspeed ball)
- (inexact->exact (* (ball-speed ball) (sin (convert-to-radians ball)))))
- ; Update-Ball Function
- ; update-ball: ball -> ball
- ; Given a ball, outputs a ball with updated
- ; x and y positions based on the x-speed claculated in
- ; the ball-xspeed function and the y-speed calculated in
- ; the ball-yspeed function. The speed, angle, and color
- ; of the ball remain constant.
- ; Examples:
- (check-expect (update-ball (make-ball 50 270 10 30 "red"))
- (make-ball (+ 50 (ball-xspeed (make-ball 50 270 10 30 "red")))
- (- 270 (ball-yspeed (make-ball 50 270 10 30 "red")))
- 10 30 "red"))
- (check-expect (update-ball (make-ball 70 270 13 30 "blue"))
- (make-ball (+ 70 (ball-xspeed (make-ball 70 270 13 30 "blue")))
- (- 270 (ball-yspeed (make-ball 70 270 13 30 "blue")))
- 13 30 "blue"))
- (check-expect (update-ball (make-ball 80 270 15 45 "black"))
- (make-ball (+ 80 (ball-xspeed (make-ball 80 270 15 45 "black")))
- (- 270 (ball-yspeed (make-ball 80 270 15 45 "black")))
- 15 45 "black"))
- (check-expect (update-ball (make-ball 100 270 24 45 "brown"))
- (make-ball (+ 100 (ball-xspeed (make-ball 100 270 24 45 "brown")))
- (- 270 (ball-yspeed (make-ball 100 270 24 45 "brown")))
- 24 45 "brown"))
- (define (update-ball ball)
- (make-ball (+ (ball-x ball) (ball-xspeed ball))
- (- (ball-y ball) (ball-yspeed ball))
- (ball-speed ball)
- (ball-angle ball)
- (ball-color ball)))
- ; Render-Ball-and-Arrow Function
- ; render-ball-and-arrow: ball image-> scene
- ; Given a ball, outputs a scene with the ball and arrow placed
- ; at the correct x and y location, with angle facing correct angle direction.
- ; Examples:
- (check-expect (render-ball-and-arrow (make-ball 50 270 10 30 "red") SCENE)
- (place-image (rotate 30 BALL-ARROW-IMAGE) 50 270 SCENE))
- (check-expect (render-ball-and-arrow (make-ball 70 270 13 30 "red") SCENE)
- (place-image (rotate 30 BALL-ARROW-IMAGE) 70 270 SCENE))
- (check-expect (render-ball-and-arrow (make-ball 80 270 15 45 "red") SCENE)
- (place-image (rotate 45 BALL-ARROW-IMAGE) 80 270 SCENE))
- (check-expect (render-ball-and-arrow (make-ball 100 270 24 45 "red") SCENE)
- (place-image (rotate 45 BALL-ARROW-IMAGE) 100 270 SCENE))
- (define (render-ball-and-arrow ball scene-so-far)
- (place-image (rotate (ball-angle ball) BALL-ARROW-IMAGE)
- (ball-x ball) (ball-y ball) scene-so-far))
- ; Render-Ball Function
- ; render-ball: ball image -> scene
- ; Given a ball that is NOT at its starrting/launching position, but rather
- ; in flight. Places the ball in the SCENE at the specific x and y locations.
- ; Examples:
- (check-expect (render-ball (make-ball 100 150 10 30 "red") SCENE)
- (place-image BALL-IMAGE 100 150 SCENE))
- (check-expect (render-ball (make-ball 170 170 13 30 "red") SCENE)
- (place-image BALL-IMAGE 170 170 SCENE))
- (check-expect (render-ball (make-ball 240 130 15 45 "red") SCENE)
- (place-image BALL-IMAGE 240 130 SCENE))
- (check-expect (render-ball (make-ball 150 200 24 45 "red") SCENE)
- (place-image BALL-IMAGE 150 200 SCENE))
- (define (render-ball ball scene-so-far)
- (place-image BALL-IMAGE (ball-x ball) (ball-y ball) scene-so-far))
- ; Update-Kicker Function
- ; update-function: kicker -> kicker
- ; Given a kicker, outputs a kicker with an updated x-location
- ; based on speed.
- ; Examples:
- (check-expect (update-kicker (make-kicker 13 270 10 "black"))
- (make-kicker 23 270 10 "black"))
- (check-expect (update-kicker (make-kicker 24 270 12 "black"))
- (make-kicker 36 270 12 "black"))
- (check-expect (update-kicker (make-kicker 30 270 14 "black"))
- (make-kicker 44 270 14 "black"))
- (check-expect (update-kicker (make-kicker 33 270 16 "black"))
- (make-kicker 49 270 16 "black"))
- (define (update-kicker kicker)
- (make-kicker (+ (kicker-x kicker) (kicker-speed kicker))
- (kicker-y kicker) (kicker-speed kicker) (kicker-color kicker)))
- ; Render-Kicker Function
- ; render-kicker: kicker image -> scene
- ; Given a kicker, outputs a scene with the kicker placed at the
- ; correct x and y locations.
- ; Examples
- (check-expect (render-kicker (make-kicker 13 270 10 "black") SCENE)
- (place-image KICKER-IMAGE 13 270 SCENE))
- (check-expect (render-kicker (make-kicker 24 270 12 "black") SCENE)
- (place-image KICKER-IMAGE 24 270 SCENE))
- (check-expect (render-kicker (make-kicker 30 270 14 "black") SCENE)
- (place-image KICKER-IMAGE 30 270 SCENE))
- (check-expect (render-kicker (make-kicker 35 270 16 "black") SCENE)
- (place-image KICKER-IMAGE 35 270 SCENE))
- (define (render-kicker kicker scene-so-far)
- (place-image KICKER-IMAGE (kicker-x kicker) (kicker-y kicker) scene-so-far))
- ; Rain-Fall Function
- ; rain-fall: rain -> rain
- ; Given a rain, outputs an updated rain, with y-position updated by speed.
- ; Examples:
- (check-expect (rain-fall (make-rain 200 10 13 "green")) (make-rain 200 23 13 "green"))
- (check-expect (rain-fall (make-rain 220 20 12 "green")) (make-rain 220 32 12 "green"))
- (check-expect (rain-fall (make-rain 240 35 11 "green")) (make-rain 240 46 11 "green"))
- (check-expect (rain-fall (make-rain 260 40 10 "green")) (make-rain 260 50 10 "green"))
- (define (rain-fall rain)
- (make-rain (rain-x rain) (+ (rain-y rain) (rain-speed rain))
- (rain-speed rain) (rain-color rain)))
- ; Rainstorm Function
- ; rainstorm: list-of-rain -> list-of-rain
- ; Given a list of rain, outputs a list of rain with updated y-locations based on speeds.
- (check-expect (rainstorm (list (make-rain 200 10 13 "green")
- (make-rain 200 40 13 "green")
- (make-rain 200 70 13 "green")))
- (list (make-rain 200 23 13 "green")
- (make-rain 200 53 13 "green")
- (make-rain 200 83 13 "green")))
- (check-expect (rainstorm (list (make-rain 180 10 13 "green")
- (make-rain 180 40 13 "green")
- (make-rain 180 70 13 "green")
- (make-rain 200 40 13 "green")
- (make-rain 200 70 13 "green")
- (make-rain 200 100 13 "green")))
- (list (make-rain 180 23 13 "green")
- (make-rain 180 53 13 "green")
- (make-rain 180 83 13 "green")
- (make-rain 200 53 13 "green")
- (make-rain 200 83 13 "green")
- (make-rain 200 113 13 "green")))
- (check-expect (rainstorm (list (make-rain 180 0 13 "green")
- (make-rain 180 30 13 "green")
- (make-rain 180 60 13 "green")
- (make-rain 200 30 13 "green")
- (make-rain 200 60 13 "green")
- (make-rain 200 90 13 "green")
- (make-rain 220 60 13 "green")
- (make-rain 220 90 13 "green")
- (make-rain 220 120 13 "green")))
- (list (make-rain 180 13 13 "green")
- (make-rain 180 43 13 "green")
- (make-rain 180 73 13 "green")
- (make-rain 200 43 13 "green")
- (make-rain 200 73 13 "green")
- (make-rain 200 103 13 "green")
- (make-rain 220 73 13 "green")
- (make-rain 220 103 13 "green")
- (make-rain 220 133 13 "green")))
- (define (rainstorm list-of-rain)
- (cond [(empty? list-of-rain) empty]
- [(>= (rain-y (first list-of-rain)) HEIGHT) (rainstorm (rest list-of-rain))]
- [else (cons (rain-fall (first list-of-rain))
- (rainstorm (rest list-of-rain)))]))
- ; Last-of-List Function
- ; last-of-list: list -> element
- ; Takes a list, outputs the last element in that list.
- (check-expect (last-of-list (list 1 2 3)) 3)
- (check-expect (last-of-list (list (make-rain 180 45 13 "green")
- (make-rain 135 54 12 "red")
- (make-rain 234 24 23 "blue")))
- (make-rain 234 24 23 "blue"))
- (define (last-of-list alist)
- (cond [(empty? (rest alist)) (first alist)]
- [else (last-of-list (rest alist))]))
- ;Render-Rain Function
- ;render-rain: list-of-rain image -> scene
- ;Given a list-of-rain, outputs a scene with each rain drop drawn at it correct locations.
- (check-expect (render-rain (list (make-rain 180 213 13 "green")
- (make-rain 180 163 13 "green")
- (make-rain 180 113 13 "green")
- (make-rain 180 63 13 "green")
- (make-rain 180 13 13 "green")) SCENE)
- (place-image RAIN 180 213
- (place-image RAIN 180 163
- (place-image RAIN 180 113
- (place-image RAIN 180 63
- (place-image RAIN 180 13 SCENE))))))
- (define (render-rain list scene-so-far)
- (cond [(empty? list) scene-so-far]
- [else (place-image RAIN (rain-x (first list)) (rain-y (first list))
- (render-rain (rest list) scene-so-far))]))
- ; Post-Random-Y Function
- ; post-random-y: number -> post
- ; Given a random dumby number, which is never used,
- ; Outputs a post with a random y position between 60 and 150.
- (define (post-random-y number) (+ (random 251) 100))
- ; Test Cases
- ; Each should output a number between 60 and 150
- (post-random-y 1)
- (post-random-y 2)
- (post-random-y 3)
- (post-random-y 4)
- ; Render-Post Function
- ; render-post: post -> scene
- ; Given a post, outputs a scene with the POST placed at the correct x and y locations.
- ; Examples:
- (check-expect (render-post (make-post 380 60) SCENE)
- (place-image POST-IMAGE 380 60 SCENE))
- (check-expect (render-post (make-post 380 90) SCENE)
- (place-image POST-IMAGE 380 90 SCENE))
- (check-expect (render-post (make-post 380 120) SCENE)
- (place-image POST-IMAGE 380 120 SCENE))
- (check-expect (render-post (make-post 380 150) SCENE)
- (place-image POST-IMAGE 380 150 SCENE))
- (define (render-post post scene-so-far)
- (place-image POST-IMAGE (post-x post) (post-y post) scene-so-far))
- ; Ball-Rain-Collision Function
- ; ball-rain collision: ball and world -> boolean
- ; Given a ball and a world, returns true if the ball hits rain.
- ; Returns false otherwise.
- (check-expect (ball-rain-collision (make-ball 100 570 24 45 "brown")
- (list
- (make-rain 400 10 13 "green")
- (make-rain 420 20 12 "green")
- (make-rain 440 35 11 "green")
- (make-rain 460 55 10 "green"))) false)
- (check-expect (ball-rain-collision (make-ball 420 30 24 45 "brown")
- (list
- (make-rain 400 10 13 "green")
- (make-rain 420 20 12 "green")
- (make-rain 440 35 11 "green")
- (make-rain 460 55 10 "green"))) true)
- (define (ball-rain-collision ball rain-list)
- (cond [(empty? rain-list) false]
- [(and (= (ball-x ball) (rain-x (first rain-list)))
- (<= (abs (- (ball-y ball) (rain-y (first rain-list))))
- (+ BALL-RADIUS (/ RAIN-HEIGHT 2)))) true]
- [else (ball-rain-collision ball (rest rain-list))]))
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; ;
- ; WORLD FUNCTIONS ;
- ; ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; Launch-Ball? Function
- ; launch-ball?: world -> boolean
- ; Given a world, returns true if the kicker of the world will launch the ball
- ; immediately (same x-position). Returns false if the kicker will not.
- ; Examples:
- (check-expect (launch-ball? (make-world (make-ball 50 70 10 30 "red")
- (make-post 380 60)
- (list (make-rain 200 10 13 "green"))
- (make-kicker 13 270 10 "black")
- (make-scoreboard 0 10))) true)
- (check-expect (launch-ball? (make-world (make-ball 60 270 10 30 "red")
- (make-post 380 60)
- (list
- (make-rain 200 10 13 "green")
- (make-rain 220 20 12 "green"))
- (make-kicker 23 270 10 "black")
- (make-scoreboard 0 10))) false)
- (check-expect (launch-ball? (make-world (make-ball 73 170 10 30 "red")
- (make-post 380 60)
- (list
- (make-rain 200 10 13 "green")
- (make-rain 220 20 12 "green")
- (make-rain 240 35 11 "green"))
- (make-kicker 73 270 10 "black")
- (make-scoreboard 15 10))) true)
- (check-expect (launch-ball? (make-world (make-ball 93 270 10 30 "red")
- (make-post 380 60)
- (list
- (make-rain 200 10 13 "green")
- (make-rain 220 20 12 "green")
- (make-rain 240 35 11 "green")
- (make-rain 260 55 10 "green"))
- (make-kicker 83 270 10 "black")
- (make-scoreboard 15 10))) false)
- (define (launch-ball? world)
- (cond [(= (ball-y (world-ball world))
- (kicker-y (world-kicker world))) false]
- [else true]))
- ;Kicker-Disappear Function
- ;kicker-disappear: world -> wold
- (check-expect (kicker-disappear (make-world (make-ball 60 270 10 30 "red")
- (make-post 380 60)
- (list
- (make-rain 200 10 13 "green")
- (make-rain 220 20 12 "green"))
- (make-kicker 23 270 10 "black")
- (make-scoreboard 0 10)))
- (make-world (make-ball 60 270 10 30 "red")
- (make-post 380 60)
- (list
- (make-rain 200 10 13 "green")
- (make-rain 220 20 12 "green"))
- (make-kicker 33 270 10 "black")
- (make-scoreboard 0 10)))
- (check-expect (kicker-disappear (make-world (make-ball 253 70 10 30 "red")
- (make-post 380 60)
- (list
- (make-rain 200 10 13 "green")
- (make-rain 220 20 12 "green")
- (make-rain 240 35 11 "green"))
- (make-kicker 43 270 10 "black")
- (make-scoreboard 15 10)))
- (make-world (make-ball (+ (ball-xspeed (make-ball 253 70 10 30 "red")) 253)
- (- 70 (ball-yspeed (make-ball 253 70 10 30 "red")))10 30 "red")
- (make-post 380 60)
- (list
- (make-rain 200 10 13 "green")
- (make-rain 220 20 12 "green")
- (make-rain 240 35 11 "green"))
- (make-kicker 900 900 10 "black")
- (make-scoreboard 15 10)))
- (define (kicker-disappear world)
- (cond [(boolean=? (launch-ball? world) true)
- (make-world (update-ball (world-ball world))
- (world-post world)
- (world-list-of-rain world)
- (make-kicker 900 900 10 "black")
- (world-scoreboard world))]
- [else (make-world (world-ball world)
- (world-post world)
- (world-list-of-rain world)
- (update-kicker (world-kicker world))
- (world-scoreboard world))]))
- ; Ball-Score? Function
- ; ball-score?: world -> boolean
- ; Given a world with the ball at its final position, returns true if the ball's
- ; x and y positions are inside the post. Returns false if otherwise.
- ; Examples:
- (check-expect (ball-score? (make-world (make-ball 800 60 10 30 "red")
- (make-post 800 60)
- (list (make-rain 200 10 13 "green"))
- (make-kicker 13 270 10 "black")
- (make-scoreboard 0 10))) true)
- (check-expect (ball-score? (make-world (make-ball 800 88 13 30 "blue")
- (make-post 800 90)
- (list(make-rain 200 10 13 "green")
- (make-rain 220 20 12 "green"))
- (make-kicker 24 270 12 "black")
- (make-scoreboard 30 10))) true)
- (check-expect (ball-score? (make-world (make-ball 270 150 15 45 "red")
- (make-post 380 120)
- (list(make-rain 200 10 13 "green")
- (make-rain 220 20 12 "green")
- (make-rain 240 35 11 "green"))
- (make-kicker 24 270 12 "black")
- (make-scoreboard 30 10))) false)
- (check-expect (ball-score? (make-world (make-ball 400 198 24 45 "brown")
- (make-post 800 150)
- (list (make-rain 200 10 13 "green")
- (make-rain 220 20 12 "green")
- (make-rain 240 35 11 "green")
- (make-rain 260 55 10 "green"))
- (make-kicker 35 270 16 "black")
- (make-scoreboard 60 0))) false)
- (define (ball-score? world)
- (cond [(and (>= (ball-x (world-ball world)) (- POST-X (/ BOX-WIDTH 2)))
- (and (>= (ball-y (world-ball world))
- (- (post-y (world-post world)) (/ BOX-HEIGHT 2)))
- (<= (ball-y (world-ball world))
- (+ (post-y (world-post world)) (/ BOX-HEIGHT 2))))) true]
- [else false]))
- ; Ball-Off-Screen? Function
- ; ball-off-screen: world -> boolean
- ; Given a world, returns true if the ball is off the screen.
- (check-expect (ball-off-screen? (make-world (make-ball 100 570 24 45 "brown")
- (make-post 760 150)
- (list (make-rain 400 10 13 "green")
- (make-rain 420 20 12 "green")
- (make-rain 440 35 11 "green")
- (make-rain 460 55 10 "green"))
- (make-kicker 35 570 16 "black")
- (make-scoreboard 60 0))) false)
- (check-expect (ball-off-screen? (make-world (make-ball -10 570 24 45 "brown")
- (make-post 760 150)
- (list (make-rain 400 10 13 "green")
- (make-rain 420 20 12 "green")
- (make-rain 440 35 11 "green")
- (make-rain 460 55 10 "green"))
- (make-kicker 35 570 16 "black")
- (make-scoreboard 60 0))) true)
- (check-expect (ball-off-screen? (make-world (make-ball 100 -570 24 45 "brown")
- (make-post 760 150)
- (list (make-rain 400 10 13 "green")
- (make-rain 420 20 12 "green")
- (make-rain 440 35 11 "green")
- (make-rain 460 55 10 "green"))
- (make-kicker 35 570 16 "black")
- (make-scoreboard 60 0))) true)
- (check-expect (ball-off-screen? (make-world (make-ball 100 670 24 45 "brown")
- (make-post 760 150)
- (list (make-rain 400 10 13 "green")
- (make-rain 420 20 12 "green")
- (make-rain 440 35 11 "green")
- (make-rain 460 55 10 "green"))
- (make-kicker 35 570 16 "black")
- (make-scoreboard 60 0))) true)
- (define (ball-off-screen? world)
- (cond [(or (< (ball-x (world-ball world)) 0)
- (< (ball-y (world-ball world)) 0)
- (> (ball-y (world-ball world)) HEIGHT)) true]
- [else false]))
- ;Rain-Frequency-Adder Function
- ;rain-frequency-adder: world -> list
- ;Given a world, adds a rain drop to the existing list-of-rain based on score.
- ;Adds a rain drop EVERY 100 pixels FOR SCORE OF 0-100
- ;Adds a rain drop EVERY 80 pixels FOR SCORE OF 100-200
- ;Adds a rain drop EVERY 60 pixels FOR SCORE OF 200-300
- ;Adds a rain drop EVERY 40 pixels FOR SCORE OF 300-400
- ; INSERT CHECK-EXPECTS
- (define (rain-frequency-adder world)
- (cond [(and (>= (scoreboard-score (world-scoreboard world)) 0)
- (<= (scoreboard-score (world-scoreboard world)) 100))
- (cond [(>= (rain-y (last-of-list (world-list-of-rain world))) 120)
- (append (rainstorm (world-list-of-rain world))
- (list (make-rain (rain-x (last-of-list (world-list-of-rain world)))
- (+ (- (rain-y (last-of-list (world-list-of-rain world))) 120)
- (rain-speed (last-of-list (world-list-of-rain world))))
- (rain-speed (last-of-list (world-list-of-rain world)))
- (rain-color (last-of-list (world-list-of-rain world))))))]
- [else (world-list-of-rain world)])]
- [(and (>= (scoreboard-score (world-scoreboard world)) 101)
- (<= (scoreboard-score (world-scoreboard world)) 200))
- (cond [(>= (rain-y (last-of-list (world-list-of-rain world))) 100)
- (append (rainstorm (world-list-of-rain world))
- (list (make-rain (rain-x (last-of-list (world-list-of-rain world)))
- (+ (- (rain-y (last-of-list (world-list-of-rain world))) 100)
- (rain-speed (last-of-list (world-list-of-rain world))))
- (rain-speed (last-of-list (world-list-of-rain world)))
- (rain-color (last-of-list (world-list-of-rain world))))))]
- [else (world-list-of-rain world)])]
- [(and (>= (scoreboard-score (world-scoreboard world)) 201)
- (<= (scoreboard-score (world-scoreboard world)) 300))
- (cond [(>= (rain-y (last-of-list (world-list-of-rain world))) 80)
- (append (rainstorm (world-list-of-rain world))
- (list (make-rain (rain-x (last-of-list (world-list-of-rain world)))
- (+ (- (rain-y (last-of-list (world-list-of-rain world))) 80)
- (rain-speed (last-of-list (world-list-of-rain world))))
- (rain-speed (last-of-list (world-list-of-rain world)))
- (rain-color (last-of-list (world-list-of-rain world))))))]
- [else (world-list-of-rain world)])]
- [(and (>= (scoreboard-score (world-scoreboard world)) 301)
- (<= (scoreboard-score (world-scoreboard world)) 405))
- (cond [(>= (rain-y (last-of-list (world-list-of-rain world))) 60)
- (append (rainstorm (world-list-of-rain world))
- (list (make-rain (rain-x (last-of-list (world-list-of-rain world)))
- (+ (- (rain-y (last-of-list (world-list-of-rain world))) 60)
- (rain-speed (last-of-list (world-list-of-rain world))))
- (rain-speed (last-of-list (world-list-of-rain world)))
- (rain-color (last-of-list (world-list-of-rain world))))))]
- [else (world-list-of-rain world)])]))
- ; Update-World-Main Function
- ; update-world-main: world -> world
- ; Given a world, outputs the updated world.
- ; The ball's x and y positions are updated by its speed, if launch-ball? is true.
- ; The ball's x stays constant if launch-ball? is false.
- ; The post stays the same.
- ; The y positions of the list-of-rains are updated by each drops speed.
- ; The kicker's x position is updated by its speed if launch-ball? is false.
- ; Otherwise, the kicker disappears.
- ; The scoreboard's score is updated by +15 points whether or not the ball has
- ; passed between the posts.
- ; The scoreboard's lives are updated by -1 if the ball has been hit by acid rain, or if it misses.
- ; INSERT CHECK-EXPECTS
- (define (update-world-main world)
- (make-world (cond [(and (< (ball-x (world-ball world)) WIDTH)
- (boolean=? (launch-ball? world) true)
- (boolean=? (ball-off-screen? world) false)
- (boolean=? (ball-rain-collision (world-ball world)
- (world-list-of-rain world)) false))
- (update-ball (world-ball world))]
- [else (world-ball world)])
- (world-post world)
- (cond [(empty? (world-list-of-rain world)) (make-rain RAIN-X 0 RAIN-SPEED "black")]
- [else (rainstorm (rain-frequency-adder world))])
- (world-kicker world)
- (cond [(and (= (ball-x (world-ball world)) POST-X)
- (boolean=? (ball-score? world) true))
- (make-scoreboard (+ (scoreboard-score (world-scoreboard world)) 15)
- (scoreboard-lives (world-scoreboard world)))]
- [(and (= (ball-x (world-ball world)) POST-X)
- (boolean=? (ball-score? world) false))
- (make-scoreboard (scoreboard-score (world-scoreboard world))
- (- (scoreboard-lives (world-scoreboard world)) 1))]
- [(boolean=? (ball-rain-collision (world-ball world) (world-list-of-rain world))
- true)
- (make-scoreboard (scoreboard-score (world-scoreboard world))
- (- (scoreboard-lives (world-scoreboard world)) 1))]
- [(boolean=? (ball-off-screen? world) true)
- (make-scoreboard (scoreboard-score (world-scoreboard world))
- (- (scoreboard-lives (world-scoreboard world)) 1))]
- [else (world-scoreboard world)])))
- ; Which-Ball-Image Function
- ; which-ball-image? : world -> image
- ; Given a world, outputs BALL image if the ball is in motion.
- ; Outputs BALL-ARROW image if the ball is at the starting position.
- ; Examples:
- (check-expect (which-ball-image? (make-world (make-ball 375 198 10 30 "red")
- (make-post 380 150)
- (list (make-rain 200 10 13 "green")
- (make-rain 200 40 13 "green")
- (make-rain 200 70 13 "green")
- (make-rain 220 40 13 "green"))
- (make-kicker 200 270 10 "black")
- (make-scoreboard 60 10))) BALL-IMAGE)
- (check-expect (which-ball-image? (make-world (make-ball 50 570 10 30 "red")
- (make-post 380 60)
- (list (make-rain 200 10 13 "green"))
- (make-kicker 10 570 10 "black")
- (make-scoreboard 0 10))) BALL-ARROW-IMAGE)
- (define (which-ball-image? world)
- (cond [(and (= (kicker-y (world-kicker world)) KICKER-Y)
- (= (ball-y (world-ball world)) BALL-Y)
- (and (>= (ball-x (world-ball world)) 0)
- (<= (ball-x (world-ball world)) 75))) BALL-ARROW-IMAGE]
- [else BALL-IMAGE]))
- ; Game-Over? Function
- ; game-over? : world -> boolean
- ; Given a world, outputs true if there are zero lives remaining.
- ; Outputs false otherwise.
- (check-expect (game-over? (make-world (make-ball 375 198 10 30 "red")
- (make-post 380 150)
- (list (make-rain 200 10 13 "green")
- (make-rain 200 40 13 "green")
- (make-rain 200 70 13 "green")
- (make-rain 220 40 13 "green"))
- (make-kicker 200 270 10 "black")
- (make-scoreboard 60 10))) false)
- (check-expect (game-over? (make-world (make-ball 375 198 10 30 "red")
- (make-post 380 150)
- (list (make-rain 200 10 13 "green")
- (make-rain 200 40 13 "green")
- (make-rain 200 70 13 "green")
- (make-rain 220 40 13 "green"))
- (make-kicker 200 270 10 "black")
- (make-scoreboard 60 0))) true)
- (define (game-over? world)
- (cond [(= (scoreboard-lives (world-scoreboard world)) 0) true]
- [else false]))
- ; Render-Scoreboard Function
- ; render-scoreboard: world -> image
- ; Given a world, outputs an image which will represent the scoreboard.
- ; Example:
- (check-expect (render-scoreboard (make-world (make-ball 50 270 24 45 "brown")
- (make-post 380 150)
- (list
- (make-rain 200 10 13 "green")
- (make-rain 200 40 13 "green")
- (make-rain 200 70 13 "green")
- (make-rain 220 40 13 "green"))
- (make-kicker 35 270 16 "black")
- (make-scoreboard 60 0)) SCENE)
- (place-image (place-image (text (string-append "SCORE: " "60")
- 18 "black") 50 30
- (place-image (text (string-append "LIVES: " "0")
- 18 "black") 50 80
- (rectangle 110 110 "solid" "red")))
- 60 60 SCENE))
- (define (render-scoreboard world scene-so-far)
- (place-image (place-image (text (string-append "SCORE: "
- (number->string (scoreboard-score (world-scoreboard world))))
- 18 "black") 50 30
- (place-image (text (string-append "LIVES: "
- (number->string
- (scoreboard-lives (world-scoreboard world))))
- 18 "black") 50 80
- (rectangle 110 110 "solid" "red"))) 60 60
- scene-so-far))
- ;Which-Message Function
- ;Which-message: world -> message
- ;Given a world, outputs a message.
- ; INSERT CHECK-EXPECTS
- (define (which-message world)
- (cond [(boolean=? (ball-off-screen? world) true) "The ball went off the screen."]
- [(boolean=? (ball-rain-collision (world-ball world) (world-list-of-rain world)) true)
- "Your ball got hit by acid rain."]
- [(>= (ball-x (world-ball world)) POST-X)
- (cond [(boolean=? (ball-score? world) true) "You scored 15 points with that kick."]
- [(boolean=? (ball-score? world) false) "Your kick missed the field goal post."])]
- [else " "]))
- ; Render-Message Function
- ; render-message: world image -> scene
- ; INSERT CHECK-EXPECTS
- (define (render-message world scene-so-far)
- (place-image (text (which-message world) 18 "black") (/ WIDTH 2) (/ HEIGHT 2) scene-so-far))
- ; Render-World Function
- ; render-world: world -> scene
- ; Given a world, outputs a scene with the objects at their correct x and y positions.
- ; Examples:
- ; INSERT CHECK-EXPECTS
- (check-expect (render-world (make-world (make-ball 90 500 24 45 "brown")
- (make-post 760 150)
- (list
- (make-rain 500 10 13 "green")
- (make-rain 500 40 13 "green")
- (make-rain 500 70 13 "green")
- (make-rain 520 40 13 "green"))
- (make-kicker 35 570 16 "black")
- (make-scoreboard 60 0)))
- (place-image KICKER-IMAGE 35 570
- (place-image BALL-IMAGE 90 500
- (place-image POST-IMAGE 760 150
- (place-image RAIN 500 10
- (place-image RAIN 500 40
- (place-image RAIN 500 70
- (place-image RAIN 520 40
- (place-image
- (place-image
- (text (string-append "SCORE: " "60") 18 "black") 50 30
- (place-image
- (text (string-append "LIVES: " "0") 18 "black") 50 80
- (rectangle 110 110 "solid" "red"))) 60 60
- (place-image (text " " 18 "black") 400 300 SCENE))))))))))
- (check-expect (render-world (make-world (make-ball 50 570 24 45 "brown")
- (make-post 760 150)
- (list
- (make-rain 500 10 13 "green")
- (make-rain 500 40 13 "green")
- (make-rain 500 70 13 "green")
- (make-rain 520 40 13 "green"))
- (make-kicker 10 570 16 "black")
- (make-scoreboard 60 10)))
- (place-image KICKER-IMAGE 10 570
- (place-image (rotate 45 BALL-ARROW-IMAGE) 50 570
- (place-image POST-IMAGE 760 150
- (place-image RAIN 500 10
- (place-image RAIN 500 40
- (place-image RAIN 500 70
- (place-image RAIN 520 40
- (place-image
- (place-image
- (text (string-append "SCORE: " "60") 18 "black") 50 30
- (place-image
- (text (string-append "LIVES: " "10") 18 "black") 50 80
- (rectangle 110 110 "solid" "red"))) 60 60
- (place-image (text " " 18 "black") 400 300 SCENE))))))))))
- (define (render-world world)
- (cond [(image=? (which-ball-image? world) BALL-ARROW-IMAGE)
- (render-kicker (world-kicker world)
- (render-ball-and-arrow (world-ball world)
- (render-post (world-post world)
- (render-rain (world-list-of-rain world)
- (render-scoreboard world
- (render-message world SCENE))))))]
- [(image=? (which-ball-image? world) BALL-IMAGE)
- (render-kicker (world-kicker world)
- (render-ball (world-ball world)
- (render-post (world-post world)
- (render-rain (world-list-of-rain world)
- (render-scoreboard world
- (render-message world SCENE))))))]))
- ;Reset Function
- ;reset: world action -> world
- ;This will be called in key-event-handler. Occurs when "enter" pressed.
- ;This function generates a world at the starting positions.
- (define (reset world)
- (make-world (make-ball (ball-x-start-position 1) BALL-Y BALL-SPEED (random 46) "red")
- (make-post POST-X (post-random-y 1))
- (list (make-rain RAIN-X 0 RAIN-SPEED "black"))
- (make-kicker KICKER-X KICKER-Y KICKER-SPEED "black")
- (world-scoreboard world)))
- ;Test Cases:
- (reset (make-world (make-ball 800 100 13 31 "red")
- (make-post 760 110)
- (list (make-rain RAIN-X 0 RAIN-SPEED "black"))
- (make-kicker 900 900 13 "black")
- (make-scoreboard 60 6)))
- (reset (make-world (make-ball 800 100 13 31 "red")
- (make-post 760 110)
- (list (make-rain RAIN-X 0 RAIN-SPEED "black"))
- (make-kicker 900 900 13 "black")
- (make-scoreboard 60 6)))
- ; Key-Event-Handler Function
- ; key-event-handler: world keyevent -> world
- ; Given a world and a key that is pressed, updates the world accordingly.
- (define (key-event-handler world key)
- (cond [(and (string=? key "up") (= (ball-y (world-ball world)) BALL-Y))
- (make-world (update-angle (world-ball world) 1 key)
- (world-post world)
- (world-list-of-rain world)
- (world-kicker world)
- (world-scoreboard world))]
- [(and (string=? key "down") (= (ball-y (world-ball world)) BALL-Y))
- (make-world (update-angle (world-ball world) 1 key)
- (world-post world)
- (world-list-of-rain world)
- (world-kicker world)
- (world-scoreboard world))]
- [(and (string=? key " ")
- (= (ball-y (world-ball world)) BALL-Y)
- (= (kicker-y (world-kicker world)) KICKER-Y))
- (cond [(< (kicker-x (world-kicker world)) (ball-x (world-ball world)))
- (make-world (world-ball world)
- (world-post world)
- (world-list-of-rain world)
- (update-kicker (world-kicker world))
- (world-scoreboard world))]
- [else (make-world (update-ball (world-ball world))
- (world-post world)
- (world-list-of-rain world)
- (world-kicker world)
- (world-scoreboard world))])]
- [(and (string=? key "\r") (>= (ball-x (world-ball world)) 760))
- (reset world)]
- [else world]))
- ; Examples
- (check-expect (key-event-handler (make-world (make-ball 50 570 13 30 "red")
- (make-post 760 60)
- (list (make-rain 200 10 13 "green"))
- (make-kicker 10 570 13 "black")
- (make-scoreboard 0 10)) "up")
- (make-world (make-ball 50 570 13 31 "red")
- (make-post 760 60)
- (list (make-rain 200 10 13 "green"))
- (make-kicker 10 570 13 "black")
- (make-scoreboard 0 10)))
- (check-expect (key-event-handler (make-world (make-ball 50 570 13 30 "red")
- (make-post 760 60)
- (list (make-rain 200 10 13 "green"))
- (make-kicker 10 570 13 "black")
- (make-scoreboard 0 10)) "down")
- (make-world (make-ball 50 570 13 29 "red")
- (make-post 760 60)
- (list (make-rain 200 10 13 "green"))
- (make-kicker 10 570 13 "black")
- (make-scoreboard 0 10)))
- (check-expect (key-event-handler (make-world (make-ball 50 570 13 30 "red")
- (make-post 760 60)
- (list (make-rain 200 10 13 "green"))
- (make-kicker 10 570 13 "black")
- (make-scoreboard 0 10)) " ")
- (make-world (make-ball 50 570 13 30 "red")
- (make-post 760 60)
- (list (make-rain 200 10 13 "green"))
- (make-kicker 23 570 13 "black")
- (make-scoreboard 0 10)))
- ;Test Case because angle and a few numbers are random:
- (key-event-handler (make-world (make-ball 800 70 13 30 "red")
- (make-post 760 60)
- (list (make-rain 500 10 13 "green"))
- (make-kicker 10 570 13 "black")
- (make-scoreboard 75 10)) "\r")
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (big-bang (make-world (make-ball (ball-x-start-position 1) BALL-Y BALL-SPEED (random 46) "red")
- (make-post POST-X (post-random-y 1))
- (list (make-rain RAIN-X 0 RAIN-SPEED "green"))
- (make-kicker KICKER-X KICKER-Y KICKER-SPEED "black")
- (make-scoreboard 110 10))
- (on-tick update-world-main)
- (on-key key-event-handler)
- (on-draw render-world)
- (stop-when game-over?))