From 6f04ad781d5588b5f56490275b4d6ae0ad3a8a8b Mon Sep 17 00:00:00 2001 From: Ricardo Wurmus Date: Sat, 21 Jul 2018 23:20:12 +0200 Subject: Merge update method, turn collides? into method. We want the update method to only apply to , not , so that the player can behave differently in other scenes. --- scenes/game.scm | 157 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 78 insertions(+), 79 deletions(-) diff --git a/scenes/game.scm b/scenes/game.scm index 4ae862d..ea3da09 100644 --- a/scenes/game.scm +++ b/scenes/game.scm @@ -124,7 +124,7 @@ map's object layer." #:name 'stats #:object player #:position (vec2 10.0 (- %height 10.0)))))) -(define* (collides? player game #:key (layer "collision")) +(define-method (collides? (player ) (game ) layer) (let* ((pos (position player)) (offset (origin game)) (player-hitbox (hitbox player)) @@ -164,89 +164,88 @@ map's object layer." (- 0 (vec2-y pos))) (move-to (child-ref game 'top-layer) (- 0 (vec2-x pos)) - (- 0 (vec2-y pos))))) - -(define-method (update (player ) dt) - (or (and=> (talking? player) - ;; Use arrow keys to select a message, hit action key to - ;; confirm the selection. - (lambda (who) - ;; Render the player messages in the selected order. - (unless (speaking? who) - (let ((bubble (child-ref (parent (parent player)) 'text-bubble)) - (messages (accepted-messages who))) - (clear-messages bubble) - (fold (lambda (message n lines) - (match message - ((message text . flags) - (when (zero? n) - (attach bubble - (make - #:name 'dialog-selection-indicator - #:region (make-rect 0.0 0.0 10 10) - #:position (vec2 0 40) - #:color region))) - (+ lines - (render-text bubble text - #:suffix message - #:y-offset - (+ (* n %message-margin) - (* lines %line-height))))))) - 0 - messages - (iota (length messages))))) - ;; Always end on #T to avoid passing through to the - ;; motion branch. - #t)) - - ;; React to current key presses with motion. We don't use the - ;; on-key-press handler here, because it does not seem to behave - ;; right when two keys are pressed at the same time (e.g. left - ;; and up). - (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) - acc)) - '() - '(left right up down)))) - (if (null? active) - (walk player '(idle)) - (walk player active)) - (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) - ;; Reset when the new position is invalid. - (when (collides? player game #:layer "collision") - (vec2-sub! pos vel)))))) - -(define-method (on-key-press (player ) key modifiers repeat?) - (when (eq? key 'q) - (switch-scene (root-node) (death))) - (let ((who (talking? player))) - (cond - ((and (not who) (eq? 'space key)) - (handle-action player)) - ((and who (not repeat?)) - (handle-talking player key))))) + (- 0 (vec2-y pos))) + + (or (and=> (talking? player) + ;; Use arrow keys to select a message, hit action key to + ;; confirm the selection. + (lambda (who) + ;; Render the player messages in the selected order. + (unless (speaking? who) + (let ((bubble (child-ref (parent (parent player)) 'text-bubble)) + (messages (accepted-messages who))) + (clear-messages bubble) + (fold (lambda (message n lines) + (match message + ((message text . flags) + (when (zero? n) + (attach bubble + (make + #:name 'dialog-selection-indicator + #:region (make-rect 0.0 0.0 10 10) + #:position (vec2 0 40) + #:color region))) + (+ lines + (render-text bubble text + #:suffix message + #:y-offset + (+ (* n %message-margin) + (* lines %line-height))))))) + 0 + messages + (iota (length messages))))) + ;; Always end on #T to avoid passing through to the + ;; motion branch. + #t)) + + ;; React to current key presses with motion. We don't use the + ;; on-key-press handler here, because it does not seem to behave + ;; right when two keys are pressed at the same time (e.g. left + ;; and up). + (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) + acc)) + '() + '(left right up down)))) + (if (null? active) + (walk player '(idle)) + (walk player active)) + (set! (previous-key-presses player) active)) + + ;; Update player position and respond to position-dependent + ;; events. + (let* ((pos (position player)) + (vel (velocity player))) + (vec2-add! pos vel) + ;; Reset when the new position is invalid. + (when (collides? player game "collision") + (vec2-sub! pos vel))))))) + +(define-method (on-key-press (game ) key modifiers repeat?) + (let ((player (child-ref game 'player))) + (when (eq? key 'q) + (switch-scene (root-node) (death))) + (let ((who (talking? player))) + (cond + ((and (not who) (eq? 'space key)) + (handle-action player)) + ((and who (not repeat?)) + (handle-talking player key)))))) (define (handle-action player) "Check if the PLAYER is on any region of the map where an action can be executed; if so, perform the action." (let ((game (parent player))) - (and=> (collides? player game #:layer "actions") + (and=> (collides? player game "actions") (lambda (obj) (match (map-object-name obj) ("enter-house" -- cgit v1.2.3