summaryrefslogtreecommitdiff
path: root/super-bloom/flower.scm
diff options
context:
space:
mode:
Diffstat (limited to 'super-bloom/flower.scm')
-rw-r--r--super-bloom/flower.scm146
1 files changed, 146 insertions, 0 deletions
diff --git a/super-bloom/flower.scm b/super-bloom/flower.scm
new file mode 100644
index 0000000..428b158
--- /dev/null
+++ b/super-bloom/flower.scm
@@ -0,0 +1,146 @@
+;;; Copyright 2023 David Thompson
+;;;
+;;; Licensed under the Apache License, Version 2.0 (the "License");
+;;; you may not use this file except in compliance with the License.
+;;; You may obtain a copy of the License at
+;;;
+;;; http://www.apache.org/licenses/LICENSE-2.0
+;;;
+;;; Unless required by applicable law or agreed to in writing, software
+;;; distributed under the License is distributed on an "AS IS" BASIS,
+;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+;;; See the License for the specific language governing permissions and
+;;; limitations under the License.
+
+(define-module (super-bloom flower)
+ #:use-module (catbird asset)
+ #:use-module (catbird mixins)
+ #:use-module (catbird node)
+ #:use-module (catbird node-2d)
+ #:use-module (chickadee audio)
+ #:use-module (chickadee graphics color)
+ #:use-module (chickadee graphics particles)
+ #:use-module (chickadee graphics path)
+ #:use-module (chickadee graphics texture)
+ #:use-module (chickadee math)
+ #:use-module (chickadee math rect)
+ #:use-module (chickadee math vector)
+ #:use-module (chickadee scripting)
+ #:use-module (oop goops)
+ #:use-module (super-bloom actor)
+ #:use-module (super-bloom common)
+ #:use-module (super-bloom water)
+ #:export (<flower>
+ water
+ damage
+ growth-goal
+ growth-progress))
+
+(define %max-water 1)
+
+(define-asset (flower-tileset (file (scope-datadir "assets/images/flower.png")))
+ (load-tileset file 48 48))
+
+;; Every growth-interval, the flower gains 1 growth point (accumulated
+;; in growth-progress) and consumes 1 unit of water. If there is no
+;; water, the flower is thirsty and stops growing.
+(define-class <flower> (<actor>)
+ (water #:accessor water #:init-value 0)
+ (growth-goal #:accessor growth-goal #:init-keyword #:growth-goal)
+ (growth-progress #:accessor growth-progress #:init-value 1)
+ (growth-interval #:accessor growth-interval #:init-keyword #:growth-interval)
+ (growth-accumulator #:accessor growth-accumulator #:init-value 0.0)
+ (hitbox #:getter hitbox #:init-form (make-rect -8.0 -8.0 16.0 16.0)))
+
+(define-method (initialize (flower <flower>) initargs)
+ (next-method)
+ (attach-to flower
+ (make <animated-sprite>
+ #:name 'sprite
+ #:atlas flower-tileset
+ #:origin (vec2 24.0 24.0)
+ #:animations `((default . ,(make <animation>
+ #:frames #(0 1)
+ #:frame-duration 0.3))
+ (stage-2 . ,(make <animation>
+ #:frames #(2 3 4 5)
+ #:frame-duration 0.3))
+ (stage-3 . ,(make <animation>
+ #:frames #(6 7 8 9)
+ #:frame-duration 0.3))
+ (stage-4 . ,(make <animation>
+ #:frames #(10 11 12 13)
+ #:frame-duration 0.3))))
+ (make <canvas>
+ #:name 'progress-meter
+ #:position (vec2 -32.0 -28.0)
+ #:width 64.0
+ #:height 8.0))
+ (update-progress-meter flower))
+
+(define-method (update-progress-meter (flower <flower>))
+ (define w 64.0)
+ (define t (/ (growth-progress flower) (growth-goal flower)))
+ (set! (painter (& flower progress-meter))
+ (superimpose
+ (with-style ((stroke-color (make-color 0.0 0.0 0.0 0.5))
+ (stroke-width 2.0))
+ (stroke
+ (line (vec2 0.0 0.0) (vec2 w 0.0))))
+ (with-style ((stroke-color db32-tahiti-gold)
+ (stroke-width 2.0))
+ (stroke
+ (line (vec2 0.0 0.0) (vec2 (* w t) 0.0))))))
+ (resize (& flower progress-meter)
+ (default-width (& flower progress-meter))
+ (default-height (& flower progress-meter))))
+
+
+(define-method (update-animation (flower <flower>))
+ (define t (/ (growth-progress flower) (growth-goal flower)))
+ (change-animation (& flower sprite)
+ (cond
+ ((< t 1/3) 'default)
+ ((< t 2/3) 'stage-2)
+ ((< t 1) 'stage-3)
+ (else 'stage-4))))
+
+(define-method (increment-water (flower <flower>) amount)
+ (set! (water flower) (min (+ (water flower) amount) %max-water)))
+
+(define-method (decrement-water (flower <flower>) amount)
+ (set! (water flower) (max (- (water flower) amount) 0)))
+
+(define-method (damage (flower <flower>) amount)
+ (set! (growth-progress flower) (max (- (growth-progress flower) amount) 0))
+ (update-animation flower)
+ (update-progress-meter flower))
+
+(define-method (thirsty? (flower <flower>))
+ (= (water flower) 0))
+
+(define-method (reset-growth-accumulator (flower <flower>))
+ (set! (growth-accumulator flower) 0))
+
+(define-method (on-splash (flower <flower>))
+ (when (thirsty? flower)
+ (increment-water flower 1)
+ (audio-play (artifact watered-sound))))
+
+(define-method (update (flower <flower>) dt)
+ (unless (thirsty? flower)
+ (let ((interval (growth-interval flower))
+ (accum (+ (growth-accumulator flower) dt)))
+ (set! (growth-accumulator flower) accum)
+ (when (>= accum interval)
+ (set! (growth-progress flower)
+ (min (+ (growth-progress flower) 1)
+ (growth-goal flower)))
+ (set! (growth-accumulator flower)
+ (if (thirsty? flower) 0 (- accum interval)))
+ (decrement-water flower 1)
+ (update-animation flower)
+ (update-progress-meter flower))))
+ (next-method)
+ (when (= (growth-progress flower) 0)
+ (detach flower)))