;===== ; CS 111 - Week 3 Lecture 2 - 2026-09-10 ; ; In-class examples, cleaned up after class! ; ; last modified: 2026-09-10 ;----- ; will be using some functions from the 2htdp/image module: (require 2htdp/image) ;----- ; AND will now ALSO be using a function, big-bang, ; from the 2htdp/universe module! (require 2htdp/universe) ;===== ; a new type: the scene type ; * provided by 2htdp/image ; * the scene data type is an interesting type in that ; it is a SUBTYPE of the image data type ; ; like a background! but you can put things in it! ; transparent, and it won't let contents overlap its edges; ;===== ; when you learn of a data type, ; you need to know WHAT you can do with it ; ; for scene, 2htdp/image provides TWO starter functions: ; * empty-scene ; * place-image ;===== ; when you have a new data type, you need a way to ; create INSTANCES of that data type; ; 2htdp/image provides the function empty-scene for ; creating a new empty scene instance ;===== ; signature: empty-scene: number number -> scene ; purpose: expects a desired width and height of a ; scene in pixels, and returns an empty scene of that ; width and height (empty-scene 400 200) ;===== ; if, within a .rkt file, I want a standard width and height ; for a bunch of scenes, ; named constants for the width and height would be nice! (define WIDTH 400) (define HEIGHT 200) (empty-scene WIDTH HEIGHT) ;===== ; how can I have a scene with something in it? ; * 2htdp/image provides a function place-image to ; add an image to a scene and result in a new scene ;===== ; signature: place-image: image number number scene -> scene ; purpose: expects an image to add to a scene, the desired ; x and y coordinates where you'd like to place that image, ; and the scene to add the image to, and returns a new scene ; with that given image centered at those coordinates in the ; given scene (and trimmed if needed to the scene's size ; if needed) ;===== ; BUT: IMPORTANT ASIDE: what is the scene data type's ; COORDINATE system? Where is x=0, y=0 in a scene? ; ; it is based on old computer monitors, where the image ; on a screen is drawn from top-to-bottom, left-to-right; ;----- ; that is, here is a scene's coordinate system: ; ; (0,0) 1 2 3 x ; -----|----|----|--> ; | ; | ; 1 - ; | ; | ; 2 - ; | ; | ; 3 - ; | ; y v ; ; SO (0, 0) is the top-left...! ; larger x values are further RIGHT, ; larger y values are further DOWN...!!!!!) ;----- ; and if I might want a scene to serve as a default backdrop ; scene for placing an image into for several or more ; place-image expressions, a named constant for THAT could ; be useful, also! ; (note: it is perfectly fine to use previously-defined named ; constants in defining other named constants) (define BACKDROP (empty-scene WIDTH HEIGHT)) ;----- ; so, this expression results in a scene of a 30-pixel-radius ; purple circle centered at ; 50 pixels from the left, ; 50 pixels down, ; in a scene that's WEIGHT pixels wide, HEIGHT pixels high (place-image (circle 30 "solid" "purple") 50 50 BACKDROP) ;----- ; so, this expression results in a scene of a 45x45 pixel ; green square centered at ; 300 pixels from the left, ; 25 pixels down, ; in a scene that's WEIGHT pixels wide, HEIGHT pixels high (place-image (square 45 "solid" "green") 300 25 BACKDROP) ;----- ; so, this expression results in a scene of a 40-pixel-radius ; pink circle centered at ; WIDTH pixels from the left, ; HEIGHT pixels down, ; in a scene that's WEIGHT pixels wide, HEIGHT pixels high ; ; (when you run this, note how the part of the circle "outside" ; the scene is cut off) (place-image (circle 40 "solid" "pink") WIDTH HEIGHT BACKDROP) (place-image (circle 30 "solid" "red") 0 HEIGHT (empty-scene WIDTH HEIGHT)) ;===== ; remember that place-image returns a scene! ; ; so, it is fine to use a place-image compound expression ; as the 4th argument to a place-image compound ; expression! (place-image (circle 15 "outline" "brown") 50 50 (place-image (triangle 20 "solid" "orange") 325 175 (place-image (star 20 "solid" "teal") 225 125 (empty-scene WIDTH HEIGHT)))) ;===== ; I decide I want to be able to create a scene of a ; centered cyan star of a specified size; ; a function could be useful for that! ; ; hey, last week's function cyan-star might be useful in ; creating this new function! ; I am COPYING its signature, purpose, tests, and ; definition from last week's examples into THIS file, ; so I can use it here ;----- ; PASTED this in from Week 2 Lecture 2 posted examples ; (INCLUDING the signature, purpose, and tests! ;----- ; signature: cyan-star: number -> image ; purpose: expects the desired distance between ; the points of a star and returns an image ; of a cyan star of that size (check-expect (cyan-star 10) (star 10 "solid" "cyan")) (check-expect (cyan-star 4) (star 4 "solid" "cyan")) (define (cyan-star star-size) (star star-size "solid" "cyan") ) ;===== ; now, going on! ; ;---- ; again, I want a function to create a scene ; of a centered cyan star of a size I specify; ; I decide: ; * to name it cyan-star-scene ; * to only have the user specify the cyan star's ; size ; * to have it always return a scene whose width is ; WIDTH and whose height is HEIGHT ;===== ; signature: cyan-star-scene: number -> scene ; purpose: expects a cyan star size and returns a scene ; of a cyan star of that size, centered. The scene will ; always be WIDTH x HEIGHT pixels. (check-expect (cyan-star-scene 20) (place-image (cyan-star 20) (* 0.5 WIDTH) (* 0.5 HEIGHT) (empty-scene WIDTH HEIGHT))) (check-expect (cyan-star-scene 50) (place-image (cyan-star 50) (* 0.5 WIDTH) (* 0.5 HEIGHT) (empty-scene WIDTH HEIGHT))) (define (cyan-star-scene star-size) (place-image (cyan-star star-size) (* 0.5 WIDTH) (* 0.5 HEIGHT) (empty-scene WIDTH HEIGHT))) (cyan-star-scene 20) (cyan-star-scene 50) ;===== ; starting intro to function: big-bang ;===== ;===== ; function big-bang is defined in the module ; 2htdp/universe, so to use it, you need: ; ; (require 2htdp/universe) ; ; (I already put this at the begining of this file, ; so I don't need to put it again) ;----- ; big-bang is a function with numerous side-effects! ;----- ; big-bang expects at least 2 arguments; ; the first is the initial value of a new "world" ; (and the type of that value becomes the type ; of the new world) ; the remainder are event-handler clauses, ; special compound expressions ; that start with the name of an event ; and are followed with the NAME of a function ; to be called when that event happens (an event-handler ; function) ; (and a few have additional optional arguments) ; ; and, big-bang returns the value of its world when it is ended ;----- ; when you call big-bang, it starts a ticker ticking, ; (about 28 times per second, although you can specify ; a different speed) ; * and each time its ticker ticks, it wants to ; create a scene and display it in a pop-up World ; window ;----- ; when does a running big-bang expression end? ; ; * when you CLOSE its World window (clicking on its ; top-left corner) ; ; * when you click DrRacket's Stop button in its ; top-right corner (but this ends your current Racket ; program, also) ; * (and the World window remains open until you close it, ; even though big-bang is no longer running) ; ; * there is also a clause, stop-when, you can add to ; specify when it should stop (more on that later) ; ; * and, a run-time error will kill it, too! (and the World window ; remains open in this case, also...) ;----- ; GOING ON: the event you MUST handle is when big-bang wants to ; depict its world, to draw a scene based on its current ; world value; ; ; to-draw ; ; (big-bang initial-world-expr ; (to-draw desired-funct) ; ...) ; ; when the to-draw event occurs (for example, after each ticker tick), ; big-bang calls the function YOU give to-draw as to-draw's argument ; with the current world value as *its* argument, ; and it displays the resulting scene in a pop-up window "should see a pop-up window with an unchanging cyan star in" " the center;" "CLOSE that window to continue!" (big-bang 100 (to-draw cyan-star-scene)) ;===== ; but, um, that's not very dynamic! ;----- ; as mentioned, each time you call function big-bang, ; big-bang starts up a ticker that ticks about ; 28 times per second; ; each time the ticker ticks, big-bang calls to-draw's function ; to depict the current world value's scene; ; BUT -- IF you ALSO call big-bang with an on-tick clause -- ; then, at the event of each ticker tick, ; big-bang calls its on-tick clause's function ; with the current world value, ; and what that function returns becomes the *new* world value! ;===== ; FUN FACT: Racket has a built-in function add1, that does what you ; would probably guess it does: adds 1 to something! ;===== ; signature: add1: number -> number ; purpose: expects a number and returns 1 + that numbers (add1 100) (add1 13) ;===== ; SO, if big-bang's world type - the type of its first argument - is number, ; I can use add1 as on-tick's argument, ; and each time big-bang's ticker ticks, ; big-bang will call add1 with the current world value ; to result in a new world value: "should see a pop-up window with a GROWING cyan star in" " the center;" "CLOSE that window to continue!" (big-bang 100 (to-draw cyan-star-scene) (on-tick add1)) ;===== ; FUN FACT: Racket also has a built-in function sub1, that ; subtracts 1 from something! ;----- ; signature: sub1: number -> number ; purpose: expects any number, and returns the result ; of subtracting 1 from it (sub1 56) (sub1 200) ;---- ; SO -- see what happens when you use sub1 as the event-handler ; function for the event on-tick: "should see a pop-up window with a SHRINKING cyan star in" " the center;" "CLOSE that window before world value gets to 0 to continue," " otherwise big-bang will be stopped by the error that happens" " when cyan-star-scene calls cyan-star and cyan-star calls" " function star with a non-zero size!" " " " (if you try out the error, you'll need to close the world pop-up" " window or it just sticks around...)" (big-bang 200 (to-draw cyan-star-scene) (on-tick sub1))