add keys and open close door at end of level

This commit is contained in:
Peter Tillemans 2024-05-23 21:46:50 +02:00
parent 182d9d5693
commit c3d97c2b91
13 changed files with 159 additions and 61 deletions

View file

@ -36,7 +36,7 @@ let the _others_ fall in so you can pass over their head.
So now, go out, collect the keys and maintain a healthy diet! So now, go out, collect the keys and maintain a healthy diet!
* Game Plan [9/16] * Game Plan [11/18]
- [X] start project organization - [X] start project organization
- [X] select some assets to start with - [X] select some assets to start with
@ -51,11 +51,13 @@ So now, go out, collect the keys and maintain a healthy diet!
- [X] ensure the assets can be found by the render packages - [X] ensure the assets can be found by the render packages
- [X] upload to itch.io - [X] upload to itch.io
- [ ] automate upload to itch.io - [ ] automate upload to itch.io
- [ ] create other's AI - [X] create other's AI
- [ ] add keys and portal - [X] add keys and portal
- [ ] add foods and bloat indicator - [ ] add foods and bloat indicator
- [ ] scale hero waist related to bloat level - [ ] scale hero waist related to bloat level
- [ ] create more levels - [ ] create more levels
- [ ] dig potholes
- [ ] make others steal keys
- [ ] some level celebration/animation - [ ] some level celebration/animation
* Installation and Development * Installation and Development

View file

@ -2,10 +2,10 @@
-- all content after a '-' is ignored -- all content after a '-' is ignored
-- --
----|----|----|----|----|----|----|----| ----|----|----|----|----|----|----|----|
WWWWGWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW WWWWWGWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
W H W W H W
W O H O W W O H O W
W H H W W H K K K H W
W O BBBBBBBBBBBBBBBBBBBBBBBBBBHB O W - W O BBBBBBBBBBBBBBBBBBBBBBBBBBHB O W -
W H W W H W
W H W W H W
@ -21,7 +21,7 @@ W H W
W H W W H W
W H W W H W
W H W W H W
W H H W - W H K H W -
W P BHBBBBBBB W W P BHBBBBBBB W
W H W W H W
W H W W H W
@ -29,6 +29,6 @@ W H W
W H W - W H W -
W H W W H W
W H W W H W
W H W W K H W
WBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBW WBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW -

View file

@ -3,9 +3,12 @@
#:use-module (game model level) #:use-module (game model level)
#:use-module (game model hero) #:use-module (game model hero)
#:use-module (game model other) #:use-module (game model other)
#:use-module (game model key)
#:use-module (game render level) #:use-module (game render level)
#:use-module (game render hero) #:use-module (game render hero)
#:use-module (game render other) #:use-module (game render other)
#:use-module (game render key)
#:use-module (game util assets)
#:use-module (chickadee) #:use-module (chickadee)
#:use-module (chickadee math rect) #:use-module (chickadee math rect)
#:use-module (chickadee math vector) #:use-module (chickadee math vector)
@ -22,28 +25,32 @@
(define repl #f) (define repl #f)
(define hero #f) (define hero #f)
(define others #f) (define others #f)
(define keys #f)
(define inputs '()) (define inputs '())
(define (load) (define (load)
(assets-load)
(render-level-load) (render-level-load)
(render-hero-load)
(render-other-load)
(set! level (level-parse-file "assets/levels/level-1.map")) (set! level (level-parse-file "assets/levels/level-1.map"))
(render-level-set! level) (render-level-set! level)
(set! hero (hero-load level)) (set! hero (hero-load level))
(set! others (other-load-others level)) (set! others (other-load-others level))
(set! keys (keys-load level))
(set! repl (spawn-coop-repl-server))) (set! repl (spawn-coop-repl-server)))
(define (update dt) (define (update dt)
(poll-coop-repl-server repl) (poll-coop-repl-server repl)
(set! hero (hero-update hero level inputs dt)) (set! hero (hero-update hero level inputs keys dt))
(set! others (map (lambda (other) (other-update other level hero others dt)) others)) (set! others (map (lambda (other) (other-update other level hero others dt)) others))
(set! keys (keys-update keys hero))
) )
(define (draw _alpha) (define (draw _alpha)
(render-level-draw level) (render-level-draw level)
(render-hero hero)
(for-each render-other others) (for-each render-other others)
(render-keys keys (level-find-goal level))
(render-hero hero)
) )
(define (set-add set item) (define (set-add set item)
@ -51,7 +58,6 @@
set set
(cons item set))) (cons item set)))
(define (key-press key _modifiers _repeat?) (define (key-press key _modifiers _repeat?)
(set! inputs (set! inputs
(cond ((eq? key 'left) (set-add inputs 'left)) (cond ((eq? key 'left) (set-add inputs 'left))

View file

@ -51,10 +51,23 @@
"return the current position of the hero" "return the current position of the hero"
(runner-position (hero-runner hero))) (runner-position (hero-runner hero)))
(define (collides? a b)
"return true if the hero collides with the given position"
(< (vec2-magnitude (vec2- a b)) level-cell-size))
(define (hero-update hero level inputs dt) (define (blocked-by-door? level keys position)
(hero-with-runner hero (runner-update (hero-runner hero) level inputs dt))) "return true if the hero is blocked by a door"
(let ((door-position (level-find-goal level)))
(pk 'blocked-by-door? keys (null? keys) position
(and (collides? position door-position)
(not (null? keys))))))
(define (hero-update hero level inputs keys dt)
(let ((new-runner (runner-update (hero-runner hero) level inputs dt)))
(if (blocked-by-door? level keys (runner-position new-runner))
hero
(hero-with-runner hero new-runner)
)))
;; Tests ;; Tests
@ -69,5 +82,13 @@
(test-equal 1.5 (hero-bloat (hero-with-bloat hero 1.5))) (test-equal 1.5 (hero-bloat (hero-with-bloat hero 1.5)))
(test-equal default-bloat (hero-bloat hero))) (test-equal default-bloat (hero-bloat hero)))
(let* ((level (level-parse "WWGWW\nW.H.W\nW.P.W\nWWWWW\n"))
(hero (hero-load level))
(goal-position (level-find-goal level)))
(test-assert (blocked-by-door? level '(dummy-key) goal-position))
(test-assert (not (blocked-by-door? level '() goal-position)))
(test-assert (blocked-by-door? level '(dummy-key) (vec2- goal-position (vec2 0 -15))))
(test-assert (not (blocked-by-door? level '(dummy-key) (vec2- goal-position (vec2 0 -16))))))
(test-end "hero-model") (test-end "hero-model")

36
game/model/key.scm Normal file
View file

@ -0,0 +1,36 @@
(define-module (game model key)
#:use-module (chickadee math vector)
#:use-module (game model level)
#:use-module (game model hero)
#:use-module (srfi srfi-9)
#:use-module (srfi srfi-9 gnu)
#:export (key?
key-near-position?
keys-load
key-position
make-key
keys-update
)
)
(define-immutable-record-type <key>
(make-key position)
key?
(position key-position)
)
(define (key-collides? key position)
(< (pk "key distance" (vec2-magnitude (vec2- (key-position key) position))) 4))
(define (keys-load level)
(map make-key (level-find-keys level)))
(define (keys-update keys hero)
(filter (lambda (key)
(not (key-collides? key (hero-position hero))))
keys))
(define (keys-open-door? keys)
(null? keys))

View file

@ -18,12 +18,15 @@
level-tile-at level-tile-at
level-cell-size level-cell-size
level-find-hero level-find-hero
level-find-goal
level-find-others level-find-others
level-find-keys
level-tile-blocked? level-tile-blocked?
level-same-cell?
)) ))
(define-record-type <level> (define-record-type <level>
(%make-level width height tiles goal hero entities) (%make-level width height tiles)
level? level?
(width level-width) (width level-width)
(height level-height) (height level-height)
@ -40,6 +43,7 @@
((#\P) 'hero) ((#\P) 'hero)
((#\O) 'other) ((#\O) 'other)
((#\G) 'goal) ((#\G) 'goal)
((#\K) 'key)
(else 'empty))) (else 'empty)))
(define (content->lines content) (define (content->lines content)
@ -65,12 +69,11 @@
(width (string-length (car lines))) (width (string-length (car lines)))
(height (length lines)) (height (length lines))
(tiles (list->vector (tiles (list->vector
(parse-lines lines))) (parse-lines lines))))
(entities '())) (%make-level width height tiles)))
(%make-level width height tiles #f #f entities)))
(define (level-parse-file filename) (define (level-parse-file filename)
(level-parse (call-with-input-file (asset-file-name filename) get-string-all))) (level-parse (call-with-input-file (assets-file-name filename) get-string-all)))
(define (level-tile-at-row-col level row col ) (define (level-tile-at-row-col level row col )
@ -119,6 +122,14 @@
(define (level-find-others level) (define (level-find-others level)
(level-find-tile level 'other)) (level-find-tile level 'other))
(define (level-find-keys level)
(level-find-tile level 'key))
(define (level-same-cell? a b)
(and (= (coord->cell (vec2-x a)) (coord->cell (vec2-x b)))
(= (coord->cell (vec2-y a)) (coord->cell (vec2-y b)))))
;; Tests ;; Tests
(test-begin "level") (test-begin "level")

View file

@ -24,10 +24,13 @@
;; They are represented by a runner and try to reach the player to give ;; They are represented by a runner and try to reach the player to give
;; unwelcome advice unwittingly killing the player with cringe. ;; unwelcome advice unwittingly killing the player with cringe.
(define-immutable-record-type <other> (define-immutable-record-type <other>
(%make-other runner) (%make-other runner has-key?)
other? other?
(runner other-runner other-with-runner) (runner other-runner other-with-runner)
) (has-key? other-has-key? other-with-key))
(define (make-other runner)
(%make-other runner #f))
(define default-state 'fall) (define default-state 'fall)
(define default-bloat 1.0) (define default-bloat 1.0)
@ -35,7 +38,7 @@
(define (other-load-others level) (define (other-load-others level)
"Create a other at the position in the level map" "Create a other at the position in the level map"
(map (map
(compose %make-other runner-load) (compose make-other runner-load)
(level-find-others level))) (level-find-others level)))
(define (other-x other) (define (other-x other)
@ -44,8 +47,7 @@
(define (other-y other) (define (other-y other)
"return the y coordinate as an integer" "return the y coordinate as an integer"
(runner-y (other-runner other)) (runner-y (other-runner other)))
)
(define (other-state other) (define (other-state other)
"return the current state of the other" "return the current state of the other"

View file

@ -13,9 +13,7 @@
runner-position runner-with-position runner-position runner-with-position
runner-x runner-with-x runner-x runner-with-x
runner-y runner-with-y runner-y runner-with-y
runner-update runner-update))
))
(define-immutable-record-type <runner> (define-immutable-record-type <runner>
(%make-runner position state) (%make-runner position state)
@ -43,7 +41,6 @@
(define (runner-with-y runner y) (define (runner-with-y runner y)
(runner-with-position runner (vec2 (runner-x runner) y))) (runner-with-position runner (vec2 (runner-x runner) y)))
;; return next state of runner ;; return next state of runner
;; @returns 'go-left 'go-right 'climb 'fall 'stationary ;; @returns 'go-left 'go-right 'climb 'fall 'stationary
(define (next-state runner level inputs) (define (next-state runner level inputs)
@ -68,12 +65,10 @@
((down) (vec2 0 (- distance))) ((down) (vec2 0 (- distance)))
(else (vec2 0 0)))) (else (vec2 0 0))))
(define (round-position pos) (define (round-position pos)
(vec2 (inexact->exact (floor (vec2-x pos))) (vec2 (inexact->exact (floor (vec2-x pos)))
(inexact->exact (floor (vec2-y pos))))) (inexact->exact (floor (vec2-y pos)))))
(define (safe-move level pos move) (define (safe-move level pos move)
(let ((new-pos (vec2+ pos move))) (let ((new-pos (vec2+ pos move)))
(if (level-tile-blocked? level new-pos) (if (level-tile-blocked? level new-pos)
@ -105,8 +100,6 @@
(runner-with-state state) (runner-with-state state)
(runner-with-position position)))) (runner-with-position position))))
;; Tests ;; Tests
(test-begin "runner-model") (test-begin "runner-model")

View file

@ -6,16 +6,7 @@
#:use-module (chickadee graphics sprite) #:use-module (chickadee graphics sprite)
#:use-module (chickadee graphics texture) #:use-module (chickadee graphics texture)
#:export (render-hero #:export (render-hero
render-hero-load) render-hero-load))
)
(define hero-texture #f)
(define hero-atlas #f)
(define (render-hero-load)
(set! hero-texture (load-image (asset-file-name "assets/images/lr_penguin2.png")))
(set! hero-atlas (split-texture hero-texture 32 32)))
;; start index of the walk animation ;; start index of the walk animation
(define hero-walking-offset 56) (define hero-walking-offset 56)

31
game/render/key.scm Normal file
View file

@ -0,0 +1,31 @@
(define-module (game render key)
#:use-module (game util assets)
#:use-module (game model key)
#:use-module (chickadee math vector)
#:use-module (chickadee graphics sprite)
#:use-module (chickadee graphics texture)
#:export (render-keys))
(define key-index 1726)
(define closed-goal-index 3404)
(define open-goal-index 3350)
(define (render-key key)
(draw-sprite
(texture-atlas-ref tile-atlas key-index)
(vec2+ (key-position key) (vec2 -8 0))))
(define (render-goal keys goal-position)
(let ((goal-index (if (null? keys) open-goal-index closed-goal-index)))
(draw-sprite
(texture-atlas-ref tile-atlas goal-index)
goal-position)))
(define (render-keys keys goal-position)
(for-each (lambda (key)
(render-key key))
keys)
(render-goal keys goal-position))

View file

@ -12,17 +12,10 @@
)) ))
(define tile-texture #f)
(define tile-atlas #f)
(define tile-index 0)
(define tile-map #f)
(define sprite-batch #f) (define sprite-batch #f)
;; load the tile texture and split it into a tile atlas ;; load the tile texture and split it into a tile atlas
(define (render-level-load) (define (render-level-load)
(set! tile-texture (load-image (asset-file-name "assets/images/simples_pimples.png")
#:transparent-color black))
(set! tile-atlas (split-texture tile-texture 16 16))
(set! sprite-batch (make-sprite-batch tile-texture #:capacity 1200)) (set! sprite-batch (make-sprite-batch tile-texture #:capacity 1200))
) )
@ -35,9 +28,10 @@
((brick) 3750) ((brick) 3750)
((wall) 3709) ((wall) 3709)
((ladder) 3350) ((ladder) 3350)
((goal) 3404) ((goal) 3800) ;; render empty tile for goal location
((hero) 3800) ;; render empty tile for hero start location ((hero) 3800) ;; render empty tile for hero start location
((other) 3800) ;; render empty tile for enemy start location ((other) 3800) ;; render empty tile for enemy start location
((key) 3800)
;; render visual reminder of unknown tile ;; render visual reminder of unknown tile
(else 3326))) (else 3326)))

View file

@ -10,11 +10,6 @@
(define other-atlas #f)
(define (render-other-load)
(set! other-atlas (split-texture (load-image (asset-file-name "assets/images/simples_pimples.png")) 16 16)))
;; start index of the walk animation ;; start index of the walk animation
(define other-walking-offset 3926) (define other-walking-offset 3926)
(define other-falling-offset 3930) (define other-falling-offset 3930)
@ -24,16 +19,16 @@
(let* ((x (other-x other)) (let* ((x (other-x other))
(animation-frame (remainder x 3)) (animation-frame (remainder x 3))
(other-index (+ other-walking-offset animation-frame))) (other-index (+ other-walking-offset animation-frame)))
(texture-atlas-ref other-atlas other-index))) (texture-atlas-ref tile-atlas other-index)))
(define (other-sprite-stationary _other) (define (other-sprite-stationary _other)
(texture-atlas-ref other-atlas other-walking-offset)) (texture-atlas-ref tile-atlas other-walking-offset))
(define (other-sprite-falling other) (define (other-sprite-falling other)
(texture-atlas-ref other-atlas other-climbing-offset)) (texture-atlas-ref tile-atlas other-climbing-offset))
(define (other-sprite-climbing other) (define (other-sprite-climbing other)
(texture-atlas-ref other-atlas other-climbing-offset)) (texture-atlas-ref tile-atlas other-climbing-offset))
(define (render-other other) (define (render-other other)
(case (other-state other) (case (other-state other)

View file

@ -1,11 +1,27 @@
(define-module (game util assets) (define-module (game util assets)
#:export (asset-file-name) #:use-module (chickadee graphics texture)
#:use-module (chickadee graphics color)
#:export (assets-load assets-file-name tile-texture tile-atlas hero-texture hero-atlas)
) )
(define tile-texture #f)
(define tile-atlas #f)
(define hero-texture #f)
(define hero-atlas #f)
(define prefix (or (getenv "ASSET_DIR") "." )) (define prefix (or (getenv "ASSET_DIR") "." ))
(define (asset-file-name name) (define (assets-file-name name)
(string-append prefix "/" name) (string-append prefix "/" name)
) )
(define (assets-load)
(set! tile-texture (load-image (assets-file-name "assets/images/simples_pimples.png")
#:transparent-color black))
(set! tile-atlas (split-texture tile-texture 16 16))
(set! hero-texture (load-image (assets-file-name "assets/images/lr_penguin2.png")))
(set! hero-atlas (split-texture hero-texture 32 32)))