summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRicardo Wurmus <rekado@elephly.net>2018-07-21 23:20:12 +0200
committerRicardo Wurmus <rekado@elephly.net>2018-07-27 17:15:47 +0200
commit6f04ad781d5588b5f56490275b4d6ae0ad3a8a8b (patch)
tree7c4e7e3d78027ebd165f9d3922ba17f18d485f68
parent2be5bb221bae718f0625569517178a66892ac14a (diff)
Merge update method, turn collides? into method.
We want the update method to only apply to <game>, not <player>, so that the player can behave differently in other scenes.
-rw-r--r--scenes/game.scm157
1 files 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 <player>) (game <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 <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 <filled-rect>
- #: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 <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 <filled-rect>
+ #: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 <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"