refactored asset loading
This commit is contained in:
parent
c4df134f53
commit
2589b236d4
6 changed files with 67 additions and 32 deletions
|
@ -69,7 +69,7 @@
|
||||||
(wrap-program (string-append out "/bin/bloatrunner")
|
(wrap-program (string-append out "/bin/bloatrunner")
|
||||||
`("GUILE_LOAD_PATH" ":" prefix (,mods))
|
`("GUILE_LOAD_PATH" ":" prefix (,mods))
|
||||||
`("GUILE_LOAD_COMPILED_PATH" ":" prefix (,objs))
|
`("GUILE_LOAD_COMPILED_PATH" ":" prefix (,objs))
|
||||||
`("ASSET_DIR" ":" prefix (,(string-append out "/share/bloatrunner")))
|
`("ASSET_DIR" ":" prefix (,(string-append out "/share/bloatrunner/assets")))
|
||||||
)))))
|
)))))
|
||||||
))
|
))
|
||||||
(native-inputs
|
(native-inputs
|
||||||
|
|
|
@ -35,13 +35,15 @@
|
||||||
(define state 'running)
|
(define state 'running)
|
||||||
|
|
||||||
(define (load)
|
(define (load)
|
||||||
|
"Load the game initial game state."
|
||||||
(assets-load)
|
(assets-load)
|
||||||
(render-level-load)
|
(render-level-load)
|
||||||
(set! levels (assets-map-levels level-parse-file))
|
(set! levels (assets-map-levels level-parse))
|
||||||
(load-level)
|
(load-level)
|
||||||
(set! repl (spawn-coop-repl-server)))
|
(set! repl (spawn-coop-repl-server)))
|
||||||
|
|
||||||
(define (load-level)
|
(define (load-level)
|
||||||
|
"Load the next level and reset game state."
|
||||||
(set! level (car levels))
|
(set! level (car levels))
|
||||||
(set! levels (cdr levels))
|
(set! levels (cdr levels))
|
||||||
(render-level-set! level)
|
(render-level-set! level)
|
||||||
|
@ -51,6 +53,7 @@
|
||||||
(set! foods (food-load level)))
|
(set! foods (food-load level)))
|
||||||
|
|
||||||
(define (update dt)
|
(define (update dt)
|
||||||
|
"Update the game state."
|
||||||
(poll-coop-repl-server repl)
|
(poll-coop-repl-server repl)
|
||||||
(set! hero (hero-update hero level inputs keys (food-total-calories-eaten foods) dt))
|
(set! hero (hero-update hero level inputs keys (food-total-calories-eaten foods) 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))
|
||||||
|
@ -60,11 +63,11 @@
|
||||||
(set! state 'lost))
|
(set! state 'lost))
|
||||||
(if (level-same-cell? (hero-position hero) (level-find-goal level))
|
(if (level-same-cell? (hero-position hero) (level-find-goal level))
|
||||||
(if (null? levels)
|
(if (null? levels)
|
||||||
(set! status 'won)
|
(set! state 'won)
|
||||||
(load-level)))
|
(load-level))))
|
||||||
)
|
|
||||||
|
|
||||||
(define (render-level)
|
(define (render-level)
|
||||||
|
"Render the level and entities for the running state"
|
||||||
(render-level-draw level)
|
(render-level-draw level)
|
||||||
(for-each render-other others)
|
(for-each render-other others)
|
||||||
(render-keys keys (level-find-goal level))
|
(render-keys keys (level-find-goal level))
|
||||||
|
@ -72,17 +75,26 @@
|
||||||
(render-hero hero))
|
(render-hero hero))
|
||||||
|
|
||||||
(define (draw _alpha)
|
(define (draw _alpha)
|
||||||
|
"Draw the game screen depending on state"
|
||||||
(case state
|
(case state
|
||||||
((won) (render-victory))
|
((won) (render-victory))
|
||||||
((lost) (render-defeat))
|
((lost) (render-defeat))
|
||||||
(else (render-level))))
|
(else (render-level))))
|
||||||
|
|
||||||
|
|
||||||
|
;; Input handling
|
||||||
|
;; keep a set of buttons which are currently pressed
|
||||||
|
;;
|
||||||
|
|
||||||
(define (set-add set item)
|
(define (set-add set item)
|
||||||
(if (member item set)
|
"Add an item to a list if it is not already present."
|
||||||
set
|
(if (member item set)
|
||||||
(cons item set)))
|
set
|
||||||
|
(cons item set)))
|
||||||
|
|
||||||
|
|
||||||
(define (key-press key _modifiers _repeat?)
|
(define (key-press key _modifiers _repeat?)
|
||||||
|
"Handle key press events by adding the input to the inputs set."
|
||||||
(set! inputs
|
(set! inputs
|
||||||
(cond ((eq? key 'left) (set-add inputs 'left))
|
(cond ((eq? key 'left) (set-add inputs 'left))
|
||||||
((eq? key 'right) (set-add inputs 'right))
|
((eq? key 'right) (set-add inputs 'right))
|
||||||
|
@ -94,6 +106,7 @@
|
||||||
|
|
||||||
|
|
||||||
(define (key-release key _modifiers)
|
(define (key-release key _modifiers)
|
||||||
|
"Handle key release events by removing the input from the inputs set."
|
||||||
(set! inputs
|
(set! inputs
|
||||||
(cond ((eq? key 'left) (delete 'left inputs))
|
(cond ((eq? key 'left) (delete 'left inputs))
|
||||||
((eq? key 'right) (delete 'right inputs))
|
((eq? key 'right) (delete 'right inputs))
|
||||||
|
@ -103,6 +116,7 @@
|
||||||
(else inputs))))
|
(else inputs))))
|
||||||
|
|
||||||
(define (launch-game args)
|
(define (launch-game args)
|
||||||
|
"Launch the game with the given arguments."
|
||||||
(run-game
|
(run-game
|
||||||
#:window-title "Bloatrunner"
|
#:window-title "Bloatrunner"
|
||||||
#:load (lambda () (load))
|
#:load (lambda () (load))
|
||||||
|
|
|
@ -91,9 +91,11 @@
|
||||||
|
|
||||||
(define (hero-update hero level inputs keys calories-eaten dt)
|
(define (hero-update hero level inputs keys calories-eaten dt)
|
||||||
(let* ((new-runner (runner-update (hero-runner hero) level inputs dt))
|
(let* ((new-runner (runner-update (hero-runner hero) level inputs dt))
|
||||||
(new-runner (if (blocked-by-door? level keys
|
(new-runner (if (blocked-by-door?
|
||||||
(runner-position new-runner)
|
level
|
||||||
(hero-bloat hero))
|
keys
|
||||||
|
(runner-position new-runner)
|
||||||
|
(hero-bloat hero))
|
||||||
(hero-runner hero)
|
(hero-runner hero)
|
||||||
new-runner
|
new-runner
|
||||||
))
|
))
|
||||||
|
@ -123,10 +125,13 @@
|
||||||
(let* ((level (level-parse "WWGWW\nW.H.W\nW.P.W\nWWWWW\n"))
|
(let* ((level (level-parse "WWGWW\nW.H.W\nW.P.W\nWWWWW\n"))
|
||||||
(hero (hero-load level))
|
(hero (hero-load level))
|
||||||
(goal-position (level-find-goal level)))
|
(goal-position (level-find-goal level)))
|
||||||
(test-assert (blocked-by-door? level '(dummy-key) goal-position))
|
(test-assert (blocked-by-door? level '(dummy-key) goal-position 1.0))
|
||||||
(test-assert (not (blocked-by-door? level '() goal-position)))
|
(test-assert (not (blocked-by-door? level '() goal-position 1.0)))
|
||||||
(test-assert (blocked-by-door? level '(dummy-key) (vec2- goal-position (vec2 0 -15))))
|
(test-assert (blocked-by-door? level '(dummy-key) (vec2- goal-position (vec2 0 -15)) 1.0))
|
||||||
(test-assert (not (blocked-by-door? level '(dummy-key) (vec2- goal-position (vec2 0 -16))))))
|
(test-assert (not (blocked-by-door? level '(dummy-key) (vec2- goal-position (vec2 0 -16)) 1.0)))
|
||||||
|
(test-assert (blocked-by-door? level '() goal-position 1.55))
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
(test-end "hero-model")
|
(test-end "hero-model")
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
(entities level-entities))
|
(entities level-entities))
|
||||||
|
|
||||||
(define (parse-tile c)
|
(define (parse-tile c)
|
||||||
|
"Parse a character into a tile type"
|
||||||
(case c
|
(case c
|
||||||
((#\W) 'wall)
|
((#\W) 'wall)
|
||||||
((#\B) 'brick)
|
((#\B) 'brick)
|
||||||
|
@ -52,6 +53,7 @@
|
||||||
(else 'empty)))
|
(else 'empty)))
|
||||||
|
|
||||||
(define (content->lines content)
|
(define (content->lines content)
|
||||||
|
"Parse a string into a list of lines, ignoring empty lines and comments"
|
||||||
(filter (lambda (line) (not (string-null? line)))
|
(filter (lambda (line) (not (string-null? line)))
|
||||||
(map
|
(map
|
||||||
(lambda (line)
|
(lambda (line)
|
||||||
|
@ -62,6 +64,7 @@
|
||||||
|
|
||||||
|
|
||||||
(define (parse-lines lines)
|
(define (parse-lines lines)
|
||||||
|
"Parse a list of lines into a list of tiles"
|
||||||
(fold append
|
(fold append
|
||||||
'()
|
'()
|
||||||
(map
|
(map
|
||||||
|
@ -70,6 +73,7 @@
|
||||||
lines)))
|
lines)))
|
||||||
|
|
||||||
(define (level-parse content)
|
(define (level-parse content)
|
||||||
|
"Parse a level from a string"
|
||||||
(let* ((lines (content->lines content))
|
(let* ((lines (content->lines content))
|
||||||
(width (string-length (car lines)))
|
(width (string-length (car lines)))
|
||||||
(height (length lines))
|
(height (length lines))
|
||||||
|
@ -77,20 +81,19 @@
|
||||||
(parse-lines lines))))
|
(parse-lines lines))))
|
||||||
(%make-level width height tiles)))
|
(%make-level width height tiles)))
|
||||||
|
|
||||||
(define (level-parse-file filename)
|
|
||||||
(level-parse (call-with-input-file filename get-string-all)))
|
|
||||||
|
|
||||||
|
|
||||||
(define (level-tile-at-row-col level row col )
|
(define (level-tile-at-row-col level row col )
|
||||||
|
"Get the tile at a given row and column"
|
||||||
(let ((index (+ (* row (level-width level)) col)))
|
(let ((index (+ (* row (level-width level)) col)))
|
||||||
(vector-ref (level-tiles level) index)))
|
(vector-ref (level-tiles level) index)))
|
||||||
|
|
||||||
(define level-cell-size 16)
|
(define level-cell-size 16)
|
||||||
|
|
||||||
(define (coord->cell coord)
|
(define (coord->cell coord)
|
||||||
|
"Convert a screen coordinate to a vector cell index"
|
||||||
(inexact->exact (floor (/ coord level-cell-size))))
|
(inexact->exact (floor (/ coord level-cell-size))))
|
||||||
|
|
||||||
(define (level-tile-at level position )
|
(define (level-tile-at level position )
|
||||||
|
"Get the tile at a given screen position"
|
||||||
(let ((x (vec2-x position))
|
(let ((x (vec2-x position))
|
||||||
(y (vec2-y position)))
|
(y (vec2-y position)))
|
||||||
(level-tile-at-row-col level (coord->cell y) (coord->cell x))))
|
(level-tile-at-row-col level (coord->cell y) (coord->cell x))))
|
||||||
|
@ -168,8 +171,8 @@
|
||||||
(test-equal (parse-tile #\F) 'bad-food)
|
(test-equal (parse-tile #\F) 'bad-food)
|
||||||
(test-equal (parse-tile #\f) 'good-food)
|
(test-equal (parse-tile #\f) 'good-food)
|
||||||
|
|
||||||
(test-equal (level-width (level-parse-file "assets/levels/level-001.map")) 40)
|
(test-equal (level-width (level-parse (read-level-map "level-001.map"))) 40)
|
||||||
(test-equal (level-height (level-parse-file "assets/levels/level-001.map")) 30)
|
(test-equal (level-height (level-parse (read-level-map "level-001.map"))) 30)
|
||||||
|
|
||||||
(test-equal
|
(test-equal
|
||||||
(level-tile-at-row-col (level-parse "WWWWW\nWP GW\nWWWWW\n") 1 1)
|
(level-tile-at-row-col (level-parse "WWWWW\nWP GW\nWWWWW\n") 1 1)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#:use-module (ice-9 textual-ports)
|
#:use-module (ice-9 textual-ports)
|
||||||
#:use-module (chickadee graphics texture)
|
#:use-module (chickadee graphics texture)
|
||||||
#:use-module (chickadee graphics color)
|
#:use-module (chickadee graphics color)
|
||||||
#:export (assets-load assets-file-name tile-texture tile-atlas hero-texture hero-atlas assets-map-levels)
|
#:export (assets-load assets-load-image tile-texture tile-atlas hero-texture hero-atlas assets-map-levels read-level-map)
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@
|
||||||
(define hero-atlas #f)
|
(define hero-atlas #f)
|
||||||
|
|
||||||
(define (assets-location)
|
(define (assets-location)
|
||||||
|
"find the location of the assets directory. The location is specified
|
||||||
|
by the ASSET_DIR environment variable, or defaults to 'assets' in the
|
||||||
|
current directory."
|
||||||
(pk "Assets location: "
|
(pk "Assets location: "
|
||||||
(if (current-filename)
|
(or (getenv "ASSET_DIR") "assets" )))
|
||||||
(string-append (dirname (current-filename)) "/../../assets")
|
|
||||||
(or (getenv "ASSET_DIR") "." )))
|
|
||||||
)
|
|
||||||
|
|
||||||
(define (assets-file-name . names)
|
(define (assets-file-name . names)
|
||||||
"Return the full path of a file in the assets directory. The file is
|
"Return the full path of a file in the assets directory. The file is
|
||||||
|
@ -29,18 +29,31 @@
|
||||||
|
|
||||||
|
|
||||||
(define (read-level-map filename)
|
(define (read-level-map filename)
|
||||||
(call-with-input-file filename get-string-all))
|
"Read a level map from a file. The map is a list of strings, where each
|
||||||
|
string is a row of the map. The map is read from the file in the
|
||||||
|
'levels' directory."
|
||||||
|
(call-with-input-file (assets-file-name "levels" filename) get-string-all))
|
||||||
|
|
||||||
|
(define (level-map? filename )
|
||||||
|
"Return true if the filename is a level map file. Level map files have
|
||||||
|
the extension '.map'."
|
||||||
|
(string-suffix? ".map" filename))
|
||||||
|
|
||||||
(define (assets-map-levels f)
|
(define (assets-map-levels f)
|
||||||
(map f
|
"Apply a function to each level map file in the 'levels' directory. The
|
||||||
(map (lambda (filename)(assets-file-name "levels" filename))
|
function is passed the filename of the level map file."
|
||||||
(scandir (assets-file-name "levels")
|
(map
|
||||||
(lambda (filename) (string-suffix? ".map" filename ))))))
|
(compose f read-level-map)
|
||||||
|
(scandir (assets-file-name "levels") level-map?)))
|
||||||
|
|
||||||
(define (assets-load-image filename)
|
(define (assets-load-image filename)
|
||||||
|
"Load an image from a file in the assets directory. The filename is
|
||||||
|
specified as a list of names, which are joined together. The image is
|
||||||
|
returned as a texture."
|
||||||
(load-image (assets-file-name "images" filename)))
|
(load-image (assets-file-name "images" filename)))
|
||||||
|
|
||||||
(define (assets-load)
|
(define (assets-load)
|
||||||
|
"Load all the assets for the game."
|
||||||
(set! tile-texture (assets-load-image "simples_pimples.png"))
|
(set! tile-texture (assets-load-image "simples_pimples.png"))
|
||||||
(set! tile-atlas (split-texture tile-texture 16 16))
|
(set! tile-atlas (split-texture tile-texture 16 16))
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,6 @@ abs_top_builddir="`cd "@abs_top_builddir@" > /dev/null; pwd`"
|
||||||
|
|
||||||
export GUILE_LOAD_COMPILED_PATH="$abs_top_builddir${GUILE_LOAD_COMPILED_PATH:+:}$GUILE_LOAD_COMPILED_PATH"
|
export GUILE_LOAD_COMPILED_PATH="$abs_top_builddir${GUILE_LOAD_COMPILED_PATH:+:}$GUILE_LOAD_COMPILED_PATH"
|
||||||
export GUILE_LOAD_PATH="$abs_top_builddir:$abs_top_srcdir${GUILE_LOAD_PATH:+:}:$GUILE_LOAD_PATH"
|
export GUILE_LOAD_PATH="$abs_top_builddir:$abs_top_srcdir${GUILE_LOAD_PATH:+:}:$GUILE_LOAD_PATH"
|
||||||
export PATH="$abs_top_builddir/scripts:$PATH"
|
export PATH="$abs_top_builddir:$PATH"
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|
Loading…
Reference in a new issue