blob: f73504926ffaa9641e98ac5044a1f33739128eed (
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
(library (strigoform level)
(export tile-width
tile-height
make-level-object
level-object?
level-object-x
level-object-type
level-object-properties
make-level
level?
level-height
level-foreground
level-collision
level-objects
level-update!
draw-level-foreground
rect-collides-with-level?)
(import (scheme base)
(hoot match)
(strigoform assets)
(strigoform canvas)
(strigoform game-area)
(strigoform math)
(strigoform type))
;; action id, sprite sheet offset, x, y
(define %tile-size (+ 4 8 8 8))
(define tile-width 16.0)
(define tile-height 16.0)
(define level-width 15)
(define-type level-object
make-level-object
level-object?
(x level-object-x set-level-object-x!)
(type level-object-type set-level-object-type!)
(properties level-object-properties set-level-object-properties!))
(define-type level
make-level
level?
(height level-height set-level-height!)
(foreground level-foreground set-level-foreground!)
(collision level-collision set-level-collision!)
(objects level-objects set-level-objects!))
(define (level-offset x y)
(+ (* level-width y) x))
(define (point-collides-with-level? level x y)
(match level
(#('level height foreground collision objects)
(let ((tx (exact (truncate (/ x tile-width))))
(ty (exact (truncate (/ y tile-height)))))
(and (>= tx 0) (< tx level-width)
(>= ty 0) (< tx height)
(= (bytevector-u8-ref collision (level-offset tx ty)) 1))))))
(define (rect-collides-with-level? level x y w h scroll)
(match level
(#('level height foreground collision objects)
(let* ((y (+ y (- (* height tile-height) game-height scroll)))
(tx0 (exact (truncate (/ x tile-width))))
(ty0 (exact (truncate (/ y tile-height))))
(tx1 (exact (truncate (/ (+ x w) tile-width))))
(ty1 (exact (truncate (/ (+ y h) tile-height)))))
(define (occupied? x y)
(and (>= x 0) (< x level-width)
(>= y 0) (< x height)
(= (bytevector-u8-ref collision (level-offset x y)) 1)))
(or (occupied? tx0 ty0)
(occupied? tx1 ty0)
(occupied? tx1 ty1)
(occupied? tx0 ty1))))))
(define (draw-level-layer context level layer parallax scroll)
(match level
(#('level height _ _ _)
(let* ((tw tile-width)
(th tile-height)
(scroll (* scroll parallax))
(pixel-y-offset (- (* height th) scroll game-height))
(scroll-y-offset (- height (exact (truncate (/ scroll tile-height)))))
(y-start (clamp (- scroll-y-offset 21) 0 height))
(y-end (clamp scroll-y-offset 0 height)))
(do ((y y-start (+ y 1)))
((= y y-end))
(let* ((row (vector-ref layer y))
(k (/ (bytevector-length row) 16))
(ty (* y tile-height)))
(do ((x 0 (+ x 1)))
((= x k))
(let* ((offset (* x 16))
(tx (f64-ref row offset))
(ix (f64-ref row (+ offset 8))))
(draw-image context image:map
ix 0.0 tw th
tx (- ty pixel-y-offset) tw th)))))))))
(define (draw-level-foreground context level scroll)
(match level
(#('level height foreground collision objects)
(draw-level-layer context level foreground 1.0 scroll))))
(define (level-update! level scroll last-row-scanned do-action)
(match level
(#('level height foreground collision objects)
(let ((row (max
(exact
(truncate
(/ (- (* height tile-height)
game-height scroll)
tile-height)))
0)))
(do ((y row (+ y 1)))
((= y last-row-scanned))
(for-each (lambda (obj)
(match obj
(#('level-object x type properties)
(let ((x* (+ (* x tile-width)
(/ tile-width 2.0)))
(y* (+ (* (- y row 1) tile-height)
(/ tile-height 2.0))))
(do-action type x* y* properties)))))
(vector-ref objects y)))
row)))))
|