diff options
author | Ricardo Wurmus <rekado@elephly.net> | 2018-07-18 23:11:10 +0200 |
---|---|---|
committer | Ricardo Wurmus <rekado@elephly.net> | 2018-07-27 17:15:45 +0200 |
commit | fe901faed35fbc4d626fa6828bbe0f2e4bbab000 (patch) | |
tree | 3ed889a75f95ee89b37918a7792518f362f97771 | |
parent | b22f0f42a89a4d23df30f293f1ec0a00595111d3 (diff) |
update: Handle message selection when talking.
-rw-r--r-- | scenes/game.scm | 146 |
1 files changed, 100 insertions, 46 deletions
diff --git a/scenes/game.scm b/scenes/game.scm index e8f0e55..c1984e0 100644 --- a/scenes/game.scm +++ b/scenes/game.scm @@ -247,19 +247,74 @@ map's object layer." (tile-map-layer-ref (asset-ref (tile-map game)) layer))))) (define-method (update (game <game>) dt) - (let ((player (child-ref game 'player))) - ;; Stop any motion in a direction when the matching key has just - ;; been released. - (let ((released (filter key-released? (previous-key-presses player)))) - (unless (null? released) - (walk player released 'stop))) - - (if (talking? player) - ;; Stop conversation on ESC. - (when (key-pressed? 'escape) - (stop-talking player)) - - ;; React to current key presses if there is no current dialogue. + ;; Keep the player in the centre + (let* ((player (child-ref game 'player)) + (pos (position player))) + (move-to game + (- 0 (vec2-x pos)) + (- 0 (vec2-y pos))) + (move-to (child-ref game 'top-layer) + (- 0 (vec2-x pos)) + (- 0 (vec2-y pos))))) + +(define-method (update (player <player>) dt) + ;; Check the action key separately. We only want to act on a + ;; state change, not when the key is held. + (when (key-released? 'space) + (set! (action-held player) #f)) + + (or (and=> (talking? player) + ;; Use arrow keys to select a message, hit action key to + ;; confirm the selection. + (lambda (who) + (when (or (and (eq? 'up (selecting-message? player)) + (key-released? 'up)) + (and (eq? 'down (selecting-message? player)) + (key-released? 'down))) + (set! (selecting-message? player) #f)) + + (match (accepted-messages who) + ;; Nothing more to say, so just wait for the action key to + ;; be hit to dismiss the dialogue. + (() + (when (and (not (action-held player)) + (key-pressed? 'space)) + (set! (action-held player) #t) + (stop-talking player))) + ((and ((and (message text) selected) . rest) messages) + (cond + ((and (not (eq? 'up (selecting-message? player))) + (key-pressed? 'up)) + (set! (accepted-messages who) + (append (list (last messages)) + (drop-right messages 1))) + (set! (selecting-message? player) 'up)) + ((and (not (eq? 'down (selecting-message? player))) + (key-pressed? 'down)) + (set! (accepted-messages who) + (append rest (list selected))) + (set! (selecting-message? player) 'down)) + ((and (not (action-held player)) + (key-pressed? 'space)) + (set! (action-held player) #t) + (talk player who message)))) + (_ #t)) + + ;; TODO: render the messages in the new order. + + ;; Always end on #T to avoid passing through to the + ;; motion branch. + #t)) + + ;; React to current key presses with motion. + (begin + ;; Stop any motion in a direction when the matching key has just + ;; been released. + (let ((released (filter key-released? (previous-key-presses player)))) + (unless (null? released) + (walk player released 'stop))) + + ;; Detect newly pressed keys. (let ((active (fold (lambda (direction acc) (if (key-pressed? direction) (cons direction acc) @@ -269,39 +324,38 @@ map's object layer." (if (null? active) (walk player '(idle)) (walk player active)) - (set! (previous-key-presses player) active))) - - (let* ((pos (position player)) - (vel (velocity player))) - (vec2-add! pos vel) - (and=> (collides? player game #:layer "collision") - (lambda (obj) - (match (map-object-type obj) - ;; Reset when the new position is invalid. - ('obstacle - (vec2-sub! pos vel)) - ('action - (when (key-pressed? 'space) - (match (map-object-name obj) - ("enter-house" - (teleport player 560.0 1800.0) - ;; TODO: change music? - (pause-music)) - ("exit-house" - (teleport player 620.0 1100.0) - (resume-music)) - ("talk-to-reaper" - (talk player (child-ref game 'reaper))) - (_ #t)))) - (_ #t)))) - - ;; Keep the player in the centre - (move-to game - (- 0 (vec2-x pos)) - (- 0 (vec2-y pos))) - (move-to (child-ref game 'top-layer) - (- 0 (vec2-x pos)) - (- 0 (vec2-y pos)))))) + (set! (previous-key-presses player) active)) + + ;; Update player position and respond to position-dependent + ;; events. + (let* ((pos (position player)) + (vel (velocity player)) + (game (parent player))) + (vec2-add! pos vel) + (and=> (collides? player game #:layer "collision") + (lambda (obj) + (match (map-object-type obj) + ;; Reset when the new position is invalid. + ('obstacle + (vec2-sub! pos vel)) + ('action + (when (and (not (action-held player)) + (key-pressed? 'space)) + (set! (action-held player) #t) + (match (map-object-name obj) + ("enter-house" + (teleport player 560.0 1800.0) + ;; TODO: change music? + (pause-music)) + ("exit-house" + (teleport player 620.0 1100.0) + (resume-music)) + ("talk-to-reaper" + (let ((reaper (child-ref game 'reaper))) + (unless (equal? (talking? player) reaper) + (talk player reaper 'hello)))) + (_ #t)))) + (_ #t)))))))) (define-method (talk (player <player>) who) (unless (talking? player) |