diff options
author | David Thompson <dthompson2@worcester.edu> | 2017-05-02 22:38:25 -0400 |
---|---|---|
committer | David Thompson <dthompson2@worcester.edu> | 2017-05-02 22:38:25 -0400 |
commit | 499a07155e137c40589b8c8383ffa6c942ce15d6 (patch) | |
tree | f66e38c50916f664e61a46a0890bf6db110d970b /doc | |
parent | dd8cf4614b6734cbd83d94a50b076a5e542c3aa4 (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.texi | 177 |
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 |