diff options
author | Case Duckworth | 2023-06-04 12:40:01 -0500 |
---|---|---|
committer | Case Duckworth | 2023-06-04 12:40:01 -0500 |
commit | 113a333adbeb97d2bbd0cdfc242cc9b2efc6e2c7 (patch) | |
tree | b62a1ebfb772450ab11e7c9d99c7e1abb7758c37 /apple.scm | |
parent | Snake eats fruit (diff) | |
download | apple-113a333adbeb97d2bbd0cdfc242cc9b2efc6e2c7.tar.gz apple-113a333adbeb97d2bbd0cdfc242cc9b2efc6e2c7.zip |
Polish exiting and add intro screen
Diffstat (limited to 'apple.scm')
-rwxr-xr-x | apple.scm | 107 |
1 files changed, 74 insertions, 33 deletions
diff --git a/apple.scm b/apple.scm index bfacbc4..abc5b8d 100755 --- a/apple.scm +++ b/apple.scm | |||
@@ -38,14 +38,24 @@ See COPYING for details. | |||
38 | (list))) | 38 | (list))) |
39 | (fruit (make-thing 'fruit (world) | 39 | (fruit (make-thing 'fruit (world) |
40 | (random-choice (fruits)) 10 20 2))) | 40 | (random-choice (fruits)) 10 20 2))) |
41 | (case (dynamic-wind game-setup | 41 | (game-intro) |
42 | game-loop | 42 | (readch) |
43 | game-cleanup) | 43 | (game-exit-message (dynamic-wind game-setup |
44 | ((win) (print "Congrats!")) | 44 | game-loop |
45 | ((lose) (print "Better luck next time.")) | 45 | game-cleanup))))) |
46 | (else)) | 46 | |
47 | (print "Thanks for playing!"))) | 47 | (define (game-exit-message msg) |
48 | #t) | 48 | (cond |
49 | ((eq? msg 'win) | ||
50 | (print "Congrats!") | ||
51 | #t) | ||
52 | ((eq? msg 'lose) | ||
53 | (print "Better luck next time.") | ||
54 | #t) | ||
55 | ((and (pair? msg) | ||
56 | (eq? (car msg) 'error)) | ||
57 | (apply error "An error occurred" (cdr error)) | ||
58 | #f))) | ||
49 | 59 | ||
50 | ;;; Parameters | 60 | ;;; Parameters |
51 | (define me (make-parameter #f)) | 61 | (define me (make-parameter #f)) |
@@ -86,14 +96,37 @@ See COPYING for details. | |||
86 | (call/cc | 96 | (call/cc |
87 | (lambda (return) | 97 | (lambda (return) |
88 | (parameterize ((game-end return)) | 98 | (parameterize ((game-end return)) |
89 | (let loop ((now (current-jiffy))) | 99 | (with-exception-handler |
90 | (unless (and (eq? (thing-x (fruit)) (thing-x (me))) | 100 | (lambda (e) (return (cons 'error e))) |
91 | (eq? (thing-y (fruit)) (thing-y (me)))) | 101 | (lambda () |
92 | (thing-place! (fruit))) | 102 | (let loop ((now (current-jiffy))) |
93 | (handle-input) | 103 | (unless (and (eq? (thing-x (fruit)) (thing-x (me))) |
94 | (snake-step (snake) now) | 104 | (eq? (thing-y (fruit)) (thing-y (me)))) |
95 | (world-draw (world)) | 105 | (thing-place! (fruit))) |
96 | (loop (current-jiffy))))))) | 106 | (handle-input) |
107 | (snake-step (snake) now) | ||
108 | (world-draw (world)) | ||
109 | (loop (current-jiffy))))))))) | ||
110 | |||
111 | (define (game-intro) | ||
112 | (draw #<#END | ||
113 | #erase-screen | ||
114 | A P P L E! | ||
115 | a Spring Lisp Game Jam 2023 entry | ||
116 | by Case Duckworth <acdw@acdw.net> | ||
117 | |||
118 | Welcome to APPLE, the game of SNAKE, except you're the apple instead! | ||
119 | Specifically, you're the RED APPLE #(thing-look (me)), running from the SNAKE #(thing-look (snake-head (snake)))·····. | ||
120 | Try to dodge the snake and get him to eat himself --- you can distract him | ||
121 | by going near other FRUIT #(fruits), which he'll eat instead of you. | ||
122 | |||
123 | Move using HJKL or arrow keys! Quit with Q, and pause with ESC. | ||
124 | |||
125 | GOOD LUCK :D | ||
126 | Press ENTER to continue ..... | ||
127 | |||
128 | END | ||
129 | )) | ||
97 | 130 | ||
98 | (define (handle-input) | 131 | (define (handle-input) |
99 | (if (char-ready?) | 132 | (if (char-ready?) |
@@ -218,7 +251,6 @@ See COPYING for details. | |||
218 | (thing-place! (wall w x y))) | 251 | (thing-place! (wall w x y))) |
219 | (else))) | 252 | (else))) |
220 | world) | 253 | world) |
221 | (draw-title world 10 10) | ||
222 | (thing-pos-randomize! (me)) | 254 | (thing-pos-randomize! (me)) |
223 | (thing-place! (me)) | 255 | (thing-place! (me)) |
224 | (thing-pos-randomize! (snake-head (snake))) | 256 | (thing-pos-randomize! (snake-head (snake))) |
@@ -233,14 +265,6 @@ See COPYING for details. | |||
233 | (thing-x-set! thing x) | 265 | (thing-x-set! thing x) |
234 | (thing-y-set! thing y))) | 266 | (thing-y-set! thing y))) |
235 | 267 | ||
236 | (define (draw-title world x y) | ||
237 | (for-each thing-place! | ||
238 | (list (make-thing 'a world (with-attrs '(italic dim) "A") x y 0) | ||
239 | (make-thing 'p world (with-attrs '(italic dim) "P") (+ x 2) y 0) | ||
240 | (make-thing 'p world (with-attrs '(italic dim) "P") (+ x 4) y 0) | ||
241 | (make-thing 'p world (with-attrs '(italic dim) "L") (+ x 6) y 0) | ||
242 | (make-thing 'p world (with-attrs '(italic dim) "E") (+ x 8) y 0)))) | ||
243 | |||
244 | ;;; Things | 268 | ;;; Things |
245 | 269 | ||
246 | (define-record-type <thing> | 270 | (define-record-type <thing> |
@@ -326,18 +350,18 @@ See COPYING for details. | |||
326 | 350 | ||
327 | (define (game-win) | 351 | (define (game-win) |
328 | (draw (cursor-move 10 10) | 352 | (draw (cursor-move 10 10) |
329 | "YOU WIN!") | 353 | "YOU WIN! ") |
330 | (sleep 1) | 354 | (sleep 1) |
355 | (flush-input) | ||
331 | (readch) | 356 | (readch) |
332 | (newline) | ||
333 | ((game-end) 'win)) | 357 | ((game-end) 'win)) |
334 | 358 | ||
335 | (define (game-lose) | 359 | (define (game-lose) |
336 | (draw (cursor-move 10 10) | 360 | (draw (cursor-move 10 10) |
337 | "YOU LOSE :(") | 361 | "YOU LOSE :( ") |
338 | (sleep 1) | 362 | (sleep 1) |
363 | (flush-input) | ||
339 | (readch) | 364 | (readch) |
340 | (newline) | ||
341 | ((game-end) 'lose)) | 365 | ((game-end) 'lose)) |
342 | 366 | ||
343 | (define (thing-up! thing) | 367 | (define (thing-up! thing) |
@@ -508,6 +532,10 @@ See COPYING for details. | |||
508 | ;; Otherwise, keep going how we're going | 532 | ;; Otherwise, keep going how we're going |
509 | (else (snake-direction snake))))) | 533 | (else (snake-direction snake))))) |
510 | 534 | ||
535 | (define (edible? thing-name) | ||
536 | (or (eq? thing-name 'me) | ||
537 | (eq? thing-name 'fruit))) | ||
538 | |||
511 | (define (snake-decide-move snake) ; snake => direction | 539 | (define (snake-decide-move snake) ; snake => direction |
512 | (let* ((head (snake-head snake)) | 540 | (let* ((head (snake-head snake)) |
513 | (direction (snake-direction snake)) | 541 | (direction (snake-direction snake)) |
@@ -515,10 +543,10 @@ See COPYING for details. | |||
515 | ;; Initial decision | 543 | ;; Initial decision |
516 | (cond | 544 | (cond |
517 | ;; If `me' is right there, move toward it | 545 | ;; If `me' is right there, move toward it |
518 | ((eq? (thing-above head) 'me) 'up) | 546 | ((edible? (thing-above head)) 'up) |
519 | ((eq? (thing-below head) 'me) 'down) | 547 | ((edible? (thing-below head)) 'down) |
520 | ((eq? (thing-to-right head) 'me) 'right) | 548 | ((edible? (thing-to-right head)) 'right) |
521 | ((eq? (thing-to-left head) 'me) 'left) | 549 | ((edible? (thing-to-left head)) 'left) |
522 | ;; If about to collide with something, dodge it. | 550 | ;; If about to collide with something, dodge it. |
523 | ((or (and (thing-above head) | 551 | ((or (and (thing-above head) |
524 | (eq? direction 'up)) | 552 | (eq? direction 'up)) |
@@ -559,3 +587,16 @@ See COPYING for details. | |||
559 | 587 | ||
560 | (define (snake-update-direction! snake) | 588 | (define (snake-update-direction! snake) |
561 | (snake-direction-set! snake (snake-decide-move snake))) | 589 | (snake-direction-set! snake (snake-decide-move snake))) |
590 | |||
591 | (define (%flush-input port) | ||
592 | (let loop ((ready? (char-ready? port))) | ||
593 | (if ready? | ||
594 | (begin (read-byte port) | ||
595 | (loop (char-ready? port))) | ||
596 | #t))) | ||
597 | |||
598 | (define flush-input | ||
599 | (case-lambda | ||
600 | (() (%flush-input (current-input-port))) | ||
601 | ((port) (%flush-input port)))) | ||
602 | |||