diff --git a/README.org b/README.org index 4057c47..580f224 100644 --- a/README.org +++ b/README.org @@ -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! -* Game Plan [9/16] +* Game Plan [11/18] - [X] start project organization - [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] upload to itch.io - [ ] automate upload to itch.io - - [ ] create other's AI - - [ ] add keys and portal + - [X] create other's AI + - [X] add keys and portal - [ ] add foods and bloat indicator - [ ] scale hero waist related to bloat level - [ ] create more levels + - [ ] dig potholes + - [ ] make others steal keys - [ ] some level celebration/animation * Installation and Development diff --git a/assets/levels/level-1.map b/assets/levels/level-1.map index 40244f8..e0e5dab 100644 --- a/assets/levels/level-1.map +++ b/assets/levels/level-1.map @@ -2,10 +2,10 @@ -- all content after a '-' is ignored -- ----|----|----|----|----|----|----|----| -WWWWGWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWGWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW W H W W O H O W -W H H W +W H K K K H W W O BBBBBBBBBBBBBBBBBBBBBBBBBBHB O 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 H W - +W H K H W - W P BHBBBBBBB 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 K H W WBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBW WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - \ No newline at end of file diff --git a/game/main.scm b/game/main.scm index 9b692a6..234009d 100644 --- a/game/main.scm +++ b/game/main.scm @@ -3,9 +3,12 @@ #:use-module (game model level) #:use-module (game model hero) #:use-module (game model other) + #:use-module (game model key) #:use-module (game render level) #:use-module (game render hero) #:use-module (game render other) + #:use-module (game render key) + #:use-module (game util assets) #:use-module (chickadee) #:use-module (chickadee math rect) #:use-module (chickadee math vector) @@ -22,28 +25,32 @@ (define repl #f) (define hero #f) (define others #f) +(define keys #f) (define inputs '()) (define (load) + (assets-load) (render-level-load) - (render-hero-load) - (render-other-load) (set! level (level-parse-file "assets/levels/level-1.map")) (render-level-set! level) (set! hero (hero-load level)) (set! others (other-load-others level)) + (set! keys (keys-load level)) (set! repl (spawn-coop-repl-server))) + (define (update dt) (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! keys (keys-update keys hero)) ) (define (draw _alpha) (render-level-draw level) - (render-hero hero) (for-each render-other others) + (render-keys keys (level-find-goal level)) + (render-hero hero) ) (define (set-add set item) @@ -51,7 +58,6 @@ set (cons item set))) - (define (key-press key _modifiers _repeat?) (set! inputs (cond ((eq? key 'left) (set-add inputs 'left)) diff --git a/game/model/hero.scm b/game/model/hero.scm index e68bb14..9f9ec89 100644 --- a/game/model/hero.scm +++ b/game/model/hero.scm @@ -51,10 +51,23 @@ "return the current position of the 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) - (hero-with-runner hero (runner-update (hero-runner hero) level inputs dt))) +(define (blocked-by-door? level keys position) + "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 @@ -69,5 +82,13 @@ (test-equal 1.5 (hero-bloat (hero-with-bloat hero 1.5))) (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") diff --git a/game/model/key.scm b/game/model/key.scm new file mode 100644 index 0000000..03dd285 --- /dev/null +++ b/game/model/key.scm @@ -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 + (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)) diff --git a/game/model/level.scm b/game/model/level.scm index b38a2dc..fe3261a 100644 --- a/game/model/level.scm +++ b/game/model/level.scm @@ -18,12 +18,15 @@ level-tile-at level-cell-size level-find-hero + level-find-goal level-find-others + level-find-keys level-tile-blocked? + level-same-cell? )) (define-record-type - (%make-level width height tiles goal hero entities) + (%make-level width height tiles) level? (width level-width) (height level-height) @@ -40,6 +43,7 @@ ((#\P) 'hero) ((#\O) 'other) ((#\G) 'goal) + ((#\K) 'key) (else 'empty))) (define (content->lines content) @@ -65,12 +69,11 @@ (width (string-length (car lines))) (height (length lines)) (tiles (list->vector - (parse-lines lines))) - (entities '())) - (%make-level width height tiles #f #f entities))) + (parse-lines lines)))) + (%make-level width height tiles))) (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 ) @@ -119,6 +122,14 @@ (define (level-find-others level) (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 (test-begin "level") diff --git a/game/model/other.scm b/game/model/other.scm index 6279652..bc9ec0b 100644 --- a/game/model/other.scm +++ b/game/model/other.scm @@ -24,10 +24,13 @@ ;; They are represented by a runner and try to reach the player to give ;; unwelcome advice unwittingly killing the player with cringe. (define-immutable-record-type - (%make-other runner) + (%make-other runner has-key?) other? (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-bloat 1.0) @@ -35,7 +38,7 @@ (define (other-load-others level) "Create a other at the position in the level map" (map - (compose %make-other runner-load) + (compose make-other runner-load) (level-find-others level))) (define (other-x other) @@ -44,8 +47,7 @@ (define (other-y other) "return the y coordinate as an integer" - (runner-y (other-runner other)) - ) + (runner-y (other-runner other))) (define (other-state other) "return the current state of the other" diff --git a/game/model/runner.scm b/game/model/runner.scm index d59c98d..9d66416 100644 --- a/game/model/runner.scm +++ b/game/model/runner.scm @@ -13,9 +13,7 @@ runner-position runner-with-position runner-x runner-with-x runner-y runner-with-y - runner-update - )) - + runner-update)) (define-immutable-record-type (%make-runner position state) @@ -43,7 +41,6 @@ (define (runner-with-y runner y) (runner-with-position runner (vec2 (runner-x runner) y))) - ;; return next state of runner ;; @returns 'go-left 'go-right 'climb 'fall 'stationary (define (next-state runner level inputs) @@ -68,12 +65,10 @@ ((down) (vec2 0 (- distance))) (else (vec2 0 0)))) - (define (round-position pos) (vec2 (inexact->exact (floor (vec2-x pos))) (inexact->exact (floor (vec2-y pos))))) - (define (safe-move level pos move) (let ((new-pos (vec2+ pos move))) (if (level-tile-blocked? level new-pos) @@ -105,8 +100,6 @@ (runner-with-state state) (runner-with-position position)))) - - ;; Tests (test-begin "runner-model") diff --git a/game/render/hero.scm b/game/render/hero.scm index 5ae28d4..51589a7 100644 --- a/game/render/hero.scm +++ b/game/render/hero.scm @@ -6,16 +6,7 @@ #:use-module (chickadee graphics sprite) #:use-module (chickadee graphics texture) #:export (render-hero - 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))) + render-hero-load)) ;; start index of the walk animation (define hero-walking-offset 56) diff --git a/game/render/key.scm b/game/render/key.scm new file mode 100644 index 0000000..8b3d345 --- /dev/null +++ b/game/render/key.scm @@ -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)) + + diff --git a/game/render/level.scm b/game/render/level.scm index 92508bf..185177d 100644 --- a/game/render/level.scm +++ b/game/render/level.scm @@ -12,17 +12,10 @@ )) -(define tile-texture #f) -(define tile-atlas #f) -(define tile-index 0) -(define tile-map #f) (define sprite-batch #f) ;; load the tile texture and split it into a tile atlas (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)) ) @@ -35,9 +28,10 @@ ((brick) 3750) ((wall) 3709) ((ladder) 3350) - ((goal) 3404) + ((goal) 3800) ;; render empty tile for goal location ((hero) 3800) ;; render empty tile for hero start location ((other) 3800) ;; render empty tile for enemy start location + ((key) 3800) ;; render visual reminder of unknown tile (else 3326))) diff --git a/game/render/other.scm b/game/render/other.scm index 8211fc8..2d30c50 100644 --- a/game/render/other.scm +++ b/game/render/other.scm @@ -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 (define other-walking-offset 3926) (define other-falling-offset 3930) @@ -24,16 +19,16 @@ (let* ((x (other-x other)) (animation-frame (remainder x 3)) (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) - (texture-atlas-ref other-atlas other-walking-offset)) + (texture-atlas-ref tile-atlas other-walking-offset)) (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) - (texture-atlas-ref other-atlas other-climbing-offset)) + (texture-atlas-ref tile-atlas other-climbing-offset)) (define (render-other other) (case (other-state other) diff --git a/game/util/assets.scm b/game/util/assets.scm index 29a2c4e..9271687 100644 --- a/game/util/assets.scm +++ b/game/util/assets.scm @@ -1,11 +1,27 @@ (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 (asset-file-name name) +(define (assets-file-name 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)))