aboutsummaryrefslogtreecommitdiff
path: root/entity.scm
blob: 891fbde2248a8da458494410debeeec437aacd20 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
(module downstroke-entity
    *
  (import scheme
	  (chicken base)
	  (chicken keyword)
	  (only srfi-1 fold))

  ;; Entities = plists with shared keys (#:type, #:x, #:y, #:width, #:height, ...).

  (define (entity-ref entity key #!optional default)
    (get-keyword key entity (if (procedure? default) default (lambda () default))))

  (define (entity-type entity)
    (entity-ref entity #:type #f))

  (define (entity-set entity key val)
    (let ((cleaned (let loop ((lst entity) (acc '()))
                     (if (null? lst)
                         (reverse acc)
                         (let ((k (car lst))
                               (v (cadr lst)))
                           (if (eq? k key)
                               (loop (cddr lst) acc)
                               (loop (cddr lst) (cons v (cons k acc)))))))))
      (cons key (cons val cleaned))))

  (define (entity-update entity key proc #!optional default)
    (entity-set entity key (proc (entity-ref entity key default))))

  ;; #:skip-pipelines — list of symbols naming frame pipeline steps to skip for this
  ;; entity. Physics documents the built-in step names (see docs/physics.org). Other
  ;; subsystems (e.g. animation, rendering) may reserve additional symbols later and
  ;; use the same predicate and define-pipeline macro.

  (define (entity-skips-pipeline? entity step)
    (let ((skips (entity-ref entity #:skip-pipelines '())))
      (and (pair? skips) (memq step skips))))

  ;; er-macro-transformer so (rename 'entity-skips-pipeline?) captures the
  ;; binding from THIS module — works across compiled unit boundaries.
  ;;
  ;; Syntax:
  ;;   (define-pipeline (name skip-sym) (entity-formal ...)
  ;;     guard: guard-expr     ;; optional — entity returned unchanged when #f
  ;;     body ...)
  (define-syntax define-pipeline
    (er-macro-transformer
      (lambda (form rename _compare)
        (let* ((name-skip (cadr form))
               (name     (car name-skip))
               (skip     (cadr name-skip))
               (formals  (caddr form))
               (f1       (car formals))
               (rest     (cdddr form))
               (has-guard? (and (pair? rest) (pair? (cdr rest))
                                (eq? (car rest) guard:)))
               (guard-expr (and has-guard? (cadr rest)))
               (body       (if has-guard? (cddr rest) rest))
               (%define  (rename 'define))
               (%if      (rename 'if))
               (%let     (rename 'let))
               (%not     (rename 'not))
               (%quote   (rename 'quote))
               (%skip?   (rename 'entity-skips-pipeline?)))
          (if has-guard?
              `(,%define (,name ,@formals)
                 (,%if (,%skip? ,f1 (,%quote ,skip))
                       ,f1
                       (,%if (,%not ,guard-expr)
                             ,f1
                             (,%let () ,@body))))
              `(,%define (,name ,@formals)
                 (,%if (,%skip? ,f1 (,%quote ,skip))
                       ,f1
                       (,%let () ,@body))))))))

  (define (make-player-entity x y width height)
    (list #:type 'player
	  #:x x
	  #:y y
	  #:width width
	  #:height height
	  #:vx 0
	  #:vy 0
	  #:gravity? #t
	  #:on-ground? #f
	  #:tile-id 29
	  #:input-map '((left  . (-2 .  0))
	                (right . ( 2 .  0))
	                (down  . ( 0 .  2)))))
)