diff options
-rw-r--r-- | 2d/actions.scm | 147 | ||||
-rw-r--r-- | 2d/observer.scm | 82 | ||||
-rw-r--r-- | 2d/scene.scm | 93 | ||||
-rw-r--r-- | 2d/stage.scm | 132 |
4 files changed, 0 insertions, 454 deletions
diff --git a/2d/actions.scm b/2d/actions.scm deleted file mode 100644 index 58d2ba9..0000000 --- a/2d/actions.scm +++ /dev/null @@ -1,147 +0,0 @@ -;;; guile-2d -;;; Copyright (C) 2013 David Thompson <dthompson2@worcester.edu> -;;; -;;; Guile-2d is free software: you can redistribute it and/or modify it -;;; under the terms of the GNU Lesser General Public License as -;;; published by the Free Software Foundation, either version 3 of the -;;; License, or (at your option) any later version. -;;; -;;; Guile-2d is distributed in the hope that it will be useful, but -;;; WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;;; Lesser General Public License for more details. -;;; -;;; You should have received a copy of the GNU Lesser General Public -;;; License along with this program. If not, see -;;; <http://www.gnu.org/licenses/>. - -;;; Commentary: -;; -;; Actions are composable procedures that perform an operation over a -;; period of game time. -;; -;;; Code: - -(define-module (2d actions) - #:use-module (srfi srfi-9) - #:use-module (srfi srfi-1) - #:use-module (2d agenda) - #:use-module (2d coroutine) - #:export (<action> - make-action - action? - null-action - null-action? - action-duration - action-proc - perform-action - schedule-action - action-cons - action-list - action-parallel - action-repeat - idle - lerp)) - -;;; -;;; Action Procedures -;;; - -;; Actions encapsulate a procedure that performs an action and the -;; duration of the action in game ticks. -(define-record-type <action> - (%make-action proc duration) - action? - (duration action-duration) - (proc action-proc)) - -(define (make-action proc duration) - "Create a new action object that takes DURATION updates to -complete. PROC is a procedure that takes a value in the range [0, 1] -as its only argument. An error is thrown if DURATION is 0." - (if (zero? duration) - (throw 'action-duration-zero) - (%make-action proc duration))) - -(define (step-action action t) - "Apply ACTION procedure to the time delta, T." - ((action-proc action) t)) - -(define (perform-action action) - "Execute ACTION. `perform-action` must be called from within a -coroutine, as it yields back to the agenda after each step." - (let ((duration (action-duration action))) - (define (step time) - (if (= duration time) - (step-action action 1) - (begin - (step-action action (/ time duration)) - (wait) - (step (1+ time))))) - (step 1))) - -(define (schedule-action action) - "Schedules a coroutine in the current agenda that will perform -ACTION on the next update." - (agenda-schedule (colambda () (perform-action action)))) - -(define (action-cons a1 a2) - "Return an action that performs A1 first, followed by A2." - (define (real-cons) - (let* ((duration (+ (action-duration a1) (action-duration a2))) - (t1 (/ (action-duration a1) duration)) - (t2 (/ (action-duration a2) duration))) - (make-action - (lambda (t) - (if (> t t1) - (step-action a2 (/ (- t t1) t2)) - (step-action a1 (/ t t1)))) - duration))) - ;; a2 can be #f, if this is the last action-cons of an action-list. - (if a2 (real-cons) a1)) - -(define (action-list . actions) - "Return an action that performs every action in the list ACTIONS." - (if (null? actions) - #f - (action-cons (car actions) (apply action-list (cdr actions))))) - -(define (action-parallel . actions) - "Perform every action in the list ACTIONS in parallel." - (let ((max-duration (reduce max 0 (map action-duration actions)))) - ;; Add idle action to each action to fill the time - ;; difference between the action's duration and the - ;; max action duration. - (define (fill-action action) - (if (= (action-duration action) max-duration) - action - (action-cons action (idle (- max-duration (action-duration action)))))) - - (let ((filled-actions (map fill-action actions))) - (make-action - (lambda (t) - (for-each (lambda (a) (step-action a t)) filled-actions)) - max-duration)))) - -(define (action-repeat n action) - "Return an action that will perform ACTION N times." - (apply action-list (make-list n action))) - -;;; -;;; Simple Actions -;;; - -(define (idle duration) - "Return an action that does nothing." - (make-action (lambda (t) #t) duration)) - -(define (lerp proc start end duration) - "Linearly interpolate a number from START to END that takes DURATION -updates. Apply PROC to the linearly interpolated at each step." - (let ((delta (- end start))) - (make-action - (lambda (t) - (if (= t 1) - (proc end) - (proc (+ start (* delta t))))) - duration))) diff --git a/2d/observer.scm b/2d/observer.scm deleted file mode 100644 index 29dc15c..0000000 --- a/2d/observer.scm +++ /dev/null @@ -1,82 +0,0 @@ -;;; guile-2d -;;; Copyright (C) 2013 David Thompson <dthompson2@worcester.edu> -;;; -;;; Guile-2d is free software: you can redistribute it and/or modify it -;;; under the terms of the GNU Lesser General Public License as -;;; published by the Free Software Foundation, either version 3 of the -;;; License, or (at your option) any later version. -;;; -;;; Guile-2d is distributed in the hope that it will be useful, but -;;; WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;;; Lesser General Public License for more details. -;;; -;;; You should have received a copy of the GNU Lesser General Public -;;; License along with this program. If not, see -;;; <http://www.gnu.org/licenses/>. - -;;; Commentary: -;; -;; Event listener. -;; -;;; Code: - -(define-module (2d observer) - #:use-module (srfi srfi-1) - #:use-module (srfi srfi-9) - #:use-module (srfi srfi-26) - #:export (<observer> - make-observer - alist->observer - observer? - observer-events - observer-callbacks - observer-on - observer-off - observer-clear - observer-trigger)) - -(define-record-type <observer> - (%make-observer events) - observer? - (events observer-events)) - -(define (make-observer) - "Create a new observer." - (%make-observer (make-hash-table))) - -(define (alist->observer alst) - "Return a new observer that registers the callbacks for events in -the alist ALST. Each pair in ALST should map one event type to one -callback procedure. For multiple event handlers of the same type, use -multiple pairs." - (let ((observer (make-observer))) - (for-each (lambda (e) (observer-on observer (car e) (cdr e))) alst) - observer)) - -(define (observer-callbacks observer event-type) - "Return a list of callback procedures for the given EVENT-TYPE. The -null list is returned if there are no callbacks for EVENT-TYPE." - (or (hash-ref (observer-events observer) event-type) - '())) - -(define (observer-on observer event-type proc) - "Register PROC as a callback for the given EVENT-TYPE." - (hash-set! (observer-events observer) - event-type - (cons proc (observer-callbacks observer event-type)))) - -(define (observer-off observer event-type proc) - "Unregister PROC as a callabck for the given EVENT-TYPE." - (hash-set! (observer-events observer) - event-type - (delete proc (observer-callbacks observer event-type)))) - -(define (observer-clear observer event-type) - "Unregister all callbacks for EVENT-TYPE." - (hash-remove! (observer-events observer) event-type)) - -(define (observer-trigger observer event-type . args) - "Call all callbacks for EVENT-TYPE with the given ARGS." - (for-each (cut apply <> args) - (observer-callbacks observer event-type))) diff --git a/2d/scene.scm b/2d/scene.scm deleted file mode 100644 index cb053b7..0000000 --- a/2d/scene.scm +++ /dev/null @@ -1,93 +0,0 @@ -;;; guile-2d -;;; Copyright (C) 2013 David Thompson <dthompson2@worcester.edu> -;;; -;;; Guile-2d is free software: you can redistribute it and/or modify it -;;; under the terms of the GNU Lesser General Public License as -;;; published by the Free Software Foundation, either version 3 of the -;;; License, or (at your option) any later version. -;;; -;;; Guile-2d is distributed in the hope that it will be useful, but -;;; WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;;; Lesser General Public License for more details. -;;; -;;; You should have received a copy of the GNU Lesser General Public -;;; License along with this program. If not, see -;;; <http://www.gnu.org/licenses/>. - -;;; Commentary: -;; -;; Scenes describe the behavioral aspects of a game. -;; -;;; Code: - -(define-module (2d scene) - #:use-module (srfi srfi-9) - #:use-module (2d observer) - #:export (<scene> - make-scene - scene? - scene-name - scene-init - scene-enter - scene-exit - scene-draw - scene-update - scene-observer - init-scene - enter-scene - exit-scene - draw-scene - update-scene - scene-trigger - default-events)) - -(define-record-type <scene> - (%make-scene name init enter exit draw update observer) - scene? - (name scene-name) - (init scene-init) - (enter scene-enter) - (exit scene-exit) - (draw scene-draw) - (update scene-update) - (observer scene-observer)) - -(define no-op (lambda args #f)) -(define default-events (make-parameter '())) - -(define* (make-scene name - #:optional #:key - (init no-op) - (enter no-op) - (exit no-op) - (draw no-op) - (update no-op) - (events (default-events))) - "Create a new scene object. All callbacks default to a no-op." - (%make-scene name init enter exit draw update - (alist->observer events))) - -(define (init-scene scene) - "Return the value returned by the state constructor thunk for -SCENE." - ((scene-init scene))) - -(define (enter-scene scene state) - "Call enter callback for SCENE with STATE." - ((scene-enter scene) state)) - -(define (exit-scene scene state) - "Call the exit callback for SCENE with STATE." - ((scene-exit scene) state)) - -(define (draw-scene scene state) - "Call the draw callback for SCENE with STATE." - ((scene-draw scene) state)) - -(define (update-scene scene state) - "Call the update callback for SCENE with STATE." - ((scene-update scene) state)) - -(define (scene-trigger scene state event . args) - (apply observer-trigger (scene-observer scene) event state args)) diff --git a/2d/stage.scm b/2d/stage.scm deleted file mode 100644 index 5f5d8ca..0000000 --- a/2d/stage.scm +++ /dev/null @@ -1,132 +0,0 @@ -;;; guile-2d -;;; Copyright (C) 2013 David Thompson <dthompson2@worcester.edu> -;;; -;;; Guile-2d is free software: you can redistribute it and/or modify it -;;; under the terms of the GNU Lesser General Public License as -;;; published by the Free Software Foundation, either version 3 of the -;;; License, or (at your option) any later version. -;;; -;;; Guile-2d is distributed in the hope that it will be useful, but -;;; WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;;; Lesser General Public License for more details. -;;; -;;; You should have received a copy of the GNU Lesser General Public -;;; License along with this program. If not, see -;;; <http://www.gnu.org/licenses/>. - -;;; Commentary: -;; -;; Stages represent the game state at the present time. -;; -;;; Code: - -(define-module (2d stage) - #:use-module (srfi srfi-9) - #:use-module (2d agenda) - #:use-module (2d scene) - #:export (make-stage - stage? - stage-agenda - stage-state - stage-scene - set-stage-scene! - enter-stage - exit-stage - draw-stage - update-stage - stage-trigger - make-stage-variable - define-stage-variable - stage-on - stage-off - current-stage - push-scene - pop-scene - replace-scene)) - -(define-record-type <stage> - (%make-stage agenda scene state) - stage? - (agenda stage-agenda) - (scene stage-scene set-stage-scene!) - (state stage-state)) - -(define (make-stage scene) - "Create a new stage object for SCENE." - (%make-stage (make-agenda) scene (init-scene scene))) - -;;; -;;; Scene callbacks -;;; - -(define (enter-stage stage) - "Call the scene enter callback for STAGE." - (with-agenda (stage-agenda stage) - (enter-scene (stage-scene stage) - (stage-state stage)))) - -(define (exit-stage stage) - "Call the scene exit callback for STAGE." - (with-agenda (stage-agenda stage) - (exit-scene (stage-scene stage) - (stage-state stage)))) - -(define (update-stage stage) - "Call the scene update callback for STAGE." - (with-agenda (stage-agenda stage) - (update-agenda) - (update-scene (stage-scene stage) - (stage-state stage)))) - -(define (draw-stage stage) - "Call the scene draw callback for STAGE." - (with-agenda (stage-agenda stage) - (draw-scene (stage-scene stage) - (stage-state stage)))) - -(define (stage-trigger stage event . args) - (with-agenda (stage-agenda stage) - (apply scene-trigger - (stage-scene stage) - (stage-state stage) - event - args))) - -;;; -;;; Stage management -;;; - -(define stack '()) - -(define (current-stage) - "Return the top of the stage stack or #f if the stack is empty." - (if (null? stack) #f (car stack))) - -(define (push-scene scene) - "Make STAGE active and push it to the top of the stack." - (let ((prev-stage (current-stage)) - (stage (make-stage scene))) - (when prev-stage - (exit-stage prev-stage)) - (set! stack (cons stage stack)) - (enter-stage stage))) - -(define (pop-scene) - "Replace the current stage with the next one on the stack, if -present." - (let ((prev-stage (current-stage))) - (when prev-stage - (exit-stage prev-stage)) - (set! stack (cdr stack)) - (when (current-stage) - (enter-stage (current-stage))))) - -(define (replace-scene scene) - "Replace the current stage with STAGE." - (let ((prev-stage (current-stage)) - (stage (make-stage scene))) - (when prev-stage - (exit-stage prev-stage)) - (set! stack (cons stage (cdr stack))) - (enter-stage stage))) |