From 499a07155e137c40589b8c8383ffa6c942ce15d6 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Tue, 2 May 2017 22:38:25 -0400 Subject: 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. --- doc/api.texi | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) (limited to 'doc') 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{} +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 () + (chickadee #:accessor chickadee #:init-value #f)) + +;; Define the logic for when the buffer is first activated. +(define-method (start (splash )) + (set! (chickadee splash) (load-image "images/chickadee.png"))) + +;; Define how the buffer should be rendered. +(define-method (draw (splash ) 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 )) + +;; Start the game! +(run-game) +@end example + +@deffn {Class} +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 -- cgit v1.2.3