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
|
(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.
(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))
(body (cdddr form))
(%define (rename 'define))
(%if (rename 'if))
(%let (rename 'let))
(%quote (rename 'quote))
(%skip? (rename 'entity-skips-pipeline?)))
`(,%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)))))
)
|