;;; 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 ( 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 () (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 ) initargs) (next-method) (attach-to flower (make #:name 'sprite #:atlas flower-tileset #:origin (vec2 24.0 24.0) #:animations `((default . ,(make #:frames #(0 1) #:frame-duration 0.3)) (stage-2 . ,(make #:frames #(2 3 4 5) #:frame-duration 0.3)) (stage-3 . ,(make #:frames #(6 7 8 9) #:frame-duration 0.3)) (stage-4 . ,(make #:frames #(10 11 12 13) #:frame-duration 0.3)))) (make #:name 'progress-meter #:position (vec2 -32.0 -28.0) #:width 64.0 #:height 8.0) (make #:name 'idle-meter #:position (vec2 -32.0 -36.0) #:width 64.0 #:height 8.0)) (update-progress-meter flower)) (define-method (update-progress-meter (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-idle-meter (flower )) (define w 64.0) (define t (- 1.0 (/ (growth-accumulator flower) (growth-interval flower)))) (define meter (& flower idle-meter)) (if (>= t 0.999) (hide meter) (begin (show meter) (set! (painter 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-mandy) (stroke-width 2.0)) (stroke (line (vec2 0.0 0.0) (vec2 (* w t) 0.0)))))) (resize meter (default-width meter) (default-height meter))))) (define-method (update-animation (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 ) amount) (set! (water flower) (min (+ (water flower) amount) %max-water))) (define-method (decrement-water (flower ) amount) (set! (water flower) (max (- (water flower) amount) 0))) (define-method (damage (flower ) amount) (set! (growth-progress flower) (max (- (growth-progress flower) amount) 0)) (update-animation flower) (update-progress-meter flower)) (define-method (thirsty? (flower )) (= (water flower) 0)) (define-method (reset-growth-accumulator (flower )) (set! (growth-accumulator flower) 0)) (define-method (on-splash (flower )) (when (thirsty? flower) (increment-water flower 1) (audio-play (artifact watered-sound)))) (define-method (update (flower ) dt) (update-idle-meter flower) (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) 0.0) (decrement-water flower 1) (update-animation flower) (update-progress-meter flower)))) (next-method) (when (= (growth-progress flower) 0) (detach flower)))