summaryrefslogtreecommitdiff
path: root/lisparuga/enemy.scm
diff options
context:
space:
mode:
Diffstat (limited to 'lisparuga/enemy.scm')
-rw-r--r--lisparuga/enemy.scm75
1 files changed, 74 insertions, 1 deletions
diff --git a/lisparuga/enemy.scm b/lisparuga/enemy.scm
index 5ecba62..0589d16 100644
--- a/lisparuga/enemy.scm
+++ b/lisparuga/enemy.scm
@@ -21,6 +21,7 @@
;;; Code:
(define-module (lisparuga enemy)
+ #:use-module (chickadee math)
#:use-module (chickadee math rect)
#:use-module (chickadee math vector)
#:use-module (chickadee scripting)
@@ -36,6 +37,8 @@
health
points
parting-shots
+ dead?
+ fire-parting-shots-maybe
make-utatsugumi))
@@ -46,7 +49,68 @@
(define-class <enemy> (<actor>)
(health #:accessor health #:init-keyword #:health)
(points #:getter points #:init-keyword #:points)
- (parting-shots #:getter parting-shots #:init-keyword #:parting-shots))
+ (parting-shots #:getter parting-shots #:init-keyword #:parting-shots)
+ (fire-parting-shots? #:accessor fire-parting-shots? #:init-form #f))
+
+(define-method (on-kill (enemy <enemy>))
+ #t)
+
+(define-method (damage (enemy <enemy>) x)
+ (set! (health enemy) (max (- (health enemy) x) 0)))
+
+(define-method (dead? (enemy <enemy>))
+ (zero? (health enemy)))
+
+(define (fire-parting-shots-maybe enemy player)
+ (when (fire-parting-shots? enemy)
+ (let* ((n (parting-shots enemy))
+ (ep (position enemy))
+ (pp (position player))
+ (angle-to-player
+ (atan (- (vec2-y pp) (vec2-y ep))
+ (- (vec2-x pp) (vec2-x ep)))))
+ (let loop ((i 0))
+ (when (< i n)
+ (let ((theta (+ angle-to-player
+ (- (* (random:uniform) (/ pi 4.0))
+ (/ pi 8.0)))))
+ (spawn-bullet (bullet-field enemy)
+ small-dot
+ (polarity enemy)
+ (+ (vec2-x ep)
+ (- (* (random:uniform) 16.0)
+ 8.0))
+ (+ (vec2-y ep)
+ (- (* (random:uniform) 16.0)
+ 8.0))
+ (* (cos theta) 4.0)
+ (* (sin theta) 4.0)))
+ (loop (+ i 1)))))))
+
+(define-method (on-collision (enemy <enemy>) bullet bullet-polarity hitbox)
+ ;; TODO: Distinguish between normal play bullets and homing shots
+ ;; that do more damage.
+ ;;
+ ;; Same polarity = 1 point of damage
+ ;; Opposite polarity = 2 points of damage
+ (let ((same-polarity? (eq? bullet-polarity (polarity enemy))))
+ (damage enemy (if same-polarity? 1 2))
+ (when (and same-polarity? (dead? enemy))
+ (set! (fire-parting-shots? enemy) #t)))
+ #t)
+
+(define %enemy-tiles
+ ;; 0: Utatsugumi - white
+ `((0.0 0.0 24.0 24.0)
+ ;; 1: Utatsugumi - black
+ (24.0 0.0 24.0 24.0)))
+
+(define (load-enemy-atlas file-name)
+ (let ((texture (load-image file-name)))
+ (list->texture-atlas texture %enemy-tiles)))
+
+(define-asset enemy-atlas
+ (load-enemy-atlas (scope-asset "images/enemies.png")))
;;;
@@ -55,6 +119,13 @@
(define-class <utatsugumi> (<enemy>))
+(define-method (on-boot (utatsugumi <utatsugumi>))
+ (attach-to utatsugumi
+ (make <atlas-sprite>
+ #:atlas enemy-atlas
+ #:index (if (eq? 'white (polarity utatsugumi)) 0 1)
+ #:origin (vec2 12.0 12.0))))
+
(define (make-utatsugumi polarity x y)
(make <utatsugumi>
#:name (gensym "utatsugumi-")
@@ -62,4 +133,6 @@
#:points 20
#:parting-shots 5
#:polarity polarity
+ #:hitboxes
+ (list (make-hitbox 'utatsugumi (make-rect -10.0 -10.0 20.0 20.0)))
#:position (vec2 x y)))