summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2017-05-02 22:38:25 -0400
committerDavid Thompson <dthompson2@worcester.edu>2017-05-02 22:38:25 -0400
commit499a07155e137c40589b8c8383ffa6c942ce15d6 (patch)
treef66e38c50916f664e61a46a0890bf6db110d970b /doc
parentdd8cf4614b6734cbd83d94a50b076a5e542c3aa4 (diff)
Add buffer module.
* chickadee/buffer.scm: New file. * Makefile.am (SOURCES): Add it. * .dir-locals.el: Add indent rules for with-buffer and with-current-buffer. * examples/buffer.scm: New file. * doc/api.texi (Buffers): Add docs.
Diffstat (limited to 'doc')
-rw-r--r--doc/api.texi177
1 files changed, 177 insertions, 0 deletions
diff --git a/doc/api.texi b/doc/api.texi
index c3543b8..f3878f5 100644
--- a/doc/api.texi
+++ b/doc/api.texi
@@ -4,6 +4,7 @@
* Math:: Linear algebra and more.
* Graphics:: Eye candy.
* Audio:: Sound effects and music.
+* Buffers:: Splitting games into logical components.
* Scripting:: Bringing the game world to life.
@end menu
@@ -904,6 +905,182 @@ Return @code{#t} if music is currently playing.
Return @code{#t} if music is currently paused.
@end deffn
+@node Buffers
+@section Buffers
+
+Games are big state machines and they can get complex quickly, thus we
+need tools to manage that complexity. One useful technique is to
+separate the many ``screens'' of a game (such as the main menu, player
+select screen, high score table, game over screen, etc.) from each
+other, so that it is possible to program the logic for one section of
+the game independent of another. In Chickadee, these ``screens'' are
+called ``buffers''. In other game engines this same construct may be
+called a ``scene'' or ``room''.
+
+A buffer knows how to update its state, render, handle input events,
+etc. Only one buffer is ever active at a time, and the current buffer
+can be changed with procedures like @code{push-buffer},
+@code{replace-buffer}, and @code{pop-buffer}.
+
+Buffers are implemented using Guile's object oriented programming
+system (@pxref{GOOPS,,, guile, GNU Guile Reference Manual}). Each
+type of buffer is represented as a subclass of the @code{<buffer>}
+class. Once a new buffer class has been created, there are many
+methods that can be specialized for that class.
+
+To install buffer support and set the initial buffer, call the
+@code{use-buffers!} procedure.
+
+Let's take a look at a simple example to see how it all comes
+together:
+
+@example
+(use-modules (chickadee)
+ (chickadee buffer)
+ (chickadee math vector)
+ (chickadee render sprite)
+ (chickadee render texture)
+ (oop goops))
+
+;; Define a new buffer type.
+(define-class <splash-screen> (<buffer>)
+ (chickadee #:accessor chickadee #:init-value #f))
+
+;; Define the logic for when the buffer is first activated.
+(define-method (start (splash <splash-screen>))
+ (set! (chickadee splash) (load-image "images/chickadee.png")))
+
+;; Define how the buffer should be rendered.
+(define-method (draw (splash <splash-screen>) alpha)
+ (draw-sprite (chickadee splash) (vec2 256.0 176.0)))
+
+;; Hook into the game engine and make the splash screen the initial buffer.
+(use-buffers! (make <splash-screen>))
+
+;; Start the game!
+(run-game)
+@end example
+
+@deffn {Class} <buffer>
+The parent class for all buffers.
+@end deffn
+
+@deffn {Method} started? @var{buffer}
+Return @code{#t} if @var{buffer} has been activated by the game engine.
+@end deffn
+
+@deffn {Method} start @var{buffer}
+Called when @var{buffer} becomes the current buffer for the first time.
+@end deffn
+
+@deffn {Method} stop @var{buffer}
+Called when @var{buffer} is no longer in use.
+@end deffn
+
+@deffn {Method} pause @var{buffer}
+Called when @var{buffer} is no longer the current buffer but still in
+use.
+@end deffn
+
+@deffn {Method} resume @var{buffer}
+Called when @var{buffer} becomes the current buffer after having been
+suspended.
+@end deffn
+
+The following methods are simply wrappers around the hooks described
+in @xref{Kernel}, so see that section for more detail about the
+arguments to these methods. The engine calls these methods with the
+current buffer as the first argument.
+
+@deffn {Method} update @var{buffer} @var{dt}
+Advance the simulation running in @var{buffer} by @var{dt} units of
+time.
+@end deffn
+
+@deffn {Method} abort @var{buffer}
+Called when the user tries to close the game window.
+@end deffn
+
+@deffn {Method} before-draw @var{buffer}
+Called before @var{buffer} is rendered.
+@end deffn
+
+@deffn {Method} after-draw @var{buffer}
+Called after @var{buffer} is rendered.
+@end deffn
+
+@deffn {Method} draw @var{buffer} @var{alpha}
+Render @var{buffer}.
+@end deffn
+
+@deffn {Method} key-press @var{buffer} @var{key} @var{scancode} @var{modifiers} @var{repeat?}
+Handle key press event.
+@end deffn
+
+@deffn {Method} key-release @var{buffer} @var{key} @var{scancode} @var{modifiers}
+Handle key release event.
+@end deffn
+
+@deffn {Method} text-input @var{buffer} @var{text}
+Handle text input event.
+@end deffn
+
+@deffn {Method} mouse-press @var{buffer} @var{button} @var{clicks} @var{x} @var{y}
+Handle mouse press event.
+@end deffn
+
+@deffn {Method} mouse-release @var{buffer} @var{button} @var{x} @var{y}
+Handle mouse release event.
+@end deffn
+
+@deffn {Method} mouse-move @var{buffer} @var{x} @var{y} @var{x-rel} @var{y-rel} @var{buttons}
+Handle mouse move event.
+@end deffn
+
+@deffn {Method} controller-add @var{buffer} @var{controller}
+Handle controller add event.
+@end deffn
+
+@deffn {Method} controller-remove @var{buffer} @var{controller}
+Handle controller remove event.
+@end deffn
+
+@deffn {Method} controller-press @var{buffer} @var{controller} @var{button}
+Handle controller press event.
+@end deffn
+
+@deffn {Method} controller-release @var{buffer} @var{controller} @var{button}
+Handle controller release event.
+@end deffn
+
+@deffn {Method} controller-move @var{buffer} @var{controller} @var{axis} @var{value}
+Handle controller move event.
+@end deffn
+
+The following procedures are used to manage the buffer stack:
+
+@deffn {Procedure} use-buffers! @var{initial-buffer}
+Install buffers into the game engine and set the current buffer to
+@var{initial-buffer}.
+@end deffn
+
+@deffn {Procedure} push-buffer! @var{buffer}
+Pause the current buffer and switch to @var{buffer}.
+@end deffn
+
+@deffn {Procedure} pop-buffer!
+Stop the current buffer and switch back to the previously active
+buffer, or terminate the game loop if the buffer stack is empty.
+@end deffn
+
+@deffn {Procedure} replace-buffer! @var{buffer}
+Stop the current buffer and switch to @var{buffer}
+@end deffn
+
+@deffn {Procedure} current-buffer
+Return the current buffer.
+@end deffn
+
@node Scripting
@section Scripting