summaryrefslogtreecommitdiff
path: root/heyllama.scm
blob: 0b90dcbf03620133c0f3413e8baf18be5e4c4a04 (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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
(use-modules (chickadee)
             (chickadee math vector)
             (chickadee math rect)
             (chickadee render font)
             (chickadee render sprite)
             (chickadee render texture)
             (chickadee render tiled)
             (oop goops))

(define-class <animal> (<object>)
  (pos #:init-keyword #:pos
       #:getter get-pos)

  (size #:init-keyword #:size
        #:getter get-size)

  (vel #:init-value #v(0.0 0.0)
       #:getter get-vel
       #:setter set-vel!)


  (walk-direction
   #:init-value 0
   #:setter set-walk-direction!
   #:getter get-walk-direction)

  (face-direction
   #:init-keyword #:face-dir
   #:setter set-face-direction!
   #:getter get-face-direction)

  (animation-step #:init-value 0
                  #:getter get-animation-step
                  #:setter set-animation-step!)

  (sprite #:init-keyword #:sprite
          #:getter get-sprite))

(define (face-row dir)
  (if (> 0 dir)
      4
      12))

(define (draw-animal animal)
  (draw-sprite (texture-atlas-ref (get-sprite animal)
                                  (+ (face-row (get-face-direction animal))
                                     (truncate (/ (get-animation-step animal) 4))))
               (get-screen-pos animal)))


(define (update-animal animal tstep)
  (let ((wd (get-walk-direction animal)))
    (unless (eq? wd 0)
      (set-face-direction! animal wd)
      (vec2-add! (get-pos animal) #v((* tstep wd 0.2) 0))
      (set-animation-step! animal
                           (floor-remainder
                            (+ (get-animation-step animal) wd)
                            16))))
  (vec2-add! (get-pos animal) (get-vel animal))
  (if (> (vec2-y (get-pos animal)) 200.0)
      (set-vel! animal
                (vec2+ (get-vel animal)
                       #v(0.0 -1.0)))
      (set-vel! animal #v(0.0 0.0))))



;; -------------- Initial game state --------------

(define llama #f)
(define tile-map #f)
(define view-pos #v(0.0 0.0))

(define (load)
  (set! llama (make <animal>
                #:pos #v(200.0 200.0)
                #:size #v(128.0 128.0)
                #:face-dir 1
                #:sprite (split-texture (load-image "llama_walk.png")
                                        128
                                        128)))

  (set! tile-map (load-tile-map "llama.tmx")))


;; ------------------------------------------------

(define (draw alpha)
  (draw-tile-map tile-map
                 #:position (vec2* view-pos -1.0))
  (draw-animal llama))


(define (get-screen-pos animal)
  (vec2- (get-pos animal) view-pos))


(define (rect-xy rect)
  #v((rect-x rect) (rect-y rect)))


(define (get-screen-rect animal)
  (let ((screen-pos (get-screen-pos animal)))
    (make-rect (vec2-x screen-pos)
               (vec2-y screen-pos)
               (vec2-x (get-size animal))
               (vec2-y (get-size animal)))))


(define (overshoot small-rect big-rect)
  (let ((moved-small-rect (rect-clamp small-rect big-rect)))
    (vec2- (rect-xy small-rect)
           (rect-xy moved-small-rect))))


(define (update tstep)

  (update-animal llama tstep)

  ;; Ensure llama is near centre of screen
  (let ((fovea (make-rect 150.0 150.0 350.0 350.0))
        (llama-rect (get-screen-rect llama)))
    (unless (rect-within? llama-rect fovea)
      (vec2-add! view-pos (overshoot llama-rect fovea)))))


(define (key-press key scancode modifier repeat?)
  (case key
    ((q) (abort-game))
    ((right) (set-walk-direction! llama 1))
    ((left) (set-walk-direction! llama -1))
    ((space) (unless repeat?
               (set-vel! llama #v(0.0 15.0))))))


(define (key-release key scancode modifier)
  (case key
    ((right) (set-walk-direction! llama 0))
    ((left) (set-walk-direction! llama 0))))


(run-game #:window-title "Hey Llama!"
          #:load load
          #:draw draw
          #:key-press key-press
          #:update-hz 60
          #:key-release key-release
          #:update update)