diff --git a/assets/level1/prize.xcf b/assets/level1/prize.xcf deleted file mode 100644 index a1f4e29..0000000 Binary files a/assets/level1/prize.xcf and /dev/null differ diff --git a/assets/level2/clouds.png b/assets/level2/clouds.png new file mode 100644 index 0000000..a3a8f21 Binary files /dev/null and b/assets/level2/clouds.png differ diff --git a/assets/level2/far.png b/assets/level2/far.png new file mode 100644 index 0000000..96a31d0 Binary files /dev/null and b/assets/level2/far.png differ diff --git a/assets/level2/ground.png b/assets/level2/ground.png new file mode 100644 index 0000000..7b0c922 Binary files /dev/null and b/assets/level2/ground.png differ diff --git a/assets/level2/middle.png b/assets/level2/middle.png new file mode 100644 index 0000000..b74f2d0 Binary files /dev/null and b/assets/level2/middle.png differ diff --git a/assets/level2/prize.png b/assets/level2/prize.png new file mode 100644 index 0000000..6d45892 Binary files /dev/null and b/assets/level2/prize.png differ diff --git a/assets/level2/sky.png b/assets/level2/sky.png new file mode 100644 index 0000000..6536c82 Binary files /dev/null and b/assets/level2/sky.png differ diff --git a/assets/level3/clouds.png b/assets/level3/clouds.png new file mode 100644 index 0000000..95355fa Binary files /dev/null and b/assets/level3/clouds.png differ diff --git a/assets/level3/far.png b/assets/level3/far.png new file mode 100644 index 0000000..9c535bd Binary files /dev/null and b/assets/level3/far.png differ diff --git a/assets/level3/ground.png b/assets/level3/ground.png new file mode 100644 index 0000000..a52ba0f Binary files /dev/null and b/assets/level3/ground.png differ diff --git a/assets/level3/middle.png b/assets/level3/middle.png new file mode 100644 index 0000000..0092d32 Binary files /dev/null and b/assets/level3/middle.png differ diff --git a/assets/level3/prize.png b/assets/level3/prize.png new file mode 100644 index 0000000..dbb22cc Binary files /dev/null and b/assets/level3/prize.png differ diff --git a/assets/level3/sky.png b/assets/level3/sky.png new file mode 100644 index 0000000..40ecff2 Binary files /dev/null and b/assets/level3/sky.png differ diff --git a/assets/level4/clouds.png b/assets/level4/clouds.png new file mode 100644 index 0000000..6eecb76 Binary files /dev/null and b/assets/level4/clouds.png differ diff --git a/assets/level4/far.png b/assets/level4/far.png new file mode 100644 index 0000000..6c55023 Binary files /dev/null and b/assets/level4/far.png differ diff --git a/assets/level4/ground.png b/assets/level4/ground.png new file mode 100644 index 0000000..572f241 Binary files /dev/null and b/assets/level4/ground.png differ diff --git a/assets/level4/middle.png b/assets/level4/middle.png new file mode 100644 index 0000000..1a45d46 Binary files /dev/null and b/assets/level4/middle.png differ diff --git a/assets/level4/prize.png b/assets/level4/prize.png new file mode 100644 index 0000000..88d7642 Binary files /dev/null and b/assets/level4/prize.png differ diff --git a/assets/level4/sky.png b/assets/level4/sky.png new file mode 100644 index 0000000..d1611b4 Binary files /dev/null and b/assets/level4/sky.png differ diff --git a/flappy-ball.lisp b/flappy-ball.lisp index 946de62..624423f 100644 --- a/flappy-ball.lisp +++ b/flappy-ball.lisp @@ -91,6 +91,14 @@ (and (<= (- x bs) bx (+ x w bs)) (not (<= (+ h bs) by (- (+ h gap) bs)))))) +(defun random-pipes (n spacing max-height gap width) + (let ((padding 25)) + (loop repeat n + for x from spacing by (+ spacing ) + collect (make-pipe x (+ padding (random (- max-height gap padding padding))) gap width))) + ) + + ;; ------------------------------------------------------------- (defun make-high-score (score time) @@ -143,10 +151,8 @@ Hash-table with level name => file name => resource.") (asdf:system-source-directory :flappy-ball))) (defun read-level-assets (level) - (print level) (let ((level-dict (serapeum:dict)) (folder (merge-pathnames (format nil "~a~a" level "/") *asset-folder*))) - (print folder) (loop for file in (list "sky.png" "clouds.png" "far.png" "middle.png" "ground.png" "prize.png") for content = (load-resource (namestring (merge-pathnames file folder))) do (setf (gethash file level-dict) content) @@ -178,13 +184,31 @@ Hash-table with level name => file name => resource.") (pipe-draw pipe pipe-pen scroll-x height)) (draw-image-layer level "ground.png" scroll-x)) -(defun random-pipes (n spacing max-height gap width) - (let ((padding 25)) - (loop repeat n - for x from spacing by (+ spacing ) - collect (make-pipe x (+ padding (random (- max-height gap padding padding))) gap width))) - ) +(defun draw-prize (level scroll-x target-x width) + (if (>= scroll-x target-x) + (let ((pic (serapeum:href *resources* level "prize.png"))) + (draw pic :x (- (+ 60 width target-x) scroll-x) :y 0 )))) +(defun draw-hud (state score high-scores) + (when (eq state 'new) + (text "Click to Start" 50 250 200 40) + (text "High Scores" 300 30 280 40) + (loop for (score . time) in high-scores + for i from 0 + do (text (format nil "~3,'0d" (floor score)) 300 (+ 70 (* i 40)) 80 30) + do (text (local-time:format-timestring nil (local-time:universal-to-timestamp time) :format '(:year "-" :month "-" :day)) 400 (+ 70 (* i 40)) 200 30) + )) + (when (eq state 'won) + (text "You Won" 380 100 160 60) + (text "Return to Restart" 300 150 320 40) + ) + (when (eq state 'died) + (text "You Died" 380 100 160 60) + (text "Return to Restart" 300 150 320 40)) + + (text (format nil "~3,'0d" (floor score)) 820 20 100 40) + + ) ;; ------------------------------------------------------------- @@ -214,57 +238,57 @@ Hash-table with level name => file name => resource.") (level "level1") ) - (draw-background level scroll-x) - (draw-foreground level pipes scroll-x pipe-pen height) - - (ball-draw ball - (if (some (lambda (pipe) (pipe-collides pipe ball scroll-x)) pipes) - (progn - (when (eq state 'running) - (setf high-scores (high-scores-add high-scores score)) - (save-high-scores "highscores" high-scores) - (setf state 'died)) - collision-pen) - ball-pen)) + (let ((ball-collides (some (lambda (pipe) (pipe-collides pipe ball scroll-x)) pipes)) + ) + + (draw-background level scroll-x) + (draw-foreground level pipes scroll-x pipe-pen height) + + (if ball-collides + (ball-draw ball collision-pen) + (ball-draw ball ball-pen)) - (if (>= scroll-x target-x) - (let ((pic (serapeum:href *resources* level "prize.png"))) - (draw pic :x (- (+ 960 target-x) scroll-x) :y 0 ))) + (draw-prize level scroll-x target-x width) - (when (eq state 'new) - (setf scroll-x 0.0) - (text "Click to Start" 50 250 200 40) - (loop for (score . time) in high-scores - for i from 0 - do (text (format nil "~3,'0d" (floor score)) 300 (+ 30 (* i 40)) 80 30) - do (text (local-time:format-timestring nil (local-time:universal-to-timestamp time) :format '(:year "-" :month "-" :day)) 400 (+ 30 (* i 40)) 200 30) - )) - (when (eq state 'won) - (text "You Won" 380 100 160 60) - (text "Return to Restart" 300 150 320 40) + (draw-hud state score high-scores) + + (when (eq state 'new) + (setf scroll-x 0.0)) + (when (eq state 'running) + (while-running sketch::*sketch*)) + ;; has to come after checking for the new state or stuck in death + (when ball-collides + (on-death sketch::*sketch*)) ) - (when (eq state 'died) - (text "You Died" 380 100 160 60) - (text "Return to Restart" 300 150 320 40)) + ) - (text (format nil "~3,'0d" (floor score)) 820 20 100 40) - (when (eq state 'running) +(defmethod while-running ((instance flappy-ball)) + (with-slots (score state + width ground-level + scroll-x scroll-speed + pipes-width pipes-spacing pipes-amount + ball gravity + high-scores) instance (setf score (1+ (/ (- scroll-x pipes-width (/ width 10)) pipes-spacing))) (setf scroll-x (+ scroll-x scroll-speed)) (setf ball (ball-move ball gravity ground-level)) (when (> (round score) pipes-amount) (setf state 'won) (setf high-scores (high-scores-add high-scores score)) - (save-high-scores "highscores" high-scores))) - ) + (save-high-scores "highscores" high-scores)))) + +(defmethod on-death ((instance flappy-ball)) + (with-slots (state high-scores score) instance + (setf high-scores (high-scores-add high-scores score)) + (save-high-scores "highscores" high-scores) + (setf state 'died))) (defmethod on-click ((instance flappy-ball) x y) (with-slots (ball flap-speed state) instance (setf ball (ball-flap ball flap-speed)) (when (eq state 'new) - (setf state 'running)) - )) + (setf state 'running)))) (defmethod on-key ((instance flappy-ball) key state) (with-slots (ball flap-speed state) instance