% Generated by Sphinx.
\def\sphinxdocclass{report}
\documentclass[letterpaper,10pt,english]{sphinxmanual}
\usepackage[utf8]{inputenc}
\DeclareUnicodeCharacter{00A0}{\nobreakspace}
\usepackage{cmap}
\usepackage[T1]{fontenc}

\usepackage{babel}
\usepackage{times}
\usepackage[Bjarne]{fncychap}
\usepackage{longtable}
\usepackage{sphinx}
\usepackage{multirow}
\usepackage{eqparbox}


\addto\captionsenglish{\renewcommand{\figurename}{Fig. }}
\addto\captionsenglish{\renewcommand{\tablename}{Table }}
\SetupFloatingEnvironment{literal-block}{name=Listing }



\title{SGE Game Engine Documentation}
\date{November 04, 2016}
\release{1.4}
\author{onpon4}
\newcommand{\sphinxlogo}{}
\renewcommand{\releasename}{Release}
\setcounter{tocdepth}{0}
\makeindex

\makeatletter
\def\PYG@reset{\let\PYG@it=\relax \let\PYG@bf=\relax%
    \let\PYG@ul=\relax \let\PYG@tc=\relax%
    \let\PYG@bc=\relax \let\PYG@ff=\relax}
\def\PYG@tok#1{\csname PYG@tok@#1\endcsname}
\def\PYG@toks#1+{\ifx\relax#1\empty\else%
    \PYG@tok{#1}\expandafter\PYG@toks\fi}
\def\PYG@do#1{\PYG@bc{\PYG@tc{\PYG@ul{%
    \PYG@it{\PYG@bf{\PYG@ff{#1}}}}}}}
\def\PYG#1#2{\PYG@reset\PYG@toks#1+\relax+\PYG@do{#2}}

\expandafter\def\csname PYG@tok@si\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.44,0.63,0.82}{##1}}}
\expandafter\def\csname PYG@tok@nl\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.13,0.44}{##1}}}
\expandafter\def\csname PYG@tok@kr\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@kd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@s1\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@ow\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@s\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@cm\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}}
\expandafter\def\csname PYG@tok@c\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}}
\expandafter\def\csname PYG@tok@na\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@sx\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}}
\expandafter\def\csname PYG@tok@sc\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@cp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@sd\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@gu\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}}
\expandafter\def\csname PYG@tok@il\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@gt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}}
\expandafter\def\csname PYG@tok@vc\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@m\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@kt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.56,0.13,0.00}{##1}}}
\expandafter\def\csname PYG@tok@cpf\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}}
\expandafter\def\csname PYG@tok@sb\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@sh\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@c1\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}}
\expandafter\def\csname PYG@tok@go\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.20}{##1}}}
\expandafter\def\csname PYG@tok@kn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@mh\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@nc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}}
\expandafter\def\csname PYG@tok@ch\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}}
\expandafter\def\csname PYG@tok@mf\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@nd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.33,0.33,0.33}{##1}}}
\expandafter\def\csname PYG@tok@nn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}}
\expandafter\def\csname PYG@tok@mb\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@s2\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@ne\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@err\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{\strut ##1}}}
\expandafter\def\csname PYG@tok@gd\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}}
\expandafter\def\csname PYG@tok@sr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.14,0.33,0.53}{##1}}}
\expandafter\def\csname PYG@tok@nv\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@gs\endcsname{\let\PYG@bf=\textbf}
\expandafter\def\csname PYG@tok@vi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@cs\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}
\expandafter\def\csname PYG@tok@vg\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}}
\expandafter\def\csname PYG@tok@gh\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
\expandafter\def\csname PYG@tok@ss\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.32,0.47,0.09}{##1}}}
\expandafter\def\csname PYG@tok@nf\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.02,0.16,0.49}{##1}}}
\expandafter\def\csname PYG@tok@w\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}}
\expandafter\def\csname PYG@tok@mi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}
\expandafter\def\csname PYG@tok@gp\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}}
\expandafter\def\csname PYG@tok@se\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}}
\expandafter\def\csname PYG@tok@ni\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.84,0.33,0.22}{##1}}}
\expandafter\def\csname PYG@tok@o\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PYG@tok@no\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.38,0.68,0.84}{##1}}}
\expandafter\def\csname PYG@tok@k\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@gi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}}
\expandafter\def\csname PYG@tok@bp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@gr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}}
\expandafter\def\csname PYG@tok@nt\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.02,0.16,0.45}{##1}}}
\expandafter\def\csname PYG@tok@kp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@nb\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@ge\endcsname{\let\PYG@it=\textit}
\expandafter\def\csname PYG@tok@kc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}}
\expandafter\def\csname PYG@tok@mo\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}}

\def\PYGZbs{\char`\\}
\def\PYGZus{\char`\_}
\def\PYGZob{\char`\{}
\def\PYGZcb{\char`\}}
\def\PYGZca{\char`\^}
\def\PYGZam{\char`\&}
\def\PYGZlt{\char`\<}
\def\PYGZgt{\char`\>}
\def\PYGZsh{\char`\#}
\def\PYGZpc{\char`\%}
\def\PYGZdl{\char`\$}
\def\PYGZhy{\char`\-}
\def\PYGZsq{\char`\'}
\def\PYGZdq{\char`\"}
\def\PYGZti{\char`\~}
% for compatibility with earlier versions
\def\PYGZat{@}
\def\PYGZlb{[}
\def\PYGZrb{]}
\makeatother

\renewcommand\PYGZsq{\textquotesingle}

\begin{document}

\maketitle
\tableofcontents
\phantomsection\label{index::doc}



\chapter{SGE Fundamentals}
\label{sge::doc}\label{sge:sge-game-engine-documentation}\label{sge:sge-fundamentals}\setbox0\vbox{
\begin{minipage}{0.95\linewidth}
\textbf{Contents}

\medskip

\begin{itemize}
\item {} 
\phantomsection\label{sge:id1}{\hyperref[sge:sge\string-fundamentals]{\emph{SGE Fundamentals}}}
\begin{itemize}
\item {} 
\phantomsection\label{sge:id2}{\hyperref[sge:sge\string-concepts]{\emph{SGE Concepts}}}
\begin{itemize}
\item {} 
\phantomsection\label{sge:id3}{\hyperref[sge:events]{\emph{Events}}}

\item {} 
\phantomsection\label{sge:id4}{\hyperref[sge:position]{\emph{Position}}}

\item {} 
\phantomsection\label{sge:id5}{\hyperref[sge:z\string-axis]{\emph{Z-Axis}}}

\item {} 
\phantomsection\label{sge:id6}{\hyperref[sge:the\string-game\string-loop]{\emph{The Game Loop}}}

\end{itemize}

\item {} 
\phantomsection\label{sge:id7}{\hyperref[sge:global\string-variables\string-and\string-constants]{\emph{Global Variables and Constants}}}

\end{itemize}

\end{itemize}
\end{minipage}}
\begin{center}\setlength{\fboxsep}{5pt}\shadowbox{\box0}\end{center}
\phantomsection\label{sge:module-sge}\index{sge (module)}
The SGE Game Engine (``SGE'', pronounced like ``Sage'') is a general-purpose
2-D game engine.  It takes care of several details for you so you can
focus on the game itself.  This makes more rapid game development
possible, and it also makes the SGE easy to learn.

The SGE is \href{http://gnu.org/philosophy/free-sw.html}{libre software},
and the SGE documentation (including all docstrings) is released to the
public domain via CC0.

Although it isn't required, you are encouraged to release your games'
code under a libre software license, such as the GNU General Public
License, the Expat License, or the Apache License.  Doing so is easy,
does not negatively affect you, and is highly appreciated as a
contribution to a free society.


\section{SGE Concepts}
\label{sge:sge-concepts}

\subsection{Events}
\label{sge:events}
The SGE uses an event-based system.  When an event occurs, a certain
event method (with a name that begins with \code{event\_}) is called. To
define actions triggered by events, simply override the appropriate
event method.

At a lower level, it is possible to read ``input events'' from
\code{sge.game.input\_events} and handle them manually.  See the
documentation for {\hyperref[input:module\string-sge.input]{\emph{\code{sge.input}}}} for more information.  This is not
recommended, however, unless you are running your own loop for some
reason (in which case it is necessary to do this in order to get input
from the user).


\subsection{Position}
\label{sge:position}
In all cases of positioning for the SGE, it is based on a
two-dimensional graph with each unit being a pixel.  This graph is not
quite like regular graphs.  The horizontal direction, normally called
\code{x}, is the same as the x-axis on a regular graph; \code{0} is the
origin, positive numbers are to the right of the origin, and negative
numbers are to the left of the origin.  However, in the vertical
direction, normally called \code{y}, \code{0} is the origin, positive numbers
are below the origin, and negative numbers are above the origin.  While
slightly jarring if you are used to normal graphs, this is in fact
common in 2-D game development and is also how pixels in most image
formats are indexed.

Except where otherwise specified, the origin is always located at the
top-leftmost position of an object.

In addition to integers, position variables are allowed by the SGE to be
floating-point numbers.


\subsection{Z-Axis}
\label{sge:z-axis}
The SGE uses a Z-axis to determine where objects are placed in the third
dimension.  Objects with a higher Z value are considered to be closer to
the viewer and thus will be placed over objects which have a lower Z
value.  Note that the Z-axis does not allow 3-D gameplay or effects; it
is only used to tell the SGE what to do with objects that overlap.  For
example, if an object called \code{spam} has a Z value of \code{5} while an
object called \code{eggs} has a Z value of \code{2}, \code{spam} will obscure
part or all of \code{eggs} when the two objects overlap.

If two objects with the same Z-axis value overlap, the object which was
most recently added to the room is placed in front.


\subsection{The Game Loop}
\label{sge:the-game-loop}
There can occasionally be times where you want to run your own loop,
independent of the SGE's main loop.  This is not recommended in general,
but if you must (to freeze the game, for example), you should know the
general game loop structure:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{while} \PYG{n+nb+bp}{True}\PYG{p}{:}
    \PYG{c+c1}{\PYGZsh{} Input events}
    \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{pump\PYGZus{}input}\PYG{p}{(}\PYG{p}{)}
    \PYG{k}{while} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{input\PYGZus{}events}\PYG{p}{:}
        \PYG{n}{event} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{input\PYGZus{}events}\PYG{o}{.}\PYG{n}{pop}\PYG{p}{(}\PYG{l+m+mi}{0}\PYG{p}{)}

        \PYG{c+c1}{\PYGZsh{} Handle event}

    \PYG{c+c1}{\PYGZsh{} Regulate speed}
    \PYG{n}{time\PYGZus{}passed} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{regulate\PYGZus{}speed}\PYG{p}{(}\PYG{p}{)}

    \PYG{c+c1}{\PYGZsh{} Logic (e.g. collision detection and step events)}

    \PYG{c+c1}{\PYGZsh{} Refresh}
    \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{refresh}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}

{\hyperref[dsp:sge.dsp.Game.pump_input]{\emph{\code{sge.dsp.Game.pump\_input()}}}} should be called every frame regardless
of whether or not user input is needed.  Failing to call it will cause
the queue to build up, but more importantly, the OS may decide that the
program has locked up if it doesn't get a response for a long time.

{\hyperref[dsp:sge.dsp.Game.regulate_speed]{\emph{\code{sge.dsp.Game.regulate\_speed()}}}} limits the frame rate of the game
and tells you how much time has passed since the last frame.  It is not
technically necessary, but using it is highly recommended; otherwise,
the CPU will be working harder than it needs to and if things are
moving, their speed will be irregular.

{\hyperref[dsp:sge.dsp.Game.refresh]{\emph{\code{sge.dsp.Game.refresh()}}}} is necessary for any changes to the screen
to be seen by the user.  This includes new objects, removed objects, new
projections, discontinued projections, etc.


\section{Global Variables and Constants}
\label{sge:global-variables-and-constants}\index{sge.IMPLEMENTATION (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.IMPLEMENTATION}\pysigline{\code{sge.}\bfcode{IMPLEMENTATION}}
A string indicating the name of the SGE implementation.

\end{fulllineitems}

\index{sge.SCALE\_METHODS (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.SCALE_METHODS}\pysigline{\code{sge.}\bfcode{SCALE\_METHODS}}
A list of specific scale methods supported by the SGE implementation.

\begin{notice}{note}{Note:}
This list does not include the generic scale methods, \code{"noblur"}
and \code{"smooth"}.  It is also possible for this list to be empty.
\end{notice}

\end{fulllineitems}

\index{sge.BLEND\_NORMAL (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.BLEND_NORMAL}\pysigline{\code{sge.}\bfcode{BLEND\_NORMAL}}
Flag indicating normal blending.

\end{fulllineitems}

\index{sge.BLEND\_RGBA\_ADD (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.BLEND_RGBA_ADD}\pysigline{\code{sge.}\bfcode{BLEND\_RGBA\_ADD}}
Flag indicating RGBA Addition blending: the red, green, blue, and
alpha color values of the source are added to the respective color
values of the destination, to a maximum of 255.

\end{fulllineitems}

\index{sge.BLEND\_RGBA\_SUBTRACT (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.BLEND_RGBA_SUBTRACT}\pysigline{\code{sge.}\bfcode{BLEND\_RGBA\_SUBTRACT}}
Flag indicating RGBA Subtract blending: the red, green, blue, and
alpha color values of the source are subtracted from the respective
color values of the destination, to a minimum of 0.

\end{fulllineitems}

\index{sge.BLEND\_RGBA\_MULTIPLY (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.BLEND_RGBA_MULTIPLY}\pysigline{\code{sge.}\bfcode{BLEND\_RGBA\_MULTIPLY}}
Flag indicating RGBA Multiply blending: the red, green, blue,
and alpha color values of the source and destination are converted to
values between 0 and 1 (divided by 255), the resulting destination
color values are multiplied by the respective resulting source color
values, and these results are converted back into values between 0
and 255 (multiplied by 255).

\end{fulllineitems}

\index{sge.BLEND\_RGBA\_SCREEN (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.BLEND_RGBA_SCREEN}\pysigline{\code{sge.}\bfcode{BLEND\_RGBA\_SCREEN}}
Flag indicating RGBA Screen blending: the red, green, blue, and alpha
color values of the source and destination are inverted (subtracted
from 255) and converted to values between 0 and 1 (divided by 255),
the resulting destination color values are multiplied by the
respective resulting source color values, and these results are
converted back into values between 0 and 255 (multiplied by 255) and
inverted again (subtracted from 255).

\end{fulllineitems}

\index{sge.BLEND\_RGBA\_MINIMUM (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.BLEND_RGBA_MINIMUM}\pysigline{\code{sge.}\bfcode{BLEND\_RGBA\_MINIMUM}}
Flag indicating RGBA Minimum (Darken Only) blending: the smallest
respective red, green, blue, and alpha color values out of the source
and destination are used.

\end{fulllineitems}

\index{sge.BLEND\_RGBA\_MAXIMUM (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.BLEND_RGBA_MAXIMUM}\pysigline{\code{sge.}\bfcode{BLEND\_RGBA\_MAXIMUM}}
Flag indicating RGBA Maximum (Lighten Only) blending: the largest
respective red, green, blue, and alpha color values out of the source
and destination are used.

\end{fulllineitems}

\index{sge.BLEND\_RGB\_ADD (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.BLEND_RGB_ADD}\pysigline{\code{sge.}\bfcode{BLEND\_RGB\_ADD}}
Flag indicating RGB Addition blending: the same thing as RGBA
Addition blending (see {\hyperref[sge:sge.sge.BLEND_RGBA_ADD]{\emph{\code{sge.BLEND\_RGBA\_ADD}}}}) except the
destination's alpha values are not changed.

\end{fulllineitems}

\index{sge.BLEND\_RGB\_SUBTRACT (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.BLEND_RGB_SUBTRACT}\pysigline{\code{sge.}\bfcode{BLEND\_RGB\_SUBTRACT}}
Flag indicating RGB Subtract blending: the same thing as RGBA
Subtract blending (see {\hyperref[sge:sge.sge.BLEND_RGBA_SUBTRACT]{\emph{\code{sge.BLEND\_RGBA\_SUBTRACT}}}}) except the
destination's alpha values are not changed.

\end{fulllineitems}

\index{sge.BLEND\_RGB\_MULTIPLY (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.BLEND_RGB_MULTIPLY}\pysigline{\code{sge.}\bfcode{BLEND\_RGB\_MULTIPLY}}
Flag indicating RGB Multiply blending: the same thing as RGBA
Multiply blending (see {\hyperref[sge:sge.sge.BLEND_RGBA_MULTIPLY]{\emph{\code{sge.BLEND\_RGBA\_MULTIPLY}}}}) except the
destination's alpha values are not changed.

\end{fulllineitems}

\index{sge.BLEND\_RGB\_SCREEN (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.BLEND_RGB_SCREEN}\pysigline{\code{sge.}\bfcode{BLEND\_RGB\_SCREEN}}
Flag indicating RGB Screen blending: the same thing as RGBA Screen
blending (see {\hyperref[sge:sge.sge.BLEND_RGBA_SCREEN]{\emph{\code{sge.BLEND\_RGBA\_SCREEN}}}}) except the destination's
alpha values are not changed.

\end{fulllineitems}

\index{sge.BLEND\_RGB\_MINIMUM (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.BLEND_RGB_MINIMUM}\pysigline{\code{sge.}\bfcode{BLEND\_RGB\_MINIMUM}}
Flag indicating RGB Minimum (Darken Only) blending: the same thing
as RGBA Minimum blending (see {\hyperref[sge:sge.sge.BLEND_RGBA_MINIMUM]{\emph{\code{sge.BLEND\_RGBA\_MINIMUM}}}}) except
the destination's alpha values are not changed.

\end{fulllineitems}

\index{sge.BLEND\_RGB\_MAXIMUM (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.BLEND_RGB_MAXIMUM}\pysigline{\code{sge.}\bfcode{BLEND\_RGB\_MAXIMUM}}
Flag indicating RGB Maximum (Lighten Only) blending: the same thing
as RGBA Maximum blending (see {\hyperref[sge:sge.sge.BLEND_RGBA_MAXIMUM]{\emph{\code{sge.BLEND\_RGBA\_MAXIMUM}}}}) except
the destination's alpha values are not changed.

\end{fulllineitems}

\index{sge.game (in module sge)}

\begin{fulllineitems}
\phantomsection\label{sge:sge.sge.game}\pysigline{\code{sge.}\bfcode{game}}
Stores the current {\hyperref[dsp:sge.dsp.Game]{\emph{\code{sge.dsp.Game}}}} object.  If there is no
{\hyperref[dsp:sge.dsp.Game]{\emph{\code{sge.dsp.Game}}}} object currently, this variable is set to
\code{None}.

\end{fulllineitems}



\chapter{Tutorial 1: Hello, world!}
\label{hello_world::doc}\label{hello_world:tutorial-1-hello-world}\setbox0\vbox{
\begin{minipage}{0.95\linewidth}
\textbf{Contents}

\medskip

\begin{itemize}
\item {} 
\phantomsection\label{hello_world:id1}{\hyperref[hello_world:tutorial\string-1\string-hello\string-world]{\emph{Tutorial 1: Hello, world!}}}
\begin{itemize}
\item {} 
\phantomsection\label{hello_world:id2}{\hyperref[hello_world:setting\string-up\string-a\string-project]{\emph{Setting Up a Project}}}
\begin{itemize}
\item {} 
\phantomsection\label{hello_world:id3}{\hyperref[hello_world:shebang]{\emph{Shebang}}}

\item {} 
\phantomsection\label{hello_world:id4}{\hyperref[hello_world:license]{\emph{License}}}

\item {} 
\phantomsection\label{hello_world:id5}{\hyperref[hello_world:imports]{\emph{Imports}}}

\end{itemize}

\item {} 
\phantomsection\label{hello_world:id6}{\hyperref[hello_world:adding\string-game\string-logic]{\emph{Adding Game Logic}}}
\begin{itemize}
\item {} 
\phantomsection\label{hello_world:id7}{\hyperref[hello_world:the\string-game\string-class]{\emph{The Game Class}}}

\item {} 
\phantomsection\label{hello_world:id8}{\hyperref[hello_world:the\string-room\string-class]{\emph{The Room Class}}}

\end{itemize}

\item {} 
\phantomsection\label{hello_world:id9}{\hyperref[hello_world:starting\string-the\string-game]{\emph{Starting the Game}}}

\item {} 
\phantomsection\label{hello_world:id10}{\hyperref[hello_world:the\string-final\string-result]{\emph{The Final Result}}}

\end{itemize}

\end{itemize}
\end{minipage}}
\begin{center}\setlength{\fboxsep}{5pt}\shadowbox{\box0}\end{center}

The easiest way to learn something new is with an example.  We will
start with a very basic example: the traditional ``Hello, world!''
program.  This example will just project ``Hello, world!'' onto the
screen.


\section{Setting Up a Project}
\label{hello_world:setting-up-a-project}
First, we must create our project directory.  I will use ``\textasciitilde{}/hello''.

Next, create the game source file inside ``\textasciitilde{}/hello''.  I am calling it
``hello.py''.

Open hello.py so you can start editing it.


\subsection{Shebang}
\label{hello_world:shebang}
All Python files which are supposed to be executed should start with
a shebang, which is a line that tells POSIX systems (such as GNU/Linux
systems, BSD, and OS X) how to execute the file.  For Python 3, the
version of Python we will be using, the shebang is:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{c+ch}{\PYGZsh{}!/usr/bin/env python3}
\end{Verbatim}

The shebang should be the very first line of the file.  You should also
make sure that the file itself uses Unix-style line endings (``\textbackslash{}n'');
this can be done in most text editors via a drop-down list available
when you save, and is done by IDLE automatically.  Windows-style line
endings (``\textbackslash{}r\textbackslash{}n'') are often interpreted wrongly in POSIX systems, which
defeats the purpose of the shebang.


\subsection{License}
\label{hello_world:license}
The file is copyrighted by default, so if you do not give the file a
license, it will be illegal for anyone to copy and share the program.
You should always choose a free/libre software license for your
programs.  In this example, I will use CC0, which is a public domain
dedication tool.  You can use CC0 if you want, or you can choose another
license.  You can learn about various free/libre software licenses at
\href{http://gnu.org/licenses/}{http://gnu.org/licenses/}.

The license text I am using for CC0 is:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{c+c1}{\PYGZsh{} Hello, world!}
\PYG{c+c1}{\PYGZsh{} Written in 2013 by Julian Marchant \PYGZlt{}onpon4@riseup.net\PYGZgt{}}
\PYG{c+c1}{\PYGZsh{}}
\PYG{c+c1}{\PYGZsh{} To the extent possible under law, the author(s) have dedicated all}
\PYG{c+c1}{\PYGZsh{} copyright and related and neighboring rights to this software to the}
\PYG{c+c1}{\PYGZsh{} public domain worldwide. This software is distributed without any}
\PYG{c+c1}{\PYGZsh{} warranty.}
\PYG{c+c1}{\PYGZsh{}}
\PYG{c+c1}{\PYGZsh{} You should have received a copy of the CC0 Public Domain Dedication}
\PYG{c+c1}{\PYGZsh{} along with this software. If not, see}
\PYG{c+c1}{\PYGZsh{} \PYGZlt{}http://creativecommons.org/publicdomain/zero/1.0/\PYGZgt{}.}
\end{Verbatim}

Place your license text just under the shebang so that it is prominent.


\subsection{Imports}
\label{hello_world:imports}
Because we are using the SGE, we must import the \code{sge} library.  Add
the following line:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k+kn}{import} \PYG{n+nn}{sge}
\end{Verbatim}


\section{Adding Game Logic}
\label{hello_world:adding-game-logic}

\subsection{The Game Class}
\label{hello_world:the-game-class}
In SGE games, everything is controlled by a ``game'' object.  The game
object controls everything at the global level, including global events.
To define global events, we need to subclass {\hyperref[dsp:sge.dsp.Game]{\emph{\code{sge.dsp.Game}}}} and
create our own game class.  We can just call this class \code{Game}:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{class} \PYG{n+nc}{Game}\PYG{p}{(}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{dsp}\PYG{o}{.}\PYG{n}{Game}\PYG{p}{)}\PYG{p}{:}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}key\PYGZus{}press}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{key}\PYG{p}{,} \PYG{n}{char}\PYG{p}{)}\PYG{p}{:}
        \PYG{k}{if} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{escape}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{event\PYGZus{}close}\PYG{p}{(}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}close}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{)}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{end}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}

Because our example is simple, we only need to define two events: the
close event, which occurs when the OS tells the game to close (most
typically when a close button is clicked on), and the key press event,
which occurs when a key is pressed.  We want the game to end if either
the OS tells it to close or the Esc key is pressed.

As you may have noticed, we define events by defining certain methods;
in our case, we defined methods to override the
{\hyperref[dsp:sge.dsp.Game.event_key_press]{\emph{\code{sge.dsp.Game.event\_key\_press()}}}} and
{\hyperref[dsp:sge.dsp.Game.event_close]{\emph{\code{sge.dsp.Game.event\_close()}}}} methods.

Our definition of \code{event\_close()} is simple enough: we just call
{\hyperref[dsp:sge.dsp.Game.end]{\emph{\code{sge.dsp.Game.end()}}}}, which ends the game.  Our definition of
\code{event\_key\_press()} is slightly more complicated; first we have to
check what key was pressed, indicated by the \code{key} argument.  If the
key is the Esc key, we call our \code{event\_close()} method.  The reason
for calling \code{event\_close()} instead of just calling \code{end()} is
simple: in the future, we might want to do more than just call
\code{end()}; perhaps, for example, we decide that we want to add a
confirmation dialog before actually quitting. By connecting the key
press event to the close event, if we do change what the close event
does, that change will also translate to the pressing of the Esc key,
avoiding needless duplication of work.


\subsection{The Room Class}
\label{hello_world:the-room-class}
Rooms are distinguished places where things happen; for example, each
level in a game would typically be its own room, the title screen might
be a room, the credits screen might be a room, and the options menu
might be a room.  In this example, we are only going to have one room,
and this room is going to serve only one function: display ``Hello,
world!'' in the center of the screen.  This will be our room class:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{class} \PYG{n+nc}{Room}\PYG{p}{(}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{dsp}\PYG{o}{.}\PYG{n}{Room}\PYG{p}{)}\PYG{p}{:}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}step}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{time\PYGZus{}passed}\PYG{p}{,} \PYG{n}{delta\PYGZus{}mult}\PYG{p}{)}\PYG{p}{:}
        \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{project\PYGZus{}text}\PYG{p}{(}\PYG{n}{font}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Hello, world!}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{width} \PYG{o}{/} \PYG{l+m+mi}{2}\PYG{p}{,}
                              \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{height} \PYG{o}{/} \PYG{l+m+mi}{2}\PYG{p}{,}
                              \PYG{n}{color}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{black}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{,} \PYG{n}{halign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{center}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,}
                              \PYG{n}{valign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{middle}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}
\end{Verbatim}

You can see that the room class is defined very similarly to the game
class.  We subclass {\hyperref[dsp:sge.dsp.Room]{\emph{\code{sge.dsp.Room}}}} and add a method to override
{\hyperref[dsp:sge.dsp.Room.event_step]{\emph{\code{sge.dsp.Room.event\_step()}}}}, which defines the step event of our
room class.  The step event happens over and over again, once every
``frame''.  You can think of frames as being like the frames in a video;
each frame makes small changes to the image on the screen and then gives
you the new image in a fraction of a second, providing an illusion of
movement.

To display ``Hello, world!'' onto the screen, we use
{\hyperref[dsp:sge.dsp.Game.project_text]{\emph{\code{sge.dsp.Game.project\_text()}}}}, which instantly displays any text we
want onto the screen.  \code{sge.game} is a variable that always points
to the {\hyperref[dsp:sge.dsp.Game]{\emph{\code{sge.dsp.Game}}}} object currently in use.

The first argument of this method is the font to use; we don't have a
font yet, but we are going to define one later and assign it to
\code{font}.  Next is the text to display, which for us is
\code{"Hello, world!"}.

The next arguments are the horizontal and vertical location of the text
on the screen; we set these to half of the game's width and height,
respectively, to place the text in the center.

Now that all required arguments are defined, we are going to define the
color of the text as a keyword argument, setting it explicitly to black.

Finally, we define \code{halign} and \code{valign} as keyword arguments; these
arguments specify the horizontal and vertical alignment of the text,
respectively.

You might be wondering: why do we keep doing this every frame? Can't we
just do it once, since we're not changing the image? In fact, we can't.
{\hyperref[dsp:sge.dsp.Game.project_text]{\emph{\code{sge.dsp.Game.project\_text()}}}} shows our text, but it only does so
for one frame.  You can think of it as working like a movie projector:
if you keep the projector on, you will continue to see the image, but as
soon as the projector stops projecting the image, you can no longer see
the image from the projector.  {\hyperref[dsp:sge.dsp.Game.project_text]{\emph{\code{sge.dsp.Game.project\_text()}}}} and
other similar projection methods work the same way.


\section{Starting the Game}
\label{hello_world:starting-the-game}
If you try to run hello.py now, you will notice that nothing happens.
This is because, while we defined the game logic, we didn't actually
execute it.

Additionally, we are still missing a resource: the font object we want
to use to project text onto the screen.  We need to load this resource.

We are going to fix both of these problems by adding some code after our
class definitions:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{c+c1}{\PYGZsh{} Create Game object}
\PYG{n}{Game}\PYG{p}{(}\PYG{p}{)}

\PYG{c+c1}{\PYGZsh{} Create backgrounds}
\PYG{n}{background} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Background}\PYG{p}{(}\PYG{p}{[}\PYG{p}{]}\PYG{p}{,} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{)}

\PYG{c+c1}{\PYGZsh{} Load fonts}
\PYG{n}{font} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Font}\PYG{p}{(}\PYG{p}{)}

\PYG{c+c1}{\PYGZsh{} Create rooms}
\PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{start\PYGZus{}room} \PYG{o}{=} \PYG{n}{Room}\PYG{p}{(}\PYG{n}{background}\PYG{o}{=}\PYG{n}{background}\PYG{p}{)}

\PYG{k}{if} \PYG{n}{\PYGZus{}\PYGZus{}name\PYGZus{}\PYGZus{}} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{\PYGZus{}\PYGZus{}main\PYGZus{}\PYGZus{}}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
    \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{start}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}

First, we create a {\hyperref[dsp:sge.dsp.Game]{\emph{\code{sge.dsp.Game}}}} object; we don't need to store
it in anything since it is automatically stored in \code{sge.game}.

Second, we create a {\hyperref[gfx:sge.gfx.Background]{\emph{\code{sge.gfx.Background}}}} object to specify what
the background looks like.  We make our background all white, with no
layers.  (Layers are used to give backgrounds more than a solid color,
which we don't need.)

Third, we create our font. We don't really care what this font looks
like, so we allow the SGE to pick a font.  If you do care what font is
used, you can pass the name of a font onto the \code{name} keyword
argument.

Fourth, we create a room.  The only argument we pass is the background
argument; we set this to the background we created earlier.  Since it is
the room that we are going to start the game with, we need to assign
this room to the special attribute, \code{sge.game.start\_room}, which
indicates the room that the game starts with.

Finally, with everything in place, we call the
{\hyperref[dsp:sge.dsp.Game.start]{\emph{\code{sge.dsp.Game.start()}}}} method of our game object.  This executes all
the game logic we defined earlier.  However, we only do this if the
special Python variable, \code{\_\_name\_\_}, is set to \code{"\_\_main\_\_"},
which means that the current module is the main module, i.e. was
executed rather than imported.  It is a good practice to include this
distinction between being executed and being imported in all of your
Python scripts.


\section{The Final Result}
\label{hello_world:the-final-result}
That's it!  If you execute the script now, you will see a white screen
with black text in the center reading ``Hello, world!'' Pressing the Esc
key or clicking on the close button in the window will close the
program.  Congratulations on writing your first SGE program!

This is the completed Hello World program:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{c+ch}{\PYGZsh{}!/usr/bin/env python3}

\PYG{c+c1}{\PYGZsh{} Hello, world!}
\PYG{c+c1}{\PYGZsh{} Written in 2013 by Julian Marchant \PYGZlt{}onpon4@riseup.net\PYGZgt{}}
\PYG{c+c1}{\PYGZsh{}}
\PYG{c+c1}{\PYGZsh{} To the extent possible under law, the author(s) have dedicated all}
\PYG{c+c1}{\PYGZsh{} copyright and related and neighboring rights to this software to the}
\PYG{c+c1}{\PYGZsh{} public domain worldwide. This software is distributed without any}
\PYG{c+c1}{\PYGZsh{} warranty.}
\PYG{c+c1}{\PYGZsh{}}
\PYG{c+c1}{\PYGZsh{} You should have received a copy of the CC0 Public Domain Dedication}
\PYG{c+c1}{\PYGZsh{} along with this software. If not, see}
\PYG{c+c1}{\PYGZsh{} \PYGZlt{}http://creativecommons.org/publicdomain/zero/1.0/\PYGZgt{}.}

\PYG{k+kn}{import} \PYG{n+nn}{sge}


\PYG{k}{class} \PYG{n+nc}{Game}\PYG{p}{(}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{dsp}\PYG{o}{.}\PYG{n}{Game}\PYG{p}{)}\PYG{p}{:}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}key\PYGZus{}press}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{key}\PYG{p}{,} \PYG{n}{char}\PYG{p}{)}\PYG{p}{:}
        \PYG{k}{if} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{escape}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{event\PYGZus{}close}\PYG{p}{(}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}close}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{)}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{end}\PYG{p}{(}\PYG{p}{)}


\PYG{k}{class} \PYG{n+nc}{Room}\PYG{p}{(}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{dsp}\PYG{o}{.}\PYG{n}{Room}\PYG{p}{)}\PYG{p}{:}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}step}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{time\PYGZus{}passed}\PYG{p}{,} \PYG{n}{delta\PYGZus{}mult}\PYG{p}{)}\PYG{p}{:}
        \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{project\PYGZus{}text}\PYG{p}{(}\PYG{n}{font}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Hello, world!}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{width} \PYG{o}{/} \PYG{l+m+mi}{2}\PYG{p}{,}
                              \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{height} \PYG{o}{/} \PYG{l+m+mi}{2}\PYG{p}{,}
                              \PYG{n}{color}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{black}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{,} \PYG{n}{halign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{center}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,}
                              \PYG{n}{valign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{middle}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}


\PYG{c+c1}{\PYGZsh{} Create Game object}
\PYG{n}{Game}\PYG{p}{(}\PYG{p}{)}

\PYG{c+c1}{\PYGZsh{} Create backgrounds}
\PYG{n}{background} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Background}\PYG{p}{(}\PYG{p}{[}\PYG{p}{]}\PYG{p}{,} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{)}

\PYG{c+c1}{\PYGZsh{} Load fonts}
\PYG{n}{font} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Font}\PYG{p}{(}\PYG{p}{)}

\PYG{c+c1}{\PYGZsh{} Create rooms}
\PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{start\PYGZus{}room} \PYG{o}{=} \PYG{n}{Room}\PYG{p}{(}\PYG{n}{background}\PYG{o}{=}\PYG{n}{background}\PYG{p}{)}

\PYG{k}{if} \PYG{n}{\PYGZus{}\PYGZus{}name\PYGZus{}\PYGZus{}} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{\PYGZus{}\PYGZus{}main\PYGZus{}\PYGZus{}}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
    \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{start}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}


\chapter{Tutorial 2: Pong}
\label{pong::doc}\label{pong:tutorial-2-pong}\setbox0\vbox{
\begin{minipage}{0.95\linewidth}
\textbf{Contents}

\medskip

\begin{itemize}
\item {} 
\phantomsection\label{pong:id2}{\hyperref[pong:tutorial\string-2\string-pong]{\emph{Tutorial 2: Pong}}}
\begin{itemize}
\item {} 
\phantomsection\label{pong:id3}{\hyperref[pong:adding\string-game\string-logic]{\emph{Adding Game Logic}}}
\begin{itemize}
\item {} 
\phantomsection\label{pong:id4}{\hyperref[pong:the\string-game\string-class]{\emph{The Game Class}}}

\item {} 
\phantomsection\label{pong:id5}{\hyperref[pong:the\string-object\string-classes]{\emph{The Object Classes}}}
\begin{itemize}
\item {} 
\phantomsection\label{pong:id6}{\hyperref[pong:player]{\emph{Player}}}

\item {} 
\phantomsection\label{pong:id7}{\hyperref[pong:ball]{\emph{Ball}}}

\end{itemize}

\end{itemize}

\item {} 
\phantomsection\label{pong:id8}{\hyperref[pong:starting\string-the\string-game]{\emph{Starting the Game}}}
\begin{itemize}
\item {} 
\phantomsection\label{pong:id9}{\hyperref[pong:loading\string-sprites]{\emph{Loading Sprites}}}

\item {} 
\phantomsection\label{pong:id10}{\hyperref[pong:loading\string-backgrounds]{\emph{Loading Backgrounds}}}

\item {} 
\phantomsection\label{pong:id11}{\hyperref[pong:creating\string-objects]{\emph{Creating Objects}}}

\item {} 
\phantomsection\label{pong:id12}{\hyperref[pong:creating\string-rooms]{\emph{Creating Rooms}}}

\item {} 
\phantomsection\label{pong:id13}{\hyperref[pong:making\string-the\string-mouse\string-invisible]{\emph{Making the Mouse Invisible}}}

\item {} 
\phantomsection\label{pong:id14}{\hyperref[pong:id1]{\emph{Starting the Game}}}

\end{itemize}

\item {} 
\phantomsection\label{pong:id15}{\hyperref[pong:the\string-final\string-result]{\emph{The Final Result}}}

\end{itemize}

\end{itemize}
\end{minipage}}
\begin{center}\setlength{\fboxsep}{5pt}\shadowbox{\box0}\end{center}

Now that you've seen the basics of the SGE, it's time to create an
actual game. Although Pong might seem extremely simple, it will give you
a great foundation for developing more complex games in the future.

Start out by setting up the project like we did in the Hello World
tutorial.


\section{Adding Game Logic}
\label{pong:adding-game-logic}

\subsection{The Game Class}
\label{pong:the-game-class}
For our {\hyperref[dsp:sge.dsp.Game]{\emph{\code{sge.dsp.Game}}}} class, we want to of course provide a way
to exit the game, and in this case, we are also going to provide a way
to pause the game.  Just for the heck of it, let's also allow the player
to take a screenshot by pressing F8 and toggle fullscreen by pressing
F11.

Let's take it one event at a time. Our close event is simple enough:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{event\PYGZus{}close}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{)}\PYG{p}{:}
    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{end}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}

Our key press event is slightly more involved.  To take a screenshot, we
simply use a combination of {\hyperref[gfx:sge.gfx.Sprite.from_screenshot]{\emph{\code{sge.gfx.Sprite.from\_screenshot()}}}} and
{\hyperref[gfx:sge.gfx.Sprite.save]{\emph{\code{sge.gfx.Sprite.save()}}}}.  To toggle fullscreen, we simply change the
value of {\hyperref[dsp:sge.dsp.Game.fullscreen]{\emph{\code{sge.dsp.Game.fullscreen}}}}.  To pause the game, we use
{\hyperref[dsp:sge.dsp.Game.pause]{\emph{\code{sge.dsp.Game.pause()}}}}.  We end up with this:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{event\PYGZus{}key\PYGZus{}press}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{key}\PYG{p}{,} \PYG{n}{char}\PYG{p}{)}\PYG{p}{:}
    \PYG{k}{if} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{f8}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
        \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Sprite}\PYG{o}{.}\PYG{n}{from\PYGZus{}screenshot}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{save}\PYG{p}{(}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{screenshot.jpg}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{)}
    \PYG{k}{elif} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{f11}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{fullscreen} \PYG{o}{=} \PYG{o+ow}{not} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{fullscreen}
    \PYG{k}{elif} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{escape}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{event\PYGZus{}close}\PYG{p}{(}\PYG{p}{)}
    \PYG{k}{elif} \PYG{n}{key} \PYG{o+ow}{in} \PYG{p}{(}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{p}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{enter}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{)}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{pause}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}

This is incomplete, though.  When {\hyperref[dsp:sge.dsp.Game.pause]{\emph{\code{sge.dsp.Game.pause()}}}} is called,
the game enters a special loop where normal events are ignored.  In
their place, we need to use ``paused'' events to give the player a chance
to unpause.  We also should allow the player to quit the game while it
is paused.  To achieve these goals, we add the special events,
\code{sge.dsp.Game.event\_paused\_key\_pressed()} and
{\hyperref[dsp:sge.dsp.Game.event_paused_close]{\emph{\code{sge.dsp.Game.event\_paused\_close()}}}}:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{event\PYGZus{}paused\PYGZus{}key\PYGZus{}press}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{key}\PYG{p}{,} \PYG{n}{char}\PYG{p}{)}\PYG{p}{:}
    \PYG{k}{if} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{escape}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
        \PYG{c+c1}{\PYGZsh{} This allows the player to still exit while the game is}
        \PYG{c+c1}{\PYGZsh{} paused, rather than having to unpause first.}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{event\PYGZus{}close}\PYG{p}{(}\PYG{p}{)}
    \PYG{k}{else}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{unpause}\PYG{p}{(}\PYG{p}{)}

\PYG{k}{def} \PYG{n+nf}{event\PYGZus{}paused\PYGZus{}close}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{)}\PYG{p}{:}
    \PYG{c+c1}{\PYGZsh{} This allows the player to still exit while the game is paused,}
    \PYG{c+c1}{\PYGZsh{} rather than having to unpause first.}
    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{event\PYGZus{}close}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}

In this case, we are defining the paused key press event to unpause the
game when any key except for the Esc key is pressed.


\subsection{The Object Classes}
\label{pong:the-object-classes}
{\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} objects are things in a game that we want to be
displayed in a room.  These objects tend to represent players, enemies,
tiles, decorations, and pretty much anything else you can think of.

For Pong, we need three objects: the two players, and the ball.  We will
define two sub-classes of {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} for this purpose:
\code{Player} and \code{Ball}.


\subsubsection{Player}
\label{pong:player}
\code{Player} is used for the paddles.  These are what the players
control.

For \code{Player}, the difference between different objects is which
player controls it. Every other difference (the position, the controls,
and the direction it hits the ball) can be easily derived from that.  We
are therefore going to define \code{Player.\_\_init\_\_()} to reflect this.

\code{Player.\_\_init\_\_()} will take a single argument, \code{player}.  This
argument will indicate which player the object is for: \code{1} for player
1, or \code{2} for player 2.  We will set a few attributes based on this:
\begin{itemize}
\item {} 
\code{up\_key} will indicate the key that moves the paddle up.  We
will set it to \code{"w"} for player 1, or \code{"up"} for player 2.

\item {} 
\code{down\_key} will indicate the key that moves the paddle down.  We
will set it to \code{"s"} for player 1, or \code{"down"} for player 2.

\item {} 
\code{x} is an attribute inherited from {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} which
indicates the horizontal position of the object.  We will set this
based on a constant we will define (technically just a variable, since
Python doesn't support constants) called \code{PADDLE\_XOFFSET}:
\code{PADDLE\_XOFFSET} for player 1, or
\code{sge.game.width - PADDLE\_XOFFSET} for player 2.  We will define
\code{PADDLE\_XOFFSET} near the top of our code file, beneath
imports, as \code{32}.

\item {} 
\code{hit\_direction} will indicate the direction the paddle hits the
ball.  We will set it to \code{1} for player 1, and \code{-1} for player 2.

\end{itemize}

Additionally, certain attributes inherited from {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}}
will be the same for both \code{Player} objects.  \code{y} will
always be \code{sge.game.height / 2} (vertically centered).  \code{sprite}
will always be \code{paddle\_sprite} (a sprite we will create later).
\code{checks\_collisions} will always be \code{False}, since player
objects don't need to check for collisions with each other; we can
therefore leave all collision checking to the ball object.

All attributes inherited from {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} will be defined by
passing their values to {\hyperref[dsp:sge.dsp.Object.__init__]{\emph{\code{sge.dsp.Object.\_\_init\_\_()}}}}, which we will
call with \code{super().\_\_init\_\_(*args, **kwargs)}.  This makes our
\code{Player.\_\_init\_\_()} defintion an extension, rather than an override,
of {\hyperref[dsp:sge.dsp.Object.__init__]{\emph{\code{sge.dsp.Object.\_\_init\_\_()}}}}, which is important; overriding this
method would be likely to break something.

Our definition of \code{Player.\_\_init\_\_{}`()} ends up looking something
like this:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{player}\PYG{p}{)}\PYG{p}{:}
    \PYG{k}{if} \PYG{n}{player} \PYG{o}{==} \PYG{l+m+mi}{1}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{joystick} \PYG{o}{=} \PYG{l+m+mi}{0}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{up\PYGZus{}key} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{w}\PYG{l+s+s2}{\PYGZdq{}}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{down\PYGZus{}key} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{s}\PYG{l+s+s2}{\PYGZdq{}}
        \PYG{n}{x} \PYG{o}{=} \PYG{n}{PADDLE\PYGZus{}XOFFSET}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{hit\PYGZus{}direction} \PYG{o}{=} \PYG{l+m+mi}{1}
    \PYG{k}{else}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{joystick} \PYG{o}{=} \PYG{l+m+mi}{1}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{up\PYGZus{}key} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{up}\PYG{l+s+s2}{\PYGZdq{}}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{down\PYGZus{}key} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{down}\PYG{l+s+s2}{\PYGZdq{}}
        \PYG{n}{x} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{width} \PYG{o}{\PYGZhy{}} \PYG{n}{PADDLE\PYGZus{}XOFFSET}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{hit\PYGZus{}direction} \PYG{o}{=} \PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1}

    \PYG{n}{y} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{height} \PYG{o}{/} \PYG{l+m+mi}{2}
    \PYG{n+nb}{super}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(}\PYG{n}{x}\PYG{p}{,} \PYG{n}{y}\PYG{p}{,} \PYG{n}{sprite}\PYG{o}{=}\PYG{n}{paddle\PYGZus{}sprite}\PYG{p}{,} \PYG{n}{checks\PYGZus{}collisions}\PYG{o}{=}\PYG{n+nb+bp}{False}\PYG{p}{)}
\end{Verbatim}

We need to allow the players to move the paddles.  We could do this by
using key press events, but since we would like the players to be able
to continuously move the paddles by holding down the key, the proper way
to do this is to check for the state of the keys every frame and move
accordingly.

{\hyperref[keyboard:sge.keyboard.get_pressed]{\emph{\code{sge.keyboard.get\_pressed()}}}} returns the state of a key on the
keyboard.  We will check this in the step event to decide how the paddle
should move on any given frame.  The step event, defined by
{\hyperref[dsp:sge.dsp.Object.event_step]{\emph{\code{sge.dsp.Object.event\_step()}}}}, is an event which always executes
every frame.

What we will do is subtract the state of \code{up\_key} from the state
of \code{down\_key}.  This will give us \code{-1} if only \code{up\_key} is
pressed, \code{1} if only \code{down\_key} is pressed, and \code{0} if neither
or both keys are pressed.  We can multiply this result by a constant,
which we will call \code{PADDLE\_SPEED}, to get the amount that the
paddle should move this frame, and assign this value to the player's
{\hyperref[dsp:sge.dsp.Object.yvelocity]{\emph{\code{sge.dsp.Object.yvelocity}}}}, an attribute which indicates the
number of pixels an object will move vertically each frame.  We will
define \code{PADDLE\_SPEED} as \code{4}.

This isn't quite enough, though.  With just this, the paddle can be
moved off-screen!  To prevent this from happening, we will check the
player object's \code{bbox\_top} and \code{bbox\_bottom} values; these
indicate the current location of the object's bounding box.  If
\code{bbox\_top} is less than \code{0}, we will set it to \code{0}.  If
\code{bbox\_bottom} is greater than \code{sge.game.current\_room.height}, we
will set it to \code{sge.game.current\_room.height}.
\code{sge.game.current\_room}, as its name implies, indicates the
currently running \code{sge.game.Room} object.

Our step event ends up looking something like this:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{event\PYGZus{}step}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{time\PYGZus{}passed}\PYG{p}{,} \PYG{n}{delta\PYGZus{}mult}\PYG{p}{)}\PYG{p}{:}
    \PYG{c+c1}{\PYGZsh{} Movement}
    \PYG{n}{key\PYGZus{}motion} \PYG{o}{=} \PYG{p}{(}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{keyboard}\PYG{o}{.}\PYG{n}{get\PYGZus{}pressed}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{down\PYGZus{}key}\PYG{p}{)} \PYG{o}{\PYGZhy{}}
                  \PYG{n}{sge}\PYG{o}{.}\PYG{n}{keyboard}\PYG{o}{.}\PYG{n}{get\PYGZus{}pressed}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{up\PYGZus{}key}\PYG{p}{)}\PYG{p}{)}

    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{n}{key\PYGZus{}motion} \PYG{o}{*} \PYG{n}{PADDLE\PYGZus{}SPEED}

    \PYG{c+c1}{\PYGZsh{} Keep the paddle inside the window}
    \PYG{k}{if} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}top} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{0}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}top} \PYG{o}{=} \PYG{l+m+mi}{0}
    \PYG{k}{elif} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}bottom} \PYG{o}{\PYGZgt{}} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{height}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}bottom} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{height}
\end{Verbatim}


\subsubsection{Ball}
\label{pong:ball}
\code{Ball} is the ball.  It is bounced back and forth by the players.
If it touches the top or bottom edge of the screen, it bounces off.  If
it passes one of the players, the other player gets a point and the ball
is returned to the playing field.

Any \code{Ball} object is always going to have the same initial
attributes as any other \code{Ball} object, so much like what we did
with \code{Player}, we are going to define a custom
\code{Ball.\_\_init\_\_()}.

In this case, it's much simpler: \code{x} and \code{y} are going to
start at the center of the screen, and \code{sprite} is going to be
\code{ball\_sprite}.  These are attributes inherited from
{\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}}, so we indicate them in a call to
\code{super().\_\_init\_\_}.  \code{Ball.\_\_init\_\_()} ends up as:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{)}\PYG{p}{:}
    \PYG{n}{x} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{width} \PYG{o}{/} \PYG{l+m+mi}{2}
    \PYG{n}{y} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{height} \PYG{o}{/} \PYG{l+m+mi}{2}
    \PYG{n+nb}{super}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(}\PYG{n}{x}\PYG{p}{,} \PYG{n}{y}\PYG{p}{,} \PYG{n}{sprite}\PYG{o}{=}\PYG{n}{ball\PYGZus{}sprite}\PYG{p}{)}
\end{Verbatim}

Since we want to serve the ball both at the start of the game and every
time the ball passes a player, we should define a \code{Ball.serve()}
method.  This method needs to do two things: first, it needs to return
the ball to its original position in the center.  Second, it needs to
set the speed so that it moves either straight to the left or straight
to the right.  If a direction isn't specified, it needs to choose a
direction at random.

For the first task, we can use {\hyperref[dsp:sge.dsp.Object.xstart]{\emph{\code{sge.dsp.Object.xstart}}}} and
{\hyperref[dsp:sge.dsp.Object.ystart]{\emph{\code{sge.dsp.Object.ystart}}}}.  These attributes indicate the original
position of an object when it was first created, which in the case of
\code{Ball} objects is in the center of the screen.

For the second task, we have an argument called \code{direction}.  If it is
\code{None}, it randomly becomes either \code{1} or \code{-1}.  The
value is then multiplied by a constant called \code{BALL\_START\_SPEED},
which we will set to \code{2}, and this becomes the ball's
{\hyperref[dsp:sge.dsp.Object.xvelocity]{\emph{\code{sge.dsp.Object.xvelocity}}}} value.  The ball's
{\hyperref[dsp:sge.dsp.Object.yvelocity]{\emph{\code{sge.dsp.Object.yvelocity}}}} value is then set to \code{0}.

The result looks like this:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{serve}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{direction}\PYG{o}{=}\PYG{n+nb+bp}{None}\PYG{p}{)}\PYG{p}{:}
    \PYG{k}{if} \PYG{n}{direction} \PYG{o+ow}{is} \PYG{n+nb+bp}{None}\PYG{p}{:}
        \PYG{n}{direction} \PYG{o}{=} \PYG{n}{random}\PYG{o}{.}\PYG{n}{choice}\PYG{p}{(}\PYG{p}{[}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1}\PYG{p}{,} \PYG{l+m+mi}{1}\PYG{p}{]}\PYG{p}{)}

    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{x} \PYG{o}{=} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xstart}
    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{y} \PYG{o}{=} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{ystart}

    \PYG{c+c1}{\PYGZsh{} Next round}
    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xvelocity} \PYG{o}{=} \PYG{n}{BALL\PYGZus{}START\PYGZus{}SPEED} \PYG{o}{*} \PYG{n}{direction}
    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{Verbatim}

\begin{notice}{note}{Note:}
Since we are now using the \code{random} module, we need to also
import it at the top of our code file.
\end{notice}

When the ball is created, we want to serve it immediately.  we will put
this in the create event, which is defined by
{\hyperref[dsp:sge.dsp.Object.event_create]{\emph{\code{sge.dsp.Object.event\_create()}}}}.  The create event happens whenever
the object is created in the room.  This is the create event of
\code{Ball}:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{event\PYGZus{}create}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{)}\PYG{p}{:}
    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{serve}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}

For \code{Ball}`s step event, we need to do two things: cause the ball
to bounce off of the top and bottom edges of the screen, and serve the
ball when it passes the left or right edge of the screen.

For the first task, we do the same thing we did with \code{Player},
but we also set whether \code{yvelocity} is positive or negative; we
make it negative when the ball touches the bottom, and positive when the
ball touches the top.

For the second task, we do a similar check, but we phrase the check such
that the ball needs to be completely outside of the room, rather than
just touching the edge.  We do this by checking \code{bbox\_right}
against the left edge, and \code{bbox\_left} against the right edge.
When the ball is outside the screen, we serve it in the direction of the
player it passed (so that the player who lost the round gets initial
control of the ball).

Our step event for \code{Ball} ends up looking something like this:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{event\PYGZus{}step}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{time\PYGZus{}passed}\PYG{p}{,} \PYG{n}{delta\PYGZus{}mult}\PYG{p}{)}\PYG{p}{:}
    \PYG{c+c1}{\PYGZsh{} Scoring}
    \PYG{k}{if} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}right} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{0}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{serve}\PYG{p}{(}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1}\PYG{p}{)}
    \PYG{k}{elif} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}left} \PYG{o}{\PYGZgt{}} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{width}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{serve}\PYG{p}{(}\PYG{l+m+mi}{1}\PYG{p}{)}

    \PYG{c+c1}{\PYGZsh{} Bouncing off of the edges}
    \PYG{k}{if} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}bottom} \PYG{o}{\PYGZgt{}} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{height}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}bottom} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{height}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{o}{\PYGZhy{}}\PYG{n+nb}{abs}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity}\PYG{p}{)}
    \PYG{k}{elif} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}top} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{0}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}top} \PYG{o}{=} \PYG{l+m+mi}{0}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{n+nb}{abs}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity}\PYG{p}{)}
\end{Verbatim}

Now, we need to allow the players to repel the ball.  We will do this
with a collision event.  Collision events, controlled by
{\hyperref[dsp:sge.dsp.Object.event_collision]{\emph{\code{sge.dsp.Object.event\_collision()}}}}, occur when two objects touch
each other.

We first need to verify what type of object we're colliding with.  The
most straightforward way is to use \code{isinstance()} to check whether
or not the object being collided with, which is passed on to the
\code{other} argument, is an instance of \code{Player}.  We write the
collision code for these two objects under this check.

The most straightforward way to do this is with directional collision
detection, but we are going to instead use \code{Player.hit\_direction}
to determine what to do.  If the \code{other.hit\_direction} is \code{1},
we bounce the ball to the right.  Otherwise, we bounce the ball to the
left.

We need to make the ball accelerate each time the ball hits a paddle, so
that the round goes faster over time.  We will store the amount of
acceleration in a constant called \code{BALL\_ACCELERATION}, which we
will define as \code{0.2}.  We will then set \code{self.xvelocity} to
\code{(abs(self.xvelocity) + BALL\_ACCELERATION) * other.hit\_direction}.

We also need to make the ball's vertical movement change based on where
it hits the paddle.  To do this, we will subtract \code{other.y} from
\code{self.y} and multiply that by a constant called
\code{PADDLE\_VERTICAL\_FORCE}, which we will define as \code{1 / 12}; this
value will be added to \code{self.yvelocity}.

There is one problem left, though it is not particularly obvious.  The
way we have it set up at this point, the ball will eventually move so
fast that it will fail to collide with the paddles.  This is due to how
movement works; it's not actual movement, but rather a slight change of
position done every frame.  If that change of position is too much, the
ball can pass right over a paddle.

To prevent this, we need to set a limit for how fast the ball can move
horizontally.  Instead of just multiplying
\code{(abs(self.xvelocity) + BALL\_ACCELERATION)} by
\code{other.hit\_direction}, we multiply the smallest out of that, and a
new constant called \code{BALL\_MAX\_SPEED}, by
\code{other.hit\_direction}.  We will define \code{BALL\_MAX\_SPEED} as
\code{15}.

Our collision event ends up looking something like this:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{event\PYGZus{}collision}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{other}\PYG{p}{,} \PYG{n}{xdirection}\PYG{p}{,} \PYG{n}{ydirection}\PYG{p}{)}\PYG{p}{:}
    \PYG{k}{if} \PYG{n+nb}{isinstance}\PYG{p}{(}\PYG{n}{other}\PYG{p}{,} \PYG{n}{Player}\PYG{p}{)}\PYG{p}{:}
        \PYG{k}{if} \PYG{n}{other}\PYG{o}{.}\PYG{n}{hit\PYGZus{}direction} \PYG{o}{==} \PYG{l+m+mi}{1}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}left} \PYG{o}{=} \PYG{n}{other}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}right} \PYG{o}{+} \PYG{l+m+mi}{1}
        \PYG{k}{else}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}right} \PYG{o}{=} \PYG{n}{other}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}left} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1}

        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xvelocity} \PYG{o}{=} \PYG{n+nb}{min}\PYG{p}{(}\PYG{n+nb}{abs}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xvelocity}\PYG{p}{)} \PYG{o}{+} \PYG{n}{BALL\PYGZus{}ACCELERATION}\PYG{p}{,}
                             \PYG{n}{BALL\PYGZus{}MAX\PYGZus{}SPEED}\PYG{p}{)} \PYG{o}{*} \PYG{n}{other}\PYG{o}{.}\PYG{n}{hit\PYGZus{}direction}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{+}\PYG{o}{=} \PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{y} \PYG{o}{\PYGZhy{}} \PYG{n}{other}\PYG{o}{.}\PYG{n}{y}\PYG{p}{)} \PYG{o}{*} \PYG{n}{PADDLE\PYGZus{}VERTICAL\PYGZus{}FORCE}
\end{Verbatim}


\section{Starting the Game}
\label{pong:starting-the-game}
It's time to get our game started.

We are going to pass some arguments to the creation of our \code{Game}
object: we are going to define \code{width} as \code{640}, \code{height} as
\code{480}, \code{fps} as \code{120}, and \code{window\_text} as \code{"Pong"}.  Specify
them as keyword arguments.


\subsection{Loading Sprites}
\label{pong:loading-sprites}
We need two sprites: a paddle sprite and a ball sprite.  We also need a
black background with a line down the middle.  We could draw these in an
image editor and load them, but since they are so simple, we are going
to generate them dynamically instead.

Sprites are stored as {\hyperref[gfx:sge.gfx.Sprite]{\emph{\code{sge.gfx.Sprite}}}} objects, so we are going
to create two of them:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{paddle\PYGZus{}sprite} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Sprite}\PYG{p}{(}\PYG{n}{width}\PYG{o}{=}\PYG{l+m+mi}{8}\PYG{p}{,} \PYG{n}{height}\PYG{o}{=}\PYG{l+m+mi}{48}\PYG{p}{,} \PYG{n}{origin\PYGZus{}x}\PYG{o}{=}\PYG{l+m+mi}{4}\PYG{p}{,} \PYG{n}{origin\PYGZus{}y}\PYG{o}{=}\PYG{l+m+mi}{24}\PYG{p}{)}
\PYG{n}{ball\PYGZus{}sprite} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Sprite}\PYG{p}{(}\PYG{n}{width}\PYG{o}{=}\PYG{l+m+mi}{8}\PYG{p}{,} \PYG{n}{height}\PYG{o}{=}\PYG{l+m+mi}{8}\PYG{p}{,} \PYG{n}{origin\PYGZus{}x}\PYG{o}{=}\PYG{l+m+mi}{4}\PYG{p}{,} \PYG{n}{origin\PYGZus{}y}\PYG{o}{=}\PYG{l+m+mi}{4}\PYG{p}{)}
\end{Verbatim}

{\hyperref[gfx:sge.gfx.Sprite.origin_x]{\emph{\code{sge.gfx.Sprite.origin\_x}}}} and {\hyperref[gfx:sge.gfx.Sprite.origin_y]{\emph{\code{sge.gfx.Sprite.origin\_y}}}}
indicate the origin of the sprite.  In this case, we are setting the
origins to the center of the sprites.  This is necessary for our method
of determining how the paddles affect vertical speed to work, and it
also makes symmetry easier.

Currently, both of these sprites are blank.  We need to draw the images
on them.  In this case, we will just draw white rectangles that fill the
entirety of the sprites, which can be done with
{\hyperref[gfx:sge.gfx.Sprite.draw_rectangle]{\emph{\code{sge.gfx.Sprite.draw\_rectangle()}}}}:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{paddle\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}rectangle}\PYG{p}{(}\PYG{l+m+mi}{0}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n}{paddle\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{width}\PYG{p}{,}
                             \PYG{n}{paddle\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{height}\PYG{p}{,} \PYG{n}{fill}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{)}
\PYG{n}{ball\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}rectangle}\PYG{p}{(}\PYG{l+m+mi}{0}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n}{ball\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{width}\PYG{p}{,} \PYG{n}{ball\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{height}\PYG{p}{,}
                           \PYG{n}{fill}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{)}
\end{Verbatim}


\subsection{Loading Backgrounds}
\label{pong:loading-backgrounds}
Now we need a background.  Our sprites are white, so we need a black
background.  We could of course leave it just at that, but that would be
boring, so we are also going to also have a white line in the middle.
We can do this easily by using the paddle sprite as a background layer.
Background layers are special objects that indicate sprites that are
used in a background.  We create the layer, put it in a list, and pass
that list onto {\hyperref[gfx:sge.gfx.Background.__init__]{\emph{\code{sge.gfx.Background.\_\_init\_\_()}}}}`s \code{layers}
argument:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{layers} \PYG{o}{=} \PYG{p}{[}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{BackgroundLayer}\PYG{p}{(}\PYG{n}{paddle\PYGZus{}sprite}\PYG{p}{,} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{width} \PYG{o}{/} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{10000}\PYG{p}{,}
                                  \PYG{n}{repeat\PYGZus{}up}\PYG{o}{=}\PYG{n+nb+bp}{True}\PYG{p}{,} \PYG{n}{repeat\PYGZus{}down}\PYG{o}{=}\PYG{n+nb+bp}{True}\PYG{p}{)}\PYG{p}{]}
\PYG{n}{background} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Background}\PYG{p}{(}\PYG{n}{layers}\PYG{p}{,} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{black}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{)}
\end{Verbatim}

The fourth argument of \code{sge.BackgroudLayer.\_\_init\_\_()} is the
layer's Z-axis value.  The Z-axis is used to determine what objects are
in front of what other objects; objects with a higher Z-axis value are
closer to the viewer.  The default Z-axis value is \code{0}.  Since we want
all objects to be in front of the layer, we set its Z-axis value to a
very low negative value.


\subsection{Creating Objects}
\label{pong:creating-objects}
Don't forget to create our objects!  In \code{player1}, store a
\code{Player} object with the \code{player} argument specified as \code{1}.
In \code{player2}, store a \code{Player} object with the \code{player}
argument specified as \code{2}.  Finally, create a \code{Ball} object and
store it in \code{ball}.  Put all of these objects in a list and assign
this list to a variable called \code{objects}.


\subsection{Creating Rooms}
\label{pong:creating-rooms}
Create a \code{Room} object.  Specify the first argument as
\code{objects}, and specify the keyword argument \code{background} as
\code{background}.  Don't forget to assign it to
\code{sge.game.start\_room}!


\subsection{Making the Mouse Invisible}
\label{pong:making-the-mouse-invisible}
Since we don't need to see the mouse cursor, we will hide it.  To do
this, set \code{sge.game.mouse.visible} to \code{False}.


\subsection{Starting the Game}
\label{pong:id1}
Add a call to \code{sge.game.start()} at the end, under a check for the
value of \code{\_\_name\_\_}.


\section{The Final Result}
\label{pong:the-final-result}
You should now have a script that looks something like this:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{c+ch}{\PYGZsh{}!/usr/bin/env python3}

\PYG{c+c1}{\PYGZsh{} Pong Example}
\PYG{c+c1}{\PYGZsh{} Written in 2013\PYGZhy{}2015 by Julie Marchant \PYGZlt{}onpon4@riseup.net\PYGZgt{}}
\PYG{c+c1}{\PYGZsh{}}
\PYG{c+c1}{\PYGZsh{} To the extent possible under law, the author(s) have dedicated all}
\PYG{c+c1}{\PYGZsh{} copyright and related and neighboring rights to this software to the}
\PYG{c+c1}{\PYGZsh{} public domain worldwide. This software is distributed without any}
\PYG{c+c1}{\PYGZsh{} warranty.}
\PYG{c+c1}{\PYGZsh{}}
\PYG{c+c1}{\PYGZsh{} You should have received a copy of the CC0 Public Domain Dedication}
\PYG{c+c1}{\PYGZsh{} along with this software. If not, see}
\PYG{c+c1}{\PYGZsh{} \PYGZlt{}http://creativecommons.org/publicdomain/zero/1.0/\PYGZgt{}.}

\PYG{k+kn}{import} \PYG{n+nn}{random}

\PYG{k+kn}{import} \PYG{n+nn}{sge}

\PYG{n}{PADDLE\PYGZus{}XOFFSET} \PYG{o}{=} \PYG{l+m+mi}{32}
\PYG{n}{PADDLE\PYGZus{}SPEED} \PYG{o}{=} \PYG{l+m+mi}{4}
\PYG{n}{PADDLE\PYGZus{}VERTICAL\PYGZus{}FORCE} \PYG{o}{=} \PYG{l+m+mi}{1} \PYG{o}{/} \PYG{l+m+mi}{12}
\PYG{n}{BALL\PYGZus{}START\PYGZus{}SPEED} \PYG{o}{=} \PYG{l+m+mi}{2}
\PYG{n}{BALL\PYGZus{}ACCELERATION} \PYG{o}{=} \PYG{l+m+mf}{0.2}
\PYG{n}{BALL\PYGZus{}MAX\PYGZus{}SPEED} \PYG{o}{=} \PYG{l+m+mi}{15}


\PYG{k}{class} \PYG{n+nc}{Game}\PYG{p}{(}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{dsp}\PYG{o}{.}\PYG{n}{Game}\PYG{p}{)}\PYG{p}{:}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}key\PYGZus{}press}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{key}\PYG{p}{,} \PYG{n}{char}\PYG{p}{)}\PYG{p}{:}
        \PYG{k}{global} \PYG{n}{game\PYGZus{}in\PYGZus{}progress}

        \PYG{k}{if} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{f8}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
            \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Sprite}\PYG{o}{.}\PYG{n}{from\PYGZus{}screenshot}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{save}\PYG{p}{(}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{screenshot.jpg}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{)}
        \PYG{k}{elif} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{f11}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{fullscreen} \PYG{o}{=} \PYG{o+ow}{not} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{fullscreen}
        \PYG{k}{elif} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{escape}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{event\PYGZus{}close}\PYG{p}{(}\PYG{p}{)}
        \PYG{k}{elif} \PYG{n}{key} \PYG{o+ow}{in} \PYG{p}{(}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{p}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{enter}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{)}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{pause}\PYG{p}{(}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}close}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{)}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{end}\PYG{p}{(}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}paused\PYGZus{}key\PYGZus{}press}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{key}\PYG{p}{,} \PYG{n}{char}\PYG{p}{)}\PYG{p}{:}
        \PYG{k}{if} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{escape}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
            \PYG{c+c1}{\PYGZsh{} This allows the player to still exit while the game is}
            \PYG{c+c1}{\PYGZsh{} paused, rather than having to unpause first.}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{event\PYGZus{}close}\PYG{p}{(}\PYG{p}{)}
        \PYG{k}{else}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{unpause}\PYG{p}{(}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}paused\PYGZus{}close}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{)}\PYG{p}{:}
        \PYG{c+c1}{\PYGZsh{} This allows the player to still exit while the game is paused,}
        \PYG{c+c1}{\PYGZsh{} rather than having to unpause first.}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{event\PYGZus{}close}\PYG{p}{(}\PYG{p}{)}


\PYG{k}{class} \PYG{n+nc}{Player}\PYG{p}{(}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{dsp}\PYG{o}{.}\PYG{n}{Object}\PYG{p}{)}\PYG{p}{:}

    \PYG{k}{def} \PYG{n+nf}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{player}\PYG{p}{)}\PYG{p}{:}
        \PYG{k}{if} \PYG{n}{player} \PYG{o}{==} \PYG{l+m+mi}{1}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{up\PYGZus{}key} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{w}\PYG{l+s+s2}{\PYGZdq{}}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{down\PYGZus{}key} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{s}\PYG{l+s+s2}{\PYGZdq{}}
            \PYG{n}{x} \PYG{o}{=} \PYG{n}{PADDLE\PYGZus{}XOFFSET}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{hit\PYGZus{}direction} \PYG{o}{=} \PYG{l+m+mi}{1}
        \PYG{k}{else}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{up\PYGZus{}key} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{up}\PYG{l+s+s2}{\PYGZdq{}}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{down\PYGZus{}key} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{down}\PYG{l+s+s2}{\PYGZdq{}}
            \PYG{n}{x} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{width} \PYG{o}{\PYGZhy{}} \PYG{n}{PADDLE\PYGZus{}XOFFSET}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{hit\PYGZus{}direction} \PYG{o}{=} \PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1}

        \PYG{n}{y} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{height} \PYG{o}{/} \PYG{l+m+mi}{2}
        \PYG{n+nb}{super}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(}\PYG{n}{x}\PYG{p}{,} \PYG{n}{y}\PYG{p}{,} \PYG{n}{sprite}\PYG{o}{=}\PYG{n}{paddle\PYGZus{}sprite}\PYG{p}{,} \PYG{n}{checks\PYGZus{}collisions}\PYG{o}{=}\PYG{n+nb+bp}{False}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}step}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{time\PYGZus{}passed}\PYG{p}{,} \PYG{n}{delta\PYGZus{}mult}\PYG{p}{)}\PYG{p}{:}
        \PYG{c+c1}{\PYGZsh{} Movement}
        \PYG{n}{key\PYGZus{}motion} \PYG{o}{=} \PYG{p}{(}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{keyboard}\PYG{o}{.}\PYG{n}{get\PYGZus{}pressed}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{down\PYGZus{}key}\PYG{p}{)} \PYG{o}{\PYGZhy{}}
                      \PYG{n}{sge}\PYG{o}{.}\PYG{n}{keyboard}\PYG{o}{.}\PYG{n}{get\PYGZus{}pressed}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{up\PYGZus{}key}\PYG{p}{)}\PYG{p}{)}

        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{n}{key\PYGZus{}motion} \PYG{o}{*} \PYG{n}{PADDLE\PYGZus{}SPEED}

        \PYG{c+c1}{\PYGZsh{} Keep the paddle inside the window}
        \PYG{k}{if} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}top} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{0}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}top} \PYG{o}{=} \PYG{l+m+mi}{0}
        \PYG{k}{elif} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}bottom} \PYG{o}{\PYGZgt{}} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{height}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}bottom} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{height}


\PYG{k}{class} \PYG{n+nc}{Ball}\PYG{p}{(}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{dsp}\PYG{o}{.}\PYG{n}{Object}\PYG{p}{)}\PYG{p}{:}

    \PYG{k}{def} \PYG{n+nf}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{)}\PYG{p}{:}
        \PYG{n}{x} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{width} \PYG{o}{/} \PYG{l+m+mi}{2}
        \PYG{n}{y} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{height} \PYG{o}{/} \PYG{l+m+mi}{2}
        \PYG{n+nb}{super}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(}\PYG{n}{x}\PYG{p}{,} \PYG{n}{y}\PYG{p}{,} \PYG{n}{sprite}\PYG{o}{=}\PYG{n}{ball\PYGZus{}sprite}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}create}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{)}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{serve}\PYG{p}{(}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}step}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{time\PYGZus{}passed}\PYG{p}{,} \PYG{n}{delta\PYGZus{}mult}\PYG{p}{)}\PYG{p}{:}
        \PYG{c+c1}{\PYGZsh{} Scoring}
        \PYG{k}{if} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}right} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{0}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{serve}\PYG{p}{(}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1}\PYG{p}{)}
        \PYG{k}{elif} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}left} \PYG{o}{\PYGZgt{}} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{width}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{serve}\PYG{p}{(}\PYG{l+m+mi}{1}\PYG{p}{)}

        \PYG{c+c1}{\PYGZsh{} Bouncing off of the edges}
        \PYG{k}{if} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}bottom} \PYG{o}{\PYGZgt{}} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{height}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}bottom} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{height}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{o}{\PYGZhy{}}\PYG{n+nb}{abs}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity}\PYG{p}{)}
        \PYG{k}{elif} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}top} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{0}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}top} \PYG{o}{=} \PYG{l+m+mi}{0}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{n+nb}{abs}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}collision}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{other}\PYG{p}{,} \PYG{n}{xdirection}\PYG{p}{,} \PYG{n}{ydirection}\PYG{p}{)}\PYG{p}{:}
        \PYG{k}{if} \PYG{n+nb}{isinstance}\PYG{p}{(}\PYG{n}{other}\PYG{p}{,} \PYG{n}{Player}\PYG{p}{)}\PYG{p}{:}
            \PYG{k}{if} \PYG{n}{other}\PYG{o}{.}\PYG{n}{hit\PYGZus{}direction} \PYG{o}{==} \PYG{l+m+mi}{1}\PYG{p}{:}
                \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}left} \PYG{o}{=} \PYG{n}{other}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}right} \PYG{o}{+} \PYG{l+m+mi}{1}
            \PYG{k}{else}\PYG{p}{:}
                \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}right} \PYG{o}{=} \PYG{n}{other}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}left} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1}

            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xvelocity} \PYG{o}{=} \PYG{n+nb}{min}\PYG{p}{(}\PYG{n+nb}{abs}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xvelocity}\PYG{p}{)} \PYG{o}{+} \PYG{n}{BALL\PYGZus{}ACCELERATION}\PYG{p}{,}
                                 \PYG{n}{BALL\PYGZus{}MAX\PYGZus{}SPEED}\PYG{p}{)} \PYG{o}{*} \PYG{n}{other}\PYG{o}{.}\PYG{n}{hit\PYGZus{}direction}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{+}\PYG{o}{=} \PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{y} \PYG{o}{\PYGZhy{}} \PYG{n}{other}\PYG{o}{.}\PYG{n}{y}\PYG{p}{)} \PYG{o}{*} \PYG{n}{PADDLE\PYGZus{}VERTICAL\PYGZus{}FORCE}

    \PYG{k}{def} \PYG{n+nf}{serve}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{direction}\PYG{o}{=}\PYG{n+nb+bp}{None}\PYG{p}{)}\PYG{p}{:}
        \PYG{k}{if} \PYG{n}{direction} \PYG{o+ow}{is} \PYG{n+nb+bp}{None}\PYG{p}{:}
            \PYG{n}{direction} \PYG{o}{=} \PYG{n}{random}\PYG{o}{.}\PYG{n}{choice}\PYG{p}{(}\PYG{p}{[}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1}\PYG{p}{,} \PYG{l+m+mi}{1}\PYG{p}{]}\PYG{p}{)}

        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{x} \PYG{o}{=} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xstart}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{y} \PYG{o}{=} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{ystart}

        \PYG{c+c1}{\PYGZsh{} Next round}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xvelocity} \PYG{o}{=} \PYG{n}{BALL\PYGZus{}START\PYGZus{}SPEED} \PYG{o}{*} \PYG{n}{direction}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{l+m+mi}{0}


\PYG{c+c1}{\PYGZsh{} Create Game object}
\PYG{n}{Game}\PYG{p}{(}\PYG{n}{width}\PYG{o}{=}\PYG{l+m+mi}{640}\PYG{p}{,} \PYG{n}{height}\PYG{o}{=}\PYG{l+m+mi}{480}\PYG{p}{,} \PYG{n}{fps}\PYG{o}{=}\PYG{l+m+mi}{120}\PYG{p}{,} \PYG{n}{window\PYGZus{}text}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Pong}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}

\PYG{c+c1}{\PYGZsh{} Load sprites}
\PYG{n}{paddle\PYGZus{}sprite} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Sprite}\PYG{p}{(}\PYG{n}{width}\PYG{o}{=}\PYG{l+m+mi}{8}\PYG{p}{,} \PYG{n}{height}\PYG{o}{=}\PYG{l+m+mi}{48}\PYG{p}{,} \PYG{n}{origin\PYGZus{}x}\PYG{o}{=}\PYG{l+m+mi}{4}\PYG{p}{,} \PYG{n}{origin\PYGZus{}y}\PYG{o}{=}\PYG{l+m+mi}{24}\PYG{p}{)}
\PYG{n}{ball\PYGZus{}sprite} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Sprite}\PYG{p}{(}\PYG{n}{width}\PYG{o}{=}\PYG{l+m+mi}{8}\PYG{p}{,} \PYG{n}{height}\PYG{o}{=}\PYG{l+m+mi}{8}\PYG{p}{,} \PYG{n}{origin\PYGZus{}x}\PYG{o}{=}\PYG{l+m+mi}{4}\PYG{p}{,} \PYG{n}{origin\PYGZus{}y}\PYG{o}{=}\PYG{l+m+mi}{4}\PYG{p}{)}
\PYG{n}{paddle\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}rectangle}\PYG{p}{(}\PYG{l+m+mi}{0}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n}{paddle\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{width}\PYG{p}{,} \PYG{n}{paddle\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{height}\PYG{p}{,}
                             \PYG{n}{fill}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{)}
\PYG{n}{ball\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}rectangle}\PYG{p}{(}\PYG{l+m+mi}{0}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n}{ball\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{width}\PYG{p}{,} \PYG{n}{ball\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{height}\PYG{p}{,}
                           \PYG{n}{fill}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{)}

\PYG{c+c1}{\PYGZsh{} Load backgrounds}
\PYG{n}{layers} \PYG{o}{=} \PYG{p}{[}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{BackgroundLayer}\PYG{p}{(}\PYG{n}{paddle\PYGZus{}sprite}\PYG{p}{,} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{width} \PYG{o}{/} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{10000}\PYG{p}{,}
                                  \PYG{n}{repeat\PYGZus{}up}\PYG{o}{=}\PYG{n+nb+bp}{True}\PYG{p}{,} \PYG{n}{repeat\PYGZus{}down}\PYG{o}{=}\PYG{n+nb+bp}{True}\PYG{p}{)}\PYG{p}{]}
\PYG{n}{background} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Background}\PYG{p}{(}\PYG{n}{layers}\PYG{p}{,} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{black}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{)}

\PYG{c+c1}{\PYGZsh{} Create objects}
\PYG{n}{player1} \PYG{o}{=} \PYG{n}{Player}\PYG{p}{(}\PYG{l+m+mi}{1}\PYG{p}{)}
\PYG{n}{player2} \PYG{o}{=} \PYG{n}{Player}\PYG{p}{(}\PYG{l+m+mi}{2}\PYG{p}{)}
\PYG{n}{ball} \PYG{o}{=} \PYG{n}{Ball}\PYG{p}{(}\PYG{p}{)}
\PYG{n}{objects} \PYG{o}{=} \PYG{p}{[}\PYG{n}{player1}\PYG{p}{,} \PYG{n}{player2}\PYG{p}{,} \PYG{n}{ball}\PYG{p}{]}

\PYG{c+c1}{\PYGZsh{} Create rooms}
\PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{start\PYGZus{}room} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{dsp}\PYG{o}{.}\PYG{n}{Room}\PYG{p}{(}\PYG{n}{objects}\PYG{p}{,} \PYG{n}{background}\PYG{o}{=}\PYG{n}{background}\PYG{p}{)}

\PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{mouse}\PYG{o}{.}\PYG{n}{visible} \PYG{o}{=} \PYG{n+nb+bp}{False}


\PYG{k}{if} \PYG{n}{\PYGZus{}\PYGZus{}name\PYGZus{}\PYGZus{}} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{\PYGZus{}\PYGZus{}main\PYGZus{}\PYGZus{}}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
    \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{start}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}

This is a basically complete Pong game, but it lacks some features.
First, this game doesn't keep track of the score.  It is left up to the
players to keep track of who is winning.  Second, there is no sound.  We
should fix both of these problems.

Additionally, it would be nice if our game could support joystick input.

In the next tutorial, we will improve on these points to make a Pong
game more on par with Atari's original Pong.


\chapter{Tutorial 3: Better Pong}
\label{pong_better::doc}\label{pong_better:tutorial-3-better-pong}\setbox0\vbox{
\begin{minipage}{0.95\linewidth}
\textbf{Contents}

\medskip

\begin{itemize}
\item {} 
\phantomsection\label{pong_better:id1}{\hyperref[pong_better:tutorial\string-3\string-better\string-pong]{\emph{Tutorial 3: Better Pong}}}
\begin{itemize}
\item {} 
\phantomsection\label{pong_better:id2}{\hyperref[pong_better:adding\string-scoring]{\emph{Adding Scoring}}}
\begin{itemize}
\item {} 
\phantomsection\label{pong_better:id3}{\hyperref[pong_better:making\string-enter\string-restart\string-the\string-game]{\emph{Making Enter Restart the Game}}}

\item {} 
\phantomsection\label{pong_better:id4}{\hyperref[pong_better:giving\string-points\string-to\string-the\string-players]{\emph{Giving Points to the Players}}}

\item {} 
\phantomsection\label{pong_better:id5}{\hyperref[pong_better:displaying\string-the\string-scores]{\emph{Displaying the Scores}}}
\begin{itemize}
\item {} 
\phantomsection\label{pong_better:id6}{\hyperref[pong_better:new\string-resources]{\emph{New Resources}}}

\item {} 
\phantomsection\label{pong_better:id7}{\hyperref[pong_better:drawing\string-the\string-hud]{\emph{Drawing the HUD}}}

\item {} 
\phantomsection\label{pong_better:id8}{\hyperref[pong_better:displaying\string-the\string-hud]{\emph{Displaying the HUD}}}

\end{itemize}

\item {} 
\phantomsection\label{pong_better:id9}{\hyperref[pong_better:giving\string-victory]{\emph{Giving Victory}}}

\end{itemize}

\item {} 
\phantomsection\label{pong_better:id10}{\hyperref[pong_better:adding\string-sounds]{\emph{Adding Sounds}}}
\begin{itemize}
\item {} 
\phantomsection\label{pong_better:id11}{\hyperref[pong_better:getting\string-the\string-sounds]{\emph{Getting the Sounds}}}

\item {} 
\phantomsection\label{pong_better:id12}{\hyperref[pong_better:loading\string-the\string-sounds]{\emph{Loading the Sounds}}}

\item {} 
\phantomsection\label{pong_better:id13}{\hyperref[pong_better:playing\string-the\string-sounds]{\emph{Playing the Sounds}}}

\end{itemize}

\item {} 
\phantomsection\label{pong_better:id14}{\hyperref[pong_better:adding\string-joystick\string-support]{\emph{Adding Joystick Support}}}
\begin{itemize}
\item {} 
\phantomsection\label{pong_better:id15}{\hyperref[pong_better:axis\string-movement]{\emph{Axis Movement}}}

\item {} 
\phantomsection\label{pong_better:id16}{\hyperref[pong_better:trackball\string-movement]{\emph{Trackball Movement}}}

\item {} 
\phantomsection\label{pong_better:id17}{\hyperref[pong_better:applying\string-the\string-joystick\string-controls]{\emph{Applying the Joystick Controls}}}

\end{itemize}

\item {} 
\phantomsection\label{pong_better:id18}{\hyperref[pong_better:the\string-final\string-result]{\emph{The Final Result}}}

\end{itemize}

\end{itemize}
\end{minipage}}
\begin{center}\setlength{\fboxsep}{5pt}\shadowbox{\box0}\end{center}

In the last tutorial, we made a simple Pong game that was kind of
boring.  We're going to make it better by adding scores, sounds, and
joystick support.


\section{Adding Scoring}
\label{pong_better:adding-scoring}
Adding a score system will make our Pong game feel more like a game and
less like a toy.  Every time a player wins a round, they will get one
point.  When a player gets ten points, they will win the game, and a new
game can be started by pressing the Enter key.


\subsection{Making Enter Restart the Game}
\label{pong_better:making-enter-restart-the-game}
We are going to need a new global variable: \code{game\_in\_progress}.
This variable will indicate whether or not a game is currently going and
will be used to determine whether to start a new game or pause when the
Enter key is pressed.  Set it to \code{True} by default.

To make pressing Enter start a new game, we will check
\code{game\_in\_progress}.  If a game is in progress, we will pause the
game, as we had it do previously.  Otherwise, we will set
\code{game\_in\_progress} to \code{True} and restart the room.

If you look through the documentation for {\hyperref[dsp:sge.dsp.Room]{\emph{\code{sge.dsp.Room}}}}, you may
notice that no ``restart'' method exists. In fact, this is a design
choice; earlier versions of the SGE did have a method to restart rooms,
but it was removed because this feature is overly difficult to maintain
properly.  But how do we restart the room, then? Well, we technically
don't.  Instead, we create a new room which is exactly like the one we
wanted to restart, and immediately start it.  We will put the creation
of the room into a new function, \code{create\_room()}.  Our definition of
\code{Game.event\_key\_press()} becomes:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{event\PYGZus{}key\PYGZus{}press}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{key}\PYG{p}{,} \PYG{n}{char}\PYG{p}{)}\PYG{p}{:}
    \PYG{k}{global} \PYG{n}{game\PYGZus{}in\PYGZus{}progress}

    \PYG{k}{if} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{f8}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
        \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Sprite}\PYG{o}{.}\PYG{n}{from\PYGZus{}screenshot}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{save}\PYG{p}{(}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{screenshot.jpg}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{)}
    \PYG{k}{elif} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{f11}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{fullscreen} \PYG{o}{=} \PYG{o+ow}{not} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{fullscreen}
    \PYG{k}{elif} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{escape}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{event\PYGZus{}close}\PYG{p}{(}\PYG{p}{)}
    \PYG{k}{elif} \PYG{n}{key} \PYG{o+ow}{in} \PYG{p}{(}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{p}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{enter}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{)}\PYG{p}{:}
        \PYG{k}{if} \PYG{n}{game\PYGZus{}in\PYGZus{}progress}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{pause}\PYG{p}{(}\PYG{p}{)}
        \PYG{k}{else}\PYG{p}{:}
            \PYG{n}{game\PYGZus{}in\PYGZus{}progress} \PYG{o}{=} \PYG{n+nb+bp}{True}
            \PYG{n}{create\PYGZus{}room}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{start}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}

Now, we need to define \code{create\_room()}.  This is very simple; we
just copy and paste the code we used at the bottom to create the room
into it, but specify that \code{player} and \code{player2} are global.
Our function is as follows:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{create\PYGZus{}room}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
    \PYG{k}{global} \PYG{n}{player1}
    \PYG{k}{global} \PYG{n}{player2}
    \PYG{n}{player1} \PYG{o}{=} \PYG{n}{Player}\PYG{p}{(}\PYG{l+m+mi}{1}\PYG{p}{)}
    \PYG{n}{player2} \PYG{o}{=} \PYG{n}{Player}\PYG{p}{(}\PYG{l+m+mi}{2}\PYG{p}{)}
    \PYG{n}{ball} \PYG{o}{=} \PYG{n}{Ball}\PYG{p}{(}\PYG{p}{)}
    \PYG{k}{return} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{dsp}\PYG{o}{.}\PYG{n}{Room}\PYG{p}{(}\PYG{p}{[}\PYG{n}{player1}\PYG{p}{,} \PYG{n}{player2}\PYG{p}{,} \PYG{n}{ball}\PYG{p}{]}\PYG{p}{,} \PYG{n}{background}\PYG{o}{=}\PYG{n}{background}\PYG{p}{)}
\end{Verbatim}

Of course, this makes the identical code at the bottom redundant, so we
will replace it with a call to \code{create\_room()}.


\subsection{Giving Points to the Players}
\label{pong_better:giving-points-to-the-players}
We now need to add score attributes to the \code{Player} objects.  We
will initialize the new attribute, \code{score}, in
\code{Player.event\_create()} as \code{0}.

Now, in \code{Ball.event\_step()}, add lines to increase
\code{player1.score} and \code{player2.score} whenever the respective
player wins a round.


\subsection{Displaying the Scores}
\label{pong_better:displaying-the-scores}
The players have points, but can't see the score!  We need to add a HUD
(heads-up display) to show the score to the players.

There are a couple of ways we can do this.  Most obviously, we can use
{\hyperref[dsp:sge.dsp.Game.project_text]{\emph{\code{sge.dsp.Game.project\_text()}}}} or {\hyperref[dsp:sge.dsp.Room.project_text]{\emph{\code{sge.dsp.Room.project\_text()}}}}.
However, there is a much better way: have a dynamically generated sprite
that represents the look of the HUD at any given time, and displaying
that sprite.


\subsubsection{New Resources}
\label{pong_better:new-resources}
We need to add a new global variable called \code{hud\_sprite}.  Assign
a new sprite to this variable with a \code{width} of \code{320}, a
\code{height} of \code{120}, an \code{origin\_x} of \code{160}, and an
\code{origin\_y} of \code{0}.

To draw text, we need a font.  Create a new {\hyperref[gfx:sge.gfx.Font]{\emph{\code{sge.gfx.Font}}}} object
and assign it to \code{hud\_font}.  For now, we will use a system font.
I am choosing \code{"Droid Sans Mono"}, but you can choose whatever font
you prefer.  Pass your choice as the first argument to
{\hyperref[gfx:sge.gfx.Font.__init__]{\emph{\code{sge.gfx.Font.\_\_init\_\_()}}}}.  Set the \code{size} keyword argument to
\code{48}.

\begin{notice}{note}{Note:}
We are using system fonts for simplicity, but it is generally a bad
idea to rely on them.  There is no standard for what fonts are
available on the system, and the set of fonts available on the system
varies widely.  In real projects, it is better to distribute a font
file with the game and use that.
\end{notice}


\subsubsection{Drawing the HUD}
\label{pong_better:drawing-the-hud}
There are a few times we need to redraw the HUD: when the game starts,
when player 1 scores, and when player 2 scores.  Therefore, we will put
the redrawing code into a function, \code{refresh\_hud()}.  This function
needs to clear the HUD sprite, draw Player 1's score, and then draw
Player 2's score.

Another constant is needed: \code{TEXT\_OFFSET}, which we will define
as \code{16}.

We clear the HUD sprite with {\hyperref[gfx:sge.gfx.Sprite.draw_clear]{\emph{\code{sge.gfx.Sprite.draw\_clear()}}}}.

To draw the text, we use {\hyperref[gfx:sge.gfx.Sprite.draw_text]{\emph{\code{sge.gfx.Sprite.draw\_text()}}}}.  Both calls
have a few arguments in common: \code{font} is set to \code{hud\_font}, \code{y}
is set to \code{TEXT\_OFFSET}, \code{color} is set to white, and \code{valign} is
set to \code{"top"}.

The rest of the arguments are different between the two.  \code{text} is
set to the respective player's score, converted to a string.  \code{x} is
set to \code{hud\_sprite.width / 2 - TEXT\_OFFSET} for player 1's score, and
\code{hud\_sprite.width / 2 + TEXT\_OFFSET} for player 2's score.  \code{halign}
is set to \code{"right"} for player 1's score, and \code{"left"} for
player 2's score.

\code{refresh\_hud()} ends up something like this:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{refresh\PYGZus{}hud}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
    \PYG{c+c1}{\PYGZsh{} This fixes the HUD sprite so that it displays the correct score.}
    \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}clear}\PYG{p}{(}\PYG{p}{)}
    \PYG{n}{x} \PYG{o}{=} \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{width} \PYG{o}{/} \PYG{l+m+mi}{2}
    \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}text}\PYG{p}{(}\PYG{n}{hud\PYGZus{}font}\PYG{p}{,} \PYG{n+nb}{str}\PYG{p}{(}\PYG{n}{player1}\PYG{o}{.}\PYG{n}{score}\PYG{p}{)}\PYG{p}{,} \PYG{n}{x} \PYG{o}{\PYGZhy{}} \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,}
                         \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,} \PYG{n}{color}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{,}
                         \PYG{n}{halign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{right}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{valign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{top}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}
    \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}text}\PYG{p}{(}\PYG{n}{hud\PYGZus{}font}\PYG{p}{,} \PYG{n+nb}{str}\PYG{p}{(}\PYG{n}{player2}\PYG{o}{.}\PYG{n}{score}\PYG{p}{)}\PYG{p}{,} \PYG{n}{x} \PYG{o}{+} \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,}
                         \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,} \PYG{n}{color}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{,}
                         \PYG{n}{halign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{left}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{valign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{top}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}
\end{Verbatim}

Add calls to \code{refresh\_hud()} in the three places where a
\code{Player.score} value changes, right after the change.  These
places are in \code{Player.event\_create()} and \code{Ball.event\_step()}.

we have one more problem.  \code{refresh\_hud()} requires \code{player1}
and \code{player2} to each have an attribute called \code{score}, but
the first time it is called, one of the player objects has not had a
chance to initialize this attribute.  To work around this, add a class
attribute to \code{Player} called \code{score}, and set it to \code{0}.
This will cause \code{player1.score} and \code{player2.score} to be
\code{0} in the event that the respective object's \code{score} has not
been initialized yet.


\subsubsection{Displaying the HUD}
\label{pong_better:displaying-the-hud}
At this point, we have our HUD, but it isn't displayed.  We will fix
this simply by adding a step event to \code{Game} which projects the
HUD sprite onto the screen:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{event\PYGZus{}step}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{time\PYGZus{}passed}\PYG{p}{,} \PYG{n}{delta\PYGZus{}mult}\PYG{p}{)}\PYG{p}{:}
    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{project\PYGZus{}sprite}\PYG{p}{(}\PYG{n}{hud\PYGZus{}sprite}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{width} \PYG{o}{/} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{)}
\end{Verbatim}

Unlike {\hyperref[dsp:sge.dsp.Room]{\emph{\code{sge.dsp.Room}}}} projections, {\hyperref[dsp:sge.dsp.Game]{\emph{\code{sge.dsp.Game}}}}
projections are relative to the screen.  Additionally, these projections
are always on top of everything else on the screen.  This is usually how
we want a HUD to be displayed, which is why we are using a
{\hyperref[dsp:sge.dsp.Game]{\emph{\code{sge.dsp.Game}}}} projection instead of a {\hyperref[dsp:sge.dsp.Room]{\emph{\code{sge.dsp.Room}}}}
projection or {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} object.

\begin{notice}{note}{Note:}
You may notice that, when you pause the game, the HUD disappears.
This is \emph{not} a bug! This happens because the step event doesn't
occur while the game is paused.  If you want the HUD to show up while
the game is paused, project it in the paused step event, defined by
{\hyperref[dsp:sge.dsp.Game.event_paused_step]{\emph{\code{sge.dsp.Game.event\_paused\_step()}}}}, as well.
\end{notice}


\subsection{Giving Victory}
\label{pong_better:giving-victory}
At this point, we have scores, but no one ever officially wins.  We need
to end the game when someone gets 10 points.  We will go a little
further and replace the scores with text that says ``WIN'' and ``LOSE'' for
the winner and loser, respectively.

Define a new constant called \code{POINTS\_TO\_WIN} as \code{10}.

In our case, the most convenient place to check for victory is within
\code{Ball.serve()}.  Specifically, put the code that sets the speed of
the ball under a conditional that checks whether the \code{score}
values of both players are less than \code{POINTS\_TO\_WIN}.  Add an
\code{else} block below that.  This is where a player has won the game.

Since the game is over, stop the movement of the ball by setting
\code{xvelocity} and \code{yvelocity} to \code{0}.  We don't want any
more scoring to happen.

Now, draw the new text onto the HUD.  We do this using the same call to
{\hyperref[gfx:sge.gfx.Sprite.draw_text]{\emph{\code{sge.gfx.Sprite.draw\_text()}}}} we used in \code{refresh\_hud()}, except
instead of drawing the scores converted to strings, we draw \code{"WIN"} or
\code{"LOSE"} depending on whether or not the respective player's score is
greater than the other player's score.

Finally, set \code{game\_in\_progress} to \code{False}.  Don't forget
to declare it with \code{global} first.

The new \code{Ball.serve()} looks something like this:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{serve}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{direction}\PYG{o}{=}\PYG{n+nb+bp}{None}\PYG{p}{)}\PYG{p}{:}
    \PYG{k}{global} \PYG{n}{game\PYGZus{}in\PYGZus{}progress}

    \PYG{k}{if} \PYG{n}{direction} \PYG{o+ow}{is} \PYG{n+nb+bp}{None}\PYG{p}{:}
        \PYG{n}{direction} \PYG{o}{=} \PYG{n}{random}\PYG{o}{.}\PYG{n}{choice}\PYG{p}{(}\PYG{p}{[}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1}\PYG{p}{,} \PYG{l+m+mi}{1}\PYG{p}{]}\PYG{p}{)}

    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{x} \PYG{o}{=} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xstart}
    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{y} \PYG{o}{=} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{ystart}

    \PYG{k}{if} \PYG{p}{(}\PYG{n}{player1}\PYG{o}{.}\PYG{n}{score} \PYG{o}{\PYGZlt{}} \PYG{n}{POINTS\PYGZus{}TO\PYGZus{}WIN} \PYG{o+ow}{and}
            \PYG{n}{player2}\PYG{o}{.}\PYG{n}{score} \PYG{o}{\PYGZlt{}} \PYG{n}{POINTS\PYGZus{}TO\PYGZus{}WIN}\PYG{p}{)}\PYG{p}{:}
        \PYG{c+c1}{\PYGZsh{} Next round}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xvelocity} \PYG{o}{=} \PYG{n}{BALL\PYGZus{}START\PYGZus{}SPEED} \PYG{o}{*} \PYG{n}{direction}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{l+m+mi}{0}
    \PYG{k}{else}\PYG{p}{:}
        \PYG{c+c1}{\PYGZsh{} Game Over!}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xvelocity} \PYG{o}{=} \PYG{l+m+mi}{0}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{l+m+mi}{0}
        \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}clear}\PYG{p}{(}\PYG{p}{)}
        \PYG{n}{x} \PYG{o}{=} \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{width} \PYG{o}{/} \PYG{l+m+mi}{2}
        \PYG{n}{p1text} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{WIN}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{if} \PYG{n}{player1}\PYG{o}{.}\PYG{n}{score} \PYG{o}{\PYGZgt{}} \PYG{n}{player2}\PYG{o}{.}\PYG{n}{score} \PYG{k}{else} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{LOSE}\PYG{l+s+s2}{\PYGZdq{}}
        \PYG{n}{p2text} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{WIN}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{if} \PYG{n}{player2}\PYG{o}{.}\PYG{n}{score} \PYG{o}{\PYGZgt{}} \PYG{n}{player1}\PYG{o}{.}\PYG{n}{score} \PYG{k}{else} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{LOSE}\PYG{l+s+s2}{\PYGZdq{}}
        \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}text}\PYG{p}{(}\PYG{n}{hud\PYGZus{}font}\PYG{p}{,} \PYG{n}{p1text}\PYG{p}{,} \PYG{n}{x} \PYG{o}{\PYGZhy{}} \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,}
                             \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,} \PYG{n}{color}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{,}
                             \PYG{n}{halign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{right}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{valign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{top}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}
        \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}text}\PYG{p}{(}\PYG{n}{hud\PYGZus{}font}\PYG{p}{,} \PYG{n}{p2text}\PYG{p}{,} \PYG{n}{x} \PYG{o}{+} \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,}
                             \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,} \PYG{n}{color}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{,}
                             \PYG{n}{halign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{left}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{valign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{top}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}
        \PYG{n}{game\PYGZus{}in\PYGZus{}progress} \PYG{o}{=} \PYG{n+nb+bp}{False}
\end{Verbatim}


\section{Adding Sounds}
\label{pong_better:adding-sounds}
We have a complete Pong game now, but it's still a little quiet.  Let's
make it more lively by adding some sounds.


\subsection{Getting the Sounds}
\label{pong_better:getting-the-sounds}
I would normally go to a database like \href{http://opengameart.org}{OpenGameArt} for sound effects, but in this case, we are
instead going to use a nice free/libre program called \href{http://www.drpetter.se/project\_sfxr.html}{Sfxr}.  This program makes it
easy to generate retro-sounding sound effects, so it's perfect for Pong
sounds.  Generate three sounds: one for the ball bouncing off a paddle
(``bounce.wav''), one for the ball bouncing off a wall
(``bounce\_wall.wav''), and one for the ball passing by a player
(``score.wav'').  Alternatively, you can copy the sounds I generated from
examples/data.  Create a folder in your project directory with the name
``data'' and put your sounds in this folder.

\begin{notice}{note}{Note:}
Some file systems, like FAT32 and NTFS, are case-insensitive and will
allow you to treat ``bounce.wav'' and ``Bounce.wav'' as if they are the
same file name, but some, such as pretty much every Linux file
system, are case-sensitive, meaning that ``bounce.wav'' and
``Bounce.wav'' are two completely different names; requesting one will
never give you the other.  If you have a case-insensitive file
system, be careful to not get the case wrong, or some people who play
the game will face a crash that will be completely invisible to you!
\end{notice}


\subsection{Loading the Sounds}
\label{pong_better:loading-the-sounds}
Sounds in the SGE are stored in {\hyperref[snd:sge.snd.Sound]{\emph{\code{sge.snd.Sound}}}} objects.  As the
only argument, indicate the full path to the file.  There are two ways
to indicate the path: using the current working directory as a base, and
using the directory of pong.py as a base.  Both of methods require the
\code{os} module, so be sure to add this to your list of imports.

The easiest way to get the path of the file is to use the current
working directory as a base, on the assumption that the current working
directory is also the directory that the ``data'' folder is located in.
This method is very simple; assuming we want the file called ``spam.wav'',
we would use this code:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{os}\PYG{o}{.}\PYG{n}{path}\PYG{o}{.}\PYG{n}{join}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{data}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{spam.wav}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}
\end{Verbatim}

However, it is not always the case that the current working directory is
the appropriate location to search for the ``data'' folder.  It could be
that the current working directory is the user's home directory, for
instance.  To prevent the game from crashing in this case, define a
constant called \code{DATA}, indicating the ``data'' directory relative
to the location of pong.py:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{DATA} \PYG{o}{=} \PYG{n}{os}\PYG{o}{.}\PYG{n}{path}\PYG{o}{.}\PYG{n}{join}\PYG{p}{(}\PYG{n}{os}\PYG{o}{.}\PYG{n}{path}\PYG{o}{.}\PYG{n}{dirname}\PYG{p}{(}\PYG{n}{\PYGZus{}\PYGZus{}file\PYGZus{}\PYGZus{}}\PYG{p}{)}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{data}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}
\end{Verbatim}

\code{\_\_file\_\_} is a special variable indicating the full path to the
current file, i.e. pong.py in this case.  By getting the directory name
of the current file, we can be certain of where to look for the ``data''
folder.  \code{DATA} now indicates the appropriate path to the ``data''
folder, so from now on, if we want a file called ``spam.wav'' located in
this directory, we use this code:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{os}\PYG{o}{.}\PYG{n}{path}\PYG{o}{.}\PYG{n}{join}\PYG{p}{(}\PYG{n}{DATA}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{spam.wav}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}
\end{Verbatim}

Assign the appropriate {\hyperref[snd:sge.snd.Sound]{\emph{\code{sge.snd.Sound}}}} objects to
\code{bounce\_sound}, \code{bounce\_wall\_sound}, and
\code{score\_sound}.


\subsection{Playing the Sounds}
\label{pong_better:playing-the-sounds}
Sounds are played with {\hyperref[snd:sge.snd.Sound.play]{\emph{\code{sge.snd.Sound.play()}}}}.  Call this method in
the appropriate places: when a player scores, when the ball bounces off
an edge of the screen, and when the ball hits a paddle.  There are five
places in total.

With that, our Pong game now has sound effects.


\section{Adding Joystick Support}
\label{pong_better:adding-joystick-support}
Joystick support is a nice thing to have in a game, so we are going to
add it.  We are going to support analog sticks and trackballs.  Mouse
control would actually be even better, but this would put one of the
players at an unfair advantage.

First, we will add an attribute to \code{Player} indicating what
joystick to use, called \code{joystick}.  Set it to \code{0} (which is the
first joystick) for player 1, and \code{1} (which is the second joystick)
for player 2.


\subsection{Axis Movement}
\label{pong_better:axis-movement}
Adding movement based on a joystick axis is easy.  For this, we use
{\hyperref[joystick:sge.joystick.get_axis]{\emph{\code{sge.joystick.get\_axis()}}}} in the step event of \code{Player}.
Pass \code{self.joystick} as the first argument, and \code{1} (which is the
Y-axis) as the second argument.  Assign it to a variable called
\code{axis\_motion}.  Later, we will be modifying the code that sets
\code{yvelocity} so that it is chosen based on axis position, trackball
movement, or key presses, whichever one would cause it to move fastest.


\subsection{Trackball Movement}
\label{pong_better:trackball-movement}
Since trackball motion is relative, it is a little trickier.  We need to
store the amount of movement it makes each frame.  We will use an
attribute called \code{trackball\_motion} for that; initialize it as
\code{0} in the create event.

We now need to define the trackball move event, which is defined by
{\hyperref[dsp:sge.dsp.Object.event_joystick_trackball_move]{\emph{\code{sge.dsp.Object.event\_joystick\_trackball\_move()}}}}.  Within this
event, if the \code{joystick} argument is the same as \code{self.joystick},
add \code{y} to \code{self.trackball\_motion}.  We are adding to it, rather
than replacing it, because the trackball might move multiple times in
the same frame.


\subsection{Applying the Joystick Controls}
\label{pong_better:applying-the-joystick-controls}
Currently, we have this line:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{n}{key\PYGZus{}motion} \PYG{o}{*} \PYG{n}{PADDLE\PYGZus{}SPEED}
\end{Verbatim}

This line uses the state of the keys to determine how to move the
paddle.  We need to change this so that the joystick controls we defined
can be used as well.  It will be replaced with the following:
\begin{itemize}
\item {} 
If the absolute value of \code{axis\_motion} is greater than the absolute
value of both \code{key\_motion} and \code{trackball\_motion}, set
\code{yvelocity} to \code{axis\_motion * PADDLE\_SPEED}.

\item {} 
Otherwise, if \code{trackball\_motion} is greater than \code{key\_motion},
set \code{yvelocity} to \code{self.trackball\_motion * PADDLE\_SPEED}

\item {} 
Otherwise, use the line we have been using up until this point.

\end{itemize}

After this, we must set \code{trackball\_motion} to \code{0}.


\section{The Final Result}
\label{pong_better:the-final-result}
Our final Pong game now has scores, sounds, and even joystick support:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{c+ch}{\PYGZsh{}!/usr/bin/env python3}

\PYG{c+c1}{\PYGZsh{} Pong Example}
\PYG{c+c1}{\PYGZsh{} Written in 2013\PYGZhy{}2015 by Julie Marchant \PYGZlt{}onpon4@riseup.net\PYGZgt{}}
\PYG{c+c1}{\PYGZsh{}}
\PYG{c+c1}{\PYGZsh{} To the extent possible under law, the author(s) have dedicated all}
\PYG{c+c1}{\PYGZsh{} copyright and related and neighboring rights to this software to the}
\PYG{c+c1}{\PYGZsh{} public domain worldwide. This software is distributed without any}
\PYG{c+c1}{\PYGZsh{} warranty.}
\PYG{c+c1}{\PYGZsh{}}
\PYG{c+c1}{\PYGZsh{} You should have received a copy of the CC0 Public Domain Dedication}
\PYG{c+c1}{\PYGZsh{} along with this software. If not, see}
\PYG{c+c1}{\PYGZsh{} \PYGZlt{}http://creativecommons.org/publicdomain/zero/1.0/\PYGZgt{}.}

\PYG{k+kn}{import} \PYG{n+nn}{random}

\PYG{k+kn}{import} \PYG{n+nn}{sge}

\PYG{n}{DATA} \PYG{o}{=} \PYG{n}{os}\PYG{o}{.}\PYG{n}{path}\PYG{o}{.}\PYG{n}{join}\PYG{p}{(}\PYG{n}{os}\PYG{o}{.}\PYG{n}{path}\PYG{o}{.}\PYG{n}{dirname}\PYG{p}{(}\PYG{n}{\PYGZus{}\PYGZus{}file\PYGZus{}\PYGZus{}}\PYG{p}{)}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{data}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}
\PYG{n}{PADDLE\PYGZus{}XOFFSET} \PYG{o}{=} \PYG{l+m+mi}{32}
\PYG{n}{PADDLE\PYGZus{}SPEED} \PYG{o}{=} \PYG{l+m+mi}{4}
\PYG{n}{PADDLE\PYGZus{}VERTICAL\PYGZus{}FORCE} \PYG{o}{=} \PYG{l+m+mi}{1} \PYG{o}{/} \PYG{l+m+mi}{12}
\PYG{n}{BALL\PYGZus{}START\PYGZus{}SPEED} \PYG{o}{=} \PYG{l+m+mi}{2}
\PYG{n}{BALL\PYGZus{}ACCELERATION} \PYG{o}{=} \PYG{l+m+mf}{0.2}
\PYG{n}{BALL\PYGZus{}MAX\PYGZus{}SPEED} \PYG{o}{=} \PYG{l+m+mi}{15}
\PYG{n}{POINTS\PYGZus{}TO\PYGZus{}WIN} \PYG{o}{=} \PYG{l+m+mi}{10}
\PYG{n}{TEXT\PYGZus{}OFFSET} \PYG{o}{=} \PYG{l+m+mi}{16}

\PYG{n}{game\PYGZus{}in\PYGZus{}progress} \PYG{o}{=} \PYG{n+nb+bp}{True}


\PYG{k}{class} \PYG{n+nc}{Game}\PYG{p}{(}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{dsp}\PYG{o}{.}\PYG{n}{Game}\PYG{p}{)}\PYG{p}{:}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}step}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{time\PYGZus{}passed}\PYG{p}{,} \PYG{n}{delta\PYGZus{}mult}\PYG{p}{)}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{project\PYGZus{}sprite}\PYG{p}{(}\PYG{n}{hud\PYGZus{}sprite}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{width} \PYG{o}{/} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}key\PYGZus{}press}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{key}\PYG{p}{,} \PYG{n}{char}\PYG{p}{)}\PYG{p}{:}
        \PYG{k}{global} \PYG{n}{game\PYGZus{}in\PYGZus{}progress}

        \PYG{k}{if} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{f8}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
            \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Sprite}\PYG{o}{.}\PYG{n}{from\PYGZus{}screenshot}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{save}\PYG{p}{(}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{screenshot.jpg}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{)}
        \PYG{k}{elif} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{f11}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{fullscreen} \PYG{o}{=} \PYG{o+ow}{not} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{fullscreen}
        \PYG{k}{elif} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{escape}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{event\PYGZus{}close}\PYG{p}{(}\PYG{p}{)}
        \PYG{k}{elif} \PYG{n}{key} \PYG{o+ow}{in} \PYG{p}{(}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{p}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{,} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{enter}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{)}\PYG{p}{:}
            \PYG{k}{if} \PYG{n}{game\PYGZus{}in\PYGZus{}progress}\PYG{p}{:}
                \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{pause}\PYG{p}{(}\PYG{p}{)}
            \PYG{k}{else}\PYG{p}{:}
                \PYG{n}{game\PYGZus{}in\PYGZus{}progress} \PYG{o}{=} \PYG{n+nb+bp}{True}
                \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{start}\PYG{p}{(}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}close}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{)}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{end}\PYG{p}{(}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}paused\PYGZus{}key\PYGZus{}press}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{key}\PYG{p}{,} \PYG{n}{char}\PYG{p}{)}\PYG{p}{:}
        \PYG{k}{if} \PYG{n}{key} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{escape}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
            \PYG{c+c1}{\PYGZsh{} This allows the player to still exit while the game is}
            \PYG{c+c1}{\PYGZsh{} paused, rather than having to unpause first.}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{event\PYGZus{}close}\PYG{p}{(}\PYG{p}{)}
        \PYG{k}{else}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{unpause}\PYG{p}{(}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}paused\PYGZus{}close}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{)}\PYG{p}{:}
        \PYG{c+c1}{\PYGZsh{} This allows the player to still exit while the game is paused,}
        \PYG{c+c1}{\PYGZsh{} rather than having to unpause first.}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{event\PYGZus{}close}\PYG{p}{(}\PYG{p}{)}


\PYG{k}{class} \PYG{n+nc}{Player}\PYG{p}{(}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{dsp}\PYG{o}{.}\PYG{n}{Object}\PYG{p}{)}\PYG{p}{:}

    \PYG{n}{score} \PYG{o}{=} \PYG{l+m+mi}{0}

    \PYG{k}{def} \PYG{n+nf}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{player}\PYG{p}{)}\PYG{p}{:}
        \PYG{k}{if} \PYG{n}{player} \PYG{o}{==} \PYG{l+m+mi}{1}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{joystick} \PYG{o}{=} \PYG{l+m+mi}{0}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{up\PYGZus{}key} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{w}\PYG{l+s+s2}{\PYGZdq{}}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{down\PYGZus{}key} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{s}\PYG{l+s+s2}{\PYGZdq{}}
            \PYG{n}{x} \PYG{o}{=} \PYG{n}{PADDLE\PYGZus{}XOFFSET}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{hit\PYGZus{}direction} \PYG{o}{=} \PYG{l+m+mi}{1}
        \PYG{k}{else}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{joystick} \PYG{o}{=} \PYG{l+m+mi}{1}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{up\PYGZus{}key} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{up}\PYG{l+s+s2}{\PYGZdq{}}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{down\PYGZus{}key} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{down}\PYG{l+s+s2}{\PYGZdq{}}
            \PYG{n}{x} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{width} \PYG{o}{\PYGZhy{}} \PYG{n}{PADDLE\PYGZus{}XOFFSET}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{hit\PYGZus{}direction} \PYG{o}{=} \PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1}

        \PYG{n}{y} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{height} \PYG{o}{/} \PYG{l+m+mi}{2}
        \PYG{n+nb}{super}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(}\PYG{n}{x}\PYG{p}{,} \PYG{n}{y}\PYG{p}{,} \PYG{n}{sprite}\PYG{o}{=}\PYG{n}{paddle\PYGZus{}sprite}\PYG{p}{,} \PYG{n}{checks\PYGZus{}collisions}\PYG{o}{=}\PYG{n+nb+bp}{False}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}create}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{)}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{score} \PYG{o}{=} \PYG{l+m+mi}{0}
        \PYG{n}{refresh\PYGZus{}hud}\PYG{p}{(}\PYG{p}{)}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{trackball\PYGZus{}motion} \PYG{o}{=} \PYG{l+m+mi}{0}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}step}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{time\PYGZus{}passed}\PYG{p}{,} \PYG{n}{delta\PYGZus{}mult}\PYG{p}{)}\PYG{p}{:}
        \PYG{c+c1}{\PYGZsh{} Movement}
        \PYG{n}{key\PYGZus{}motion} \PYG{o}{=} \PYG{p}{(}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{keyboard}\PYG{o}{.}\PYG{n}{get\PYGZus{}pressed}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{down\PYGZus{}key}\PYG{p}{)} \PYG{o}{\PYGZhy{}}
                      \PYG{n}{sge}\PYG{o}{.}\PYG{n}{keyboard}\PYG{o}{.}\PYG{n}{get\PYGZus{}pressed}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{up\PYGZus{}key}\PYG{p}{)}\PYG{p}{)}
        \PYG{n}{axis\PYGZus{}motion} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{joystick}\PYG{o}{.}\PYG{n}{get\PYGZus{}axis}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{joystick}\PYG{p}{,} \PYG{l+m+mi}{1}\PYG{p}{)}

        \PYG{k}{if} \PYG{p}{(}\PYG{n+nb}{abs}\PYG{p}{(}\PYG{n}{axis\PYGZus{}motion}\PYG{p}{)} \PYG{o}{\PYGZgt{}} \PYG{n+nb}{abs}\PYG{p}{(}\PYG{n}{key\PYGZus{}motion}\PYG{p}{)} \PYG{o+ow}{and}
                \PYG{n+nb}{abs}\PYG{p}{(}\PYG{n}{axis\PYGZus{}motion}\PYG{p}{)} \PYG{o}{\PYGZgt{}} \PYG{n+nb}{abs}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{trackball\PYGZus{}motion}\PYG{p}{)}\PYG{p}{)}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{n}{axis\PYGZus{}motion} \PYG{o}{*} \PYG{n}{PADDLE\PYGZus{}SPEED}
        \PYG{k}{elif} \PYG{n+nb}{abs}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{trackball\PYGZus{}motion}\PYG{p}{)} \PYG{o}{\PYGZgt{}} \PYG{n+nb}{abs}\PYG{p}{(}\PYG{n}{key\PYGZus{}motion}\PYG{p}{)}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{trackball\PYGZus{}motion} \PYG{o}{*} \PYG{n}{PADDLE\PYGZus{}SPEED}
        \PYG{k}{else}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{n}{key\PYGZus{}motion} \PYG{o}{*} \PYG{n}{PADDLE\PYGZus{}SPEED}

        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{trackball\PYGZus{}motion} \PYG{o}{=} \PYG{l+m+mi}{0}

        \PYG{c+c1}{\PYGZsh{} Keep the paddle inside the window}
        \PYG{k}{if} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}top} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{0}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}top} \PYG{o}{=} \PYG{l+m+mi}{0}
        \PYG{k}{elif} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}bottom} \PYG{o}{\PYGZgt{}} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{height}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}bottom} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{height}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}joystick\PYGZus{}trackball\PYGZus{}move}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{joystick}\PYG{p}{,} \PYG{n}{ball}\PYG{p}{,} \PYG{n}{x}\PYG{p}{,} \PYG{n}{y}\PYG{p}{)}\PYG{p}{:}
        \PYG{k}{if} \PYG{n}{joystick} \PYG{o}{==} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{joystick}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{trackball\PYGZus{}motion} \PYG{o}{+}\PYG{o}{=} \PYG{n}{y}


\PYG{k}{class} \PYG{n+nc}{Ball}\PYG{p}{(}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{dsp}\PYG{o}{.}\PYG{n}{Object}\PYG{p}{)}\PYG{p}{:}

    \PYG{k}{def} \PYG{n+nf}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{)}\PYG{p}{:}
        \PYG{n}{x} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{width} \PYG{o}{/} \PYG{l+m+mi}{2}
        \PYG{n}{y} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{height} \PYG{o}{/} \PYG{l+m+mi}{2}
        \PYG{n+nb}{super}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(}\PYG{n}{x}\PYG{p}{,} \PYG{n}{y}\PYG{p}{,} \PYG{n}{sprite}\PYG{o}{=}\PYG{n}{ball\PYGZus{}sprite}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}create}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{)}\PYG{p}{:}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{serve}\PYG{p}{(}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}step}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{time\PYGZus{}passed}\PYG{p}{,} \PYG{n}{delta\PYGZus{}mult}\PYG{p}{)}\PYG{p}{:}
        \PYG{c+c1}{\PYGZsh{} Scoring}
        \PYG{k}{if} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}right} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{0}\PYG{p}{:}
            \PYG{n}{player2}\PYG{o}{.}\PYG{n}{score} \PYG{o}{+}\PYG{o}{=} \PYG{l+m+mi}{1}
            \PYG{n}{refresh\PYGZus{}hud}\PYG{p}{(}\PYG{p}{)}
            \PYG{n}{score\PYGZus{}sound}\PYG{o}{.}\PYG{n}{play}\PYG{p}{(}\PYG{p}{)}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{serve}\PYG{p}{(}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1}\PYG{p}{)}
        \PYG{k}{elif} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}left} \PYG{o}{\PYGZgt{}} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{width}\PYG{p}{:}
            \PYG{n}{player1}\PYG{o}{.}\PYG{n}{score} \PYG{o}{+}\PYG{o}{=} \PYG{l+m+mi}{1}
            \PYG{n}{refresh\PYGZus{}hud}\PYG{p}{(}\PYG{p}{)}
            \PYG{n}{score\PYGZus{}sound}\PYG{o}{.}\PYG{n}{play}\PYG{p}{(}\PYG{p}{)}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{serve}\PYG{p}{(}\PYG{l+m+mi}{1}\PYG{p}{)}

        \PYG{c+c1}{\PYGZsh{} Bouncing off of the edges}
        \PYG{k}{if} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}bottom} \PYG{o}{\PYGZgt{}} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{height}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}bottom} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{height}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{o}{\PYGZhy{}}\PYG{n+nb}{abs}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity}\PYG{p}{)}
            \PYG{n}{bounce\PYGZus{}wall\PYGZus{}sound}\PYG{o}{.}\PYG{n}{play}\PYG{p}{(}\PYG{p}{)}
        \PYG{k}{elif} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}top} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{0}\PYG{p}{:}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}top} \PYG{o}{=} \PYG{l+m+mi}{0}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{n+nb}{abs}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity}\PYG{p}{)}
            \PYG{n}{bounce\PYGZus{}wall\PYGZus{}sound}\PYG{o}{.}\PYG{n}{play}\PYG{p}{(}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{event\PYGZus{}collision}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{other}\PYG{p}{,} \PYG{n}{xdirection}\PYG{p}{,} \PYG{n}{ydirection}\PYG{p}{)}\PYG{p}{:}
        \PYG{k}{if} \PYG{n+nb}{isinstance}\PYG{p}{(}\PYG{n}{other}\PYG{p}{,} \PYG{n}{Player}\PYG{p}{)}\PYG{p}{:}
            \PYG{k}{if} \PYG{n}{other}\PYG{o}{.}\PYG{n}{hit\PYGZus{}direction} \PYG{o}{==} \PYG{l+m+mi}{1}\PYG{p}{:}
                \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}left} \PYG{o}{=} \PYG{n}{other}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}right} \PYG{o}{+} \PYG{l+m+mi}{1}
            \PYG{k}{else}\PYG{p}{:}
                \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}right} \PYG{o}{=} \PYG{n}{other}\PYG{o}{.}\PYG{n}{bbox\PYGZus{}left} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1}

            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xvelocity} \PYG{o}{=} \PYG{n+nb}{min}\PYG{p}{(}\PYG{n+nb}{abs}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xvelocity}\PYG{p}{)} \PYG{o}{+} \PYG{n}{BALL\PYGZus{}ACCELERATION}\PYG{p}{,}
                                 \PYG{n}{BALL\PYGZus{}MAX\PYGZus{}SPEED}\PYG{p}{)} \PYG{o}{*} \PYG{n}{other}\PYG{o}{.}\PYG{n}{hit\PYGZus{}direction}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{+}\PYG{o}{=} \PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{y} \PYG{o}{\PYGZhy{}} \PYG{n}{other}\PYG{o}{.}\PYG{n}{y}\PYG{p}{)} \PYG{o}{*} \PYG{n}{PADDLE\PYGZus{}VERTICAL\PYGZus{}FORCE}
            \PYG{n}{bounce\PYGZus{}sound}\PYG{o}{.}\PYG{n}{play}\PYG{p}{(}\PYG{p}{)}

    \PYG{k}{def} \PYG{n+nf}{serve}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{direction}\PYG{o}{=}\PYG{n+nb+bp}{None}\PYG{p}{)}\PYG{p}{:}
        \PYG{k}{global} \PYG{n}{game\PYGZus{}in\PYGZus{}progress}

        \PYG{k}{if} \PYG{n}{direction} \PYG{o+ow}{is} \PYG{n+nb+bp}{None}\PYG{p}{:}
            \PYG{n}{direction} \PYG{o}{=} \PYG{n}{random}\PYG{o}{.}\PYG{n}{choice}\PYG{p}{(}\PYG{p}{[}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1}\PYG{p}{,} \PYG{l+m+mi}{1}\PYG{p}{]}\PYG{p}{)}

        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{x} \PYG{o}{=} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xstart}
        \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{y} \PYG{o}{=} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{ystart}

        \PYG{k}{if} \PYG{p}{(}\PYG{n}{player1}\PYG{o}{.}\PYG{n}{score} \PYG{o}{\PYGZlt{}} \PYG{n}{POINTS\PYGZus{}TO\PYGZus{}WIN} \PYG{o+ow}{and}
                \PYG{n}{player2}\PYG{o}{.}\PYG{n}{score} \PYG{o}{\PYGZlt{}} \PYG{n}{POINTS\PYGZus{}TO\PYGZus{}WIN}\PYG{p}{)}\PYG{p}{:}
            \PYG{c+c1}{\PYGZsh{} Next round}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xvelocity} \PYG{o}{=} \PYG{n}{BALL\PYGZus{}START\PYGZus{}SPEED} \PYG{o}{*} \PYG{n}{direction}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{l+m+mi}{0}
        \PYG{k}{else}\PYG{p}{:}
            \PYG{c+c1}{\PYGZsh{} Game Over!}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xvelocity} \PYG{o}{=} \PYG{l+m+mi}{0}
            \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{l+m+mi}{0}
            \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}clear}\PYG{p}{(}\PYG{p}{)}
            \PYG{n}{x} \PYG{o}{=} \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{width} \PYG{o}{/} \PYG{l+m+mi}{2}
            \PYG{n}{p1text} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{WIN}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{if} \PYG{n}{player1}\PYG{o}{.}\PYG{n}{score} \PYG{o}{\PYGZgt{}} \PYG{n}{player2}\PYG{o}{.}\PYG{n}{score} \PYG{k}{else} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{LOSE}\PYG{l+s+s2}{\PYGZdq{}}
            \PYG{n}{p2text} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{WIN}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{if} \PYG{n}{player2}\PYG{o}{.}\PYG{n}{score} \PYG{o}{\PYGZgt{}} \PYG{n}{player1}\PYG{o}{.}\PYG{n}{score} \PYG{k}{else} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{LOSE}\PYG{l+s+s2}{\PYGZdq{}}
            \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}text}\PYG{p}{(}\PYG{n}{hud\PYGZus{}font}\PYG{p}{,} \PYG{n}{p1text}\PYG{p}{,} \PYG{n}{x} \PYG{o}{\PYGZhy{}} \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,}
                                 \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,} \PYG{n}{color}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{,}
                                 \PYG{n}{halign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{right}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{valign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{top}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}
            \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}text}\PYG{p}{(}\PYG{n}{hud\PYGZus{}font}\PYG{p}{,} \PYG{n}{p2text}\PYG{p}{,} \PYG{n}{x} \PYG{o}{+} \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,}
                                 \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,} \PYG{n}{color}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{,}
                                 \PYG{n}{halign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{left}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{valign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{top}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}
            \PYG{n}{game\PYGZus{}in\PYGZus{}progress} \PYG{o}{=} \PYG{n+nb+bp}{False}


\PYG{k}{def} \PYG{n+nf}{create\PYGZus{}room}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
    \PYG{k}{global} \PYG{n}{player1}
    \PYG{k}{global} \PYG{n}{player2}
    \PYG{n}{player1} \PYG{o}{=} \PYG{n}{Player}\PYG{p}{(}\PYG{l+m+mi}{1}\PYG{p}{)}
    \PYG{n}{player2} \PYG{o}{=} \PYG{n}{Player}\PYG{p}{(}\PYG{l+m+mi}{2}\PYG{p}{)}
    \PYG{n}{ball} \PYG{o}{=} \PYG{n}{Ball}\PYG{p}{(}\PYG{p}{)}
    \PYG{k}{return} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{dsp}\PYG{o}{.}\PYG{n}{Room}\PYG{p}{(}\PYG{p}{[}\PYG{n}{player1}\PYG{p}{,} \PYG{n}{player2}\PYG{p}{,} \PYG{n}{ball}\PYG{p}{]}\PYG{p}{,} \PYG{n}{background}\PYG{o}{=}\PYG{n}{background}\PYG{p}{)}


\PYG{k}{def} \PYG{n+nf}{refresh\PYGZus{}hud}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
    \PYG{c+c1}{\PYGZsh{} This fixes the HUD sprite so that it displays the correct score.}
    \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}clear}\PYG{p}{(}\PYG{p}{)}
    \PYG{n}{x} \PYG{o}{=} \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{width} \PYG{o}{/} \PYG{l+m+mi}{2}
    \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}text}\PYG{p}{(}\PYG{n}{hud\PYGZus{}font}\PYG{p}{,} \PYG{n+nb}{str}\PYG{p}{(}\PYG{n}{player1}\PYG{o}{.}\PYG{n}{score}\PYG{p}{)}\PYG{p}{,} \PYG{n}{x} \PYG{o}{\PYGZhy{}} \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,}
                         \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,} \PYG{n}{color}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{,}
                         \PYG{n}{halign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{right}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{valign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{top}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}
    \PYG{n}{hud\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}text}\PYG{p}{(}\PYG{n}{hud\PYGZus{}font}\PYG{p}{,} \PYG{n+nb}{str}\PYG{p}{(}\PYG{n}{player2}\PYG{o}{.}\PYG{n}{score}\PYG{p}{)}\PYG{p}{,} \PYG{n}{x} \PYG{o}{+} \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,}
                         \PYG{n}{TEXT\PYGZus{}OFFSET}\PYG{p}{,} \PYG{n}{color}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{,}
                         \PYG{n}{halign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{left}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{valign}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{top}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}


\PYG{c+c1}{\PYGZsh{} Create Game object}
\PYG{n}{Game}\PYG{p}{(}\PYG{n}{width}\PYG{o}{=}\PYG{l+m+mi}{640}\PYG{p}{,} \PYG{n}{height}\PYG{o}{=}\PYG{l+m+mi}{480}\PYG{p}{,} \PYG{n}{fps}\PYG{o}{=}\PYG{l+m+mi}{120}\PYG{p}{,} \PYG{n}{window\PYGZus{}text}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Pong}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}

\PYG{c+c1}{\PYGZsh{} Load sprites}
\PYG{n}{paddle\PYGZus{}sprite} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Sprite}\PYG{p}{(}\PYG{n}{width}\PYG{o}{=}\PYG{l+m+mi}{8}\PYG{p}{,} \PYG{n}{height}\PYG{o}{=}\PYG{l+m+mi}{48}\PYG{p}{,} \PYG{n}{origin\PYGZus{}x}\PYG{o}{=}\PYG{l+m+mi}{4}\PYG{p}{,} \PYG{n}{origin\PYGZus{}y}\PYG{o}{=}\PYG{l+m+mi}{24}\PYG{p}{)}
\PYG{n}{ball\PYGZus{}sprite} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Sprite}\PYG{p}{(}\PYG{n}{width}\PYG{o}{=}\PYG{l+m+mi}{8}\PYG{p}{,} \PYG{n}{height}\PYG{o}{=}\PYG{l+m+mi}{8}\PYG{p}{,} \PYG{n}{origin\PYGZus{}x}\PYG{o}{=}\PYG{l+m+mi}{4}\PYG{p}{,} \PYG{n}{origin\PYGZus{}y}\PYG{o}{=}\PYG{l+m+mi}{4}\PYG{p}{)}
\PYG{n}{paddle\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}rectangle}\PYG{p}{(}\PYG{l+m+mi}{0}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n}{paddle\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{width}\PYG{p}{,} \PYG{n}{paddle\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{height}\PYG{p}{,}
                             \PYG{n}{fill}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{)}
\PYG{n}{ball\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{draw\PYGZus{}rectangle}\PYG{p}{(}\PYG{l+m+mi}{0}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n}{ball\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{width}\PYG{p}{,} \PYG{n}{ball\PYGZus{}sprite}\PYG{o}{.}\PYG{n}{height}\PYG{p}{,}
                           \PYG{n}{fill}\PYG{o}{=}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{white}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{)}
\PYG{n}{hud\PYGZus{}sprite} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Sprite}\PYG{p}{(}\PYG{n}{width}\PYG{o}{=}\PYG{l+m+mi}{320}\PYG{p}{,} \PYG{n}{height}\PYG{o}{=}\PYG{l+m+mi}{120}\PYG{p}{,} \PYG{n}{origin\PYGZus{}x}\PYG{o}{=}\PYG{l+m+mi}{160}\PYG{p}{,} \PYG{n}{origin\PYGZus{}y}\PYG{o}{=}\PYG{l+m+mi}{0}\PYG{p}{)}

\PYG{c+c1}{\PYGZsh{} Load backgrounds}
\PYG{n}{layers} \PYG{o}{=} \PYG{p}{[}\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{BackgroundLayer}\PYG{p}{(}\PYG{n}{paddle\PYGZus{}sprite}\PYG{p}{,} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{width} \PYG{o}{/} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{10000}\PYG{p}{,}
                                  \PYG{n}{repeat\PYGZus{}up}\PYG{o}{=}\PYG{n+nb+bp}{True}\PYG{p}{,} \PYG{n}{repeat\PYGZus{}down}\PYG{o}{=}\PYG{n+nb+bp}{True}\PYG{p}{)}\PYG{p}{]}
\PYG{n}{background} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Background}\PYG{p}{(}\PYG{n}{layers}\PYG{p}{,} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Color}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{black}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{)}

\PYG{c+c1}{\PYGZsh{} Load fonts}
\PYG{n}{hud\PYGZus{}font} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Font}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Droid Sans Mono}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{size}\PYG{o}{=}\PYG{l+m+mi}{48}\PYG{p}{)}

\PYG{c+c1}{\PYGZsh{} Load sounds}
\PYG{n}{bounce\PYGZus{}sound} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{snd}\PYG{o}{.}\PYG{n}{Sound}\PYG{p}{(}\PYG{n}{os}\PYG{o}{.}\PYG{n}{path}\PYG{o}{.}\PYG{n}{join}\PYG{p}{(}\PYG{n}{DATA}\PYG{p}{,} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{bounce.wav}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{)}\PYG{p}{)}
\PYG{n}{bounce\PYGZus{}wall\PYGZus{}sound} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{snd}\PYG{o}{.}\PYG{n}{Sound}\PYG{p}{(}\PYG{n}{os}\PYG{o}{.}\PYG{n}{path}\PYG{o}{.}\PYG{n}{join}\PYG{p}{(}\PYG{n}{DATA}\PYG{p}{,} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{bounce\PYGZus{}wall.wav}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{)}\PYG{p}{)}
\PYG{n}{score\PYGZus{}sound} \PYG{o}{=} \PYG{n}{sge}\PYG{o}{.}\PYG{n}{snd}\PYG{o}{.}\PYG{n}{Sound}\PYG{p}{(}\PYG{n}{os}\PYG{o}{.}\PYG{n}{path}\PYG{o}{.}\PYG{n}{join}\PYG{p}{(}\PYG{n}{DATA}\PYG{p}{,} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{score.wav}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{)}\PYG{p}{)}

\PYG{c+c1}{\PYGZsh{} Create rooms}
\PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{start\PYGZus{}room} \PYG{o}{=} \PYG{n}{create\PYGZus{}room}\PYG{p}{(}\PYG{p}{)}

\PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{mouse}\PYG{o}{.}\PYG{n}{visible} \PYG{o}{=} \PYG{n+nb+bp}{False}


\PYG{k}{if} \PYG{n}{\PYGZus{}\PYGZus{}name\PYGZus{}\PYGZus{}} \PYG{o}{==} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{\PYGZus{}\PYGZus{}main\PYGZus{}\PYGZus{}}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{:}
    \PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{start}\PYG{p}{(}\PYG{p}{)}
\end{Verbatim}


\chapter{sge.input}
\label{input::doc}\label{input:sge-input}\setbox0\vbox{
\begin{minipage}{0.95\linewidth}
\textbf{Contents}

\medskip

\begin{itemize}
\item {} 
\phantomsection\label{input:id1}{\hyperref[input:sge\string-input]{\emph{sge.input}}}
\begin{itemize}
\item {} 
\phantomsection\label{input:id2}{\hyperref[input:input\string-event\string-classes]{\emph{Input Event Classes}}}

\end{itemize}

\end{itemize}
\end{minipage}}
\begin{center}\setlength{\fboxsep}{5pt}\shadowbox{\box0}\end{center}
\phantomsection\label{input:module-sge.input}\index{sge.input (module)}
This module provides input event classes.  Input event objects are used
to consolidate all necessary information about input events in a clean
way.

You normally don't need to use input event objects directly.  Input
events are handled automatically in each frame of the SGE's main loop.
You only need to use input event objects directly if you take control
away from the SGE's main loop, e.g. to create your own loop.


\section{Input Event Classes}
\label{input:input-event-classes}\index{KeyPress (class in sge.input)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.KeyPress}\pysiglinewithargsret{\strong{class }\code{sge.input.}\bfcode{KeyPress}}{\emph{key}, \emph{char}}{}
This input event represents a key on the keyboard being pressed.
\index{key (sge.input.KeyPress attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.KeyPress.key}\pysigline{\bfcode{key}}
The identifier string of the key that was pressed.  See the
table below.

\end{fulllineitems}

\index{char (sge.input.KeyPress attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.KeyPress.char}\pysigline{\bfcode{char}}
The Unicode character associated with the key press, or an empty
Unicode string if no Unicode character is associated with the key
press.  See the table below.

\end{fulllineitems}


\begin{longtable}{|l|l|l|}
\hline
\textsf{\relax 
Key Name
} & \textsf{\relax 
Identifier String
} & \textsf{\relax 
Unicode Character
}\\
\hline\endfirsthead

\multicolumn{3}{c}%
{{\textsf{\tablename\ \thetable{} -- continued from previous page}}} \\
\hline
\textsf{\relax 
Key Name
} & \textsf{\relax 
Identifier String
} & \textsf{\relax 
Unicode Character
}\\
\hline\endhead

\hline \multicolumn{3}{|r|}{{\textsf{Continued on next page}}} \\ \hline
\endfoot

\endlastfoot


0
 & 
\code{"0"}
 & 
\code{"0"}
\\
\hline
1
 & 
\code{"1"}
 & 
\code{"1"}
\\
\hline
2
 & 
\code{"2"}
 & 
\code{"2"}
\\
\hline
3
 & 
\code{"3"}
 & 
\code{"3"}
\\
\hline
4
 & 
\code{"4"}
 & 
\code{"4"}
\\
\hline
5
 & 
\code{"5"}
 & 
\code{"5"}
\\
\hline
6
 & 
\code{"6"}
 & 
\code{"6"}
\\
\hline
7
 & 
\code{"7"}
 & 
\code{"7"}
\\
\hline
8
 & 
\code{"8"}
 & 
\code{"8"}
\\
\hline
9
 & 
\code{"9"}
 & 
\code{"9"}
\\
\hline
A
 & 
\code{"a"}
 & 
\code{"a"}
\\
\hline
B
 & 
\code{"b"}
 & 
\code{"b"}
\\
\hline
C
 & 
\code{"c"}
 & 
\code{"c"}
\\
\hline
D
 & 
\code{"d"}
 & 
\code{"d"}
\\
\hline
E
 & 
\code{"e"}
 & 
\code{"e"}
\\
\hline
F
 & 
\code{"f"}
 & 
\code{"f"}
\\
\hline
G
 & 
\code{"g"}
 & 
\code{"g"}
\\
\hline
H
 & 
\code{"h"}
 & 
\code{"h"}
\\
\hline
I
 & 
\code{"i"}
 & 
\code{"i"}
\\
\hline
J
 & 
\code{"j"}
 & 
\code{"j"}
\\
\hline
K
 & 
\code{"k"}
 & 
\code{"k"}
\\
\hline
L
 & 
\code{"l"}
 & 
\code{"l"}
\\
\hline
M
 & 
\code{"m"}
 & 
\code{"m"}
\\
\hline
N
 & 
\code{"n"}
 & 
\code{"n"}
\\
\hline
O
 & 
\code{"o"}
 & 
\code{"o"}
\\
\hline
P
 & 
\code{"p"}
 & 
\code{"p"}
\\
\hline
Q
 & 
\code{"q"}
 & 
\code{"q"}
\\
\hline
R
 & 
\code{"r"}
 & 
\code{"r"}
\\
\hline
S
 & 
\code{"s"}
 & 
\code{"s"}
\\
\hline
T
 & 
\code{"t"}
 & 
\code{"t"}
\\
\hline
U
 & 
\code{"u"}
 & 
\code{"u"}
\\
\hline
V
 & 
\code{"v"}
 & 
\code{"v"}
\\
\hline
W
 & 
\code{"w"}
 & 
\code{"w"}
\\
\hline
X
 & 
\code{"x"}
 & 
\code{"x"}
\\
\hline
Y
 & 
\code{"y"}
 & 
\code{"y"}
\\
\hline
Z
 & 
\code{"z"}
 & 
\code{"z"}
\\
\hline
Period
 & 
\code{"period"}
 & 
\code{"."}
\\
\hline
Comma
 & 
\code{"comma"}
 & 
\code{","}
\\
\hline
Less Than
 & 
\code{"less\_than"}
 & 
\code{"\textless{}"}
\\
\hline
Greater Than
 & 
\code{"greater\_than"}
 & 
\code{"\textgreater{}"}
\\
\hline
Forward Slash
 & 
\code{"slash"}
 & 
\code{"/"}
\\
\hline
Question Mark
 & 
\code{"question"}
 & 
\code{"?"}
\\
\hline
Apostrophe
 & 
\code{"apostrophe"}
 & 
\code{"'"}
\\
\hline
Quotation Mark
 & 
\code{"quote"}
 & 
\code{'"'}
\\
\hline
Colon
 & 
\code{"colon"}
 & 
\code{":"}
\\
\hline
Semicolon
 & 
\code{"semicolon"}
 & 
\code{";"}
\\
\hline
Exclamation Point
 & 
\code{"exclamation"}
 & 
\code{"!"}
\\
\hline
At
 & 
\code{"at"}
 & 
\code{"@"}
\\
\hline
Hash
 & 
\code{"hash"}
 & 
\code{"\#"}
\\
\hline
Dollar Sign
 & 
\code{"dollar"}
 & 
\code{"\$"}
\\
\hline
Carat
 & 
\code{"carat"}
 & 
\code{"\textasciicircum{}"}
\\
\hline
Ampersand
 & 
\code{"ampersand"}
 & 
\code{"\&"}
\\
\hline
Asterisk
 & 
\code{"asterisk"}
 & 
\code{"*"}
\\
\hline
Left Parenthesis
 & 
\code{"parenthesis\_left"}
 & 
\code{"("}
\\
\hline
Right Parenthesis
 & 
\code{"parenthesis\_right"}
 & 
\code{")"}
\\
\hline
Hyphen
 & 
\code{"hyphen"}
 & 
\code{"-"}
\\
\hline
Underscore
 & 
\code{"underscore"}
 & 
\code{"\_"}
\\
\hline
Plus Sign
 & 
\code{"plus"}
 & 
\code{"+"}
\\
\hline
Equals Sign
 & 
\code{"equals"}
 & 
\code{"="}
\\
\hline
Left Bracket
 & 
\code{"bracket\_left"}
 & 
\code{"{[}"}
\\
\hline
Right Bracket
 & 
\code{"bracket\_right"}
 & 
\code{"{]}"}
\\
\hline
Backslash
 & 
\code{"backslash"}
 & 
\code{"\textbackslash{}\textbackslash{}"}
\\
\hline
Backtick
 & 
\code{"backtick"}
 & 
\code{"{}`"}
\\
\hline
Euro
 & 
\code{"euro"}
 & 
\code{"\textbackslash{}u20ac"}
\\
\hline
Keypad 0
 & 
\code{"kp\_0"}
 & 
\code{"0"}
\\
\hline
Keypad 1
 & 
\code{"kp\_1"}
 & 
\code{"1"}
\\
\hline
Keypad 2
 & 
\code{"kp\_2"}
 & 
\code{"2"}
\\
\hline
Keypad 3
 & 
\code{"kp\_3"}
 & 
\code{"3"}
\\
\hline
Keypad 4
 & 
\code{"kp\_4"}
 & 
\code{"4"}
\\
\hline
Keypad 5
 & 
\code{"kp\_5"}
 & 
\code{"5"}
\\
\hline
Keypad 6
 & 
\code{"kp\_6"}
 & 
\code{"6"}
\\
\hline
Keypad 7
 & 
\code{"kp\_7"}
 & 
\code{"7"}
\\
\hline
Keypad 8
 & 
\code{"kp\_8"}
 & 
\code{"8"}
\\
\hline
Keypad 9
 & 
\code{"kp\_9"}
 & 
\code{"9"}
\\
\hline
Keypad Decimal Point
 & 
\code{"kp\_point"}
 & 
\code{"."}
\\
\hline
Keypad Plus
 & 
\code{"kp\_plus"}
 & 
\code{"+"}
\\
\hline
Keypad Minus
 & 
\code{"kp\_minus"}
 & 
\code{"-"}
\\
\hline
Keypad Multiply
 & 
\code{"kp\_multiply"}
 & 
\code{"*"}
\\
\hline
Keypad Divide
 & 
\code{"kp\_divide"}
 & 
\code{"/"}
\\
\hline
Keypad Equals
 & 
\code{"kp\_equals"}
 & 
\code{"="}
\\
\hline
Keypad Enter
 & 
\code{"kp\_enter"}
 & 
\code{"\textbackslash{}n"}
\\
\hline
Left Arrow
 & 
\code{"left"}
 & 
\code{""}
\\
\hline
Right Arrow
 & 
\code{"right"}
 & 
\code{""}
\\
\hline
Up Arrow
 & 
\code{"up"}
 & 
\code{""}
\\
\hline
Down Arrow
 & 
\code{"down"}
 & 
\code{""}
\\
\hline
Home
 & 
\code{"home"}
 & 
\code{""}
\\
\hline
End
 & 
\code{"end"}
 & 
\code{""}
\\
\hline
Page Up
 & 
\code{"pageup"}
 & 
\code{""}
\\
\hline
Page Down
 & 
\code{"pagedown"}
 & 
\code{""}
\\
\hline
Tab
 & 
\code{"tab"}
 & 
\code{"\textbackslash{}t"}
\\
\hline
Space Bar
 & 
\code{"space"}
 & 
\code{" "}
\\
\hline
Enter/Return
 & 
\code{"enter"}
 & 
\code{"\textbackslash{}n"}
\\
\hline
Backspace
 & 
\code{"backspace"}
 & 
\code{"\textbackslash{}b"}
\\
\hline
Delete
 & 
\code{"delete"}
 & 
\code{""}
\\
\hline
Clear
 & 
\code{"clear"}
 & 
\code{""}
\\
\hline
Left Shift
 & 
\code{"shift\_left"}
 & 
\code{""}
\\
\hline
Right Shift
 & 
\code{"shift\_right"}
 & 
\code{""}
\\
\hline
Left Ctrl
 & 
\code{"ctrl\_left"}
 & 
\code{""}
\\
\hline
Right Ctrl
 & 
\code{"ctrl\_right"}
 & 
\code{""}
\\
\hline
Left Alt
 & 
\code{"alt\_left"}
 & 
\code{""}
\\
\hline
Right Alt
 & 
\code{"alt\_right"}
 & 
\code{""}
\\
\hline
Left Super
 & 
\code{"super\_left"}
 & 
\code{""}
\\
\hline
Right Super
 & 
\code{"super\_right"}
 & 
\code{""}
\\
\hline
Mode
 & 
\code{"mode"}
 & 
\code{""}
\\
\hline
Menu
 & 
\code{"menu"}
 & 
\code{""}
\\
\hline
Caps Lock
 & 
\code{"caps\_lock"}
 & 
\code{""}
\\
\hline
Esc
 & 
\code{"escape"}
 & 
\code{""}
\\
\hline
Num Lock
 & 
\code{"num\_lock"}
 & 
\code{""}
\\
\hline
Scroll Lock
 & 
\code{"scroll\_lock"}
 & 
\code{""}
\\
\hline
Break
 & 
\code{"break"}
 & 
\code{""}
\\
\hline
Insert
 & 
\code{"insert"}
 & 
\code{""}
\\
\hline
Pause
 & 
\code{"pause"}
 & 
\code{""}
\\
\hline
Power
 & 
\code{"power"}
 & 
\code{""}
\\
\hline
Print Screen
 & 
\code{"print\_screen"}
 & 
\code{""}
\\
\hline
SysRq
 & 
\code{"sysrq"}
 & 
\code{""}
\\
\hline
F1
 & 
\code{"f1"}
 & 
\code{""}
\\
\hline
F2
 & 
\code{"f2"}
 & 
\code{""}
\\
\hline
F3
 & 
\code{"f3"}
 & 
\code{""}
\\
\hline
F4
 & 
\code{"f4"}
 & 
\code{""}
\\
\hline
F5
 & 
\code{"f5"}
 & 
\code{""}
\\
\hline
F6
 & 
\code{"f6"}
 & 
\code{""}
\\
\hline
F7
 & 
\code{"f7"}
 & 
\code{""}
\\
\hline
F8
 & 
\code{"f8"}
 & 
\code{""}
\\
\hline
F9
 & 
\code{"f9"}
 & 
\code{""}
\\
\hline
F10
 & 
\code{"f10"}
 & 
\code{""}
\\
\hline
F11
 & 
\code{"f11"}
 & 
\code{""}
\\
\hline
F12
 & 
\code{"f12"}
 & 
\code{""}
\\
\hline\end{longtable}


\end{fulllineitems}

\index{KeyRelease (class in sge.input)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.KeyRelease}\pysiglinewithargsret{\strong{class }\code{sge.input.}\bfcode{KeyRelease}}{\emph{key}}{}
This input event represents a key on the keyboard being released.
\index{key (sge.input.KeyRelease attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.KeyRelease.key}\pysigline{\bfcode{key}}
The identifier string of the key that was released.  See the
table in the documentation for {\hyperref[input:sge.input.KeyPress]{\emph{\code{sge.input.KeyPress}}}}.

\end{fulllineitems}


\end{fulllineitems}

\index{MouseMove (class in sge.input)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.MouseMove}\pysiglinewithargsret{\strong{class }\code{sge.input.}\bfcode{MouseMove}}{\emph{x}, \emph{y}}{}
This input event represents the mouse being moved.
\index{x (sge.input.MouseMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.MouseMove.x}\pysigline{\bfcode{x}}
The horizontal relative movement of the mouse.

\end{fulllineitems}

\index{y (sge.input.MouseMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.MouseMove.y}\pysigline{\bfcode{y}}
The vertical relative movement of the mouse.

\end{fulllineitems}


\end{fulllineitems}

\index{MouseButtonPress (class in sge.input)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.MouseButtonPress}\pysiglinewithargsret{\strong{class }\code{sge.input.}\bfcode{MouseButtonPress}}{\emph{button}}{}
This input event represents a mouse button being pressed.
\index{button (sge.input.MouseButtonPress attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.MouseButtonPress.button}\pysigline{\bfcode{button}}
The identifier string of the mouse button that was pressed.  See
the table below.

\end{fulllineitems}


\begin{tabulary}{\linewidth}{|L|L|}
\hline
\textsf{\relax 
Mouse Button Name
} & \textsf{\relax 
Identifier String
}\\
\hline
Left mouse button
 & 
\code{"left"}
\\
\hline
Right mouse button
 & 
\code{"right"}
\\
\hline
Middle mouse button
 & 
\code{"middle"}
\\
\hline
Mouse wheel up
 & 
\code{"wheel\_up"}
\\
\hline
Mouse wheel down
 & 
\code{"wheel\_down"}
\\
\hline
Mouse wheel tilt left
 & 
\code{"wheel\_left"}
\\
\hline
Mouse wheel tilt right
 & 
\code{"wheel\_right"}
\\
\hline\end{tabulary}


\end{fulllineitems}

\index{MouseButtonRelease (class in sge.input)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.MouseButtonRelease}\pysiglinewithargsret{\strong{class }\code{sge.input.}\bfcode{MouseButtonRelease}}{\emph{button}}{}
This input event represents a mouse button being released.
\index{button (sge.input.MouseButtonRelease attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.MouseButtonRelease.button}\pysigline{\bfcode{button}}
The identifier string of the mouse button that was released.  See
the table in the documentation for
{\hyperref[input:sge.input.MouseButtonPress]{\emph{\code{sge.input.MouseButtonPress}}}}.

\end{fulllineitems}


\end{fulllineitems}

\index{JoystickAxisMove (class in sge.input)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickAxisMove}\pysiglinewithargsret{\strong{class }\code{sge.input.}\bfcode{JoystickAxisMove}}{\emph{js\_name}, \emph{js\_id}, \emph{axis}, \emph{value}}{}
This input event represents a joystick axis moving.
\index{js\_name (sge.input.JoystickAxisMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickAxisMove.js_name}\pysigline{\bfcode{js\_name}}
The name of the joystick.

\end{fulllineitems}

\index{js\_id (sge.input.JoystickAxisMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickAxisMove.js_id}\pysigline{\bfcode{js\_id}}
The number of the joystick, where \code{0} is the first joystick.

\end{fulllineitems}

\index{axis (sge.input.JoystickAxisMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickAxisMove.axis}\pysigline{\bfcode{axis}}
The number of the axis that moved, where \code{0} is the first axis
on the joystick.

\end{fulllineitems}

\index{value (sge.input.JoystickAxisMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickAxisMove.value}\pysigline{\bfcode{value}}
The tilt of the axis as a float from \code{-1} to \code{1}, where \code{0}
is centered, \code{-1} is all the way to the left or up, and \code{1}
is all the way to the right or down.

\end{fulllineitems}


\end{fulllineitems}

\index{JoystickHatMove (class in sge.input)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickHatMove}\pysiglinewithargsret{\strong{class }\code{sge.input.}\bfcode{JoystickHatMove}}{\emph{js\_name}, \emph{js\_id}, \emph{hat}, \emph{x}, \emph{y}}{}
This input event represents a joystick hat moving.
\index{js\_name (sge.input.JoystickHatMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickHatMove.js_name}\pysigline{\bfcode{js\_name}}
The name of the joystick.

\end{fulllineitems}

\index{js\_id (sge.input.JoystickHatMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickHatMove.js_id}\pysigline{\bfcode{js\_id}}
The number of the joystick, where \code{0} is the first joystick.

\end{fulllineitems}

\index{hat (sge.input.JoystickHatMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickHatMove.hat}\pysigline{\bfcode{hat}}
The number of the hat that moved, where \code{0} is the first axis
on the joystick.

\end{fulllineitems}

\index{x (sge.input.JoystickHatMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickHatMove.x}\pysigline{\bfcode{x}}
The horizontal position of the hat, where \code{0} is centered,
\code{-1} is left, and \code{1} is right.

\end{fulllineitems}

\index{y (sge.input.JoystickHatMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickHatMove.y}\pysigline{\bfcode{y}}
The vertical position of the hat, where \code{0} is centered, \code{-1}
is up, and \code{1} is down.

\end{fulllineitems}


\end{fulllineitems}

\index{JoystickTrackballMove (class in sge.input)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickTrackballMove}\pysiglinewithargsret{\strong{class }\code{sge.input.}\bfcode{JoystickTrackballMove}}{\emph{js\_name}, \emph{js\_id}, \emph{ball}, \emph{x}, \emph{y}}{}
This input event represents a joystick trackball moving.
\index{js\_name (sge.input.JoystickTrackballMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickTrackballMove.js_name}\pysigline{\bfcode{js\_name}}
The name of the joystick.

\end{fulllineitems}

\index{js\_id (sge.input.JoystickTrackballMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickTrackballMove.js_id}\pysigline{\bfcode{js\_id}}
The number of the joystick, where \code{0} is the first joystick.

\end{fulllineitems}

\index{ball (sge.input.JoystickTrackballMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickTrackballMove.ball}\pysigline{\bfcode{ball}}
The number of the trackball that moved, where \code{0} is the first
trackball on the joystick.

\end{fulllineitems}

\index{x (sge.input.JoystickTrackballMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickTrackballMove.x}\pysigline{\bfcode{x}}
The horizontal relative movement of the trackball.

\end{fulllineitems}

\index{y (sge.input.JoystickTrackballMove attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickTrackballMove.y}\pysigline{\bfcode{y}}
The vertical relative movement of the trackball.

\end{fulllineitems}


\end{fulllineitems}

\index{JoystickButtonPress (class in sge.input)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickButtonPress}\pysiglinewithargsret{\strong{class }\code{sge.input.}\bfcode{JoystickButtonPress}}{\emph{js\_name}, \emph{js\_id}, \emph{button}}{}
This input event represents a joystick button being pressed.
\index{js\_name (sge.input.JoystickButtonPress attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickButtonPress.js_name}\pysigline{\bfcode{js\_name}}
The name of the joystick.

\end{fulllineitems}

\index{js\_id (sge.input.JoystickButtonPress attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickButtonPress.js_id}\pysigline{\bfcode{js\_id}}
The number of the joystick, where \code{0} is the first joystick.

\end{fulllineitems}

\index{button (sge.input.JoystickButtonPress attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickButtonPress.button}\pysigline{\bfcode{button}}
The number of the button that was pressed, where \code{0} is the
first button on the joystick.

\end{fulllineitems}


\end{fulllineitems}

\index{JoystickButtonRelease (class in sge.input)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickButtonRelease}\pysiglinewithargsret{\strong{class }\code{sge.input.}\bfcode{JoystickButtonRelease}}{\emph{js\_name}, \emph{js\_id}, \emph{button}}{}
This input event represents a joystick button being released.
\index{js\_name (sge.input.JoystickButtonRelease attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickButtonRelease.js_name}\pysigline{\bfcode{js\_name}}
The name of the joystick.

\end{fulllineitems}

\index{js\_id (sge.input.JoystickButtonRelease attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickButtonRelease.js_id}\pysigline{\bfcode{js\_id}}
The number of the joystick, where \code{0} is the first joystick.

\end{fulllineitems}

\index{button (sge.input.JoystickButtonRelease attribute)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.JoystickButtonRelease.button}\pysigline{\bfcode{button}}
The number of the button that was released, where \code{0} is the
first button on the joystick.

\end{fulllineitems}


\end{fulllineitems}

\index{KeyboardFocusGain (class in sge.input)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.KeyboardFocusGain}\pysigline{\strong{class }\code{sge.input.}\bfcode{KeyboardFocusGain}}
This input event represents the game window gaining keyboard focus.
Keyboard focus is normally needed for keyboard input to be received.

\begin{notice}{note}{Note:}
On some window systems, such as the one used by Windows, no
distinction is made between keyboard and mouse focus, but on
some other window systems, such as the X Window System, a
distinction is made: one window can have keyboard focus while
another has mouse focus.  Be careful to observe the
difference; failing to do so may result in annoying bugs,
and you won't notice these bugs if you are testing on a
window manager that doesn't recognize the difference.
\end{notice}

\end{fulllineitems}

\index{KeyboardFocusLose (class in sge.input)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.KeyboardFocusLose}\pysigline{\strong{class }\code{sge.input.}\bfcode{KeyboardFocusLose}}
This input event represents the game window losing keyboard focus.
Keyboard focus is normally needed for keyboard input to be received.

\begin{notice}{note}{Note:}
See the note in the documentation for
{\hyperref[input:sge.input.KeyboardFocusGain]{\emph{\code{sge.input.KeyboardFocusGain}}}}.
\end{notice}

\end{fulllineitems}

\index{MouseFocusGain (class in sge.input)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.MouseFocusGain}\pysigline{\strong{class }\code{sge.input.}\bfcode{MouseFocusGain}}
This input event represents the game window gaining mouse focus.
Mouse focus is normally needed for mouse input to be received.

\begin{notice}{note}{Note:}
See the note in the documentation for
{\hyperref[input:sge.input.KeyboardFocusGain]{\emph{\code{sge.input.KeyboardFocusGain}}}}.
\end{notice}

\end{fulllineitems}

\index{MouseFocusLose (class in sge.input)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.MouseFocusLose}\pysigline{\strong{class }\code{sge.input.}\bfcode{MouseFocusLose}}
This input event represents the game window losing mouse focus.
Mouse focus is normally needed for mouse input to be received.

\begin{notice}{note}{Note:}
See the note in the documentation for
{\hyperref[input:sge.input.KeyboardFocusGain]{\emph{\code{sge.input.KeyboardFocusGain}}}}.
\end{notice}

\end{fulllineitems}

\index{QuitRequest (class in sge.input)}

\begin{fulllineitems}
\phantomsection\label{input:sge.input.QuitRequest}\pysigline{\strong{class }\code{sge.input.}\bfcode{QuitRequest}}
This input event represents the OS requesting for the program to
close (e.g. when the user presses a ``close'' button on the window
border).

\end{fulllineitems}



\chapter{sge.dsp}
\label{dsp::doc}\label{dsp:sge-dsp}\setbox0\vbox{
\begin{minipage}{0.95\linewidth}
\textbf{Contents}

\medskip

\begin{itemize}
\item {} 
\phantomsection\label{dsp:id1}{\hyperref[dsp:sge\string-dsp]{\emph{sge.dsp}}}
\begin{itemize}
\item {} 
\phantomsection\label{dsp:id2}{\hyperref[dsp:sge\string-dsp\string-classes]{\emph{sge.dsp Classes}}}
\begin{itemize}
\item {} 
\phantomsection\label{dsp:id3}{\hyperref[dsp:sge\string-dsp\string-game]{\emph{sge.dsp.Game}}}
\begin{itemize}
\item {} 
\phantomsection\label{dsp:id4}{\hyperref[dsp:sge\string-dsp\string-game\string-methods]{\emph{sge.dsp.Game Methods}}}

\item {} 
\phantomsection\label{dsp:id5}{\hyperref[dsp:sge\string-dsp\string-game\string-event\string-methods]{\emph{sge.dsp.Game Event Methods}}}

\end{itemize}

\item {} 
\phantomsection\label{dsp:id6}{\hyperref[dsp:sge\string-dsp\string-room]{\emph{sge.dsp.Room}}}
\begin{itemize}
\item {} 
\phantomsection\label{dsp:id7}{\hyperref[dsp:sge\string-dsp\string-room\string-methods]{\emph{sge.dsp.Room Methods}}}

\item {} 
\phantomsection\label{dsp:id8}{\hyperref[dsp:sge\string-dsp\string-room\string-event\string-methods]{\emph{sge.dsp.Room Event Methods}}}

\end{itemize}

\item {} 
\phantomsection\label{dsp:id9}{\hyperref[dsp:sge\string-dsp\string-view]{\emph{sge.dsp.View}}}
\begin{itemize}
\item {} 
\phantomsection\label{dsp:id10}{\hyperref[dsp:sge\string-dsp\string-view\string-methods]{\emph{sge.dsp.View Methods}}}

\end{itemize}

\item {} 
\phantomsection\label{dsp:id11}{\hyperref[dsp:sge\string-dsp\string-object]{\emph{sge.dsp.Object}}}
\begin{itemize}
\item {} 
\phantomsection\label{dsp:id12}{\hyperref[dsp:sge\string-dsp\string-object\string-methods]{\emph{sge.dsp.Object Methods}}}

\item {} 
\phantomsection\label{dsp:id13}{\hyperref[dsp:sge\string-dsp\string-object\string-event\string-methods]{\emph{sge.dsp.Object Event Methods}}}

\end{itemize}

\end{itemize}

\end{itemize}

\end{itemize}
\end{minipage}}
\begin{center}\setlength{\fboxsep}{5pt}\shadowbox{\box0}\end{center}
\phantomsection\label{dsp:module-sge.dsp}\index{sge.dsp (module)}
This module provides classes related to the graphical display.


\section{sge.dsp Classes}
\label{dsp:sge-dsp-classes}

\subsection{sge.dsp.Game}
\label{dsp:sge-dsp-game}\index{Game (class in sge.dsp)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game}\pysiglinewithargsret{\strong{class }\code{sge.dsp.}\bfcode{Game}}{\emph{width=640}, \emph{height=480}, \emph{fullscreen=False}, \emph{scale=None}, \emph{scale\_proportional=True}, \emph{scale\_method=None}, \emph{fps=60}, \emph{delta=False}, \emph{delta\_min=15}, \emph{delta\_max=None}, \emph{grab\_input=False}, \emph{window\_text=None}, \emph{window\_icon=None}, \emph{collision\_events\_enabled=True}}{}
This class handles most parts of the game which operate on a global
scale, such as global game events.  Before anything else is done
with the SGE, an object either of this class or of a class derived
from it must be created.

When an object of this class is created, it is automatically
assigned to \code{sge.game}.

\begin{notice}{note}{Note:}
This class is designed to be used as a singleton.  Do not create
multiple {\hyperref[dsp:sge.dsp.Game]{\emph{\code{sge.dsp.Game}}}} objects.  Doing so is unsupported
and may cause errors.
\end{notice}
\index{width (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.width}\pysigline{\bfcode{width}}
The width of the game's display.

\end{fulllineitems}

\index{height (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.height}\pysigline{\bfcode{height}}
The height of the game's display.

\end{fulllineitems}

\index{fullscreen (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.fullscreen}\pysigline{\bfcode{fullscreen}}
Whether or not the game should be in fullscreen mode.

\end{fulllineitems}

\index{scale (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.scale}\pysigline{\bfcode{scale}}
A number indicating a fixed scale factor (e.g. \code{1} for no
scaling, \code{2} for doubled size).  If set to \code{None} or
\code{0}, scaling is automatic (causes the game to fit the window or
screen).

If a fixed scale factor is defined and the game is in fullscreen
mode, the scale factor multiplied by {\hyperref[dsp:sge.dsp.Game.width]{\emph{\code{width}}}} and
{\hyperref[dsp:sge.dsp.Game.height]{\emph{\code{height}}}} is used to suggest what resolution to use.

\end{fulllineitems}

\index{scale\_proportional (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.scale_proportional}\pysigline{\bfcode{scale\_proportional}}
If set to \code{True}, scaling is always proportional.  If set
to \code{False}, the image will be distorted to completely fill
the game window or screen.  This has no effect unless
{\hyperref[dsp:sge.dsp.Game.scale]{\emph{\code{scale}}}} is \code{None} or \code{0}.

\end{fulllineitems}

\index{scale\_method (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.scale_method}\pysigline{\bfcode{scale\_method}}
A string indicating the type of scaling method to use.  Can be
one of the following:
\begin{itemize}
\item {} 
\code{"noblur"} -- Request a non-blurry scale method, generally
optimal for pixel art.

\item {} 
\code{"smooth"} -- Request a smooth scale method, generally
optimal for images other than pixel art.

\end{itemize}

Alternatively, this attribute can be set to one of the values in
\code{sge.SCALE\_METHODS} to request an exact scale method to
use.

The value of this attribute is only a request.  If this value is
either an unsupported value or \code{None}, the fastest
available scale method is chosen.

\end{fulllineitems}

\index{fps (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.fps}\pysigline{\bfcode{fps}}
The rate the game should run in frames per second.

\begin{notice}{note}{Note:}
This is only the maximum; if the computer is not fast enough,
the game may run more slowly.
\end{notice}

\end{fulllineitems}

\index{delta (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.delta}\pysigline{\bfcode{delta}}
Whether or not delta timing should be used.  Delta timing affects
object speeds, animation rates, and alarms.

\end{fulllineitems}

\index{delta\_min (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.delta_min}\pysigline{\bfcode{delta\_min}}
Delta timing can cause the game to be choppy.  This attribute
limits this by pretending that the frame rate is never lower than
this amount, resulting in the game slowing down like normal if it
is.

\end{fulllineitems}

\index{delta\_max (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.delta_max}\pysigline{\bfcode{delta\_max}}
Indicates a higher frame rate cap than {\hyperref[dsp:sge.dsp.Game.fps]{\emph{\code{fps}}}} to allow the
game to reach by using delta timing to slow object speeds,
animation rates, and alarms down.  If set to \code{None}, this
feature is disabled and the game will not be permitted to run
faster than {\hyperref[dsp:sge.dsp.Game.fps]{\emph{\code{fps}}}}.

This attribute has no effect unless {\hyperref[dsp:sge.dsp.Game.delta]{\emph{\code{delta}}}} is
\code{True}.

\end{fulllineitems}

\index{grab\_input (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.grab_input}\pysigline{\bfcode{grab\_input}}
Whether or not all input should be forcibly grabbed by the game.
If this is \code{True} and \code{sge.mouse.visible} is
\code{False}, the mouse will be in relative mode.  Otherwise,
the mouse will be in absolute mode.

\end{fulllineitems}

\index{window\_text (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.window_text}\pysigline{\bfcode{window\_text}}
The text for the OS to display as the window title, e.g. in the
frame of the window.  If set to \code{None}, the SGE chooses
the text.

\end{fulllineitems}

\index{window\_icon (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.window_icon}\pysigline{\bfcode{window\_icon}}
The path to the image file to use as the window icon.  If set
to \code{None}, the SGE chooses the icon.  If the file
specified does not exist, \code{OSError} is raised.

\end{fulllineitems}

\index{collision\_events\_enabled (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.collision_events_enabled}\pysigline{\bfcode{collision\_events\_enabled}}
Whether or not collision events should be executed.  Setting this
to \code{False} will improve performence if collision events
are not needed.

\end{fulllineitems}

\index{alarms (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.alarms}\pysigline{\bfcode{alarms}}
A dictionary containing the global alarms of the game.  Each
value decreases by 1 each frame (adjusted for delta timing if it
is enabled).  When a value is at or below 0,
{\hyperref[dsp:sge.dsp.Game.event_alarm]{\emph{\code{sge.dsp.Game.event\_alarm()}}}} is executed with \code{alarm\_id}
set to the respective key, and the item is deleted from this
dictionary.

\end{fulllineitems}

\index{input\_events (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.input_events}\pysigline{\bfcode{input\_events}}
A list containing all input event objects which have not yet been
handled, in the order in which they occurred.

\begin{notice}{note}{Note:}
If you handle input events manually, be sure to delete them
from this list, preferably by getting them with
\code{list.pop()}.  Otherwise, the event will be handled more
than once, which is usually not what you want.
\end{notice}

\end{fulllineitems}

\index{start\_room (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.start_room}\pysigline{\bfcode{start\_room}}
The room which becomes active when the game first starts and when
it restarts.  Must be set exactly once, before the game first
starts, and should not be set again afterwards.

\end{fulllineitems}

\index{current\_room (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.current_room}\pysigline{\bfcode{current\_room}}
The room which is currently active.  (Read-only)

\end{fulllineitems}

\index{mouse (sge.dsp.Game attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.mouse}\pysigline{\bfcode{mouse}}
A {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} object which represents the mouse
cursor.  Its bounding box is a one-pixel square.  It is
automatically added to every room's default list of objects.

Some of this object's attributes control properties of the mouse.
See the documentation for {\hyperref[mouse:module\string-sge.mouse]{\emph{\code{sge.mouse}}}} for more information.

(Read-only)

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{sge.dsp.Game Methods}
\label{dsp:sge-dsp-game-methods}\index{\_\_init\_\_() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.__init__}\pysiglinewithargsret{\code{Game.}\bfcode{\_\_init\_\_}}{\emph{width=640}, \emph{height=480}, \emph{fullscreen=False}, \emph{scale=None}, \emph{scale\_proportional=True}, \emph{scale\_method=None}, \emph{fps=60}, \emph{delta=False}, \emph{delta\_min=15}, \emph{delta\_max=None}, \emph{grab\_input=False}, \emph{window\_text=None}, \emph{window\_icon=None}, \emph{collision\_events\_enabled=True}}{}
Arguments set the respective initial attributes of the game.
See the documentation for {\hyperref[dsp:sge.dsp.Game]{\emph{\code{sge.dsp.Game}}}} for more
information.

The created {\hyperref[dsp:sge.dsp.Game]{\emph{\code{sge.dsp.Game}}}} object is automatically
assigned to \code{sge.game}.

\end{fulllineitems}

\index{start() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.start}\pysiglinewithargsret{\code{Game.}\bfcode{start}}{}{}
Start the game.  Should only be called once; the effect of any
further calls is undefined.

\end{fulllineitems}

\index{end() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.end}\pysiglinewithargsret{\code{Game.}\bfcode{end}}{}{}
Properly end the game.

\end{fulllineitems}

\index{pause() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.pause}\pysiglinewithargsret{\code{Game.}\bfcode{pause}}{\emph{sprite=None}}{}
Pause the game.

Arguments:
\begin{itemize}
\item {} 
\code{sprite} -- The sprite to show in the center of the screen
while the game is paused.  If set to \code{None}, the SGE
chooses the image.

\end{itemize}

Normal events are not executed while the game is paused.
Instead, events with the same name, but prefixed with
\code{event\_paused\_} instead of \code{event\_} are executed.  Note that
not all events have these alternative ``paused'' events associated
with them.

\end{fulllineitems}

\index{unpause() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.unpause}\pysiglinewithargsret{\code{Game.}\bfcode{unpause}}{}{}
Unpause the game.

\end{fulllineitems}

\index{pump\_input() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.pump_input}\pysiglinewithargsret{\code{Game.}\bfcode{pump\_input}}{}{}
Cause the SGE to recieve input from the OS.

This method needs to be called periodically for the SGE to
recieve events from the OS, such as key presses and mouse
movement, as well as to assure the OS that the program is not
locked up.

Upon calling this, each event is translated into the appropriate
class in {\hyperref[input:module\string-sge.input]{\emph{\code{sge.input}}}} and the resulting object is appended
to {\hyperref[dsp:sge.dsp.Game.input_events]{\emph{\code{input\_events}}}}.

You normally don't need to use this function directly.  It is
called automatically in each frame of the SGE's main loop.  You
only need to use this function directly if you take control away
from the SGE's main loop, e.g. to create your own loop.

\end{fulllineitems}

\index{regulate\_speed() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.regulate_speed}\pysiglinewithargsret{\code{Game.}\bfcode{regulate\_speed}}{\emph{fps=None}}{}
Regulate the SGE's running speed and return the time passed.

Arguments:
\begin{itemize}
\item {} 
\code{fps} -- The target frame rate in frames per second.  Set to
\code{None} to target the current value of {\hyperref[dsp:sge.dsp.Game.fps]{\emph{\code{fps}}}}.

\end{itemize}

When this method is called, the program will sleep long enough
so that the game runs at \code{fps} frames per second, then return
the number of milliseconds that passed between the previous call
and the current call of this method.

You normally don't need to use this function directly.  It is
called automatically in each frame of the SGE's main loop.  You
only need to use this function directly if you want to create
your own loop.

\end{fulllineitems}

\index{refresh() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.refresh}\pysiglinewithargsret{\code{Game.}\bfcode{refresh}}{}{}
Refresh the screen.

This method needs to be called for changes to the screen to be
seen by the user.  It should be called every frame.

You normally don't need to use this function directly.  It is
called automatically in each frame of the SGE's main loop.  You
only need to use this function directly if you take control away
from the SGE's main loop, e.g. to create your own loop.

\end{fulllineitems}

\index{project\_dot() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.project_dot}\pysiglinewithargsret{\code{Game.}\bfcode{project\_dot}}{\emph{x}, \emph{y}, \emph{color}, \emph{z=0}, \emph{blend\_mode=None}}{}
Project a single-pixel dot onto the game window.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the window to
project the dot.

\item {} 
\code{y} -- The vertical location relative to the window to
project the dot.

\item {} 
\code{z} -- The Z-axis position of the projection in relation to
other window projections.

\end{itemize}

Window projections are projections made directly onto the game
window, independent of the room or any views.

\begin{notice}{note}{Note:}
The Z-axis position of a window projection does not
correlate with the Z-axis position of anything positioned
within the room, such as room projections and
{\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} objects.  Window projections are
always positioned in front of such things.
\end{notice}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_dot]{\emph{\code{sge.gfx.Sprite.draw\_dot()}}}} for
more information.

\end{fulllineitems}

\index{project\_line() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.project_line}\pysiglinewithargsret{\code{Game.}\bfcode{project\_line}}{\emph{x1}, \emph{y1}, \emph{x2}, \emph{y2}, \emph{color}, \emph{z=0}, \emph{thickness=1}, \emph{anti\_alias=False}, \emph{blend\_mode=None}}{}
Project a line segment onto the game window.

Arguments:
\begin{itemize}
\item {} 
\code{x1} -- The horizontal location relative to the window of
the first endpoint of the projected line segment.

\item {} 
\code{y1} -- The vertical location relative to the window of the
first endpoint of the projected line segment.

\item {} 
\code{x2} -- The horizontal location relative to the window of
the second endpoint of the projected line segment.

\item {} 
\code{y2} -- The vertical location relative to the window of the
second endpoint of the projected line segment.

\item {} 
\code{z} -- The Z-axis position of the projection in relation to
other window projections.

\end{itemize}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_line]{\emph{\code{sge.gfx.Sprite.draw\_line()}}}} and
{\hyperref[dsp:sge.dsp.Game.project_dot]{\emph{\code{sge.dsp.Game.project\_dot()}}}} for more information.

\end{fulllineitems}

\index{project\_rectangle() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.project_rectangle}\pysiglinewithargsret{\code{Game.}\bfcode{project\_rectangle}}{\emph{x}, \emph{y}, \emph{width}, \emph{height}, \emph{z=0}, \emph{fill=None}, \emph{outline=None}, \emph{outline\_thickness=1}, \emph{blend\_mode=None}}{}
Project a rectangle onto the game window.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the window to
project the rectangle.

\item {} 
\code{y} -- The vertical location relative to the window to
project the rectangle.

\item {} 
\code{z} -- The Z-axis position of the projection in relation to
other window projections.

\end{itemize}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_rectangle]{\emph{\code{sge.gfx.Sprite.draw\_rectangle()}}}}
and {\hyperref[dsp:sge.dsp.Game.project_dot]{\emph{\code{sge.dsp.Game.project\_dot()}}}} for more information.

\end{fulllineitems}

\index{project\_ellipse() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.project_ellipse}\pysiglinewithargsret{\code{Game.}\bfcode{project\_ellipse}}{\emph{x}, \emph{y}, \emph{width}, \emph{height}, \emph{z=0}, \emph{fill=None}, \emph{outline=None}, \emph{outline\_thickness=1}, \emph{anti\_alias=False}, \emph{blend\_mode=None}}{}
Project an ellipse onto the game window.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the window to
position the imaginary rectangle containing the ellipse.

\item {} 
\code{y} -- The vertical location relative to the window to
position the imaginary rectangle containing the ellipse.

\item {} 
\code{z} -- The Z-axis position of the projection in relation to
other window projections.

\item {} 
\code{width} -- The width of the ellipse.

\item {} 
\code{height} -- The height of the ellipse.

\item {} 
\code{outline\_thickness} -- The thickness of the outline of the
ellipse.

\item {} 
\code{anti\_alias} -- Whether or not anti-aliasing should be used.

\end{itemize}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_ellipse]{\emph{\code{sge.gfx.Sprite.draw\_ellipse()}}}}
and {\hyperref[dsp:sge.dsp.Game.project_dot]{\emph{\code{sge.dsp.Game.project\_dot()}}}} for more information.

\end{fulllineitems}

\index{project\_circle() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.project_circle}\pysiglinewithargsret{\code{Game.}\bfcode{project\_circle}}{\emph{x}, \emph{y}, \emph{radius}, \emph{z=0}, \emph{fill=None}, \emph{outline=None}, \emph{outline\_thickness=1}, \emph{anti\_alias=False}, \emph{blend\_mode=None}}{}
Project a circle onto the game window.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the window to
position the center of the circle.

\item {} 
\code{y} -- The vertical location relative to the window to
position the center of the circle.

\item {} 
\code{z} -- The Z-axis position of the projection in relation to
other window projections.

\end{itemize}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_circle]{\emph{\code{sge.gfx.Sprite.draw\_circle()}}}} and
{\hyperref[dsp:sge.dsp.Game.project_dot]{\emph{\code{sge.dsp.Game.project\_dot()}}}} for more information.

\end{fulllineitems}

\index{project\_polygon() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.project_polygon}\pysiglinewithargsret{\code{Game.}\bfcode{project\_polygon}}{\emph{points}, \emph{z=0}, \emph{fill=None}, \emph{outline=None}, \emph{outline\_thickness=1}, \emph{anti\_alias=False}, \emph{blend\_mode=None}}{}
Draw a polygon on the sprite.

Arguments:
\begin{itemize}
\item {} 
\code{points} -- A list of points relative to the room to
position each of the polygon's angles.  Each point should be a
tuple in the form \code{(x, y)}, where x is the horizontal
location and y is the vertical location.

\item {} 
\code{z} -- The Z-axis position of the projection in relation to
other window projections.

\end{itemize}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_polygon]{\emph{\code{sge.gfx.Sprite.draw\_polygon()}}}}
and {\hyperref[dsp:sge.dsp.Game.project_dot]{\emph{\code{sge.dsp.Game.project\_dot()}}}} for more information.

\end{fulllineitems}

\index{project\_sprite() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.project_sprite}\pysiglinewithargsret{\code{Game.}\bfcode{project\_sprite}}{\emph{sprite}, \emph{image}, \emph{x}, \emph{y}, \emph{z=0}, \emph{blend\_mode=None}}{}
Project a sprite onto the game window.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the window to
project \code{sprite}.

\item {} 
\code{y} -- The vertical location relative to the window to
project \code{sprite}.

\item {} 
\code{z} -- The Z-axis position of the projection in relation to
other window projections.

\end{itemize}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_sprite]{\emph{\code{sge.gfx.Sprite.draw\_sprite()}}}} and
{\hyperref[dsp:sge.dsp.Game.project_dot]{\emph{\code{sge.dsp.Game.project\_dot()}}}} for more information.

\end{fulllineitems}

\index{project\_text() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.project_text}\pysiglinewithargsret{\code{Game.}\bfcode{project\_text}}{\emph{font}, \emph{text}, \emph{x}, \emph{y}, \emph{z=0}, \emph{width=None}, \emph{height=None}, \emph{color=sge.gfx.Color(``white'')}, \emph{halign='left'}, \emph{valign='top'}, \emph{anti\_alias=True}, \emph{blend\_mode=None}}{}
Project text onto the game window.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the window to
project the text.

\item {} 
\code{y} -- The vertical location relative to the window to
project the text.

\item {} 
\code{z} -- The Z-axis position of the projection in relation to
other window projections.

\end{itemize}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_text]{\emph{\code{sge.gfx.Sprite.draw\_text()}}}} and
{\hyperref[dsp:sge.dsp.Game.project_dot]{\emph{\code{sge.dsp.Game.project\_dot()}}}} for more information.

\end{fulllineitems}



\subsubsection{sge.dsp.Game Event Methods}
\label{dsp:sge-dsp-game-event-methods}\index{event\_step() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_step}\pysiglinewithargsret{\code{Game.}\bfcode{event\_step}}{\emph{time\_passed}, \emph{delta\_mult}}{}
Called once each frame.

Arguments:
\begin{itemize}
\item {} 
\code{time\_passed} -- The number of milliseconds that have passed
during the last frame.

\item {} 
\code{delta\_mult} -- What speed and movement should be multiplied
by this frame due to delta timing.  If {\hyperref[dsp:sge.dsp.Game.delta]{\emph{\code{delta}}}} is
\code{False}, this is always \code{1}.

\end{itemize}

\end{fulllineitems}

\index{event\_alarm() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_alarm}\pysiglinewithargsret{\code{Game.}\bfcode{event\_alarm}}{\emph{alarm\_id}}{}
Called when the value of an alarm reaches 0.

See the documentation for {\hyperref[dsp:sge.dsp.Game.alarms]{\emph{\code{sge.dsp.Game.alarms}}}} for more
information.

\end{fulllineitems}

\index{event\_key\_press() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_key_press}\pysiglinewithargsret{\code{Game.}\bfcode{event\_key\_press}}{\emph{key}, \emph{char}}{}
See the documentation for {\hyperref[input:sge.input.KeyPress]{\emph{\code{sge.input.KeyPress}}}} for more
information.

\end{fulllineitems}

\index{event\_key\_release() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_key_release}\pysiglinewithargsret{\code{Game.}\bfcode{event\_key\_release}}{\emph{key}}{}
See the documentation for {\hyperref[input:sge.input.KeyRelease]{\emph{\code{sge.input.KeyRelease}}}} for more
information.

\end{fulllineitems}

\index{event\_mouse\_move() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_mouse_move}\pysiglinewithargsret{\code{Game.}\bfcode{event\_mouse\_move}}{\emph{x}, \emph{y}}{}
See the documentation for {\hyperref[input:sge.input.MouseMove]{\emph{\code{sge.input.MouseMove}}}} for more
information.

\end{fulllineitems}

\index{event\_mouse\_button\_press() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_mouse_button_press}\pysiglinewithargsret{\code{Game.}\bfcode{event\_mouse\_button\_press}}{\emph{button}}{}
See the documentation for {\hyperref[input:sge.input.MouseButtonPress]{\emph{\code{sge.input.MouseButtonPress}}}}
for more information.

\end{fulllineitems}

\index{event\_mouse\_button\_release() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_mouse_button_release}\pysiglinewithargsret{\code{Game.}\bfcode{event\_mouse\_button\_release}}{\emph{button}}{}
See the documentation for {\hyperref[input:sge.input.MouseButtonRelease]{\emph{\code{sge.input.MouseButtonRelease}}}}
for more information.

\end{fulllineitems}

\index{event\_joystick() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_joystick}\pysiglinewithargsret{\code{Game.}\bfcode{event\_joystick}}{\emph{js\_name}, \emph{js\_id}, \emph{input\_type}, \emph{input\_id}, \emph{value}}{}
See the documentation for \code{sge.input.JoystickEvent} for
more information.

\end{fulllineitems}

\index{event\_joystick\_axis\_move() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_joystick_axis_move}\pysiglinewithargsret{\code{Game.}\bfcode{event\_joystick\_axis\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{axis}, \emph{value}}{}
See the documentation for {\hyperref[input:sge.input.JoystickAxisMove]{\emph{\code{sge.input.JoystickAxisMove}}}}
for more information.

\end{fulllineitems}

\index{event\_joystick\_hat\_move() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_joystick_hat_move}\pysiglinewithargsret{\code{Game.}\bfcode{event\_joystick\_hat\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{hat}, \emph{x}, \emph{y}}{}
See the documentation for {\hyperref[input:sge.input.JoystickHatMove]{\emph{\code{sge.input.JoystickHatMove}}}}
for more information.

\end{fulllineitems}

\index{event\_joystick\_trackball\_move() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_joystick_trackball_move}\pysiglinewithargsret{\code{Game.}\bfcode{event\_joystick\_trackball\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{ball}, \emph{x}, \emph{y}}{}
See the documentation for
{\hyperref[input:sge.input.JoystickTrackballMove]{\emph{\code{sge.input.JoystickTrackballMove}}}} for more information.

\end{fulllineitems}

\index{event\_joystick\_button\_press() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_joystick_button_press}\pysiglinewithargsret{\code{Game.}\bfcode{event\_joystick\_button\_press}}{\emph{js\_name}, \emph{js\_id}, \emph{button}}{}
See the documentation for {\hyperref[input:sge.input.JoystickButtonPress]{\emph{\code{sge.input.JoystickButtonPress}}}}
for more information.

\end{fulllineitems}

\index{event\_joystick\_button\_release() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_joystick_button_release}\pysiglinewithargsret{\code{Game.}\bfcode{event\_joystick\_button\_release}}{\emph{js\_name}, \emph{js\_id}, \emph{button}}{}
See the documentation for
{\hyperref[input:sge.input.JoystickButtonRelease]{\emph{\code{sge.input.JoystickButtonRelease}}}} for more information.

\end{fulllineitems}

\index{event\_gain\_keyboard\_focus() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_gain_keyboard_focus}\pysiglinewithargsret{\code{Game.}\bfcode{event\_gain\_keyboard\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.KeyboardFocusGain]{\emph{\code{sge.input.KeyboardFocusGain}}}}
for more information.

\end{fulllineitems}

\index{event\_lose\_keyboard\_focus() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_lose_keyboard_focus}\pysiglinewithargsret{\code{Game.}\bfcode{event\_lose\_keyboard\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.KeyboardFocusLose]{\emph{\code{sge.input.KeyboardFocusLose}}}}
for more information.

\end{fulllineitems}

\index{event\_gain\_mouse\_focus() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_gain_mouse_focus}\pysiglinewithargsret{\code{Game.}\bfcode{event\_gain\_mouse\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.MouseFocusGain]{\emph{\code{sge.input.MouseFocusGain}}}} for
more information.

\end{fulllineitems}

\index{event\_lose\_mouse\_focus() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_lose_mouse_focus}\pysiglinewithargsret{\code{Game.}\bfcode{event\_lose\_mouse\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.MouseFocusLose]{\emph{\code{sge.input.MouseFocusLose}}}} for
more information.

\end{fulllineitems}

\index{event\_close() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_close}\pysiglinewithargsret{\code{Game.}\bfcode{event\_close}}{}{}
See the documentation for {\hyperref[input:sge.input.QuitRequest]{\emph{\code{sge.input.QuitRequest}}}} for
more information.

This is always called after any {\hyperref[dsp:sge.dsp.Room.event_close]{\emph{\code{sge.dsp.Room.event\_close()}}}}
occurring at the same time.

\end{fulllineitems}

\index{event\_mouse\_collision() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_mouse_collision}\pysiglinewithargsret{\code{Game.}\bfcode{event\_mouse\_collision}}{\emph{other}, \emph{xdirection}, \emph{ydirection}}{}
Proxy for \code{sge.game.mouse.event\_collision()}.  See the
documentation for {\hyperref[dsp:sge.dsp.Object.event_collision]{\emph{\code{sge.dsp.Object.event\_collision()}}}} for
more information.

\end{fulllineitems}

\index{event\_paused\_step() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_step}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_step}}{\emph{time\_passed}, \emph{delta\_mult}}{}
See the documentation for {\hyperref[dsp:sge.dsp.Game.event_step]{\emph{\code{sge.dsp.Game.event\_step()}}}} for
more information.

\end{fulllineitems}

\index{event\_paused\_key\_press() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_key_press}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_key\_press}}{\emph{key}, \emph{char}}{}
See the documentation for {\hyperref[input:sge.input.KeyPress]{\emph{\code{sge.input.KeyPress}}}} for more
information.

\end{fulllineitems}

\index{event\_paused\_key\_release() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_key_release}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_key\_release}}{\emph{key}}{}
See the documentation for {\hyperref[input:sge.input.KeyRelease]{\emph{\code{sge.input.KeyRelease}}}} for more
information.

\end{fulllineitems}

\index{event\_paused\_mouse\_move() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_mouse_move}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_mouse\_move}}{\emph{x}, \emph{y}}{}
See the documentation for {\hyperref[input:sge.input.MouseMove]{\emph{\code{sge.input.MouseMove}}}} for more
information.

\end{fulllineitems}

\index{event\_paused\_mouse\_button\_press() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_mouse_button_press}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_mouse\_button\_press}}{\emph{button}}{}
See the documentation for {\hyperref[input:sge.input.MouseButtonPress]{\emph{\code{sge.input.MouseButtonPress}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_mouse\_button\_release() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_mouse_button_release}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_mouse\_button\_release}}{\emph{button}}{}
See the documentation for {\hyperref[input:sge.input.MouseButtonRelease]{\emph{\code{sge.input.MouseButtonRelease}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_joystick() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_joystick}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_joystick}}{\emph{js\_name}, \emph{js\_id}, \emph{input\_type}, \emph{input\_id}, \emph{value}}{}
See the documentation for \code{sge.input.JoystickEvent} for
more information.

\end{fulllineitems}

\index{event\_paused\_joystick\_axis\_move() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_joystick_axis_move}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_joystick\_axis\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{axis}, \emph{value}}{}
See the documentation for {\hyperref[input:sge.input.JoystickAxisMove]{\emph{\code{sge.input.JoystickAxisMove}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_joystick\_hat\_move() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_joystick_hat_move}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_joystick\_hat\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{hat}, \emph{x}, \emph{y}}{}
See the documentation for {\hyperref[input:sge.input.JoystickHatMove]{\emph{\code{sge.input.JoystickHatMove}}}} for
more information.

\end{fulllineitems}

\index{event\_paused\_joystick\_trackball\_move() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_joystick_trackball_move}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_joystick\_trackball\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{ball}, \emph{x}, \emph{y}}{}
See the documentation for
{\hyperref[input:sge.input.JoystickTrackballMove]{\emph{\code{sge.input.JoystickTrackballMove}}}} for more information.

\end{fulllineitems}

\index{event\_paused\_joystick\_button\_press() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_joystick_button_press}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_joystick\_button\_press}}{\emph{js\_name}, \emph{js\_id}, \emph{button}}{}
See the documentation for {\hyperref[input:sge.input.JoystickButtonPress]{\emph{\code{sge.input.JoystickButtonPress}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_joystick\_button\_release() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_joystick_button_release}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_joystick\_button\_release}}{\emph{js\_name}, \emph{js\_id}, \emph{button}}{}
See the documentation for
{\hyperref[input:sge.input.JoystickButtonRelease]{\emph{\code{sge.input.JoystickButtonRelease}}}} for more information.

\end{fulllineitems}

\index{event\_paused\_gain\_keyboard\_focus() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_gain_keyboard_focus}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_gain\_keyboard\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.KeyboardFocusGain]{\emph{\code{sge.input.KeyboardFocusGain}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_lose\_keyboard\_focus() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_lose_keyboard_focus}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_lose\_keyboard\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.KeyboardFocusLose]{\emph{\code{sge.input.KeyboardFocusLose}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_gain\_mouse\_focus() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_gain_mouse_focus}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_gain\_mouse\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.MouseFocusGain]{\emph{\code{sge.input.MouseFocusGain}}}} for
more information.

\end{fulllineitems}

\index{event\_paused\_lose\_mouse\_focus() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_lose_mouse_focus}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_lose\_mouse\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.MouseFocusLose]{\emph{\code{sge.input.MouseFocusLose}}}} for
more information.

\end{fulllineitems}

\index{event\_paused\_close() (sge.dsp.Game method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Game.event_paused_close}\pysiglinewithargsret{\code{Game.}\bfcode{event\_paused\_close}}{}{}
See the documentation for {\hyperref[dsp:sge.dsp.Game.event_close]{\emph{\code{sge.dsp.Game.event\_close()}}}} for
more information.

\end{fulllineitems}



\subsection{sge.dsp.Room}
\label{dsp:sge-dsp-room}\index{Room (class in sge.dsp)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room}\pysiglinewithargsret{\strong{class }\code{sge.dsp.}\bfcode{Room}}{\emph{objects=()}, \emph{width=None}, \emph{height=None}, \emph{views=None}, \emph{background=None}, \emph{background\_x=0}, \emph{background\_y=0}, \emph{object\_area\_width=None}, \emph{object\_area\_height=None}}{}
This class stores the settings and objects found in a room.  Rooms
are used to create separate parts of the game, such as levels and
menu screens.
\index{width (sge.dsp.Room attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.width}\pysigline{\bfcode{width}}
The width of the room in pixels.  If set to \code{None},
\code{sge.game.width} is used.

\end{fulllineitems}

\index{height (sge.dsp.Room attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.height}\pysigline{\bfcode{height}}
The height of the room in pixels.  If set to \code{None},
\code{sge.game.height} is used.

\end{fulllineitems}

\index{views (sge.dsp.Room attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.views}\pysigline{\bfcode{views}}
A list containing all {\hyperref[dsp:sge.dsp.View]{\emph{\code{sge.dsp.View}}}} objects in the room.

\end{fulllineitems}

\index{background (sge.dsp.Room attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.background}\pysigline{\bfcode{background}}
The {\hyperref[gfx:sge.gfx.Background]{\emph{\code{sge.gfx.Background}}}} object used.

\end{fulllineitems}

\index{background\_x (sge.dsp.Room attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.background_x}\pysigline{\bfcode{background\_x}}
The horizontal position of the background in the room.

\end{fulllineitems}

\index{background\_y (sge.dsp.Room attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.background_y}\pysigline{\bfcode{background\_y}}
The vertical position of the background in the room.

\end{fulllineitems}

\index{object\_area\_width (sge.dsp.Room attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.object_area_width}\pysigline{\bfcode{object\_area\_width}}
The width of this room's object areas in pixels.  If set to
\code{None}, \code{sge.game.width} is used.  For optimum
performance, this should generally be about the average width of
objects in the room which check for collisions.

\end{fulllineitems}

\index{object\_area\_height (sge.dsp.Room attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.object_area_height}\pysigline{\bfcode{object\_area\_height}}
The height of this room's object areas in pixels.  If set to
\code{None}, \code{sge.game.height} is used.  For optimum
performance, this should generally be about the average height of
objects in the room which check for collisions.

\end{fulllineitems}

\index{alarms (sge.dsp.Room attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.alarms}\pysigline{\bfcode{alarms}}
A dictionary containing the alarms of the room.  Each value
decreases by 1 each frame (adjusted for delta timing if it is
enabled).  When a value is at or below 0,
{\hyperref[dsp:sge.dsp.Room.event_alarm]{\emph{\code{event\_alarm()}}}} is executed with \code{alarm\_id} set to the
respective key, and the item is deleted from this dictionary.

\end{fulllineitems}

\index{objects (sge.dsp.Room attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.objects}\pysigline{\bfcode{objects}}
A list containing all {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} objects in the
room.  (Read-only)

\end{fulllineitems}

\index{object\_areas (sge.dsp.Room attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.object_areas}\pysigline{\bfcode{object\_areas}}
A 2-dimensional list of object areas, indexed in the following
way:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{object\PYGZus{}areas}\PYG{p}{[}\PYG{n}{x}\PYG{p}{]}\PYG{p}{[}\PYG{n}{y}\PYG{p}{]}
\end{Verbatim}

Where \code{x} is the horizontal location of the left edge of the
area in the room divided by {\hyperref[dsp:sge.dsp.Room.object_area_width]{\emph{\code{object\_area\_width}}}}, and \code{y}
is the vertical location of the top edge of the area in the room
divided by {\hyperref[dsp:sge.dsp.Room.object_area_height]{\emph{\code{object\_area\_height}}}}.

For example, if {\hyperref[dsp:sge.dsp.Room.object_area_width]{\emph{\code{object\_area\_width}}}} is \code{32} and
{\hyperref[dsp:sge.dsp.Room.object_area_height]{\emph{\code{object\_area\_height}}}} is \code{48}, then
\code{object\_areas{[}2{]}{[}4{]}} indicates the object area with an x
location of 64 and a y location of 192.

Each object area is a set containing {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}}
objects whose sprites or bounding boxes reside within the object
area.

Object areas are only created within the room, i.e. the
horizontal location of an object area will always be less than
{\hyperref[dsp:sge.dsp.Room.width]{\emph{\code{width}}}}, and the vertical location of an object area will
always be less than {\hyperref[dsp:sge.dsp.Room.height]{\emph{\code{height}}}}.  Depending on the size of
collision areas and the size of the room, however, the last row
and/or the last column of collision areas may partially reside
outside of the room.

\begin{notice}{note}{Note:}
It is generally easier to use {\hyperref[dsp:sge.dsp.Room.get_objects_at]{\emph{\code{get\_objects\_at()}}}} than to
access this list directly.
\end{notice}

\end{fulllineitems}

\index{object\_area\_void (sge.dsp.Room attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.object_area_void}\pysigline{\bfcode{object\_area\_void}}
A set containing {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} objects whose sprites or
bounding boxes reside within any area not covered by the room's
object area.

\begin{notice}{note}{Note:}
Depending on the size of object areas and the size of the
room, the ``void'' area may not include the entirety of the
outside of the room.  There may be some space to the right of
and/or below the room which is covered by collision areas.
\end{notice}

\end{fulllineitems}

\index{rd (sge.dsp.Room attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.rd}\pysigline{\bfcode{rd}}
Reserved dictionary for internal use by the SGE.  (Read-only)

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{sge.dsp.Room Methods}
\label{dsp:sge-dsp-room-methods}\index{\_\_init\_\_() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.__init__}\pysiglinewithargsret{\code{Room.}\bfcode{\_\_init\_\_}}{\emph{objects=()}, \emph{width=None}, \emph{height=None}, \emph{views=None}, \emph{background=None}, \emph{background\_x=0}, \emph{background\_y=0}, \emph{object\_area\_width=None}, \emph{object\_area\_height=None}}{}
Arguments:
\begin{itemize}
\item {} 
\code{views} -- A list containing all {\hyperref[dsp:sge.dsp.View]{\emph{\code{sge.dsp.View}}}}
objects in the room.  If set to \code{None}, a new view will
be created with \code{x=0}, \code{y=0}, and all other arguments
unspecified, which will become the first view of the room.

\item {} 
\code{background} -- The {\hyperref[gfx:sge.gfx.Background]{\emph{\code{sge.gfx.Background}}}} object used.
If set to \code{None}, a new background will be created with
no layers and the color set to black.

\end{itemize}

All other arguments set the respective initial attributes of the
room.  See the documentation for {\hyperref[dsp:sge.dsp.Room]{\emph{\code{sge.dsp.Room}}}} for more
information.

\end{fulllineitems}

\index{add() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.add}\pysiglinewithargsret{\code{Room.}\bfcode{add}}{\emph{obj}}{}
Add an object to the room.

Arguments:
\begin{itemize}
\item {} 
\code{obj} -- The {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} object to add.

\end{itemize}

\begin{notice}{warning}{Warning:}
This method modifies the contents of {\hyperref[dsp:sge.dsp.Room.objects]{\emph{\code{objects}}}}.  Do not
call this method during a loop through {\hyperref[dsp:sge.dsp.Room.objects]{\emph{\code{objects}}}}; doing
so may cause problems with the loop. To get around this, you
can create a shallow copy of {\hyperref[dsp:sge.dsp.Room.objects]{\emph{\code{objects}}}} to iterate
through instead, e.g.:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{for} \PYG{n}{obj} \PYG{o+ow}{in} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{objects}\PYG{p}{[}\PYG{p}{:}\PYG{p}{]}\PYG{p}{:}
    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{add}\PYG{p}{(}\PYG{n}{obj}\PYG{o}{.}\PYG{n}{friend}\PYG{p}{)}
\end{Verbatim}
\end{notice}

\end{fulllineitems}

\index{remove() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.remove}\pysiglinewithargsret{\code{Room.}\bfcode{remove}}{\emph{obj}}{}
Remove an object from the room.

Arguments:
\begin{itemize}
\item {} 
\code{obj} -- The {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} object to remove.

\end{itemize}

\begin{notice}{warning}{Warning:}
This method modifies the contents of {\hyperref[dsp:sge.dsp.Room.objects]{\emph{\code{objects}}}}.  Do not
call this method during a loop through {\hyperref[dsp:sge.dsp.Room.objects]{\emph{\code{objects}}}}; doing
so may cause problems with the loop. To get around this, you
can create a shallow copy of {\hyperref[dsp:sge.dsp.Room.objects]{\emph{\code{objects}}}} to iterate
through instead, e.g.:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{for} \PYG{n}{obj} \PYG{o+ow}{in} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{objects}\PYG{p}{[}\PYG{p}{:}\PYG{p}{]}\PYG{p}{:}
    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{remove}\PYG{p}{(}\PYG{n}{obj}\PYG{p}{)}
\end{Verbatim}
\end{notice}

\end{fulllineitems}

\index{start() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.start}\pysiglinewithargsret{\code{Room.}\bfcode{start}}{\emph{transition=None}, \emph{transition\_time=1500}, \emph{transition\_arg=None}}{}
Start the room.

Arguments:
\begin{itemize}
\item {} 
\code{transition} -- The type of transition to use.  Should be
one of the following:
\begin{itemize}
\item {} 
\code{None} (no transition)

\item {} 
\code{"fade"} (fade to black)

\item {} 
\code{"dissolve"}

\item {} 
\code{"pixelate"}

\item {} 
\code{"wipe\_left"} (wipe right to left)

\item {} 
\code{"wipe\_right"} (wipe left to right)

\item {} 
\code{"wipe\_up"} (wipe bottom to top)

\item {} 
\code{"wipe\_down"} (wipe top to bottom)

\item {} 
\code{"wipe\_upleft"} (wipe bottom-right to top-left)

\item {} 
\code{"wipe\_upright"} (wipe bottom-left to top-right)

\item {} 
\code{"wipe\_downleft"} (wipe top-right to bottom-left)

\item {} 
\code{"wipe\_downright"} (wipe top-left to bottom-right)

\item {} 
\code{"wipe\_matrix"}

\item {} 
\code{"iris\_in"}

\item {} 
\code{"iris\_out"}

\end{itemize}

If an unsupported value is given, default to \code{None}.

\item {} 
\code{transition\_time} -- The time the transition should take in
milliseconds.  Has no effect if \code{transition} is
\code{None}.

\item {} 
\code{transition\_arg} -- An arbitrary argument that can be used
by the following transitions:
\begin{itemize}
\item {} 
\code{"wipe\_matrix"} -- The size of each square in the matrix
transition as a tuple in the form \code{(w, h)}, where \code{w} is
the width and \code{h} is the height.  Default is \code{(4, 4)}.

\item {} 
\code{"iris\_in"} and \code{"iris\_out"} -- The position of the
center of the iris as a tuple in the form \code{(x, y)}, where
\code{x} is the horizontal location relative to the window and
\code{y} is the vertical location relative to the window.
Default is the center of the window.

\end{itemize}

\end{itemize}

\end{fulllineitems}

\index{get\_objects\_at() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.get_objects_at}\pysiglinewithargsret{\code{Room.}\bfcode{get\_objects\_at}}{\emph{x}, \emph{y}, \emph{width}, \emph{height}}{}
Return a set of objects near a particular area.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the room of the
left edge of the area.

\item {} 
\code{y} -- The vertical location relative to the room of the
top edge of the area.

\item {} 
\code{width} -- The width of the area in pixels.

\item {} 
\code{height} -- The height of the area in pixels.

\end{itemize}

\begin{notice}{note}{Note:}
This function does not ensure that objects returned are
actually \emph{within} the given area.  It simply combines all
object areas that need to be checked into a single set.  To
ensure that an object is actually within the area, you must
check the object manually, or use
{\hyperref[collision:sge.collision.rectangle]{\emph{\code{sge.collision.rectangle()}}}} instead.
\end{notice}

\end{fulllineitems}

\index{project\_dot() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.project_dot}\pysiglinewithargsret{\code{Room.}\bfcode{project\_dot}}{\emph{x}, \emph{y}, \emph{z}, \emph{color}, \emph{blend\_mode=None}}{}
Project a single-pixel dot onto the room.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the room to
project the dot.

\item {} 
\code{y} -- The vertical location relative to the room to project
the dot.

\item {} 
\code{z} -- The Z-axis position of the projection in the room.

\end{itemize}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_dot]{\emph{\code{sge.gfx.Sprite.draw\_dot()}}}} for
more information.

\end{fulllineitems}

\index{project\_line() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.project_line}\pysiglinewithargsret{\code{Room.}\bfcode{project\_line}}{\emph{x1}, \emph{y1}, \emph{x2}, \emph{y2}, \emph{z}, \emph{color}, \emph{thickness=1}, \emph{anti\_alias=False}, \emph{blend\_mode=None}}{}
Project a line segment onto the room.

Arguments:
\begin{itemize}
\item {} 
\code{x1} -- The horizontal location relative to the room of the
first endpoint of the projected line segment.

\item {} 
\code{y1} -- The vertical location relative to the room of the
first endpoint of the projected line segment.

\item {} 
\code{x2} -- The horizontal location relative to the room of the
second endpoint of the projected line segment.

\item {} 
\code{y2} -- The vertical location relative to the room of the
second endpoint of the projected line segment.

\item {} 
\code{z} -- The Z-axis position of the projection in the room.

\end{itemize}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_line]{\emph{\code{sge.gfx.Sprite.draw\_line()}}}} for
more information.

\end{fulllineitems}

\index{project\_rectangle() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.project_rectangle}\pysiglinewithargsret{\code{Room.}\bfcode{project\_rectangle}}{\emph{x}, \emph{y}, \emph{z}, \emph{width}, \emph{height}, \emph{fill=None}, \emph{outline=None}, \emph{outline\_thickness=1}, \emph{blend\_mode=None}}{}
Project a rectangle onto the room.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the room to
project the rectangle.

\item {} 
\code{y} -- The vertical location relative to the room to project
the rectangle.

\item {} 
\code{z} -- The Z-axis position of the projection in the room.

\end{itemize}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_rectangle]{\emph{\code{sge.gfx.Sprite.draw\_rectangle()}}}}
for more information.

\end{fulllineitems}

\index{project\_ellipse() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.project_ellipse}\pysiglinewithargsret{\code{Room.}\bfcode{project\_ellipse}}{\emph{x}, \emph{y}, \emph{z}, \emph{width}, \emph{height}, \emph{fill=None}, \emph{outline=None}, \emph{outline\_thickness=1}, \emph{anti\_alias=False}, \emph{blend\_mode=None}}{}
Project an ellipse onto the room.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the room to
position the imaginary rectangle containing the ellipse.

\item {} 
\code{y} -- The vertical location relative to the room to
position the imaginary rectangle containing the ellipse.

\item {} 
\code{z} -- The Z-axis position of the projection in the room.

\item {} 
\code{width} -- The width of the ellipse.

\item {} 
\code{height} -- The height of the ellipse.

\item {} 
\code{outline\_thickness} -- The thickness of the outline of the
ellipse.

\item {} 
\code{anti\_alias} -- Whether or not anti-aliasing should be used.

\end{itemize}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_ellipse]{\emph{\code{sge.gfx.Sprite.draw\_ellipse()}}}}
for more information.

\end{fulllineitems}

\index{project\_circle() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.project_circle}\pysiglinewithargsret{\code{Room.}\bfcode{project\_circle}}{\emph{x}, \emph{y}, \emph{z}, \emph{radius}, \emph{fill=None}, \emph{outline=None}, \emph{outline\_thickness=1}, \emph{anti\_alias=False}, \emph{blend\_mode=None}}{}
Project a circle onto the room.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the room to
position the center of the circle.

\item {} 
\code{y} -- The vertical location relative to the room to
position the center of the circle.

\item {} 
\code{z} -- The Z-axis position of the projection in the room.

\end{itemize}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_circle]{\emph{\code{sge.gfx.Sprite.draw\_circle()}}}} for
more information.

\end{fulllineitems}

\index{project\_polygon() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.project_polygon}\pysiglinewithargsret{\code{Room.}\bfcode{project\_polygon}}{\emph{points}, \emph{z}, \emph{fill=None}, \emph{outline=None}, \emph{outline\_thickness=1}, \emph{anti\_alias=False}, \emph{blend\_mode=None}}{}
Draw a polygon on the sprite.

Arguments:
\begin{itemize}
\item {} 
\code{points} -- A list of points relative to the room to
position each of the polygon's angles.  Each point should be a
tuple in the form \code{(x, y)}, where x is the horizontal
location and y is the vertical location.

\item {} 
\code{z} -- The Z-axis position of the projection in the room.

\end{itemize}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_polygon]{\emph{\code{sge.gfx.Sprite.draw\_polygon()}}}}
for more information.

\end{fulllineitems}

\index{project\_sprite() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.project_sprite}\pysiglinewithargsret{\code{Room.}\bfcode{project\_sprite}}{\emph{sprite}, \emph{image}, \emph{x}, \emph{y}, \emph{z}, \emph{blend\_mode=None}}{}
Project a sprite onto the room.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the room to
project \code{sprite}.

\item {} 
\code{y} -- The vertical location relative to the room to project
\code{sprite}.

\item {} 
\code{z} -- The Z-axis position of the projection in the room.

\end{itemize}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_sprite]{\emph{\code{sge.gfx.Sprite.draw\_sprite()}}}} for
more information.

\end{fulllineitems}

\index{project\_text() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.project_text}\pysiglinewithargsret{\code{Room.}\bfcode{project\_text}}{\emph{font}, \emph{text}, \emph{x}, \emph{y}, \emph{z}, \emph{width=None}, \emph{height=None}, \emph{color=sge.gfx.Color(``white'')}, \emph{halign='left'}, \emph{valign='top'}, \emph{anti\_alias=True}, \emph{blend\_mode=None}}{}
Project text onto the room.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the room to
project the text.

\item {} 
\code{y} -- The vertical location relative to the room to project
the text.

\item {} 
\code{z} -- The Z-axis position of the projection in the room.

\end{itemize}

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_text]{\emph{\code{sge.gfx.Sprite.draw\_text()}}}} for
more information.

\end{fulllineitems}



\subsubsection{sge.dsp.Room Event Methods}
\label{dsp:sge-dsp-room-event-methods}\index{event\_room\_start() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_room_start}\pysiglinewithargsret{\code{Room.}\bfcode{event\_room\_start}}{}{}
Called when the room is started for the first time.  It is
always called after any \code{sge.dsp.Game.event\_game\_start()}
and before any {\hyperref[dsp:sge.dsp.Object.event_create]{\emph{\code{sge.dsp.Object.event\_create}}}} occurring at
the same time.

\end{fulllineitems}

\index{event\_room\_resume() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_room_resume}\pysiglinewithargsret{\code{Room.}\bfcode{event\_room\_resume}}{}{}
Called when the room is started after it has already previously
been started.  It is always called before any
{\hyperref[dsp:sge.dsp.Object.event_create]{\emph{\code{sge.dsp.Object.event\_create()}}}} occurring at the same time.

\end{fulllineitems}

\index{event\_room\_end() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_room_end}\pysiglinewithargsret{\code{Room.}\bfcode{event\_room\_end}}{}{}
Called when another room is started or the game ends while this
room is the current room.  It is always called before any
\code{sge.dsp.Game.event\_game\_end()} occurring at the same time.

\end{fulllineitems}

\index{event\_step() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_step}\pysiglinewithargsret{\code{Room.}\bfcode{event\_step}}{\emph{time\_passed}, \emph{delta\_mult}}{}
See the documentation for {\hyperref[dsp:sge.dsp.Game.event_step]{\emph{\code{sge.dsp.Game.event\_step()}}}} for
more information.

\end{fulllineitems}

\index{event\_alarm() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_alarm}\pysiglinewithargsret{\code{Room.}\bfcode{event\_alarm}}{\emph{alarm\_id}}{}
See the documentation for {\hyperref[dsp:sge.dsp.Room.alarms]{\emph{\code{sge.dsp.Room.alarms}}}} for more
information.

\end{fulllineitems}

\index{event\_key\_press() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_key_press}\pysiglinewithargsret{\code{Room.}\bfcode{event\_key\_press}}{\emph{key}, \emph{char}}{}
See the documentation for {\hyperref[input:sge.input.KeyPress]{\emph{\code{sge.input.KeyPress}}}} for more
information.

\end{fulllineitems}

\index{event\_key\_release() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_key_release}\pysiglinewithargsret{\code{Room.}\bfcode{event\_key\_release}}{\emph{key}}{}
See the documentation for {\hyperref[input:sge.input.KeyRelease]{\emph{\code{sge.input.KeyRelease}}}} for more
information.

\end{fulllineitems}

\index{event\_mouse\_move() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_mouse_move}\pysiglinewithargsret{\code{Room.}\bfcode{event\_mouse\_move}}{\emph{x}, \emph{y}}{}
See the documentation for {\hyperref[input:sge.input.MouseMove]{\emph{\code{sge.input.MouseMove}}}} for more
information.

\end{fulllineitems}

\index{event\_mouse\_button\_press() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_mouse_button_press}\pysiglinewithargsret{\code{Room.}\bfcode{event\_mouse\_button\_press}}{\emph{button}}{}
Mouse button press event.

See the documentation for {\hyperref[input:sge.input.MouseButtonPress]{\emph{\code{sge.input.MouseButtonPress}}}}
for more information.

\end{fulllineitems}

\index{event\_mouse\_button\_release() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_mouse_button_release}\pysiglinewithargsret{\code{Room.}\bfcode{event\_mouse\_button\_release}}{\emph{button}}{}
See the documentation for {\hyperref[input:sge.input.MouseButtonRelease]{\emph{\code{sge.input.MouseButtonRelease}}}}
for more information.

\end{fulllineitems}

\index{event\_joystick() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_joystick}\pysiglinewithargsret{\code{Room.}\bfcode{event\_joystick}}{\emph{js\_name}, \emph{js\_id}, \emph{input\_type}, \emph{input\_id}, \emph{value}}{}
See the documentation for \code{sge.input.JoystickEvent} for
more information.

\end{fulllineitems}

\index{event\_joystick\_axis\_move() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_joystick_axis_move}\pysiglinewithargsret{\code{Room.}\bfcode{event\_joystick\_axis\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{axis}, \emph{value}}{}
See the documentation for {\hyperref[input:sge.input.JoystickAxisMove]{\emph{\code{sge.input.JoystickAxisMove}}}}
for more information.

\end{fulllineitems}

\index{event\_joystick\_hat\_move() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_joystick_hat_move}\pysiglinewithargsret{\code{Room.}\bfcode{event\_joystick\_hat\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{hat}, \emph{x}, \emph{y}}{}
See the documentation for {\hyperref[input:sge.input.JoystickHatMove]{\emph{\code{sge.input.JoystickHatMove}}}} for
more information.

\end{fulllineitems}

\index{event\_joystick\_trackball\_move() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_joystick_trackball_move}\pysiglinewithargsret{\code{Room.}\bfcode{event\_joystick\_trackball\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{ball}, \emph{x}, \emph{y}}{}
See the documentation for
{\hyperref[input:sge.input.JoystickTrackballMove]{\emph{\code{sge.input.JoystickTrackballMove}}}} for more information.

\end{fulllineitems}

\index{event\_joystick\_button\_press() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_joystick_button_press}\pysiglinewithargsret{\code{Room.}\bfcode{event\_joystick\_button\_press}}{\emph{js\_name}, \emph{js\_id}, \emph{button}}{}
See the documentation for {\hyperref[input:sge.input.JoystickButtonPress]{\emph{\code{sge.input.JoystickButtonPress}}}}
for more information.

\end{fulllineitems}

\index{event\_joystick\_button\_release() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_joystick_button_release}\pysiglinewithargsret{\code{Room.}\bfcode{event\_joystick\_button\_release}}{\emph{js\_name}, \emph{js\_id}, \emph{button}}{}
See the documentation for
{\hyperref[input:sge.input.JoystickButtonRelease]{\emph{\code{sge.input.JoystickButtonRelease}}}} for more information.

\end{fulllineitems}

\index{event\_gain\_keyboard\_focus() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_gain_keyboard_focus}\pysiglinewithargsret{\code{Room.}\bfcode{event\_gain\_keyboard\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.KeyboardFocusGain]{\emph{\code{sge.input.KeyboardFocusGain}}}}
for more information.

\end{fulllineitems}

\index{event\_lose\_keyboard\_focus() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_lose_keyboard_focus}\pysiglinewithargsret{\code{Room.}\bfcode{event\_lose\_keyboard\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.KeyboardFocusLose]{\emph{\code{sge.input.KeyboardFocusLose}}}}
for more information.

\end{fulllineitems}

\index{event\_gain\_mouse\_focus() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_gain_mouse_focus}\pysiglinewithargsret{\code{Room.}\bfcode{event\_gain\_mouse\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.MouseFocusGain]{\emph{\code{sge.input.MouseFocusGain}}}} for
more information.

\end{fulllineitems}

\index{event\_lose\_mouse\_focus() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_lose_mouse_focus}\pysiglinewithargsret{\code{Room.}\bfcode{event\_lose\_mouse\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.MouseFocusLose]{\emph{\code{sge.input.MouseFocusLose}}}} for
more information.

\end{fulllineitems}

\index{event\_close() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_close}\pysiglinewithargsret{\code{Room.}\bfcode{event\_close}}{}{}
This is always called before any
{\hyperref[dsp:sge.dsp.Game.event_close]{\emph{\code{sge.dsp.Game.event\_close()}}}} occurring at the same time.

See the documentation for {\hyperref[input:sge.input.QuitRequest]{\emph{\code{sge.input.QuitRequest}}}} for
more information.

\end{fulllineitems}

\index{event\_paused\_step() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_step}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_step}}{\emph{time\_passed}, \emph{delta\_mult}}{}
See the documentation for {\hyperref[dsp:sge.dsp.Game.event_step]{\emph{\code{sge.dsp.Game.event\_step()}}}} for
more information.

\end{fulllineitems}

\index{event\_paused\_key\_press() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_key_press}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_key\_press}}{\emph{key}, \emph{char}}{}
See the documentation for {\hyperref[input:sge.input.KeyPress]{\emph{\code{sge.input.KeyPress}}}} for more
information.

\end{fulllineitems}

\index{event\_paused\_key\_release() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_key_release}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_key\_release}}{\emph{key}}{}
See the documentation for {\hyperref[input:sge.input.KeyRelease]{\emph{\code{sge.input.KeyRelease}}}} for more
information.

\end{fulllineitems}

\index{event\_paused\_mouse\_move() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_mouse_move}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_mouse\_move}}{\emph{x}, \emph{y}}{}
See the documentation for {\hyperref[input:sge.input.MouseMove]{\emph{\code{sge.input.MouseMove}}}} for more
information.

\end{fulllineitems}

\index{event\_paused\_mouse\_button\_press() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_mouse_button_press}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_mouse\_button\_press}}{\emph{button}}{}
See the documentation for {\hyperref[input:sge.input.MouseButtonPress]{\emph{\code{sge.input.MouseButtonPress}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_mouse\_button\_release() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_mouse_button_release}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_mouse\_button\_release}}{\emph{button}}{}
See the documentation for {\hyperref[input:sge.input.MouseButtonRelease]{\emph{\code{sge.input.MouseButtonRelease}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_joystick() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_joystick}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_joystick}}{\emph{js\_name}, \emph{js\_id}, \emph{input\_type}, \emph{input\_id}, \emph{value}}{}
See the documentation for \code{sge.input.JoystickEvent} for
more information.

\end{fulllineitems}

\index{event\_paused\_joystick\_axis\_move() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_joystick_axis_move}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_joystick\_axis\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{axis}, \emph{value}}{}
See the documentation for {\hyperref[input:sge.input.JoystickAxisMove]{\emph{\code{sge.input.JoystickAxisMove}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_joystick\_hat\_move() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_joystick_hat_move}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_joystick\_hat\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{hat}, \emph{x}, \emph{y}}{}
See the documentation for {\hyperref[input:sge.input.JoystickHatMove]{\emph{\code{sge.input.JoystickHatMove}}}} for
more information.

\end{fulllineitems}

\index{event\_paused\_joystick\_trackball\_move() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_joystick_trackball_move}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_joystick\_trackball\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{ball}, \emph{x}, \emph{y}}{}
See the documentation for
{\hyperref[input:sge.input.JoystickTrackballMove]{\emph{\code{sge.input.JoystickTrackballMove}}}} for more information.

\end{fulllineitems}

\index{event\_paused\_joystick\_button\_press() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_joystick_button_press}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_joystick\_button\_press}}{\emph{js\_name}, \emph{js\_id}, \emph{button}}{}
See the documentation for {\hyperref[input:sge.input.JoystickButtonPress]{\emph{\code{sge.input.JoystickButtonPress}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_joystick\_button\_release() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_joystick_button_release}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_joystick\_button\_release}}{\emph{js\_name}, \emph{js\_id}, \emph{button}}{}
See the documentation for
{\hyperref[input:sge.input.JoystickButtonRelease]{\emph{\code{sge.input.JoystickButtonRelease}}}} for more information.

\end{fulllineitems}

\index{event\_paused\_gain\_keyboard\_focus() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_gain_keyboard_focus}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_gain\_keyboard\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.KeyboardFocusGain]{\emph{\code{sge.input.KeyboardFocusGain}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_lose\_keyboard\_focus() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_lose_keyboard_focus}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_lose\_keyboard\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.KeyboardFocusLose]{\emph{\code{sge.input.KeyboardFocusLose}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_gain\_mouse\_focus() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_gain_mouse_focus}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_gain\_mouse\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.MouseFocusGain]{\emph{\code{sge.input.MouseFocusGain}}}} for
more information.

\end{fulllineitems}

\index{event\_paused\_lose\_mouse\_focus() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_lose_mouse_focus}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_lose\_mouse\_focus}}{}{}
See the documentation for {\hyperref[input:sge.input.MouseFocusLose]{\emph{\code{sge.input.MouseFocusLose}}}} for
more information.

\end{fulllineitems}

\index{event\_paused\_close() (sge.dsp.Room method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Room.event_paused_close}\pysiglinewithargsret{\code{Room.}\bfcode{event\_paused\_close}}{}{}
See the documentation for {\hyperref[dsp:sge.dsp.Room.event_close]{\emph{\code{sge.dsp.Room.event\_close()}}}} for
more information.

\end{fulllineitems}



\subsection{sge.dsp.View}
\label{dsp:sge-dsp-view}\index{View (class in sge.dsp)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.View}\pysiglinewithargsret{\strong{class }\code{sge.dsp.}\bfcode{View}}{\emph{x}, \emph{y}, \emph{xport=0}, \emph{yport=0}, \emph{width=None}, \emph{height=None}, \emph{wport=None}, \emph{hport=None}}{}
This class controls what the player sees in a room at any given
time.  Multiple views can exist in a room, and this can be used to
create a split-screen effect.
\index{x (sge.dsp.View attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.View.x}\pysigline{\bfcode{x}}
The horizontal position of the view in the room.  When set, if it
brings the view outside of the room it is in, it will be
re-adjusted so that the view is completely inside the room.

\end{fulllineitems}

\index{y (sge.dsp.View attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.View.y}\pysigline{\bfcode{y}}
The vertical position of the view in the room.  When set, if it
brings the view outside of the room it is in, it will be
re-adjusted so that the view is completely inside the room.

\end{fulllineitems}

\index{xport (sge.dsp.View attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.View.xport}\pysigline{\bfcode{xport}}
The horizontal position of the view port on the window.

\end{fulllineitems}

\index{yport (sge.dsp.View attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.View.yport}\pysigline{\bfcode{yport}}
The vertical position of the view port on the window.

\end{fulllineitems}

\index{width (sge.dsp.View attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.View.width}\pysigline{\bfcode{width}}
The width of the view.  When set, if it results in the view being
outside of the room it is in, {\hyperref[dsp:sge.dsp.View.x]{\emph{\code{x}}}} will be adjusted so that
the view is completely inside the room.

\end{fulllineitems}

\index{height (sge.dsp.View attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.View.height}\pysigline{\bfcode{height}}
The height of the view.  When set, if it results in the view
being outside the room it is in, {\hyperref[dsp:sge.dsp.View.y]{\emph{\code{y}}}} will be adjusted so
that the view is completely inside the room.

\end{fulllineitems}

\index{wport (sge.dsp.View attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.View.wport}\pysigline{\bfcode{wport}}
The width of the view port.  Set to \code{None} to make it the
same as {\hyperref[dsp:sge.dsp.View.width]{\emph{\code{width}}}}.  If this value differs from {\hyperref[dsp:sge.dsp.View.width]{\emph{\code{width}}}},
the image will be horizontally scaled so that it fills the port.

\end{fulllineitems}

\index{hport (sge.dsp.View attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.View.hport}\pysigline{\bfcode{hport}}
The height of the view port.  Set to \code{None} to make it the
same as {\hyperref[dsp:sge.dsp.View.height]{\emph{\code{height}}}}.  If this value differs from
{\hyperref[dsp:sge.dsp.View.height]{\emph{\code{height}}}}, the image will be vertically scaled so that it
fills the port.

\end{fulllineitems}

\index{rd (sge.dsp.View attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.View.rd}\pysigline{\bfcode{rd}}
Reserved dictionary for internal use by the SGE.  (Read-only)

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{sge.dsp.View Methods}
\label{dsp:sge-dsp-view-methods}\index{\_\_init\_\_() (sge.dsp.View method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.View.__init__}\pysiglinewithargsret{\code{View.}\bfcode{\_\_init\_\_}}{\emph{x}, \emph{y}, \emph{xport=0}, \emph{yport=0}, \emph{width=None}, \emph{height=None}, \emph{wport=None}, \emph{hport=None}}{}
Arguments:
\begin{itemize}
\item {} 
\code{width} -- The width of the view.  If set to \code{None},
it will become \code{sge.game.width - xport}.

\item {} 
\code{height} -- The height of the view.  If set to
\code{None}, it will become \code{sge.game.height - yport}.

\end{itemize}

All other arugments set the respective initial attributes of the
view.  See the documentation for {\hyperref[dsp:sge.dsp.View]{\emph{\code{sge.dsp.View}}}} for more
information.

\end{fulllineitems}



\subsection{sge.dsp.Object}
\label{dsp:sge-dsp-object}\index{Object (class in sge.dsp)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object}\pysiglinewithargsret{\strong{class }\code{sge.dsp.}\bfcode{Object}}{\emph{x}, \emph{y}, \emph{z=0}, \emph{sprite=None}, \emph{visible=True}, \emph{active=True}, \emph{checks\_collisions=True}, \emph{tangible=True}, \emph{bbox\_x=None}, \emph{bbox\_y=None}, \emph{bbox\_width=None}, \emph{bbox\_height=None}, \emph{regulate\_origin=False}, \emph{collision\_ellipse=False}, \emph{collision\_precise=False}, \emph{xvelocity=0}, \emph{yvelocity=0}, \emph{xacceleration=0}, \emph{yacceleration=0}, \emph{xdeceleration=0}, \emph{ydeceleration=0}, \emph{image\_index=0}, \emph{image\_origin\_x=None}, \emph{image\_origin\_y=None}, \emph{image\_fps=None}, \emph{image\_xscale=1}, \emph{image\_yscale=1}, \emph{image\_rotation=0}, \emph{image\_alpha=255}, \emph{image\_blend=None}, \emph{image\_blend\_mode=None}}{}
This class is used for game objects, such as the player, enemies,
bullets, and the HUD.  Generally, each type of object has its own
subclass of {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}}.
\index{x (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.x}\pysigline{\bfcode{x}}
The horizontal position of the object in the room.

\end{fulllineitems}

\index{y (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.y}\pysigline{\bfcode{y}}
The vertical position of the object in the room.

\end{fulllineitems}

\index{z (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.z}\pysigline{\bfcode{z}}
The Z-axis position of the object in the room.

\end{fulllineitems}

\index{sprite (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.sprite}\pysigline{\bfcode{sprite}}
The sprite currently in use by this object.  Can be either a
{\hyperref[gfx:sge.gfx.Sprite]{\emph{\code{sge.gfx.Sprite}}}} object or a \code{sge.gfx.TileGrid}
object.  Set to \code{None} for no sprite.

\end{fulllineitems}

\index{visible (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.visible}\pysigline{\bfcode{visible}}
Whether or not the object's sprite should be projected onto the
screen.

\end{fulllineitems}

\index{active (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.active}\pysigline{\bfcode{active}}
Indicates whether the object is active (\code{True}) or
inactive (\code{False}).  While the object is active, it will
exhibit normal behavior; events will be executed normally as will
any other automatic functionality, such as adding
{\hyperref[dsp:sge.dsp.Object.xvelocity]{\emph{\code{xvelocity}}}} and {\hyperref[dsp:sge.dsp.Object.yvelocity]{\emph{\code{yvelocity}}}}
to {\hyperref[dsp:sge.dsp.Object.x]{\emph{\code{x}}}} and {\hyperref[dsp:sge.dsp.Object.y]{\emph{\code{y}}}}.  If {\hyperref[dsp:sge.dsp.Object.active]{\emph{\code{active}}}} is \code{False},
automatic functionality and normal events will be disabled.

\begin{notice}{note}{Note:}
Inactive {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} objects are still visible
by default and continue to be involved in collisions.  In
addition, collision events and destroy events still occur even
if the object is inactive.  If you wish for the object to not
be visible, set {\hyperref[dsp:sge.dsp.Object.visible]{\emph{\code{visible}}}} to \code{False}.  If you
wish for the object to not perform collision events, set
{\hyperref[dsp:sge.dsp.Object.tangible]{\emph{\code{tangible}}}} to \code{False}.
\end{notice}

\end{fulllineitems}

\index{checks\_collisions (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.checks_collisions}\pysigline{\bfcode{checks\_collisions}}
Whether or not the object should check for collisions
automatically and cause collision events.  If an object is not
using collision events, setting this to \code{False} will give
a boost in performance.

\begin{notice}{note}{Note:}
This will not prevent automatic collision detection by other
objects from detecting this object, and it will also not
prevent this object's collision events from being executed.
If you wish to disable collision detection entirely, set
{\hyperref[dsp:sge.dsp.Object.tangible]{\emph{\code{tangible}}}} to \code{False}.
\end{notice}

\end{fulllineitems}

\index{tangible (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.tangible}\pysigline{\bfcode{tangible}}
Whether or not collisions involving the object can be detected.
Setting this to \code{False} can improve performance if the
object doesn't need to be involved in collisions.

Depending on the game, a useful strategy to boost performance can
be to exclude an object from collision detection while it is
outside the view.  If you do this, you likely want to set
{\hyperref[dsp:sge.dsp.Object.active]{\emph{\code{active}}}} to \code{False} as well so that the object
doesn't move in undesireable ways (e.g. through walls).

\begin{notice}{note}{Note:}
If this is \code{False}, {\hyperref[dsp:sge.dsp.Object.checks_collisions]{\emph{\code{checks\_collisions}}}} is
implied to be \code{False} as well regardless of its actual
value.  This is because checking for collisions which can't be
detected is meaningless.
\end{notice}

\end{fulllineitems}

\index{bbox\_x (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.bbox_x}\pysigline{\bfcode{bbox\_x}}
The horizontal location of the bounding box relative to the
object's position.  If set to \code{None}, the value
recommended by the sprite is used.

\end{fulllineitems}

\index{bbox\_y (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.bbox_y}\pysigline{\bfcode{bbox\_y}}
The vertical location of the bounding box relative to the
object's position.  If set to \code{None}, the value
recommended by the sprite is used.

\end{fulllineitems}

\index{bbox\_width (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.bbox_width}\pysigline{\bfcode{bbox\_width}}
The width of the bounding box in pixels.  If set to
\code{None}, the value recommended by the sprite is used.

\end{fulllineitems}

\index{bbox\_height (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.bbox_height}\pysigline{\bfcode{bbox\_height}}
The height of the bounding box in pixels.  If set to
\code{None}, the value recommended by the sprite is used.

\end{fulllineitems}

\index{regulate\_origin (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.regulate_origin}\pysigline{\bfcode{regulate\_origin}}
If set to \code{True}, the origin is automatically adjusted to
be the location of the pixel recommended by the sprite after
transformation.  This will cause rotation to be about the origin
rather than being about the center of the image.

\begin{notice}{note}{Note:}
The value of this attribute has no effect on the bounding box.
If you wish for the bounding box to be adjusted as well, you
must do so manually.  As an alternative, you may want to
consider using precise collision detection instead.
\end{notice}

\end{fulllineitems}

\index{collision\_ellipse (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.collision_ellipse}\pysigline{\bfcode{collision\_ellipse}}
Whether or not an ellipse (rather than a rectangle) should be
used for collision detection.

\end{fulllineitems}

\index{collision\_precise (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.collision_precise}\pysigline{\bfcode{collision\_precise}}
Whether or not precise (pixel-perfect) collision detection should
be used.  Note that this can be inefficient and does not work
well with animated sprites.

\end{fulllineitems}

\index{bbox\_left (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.bbox_left}\pysigline{\bfcode{bbox\_left}}
The position of the left side of the bounding box in the room
(same as {\hyperref[dsp:sge.dsp.Object.x]{\emph{\code{x}}}} + {\hyperref[dsp:sge.dsp.Object.bbox_x]{\emph{\code{bbox\_x}}}}).

\end{fulllineitems}

\index{bbox\_right (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.bbox_right}\pysigline{\bfcode{bbox\_right}}
The position of the right side of the bounding box in the room
(same as {\hyperref[dsp:sge.dsp.Object.bbox_left]{\emph{\code{bbox\_left}}}} + {\hyperref[dsp:sge.dsp.Object.bbox_width]{\emph{\code{bbox\_width}}}}).

\end{fulllineitems}

\index{bbox\_top (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.bbox_top}\pysigline{\bfcode{bbox\_top}}
The position of the top side of the bounding box in the room
(same as {\hyperref[dsp:sge.dsp.Object.y]{\emph{\code{y}}}} + {\hyperref[dsp:sge.dsp.Object.bbox_y]{\emph{\code{bbox\_y}}}}).

\end{fulllineitems}

\index{bbox\_bottom (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.bbox_bottom}\pysigline{\bfcode{bbox\_bottom}}
The position of the bottom side of the bounding box in the room
(same as {\hyperref[dsp:sge.dsp.Object.bbox_top]{\emph{\code{bbox\_top}}}} + {\hyperref[dsp:sge.dsp.Object.bbox_height]{\emph{\code{bbox\_height}}}}).

\end{fulllineitems}

\index{xvelocity (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.xvelocity}\pysigline{\bfcode{xvelocity}}
The velocity of the object toward the right in pixels per frame.

\end{fulllineitems}

\index{yvelocity (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.yvelocity}\pysigline{\bfcode{yvelocity}}
The velocity of the object toward the bottom in pixels per frame.

\end{fulllineitems}

\index{speed (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.speed}\pysigline{\bfcode{speed}}
The total (directional) speed of the object in pixels per frame.

\end{fulllineitems}

\index{move\_direction (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.move_direction}\pysigline{\bfcode{move\_direction}}
The direction of the object's movement in degrees, with \code{0}
being directly to the right and rotation in a positive direction
being clockwise.

\end{fulllineitems}

\index{xacceleration (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.xacceleration}\pysigline{\bfcode{xacceleration}}
The acceleration of the object to the right in pixels per frame.
If non-zero, movement as a result of {\hyperref[dsp:sge.dsp.Object.xvelocity]{\emph{\code{xvelocity}}}} will be
adjusted based on the kinematic equation,
\code{v{[}f{]}\textasciicircum{}2 = v{[}i{]}\textasciicircum{}2 + 2*a*d}.

\end{fulllineitems}

\index{yacceleration (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.yacceleration}\pysigline{\bfcode{yacceleration}}
The acceleration of the object downward in pixels per frame.  If
non-zero, movement as a result of {\hyperref[dsp:sge.dsp.Object.yvelocity]{\emph{\code{yvelocity}}}} will be
adjusted based on the kinematic equation,
\code{v{[}f{]}\textasciicircum{}2 = v{[}i{]}\textasciicircum{}2 + 2*a*d}.

\end{fulllineitems}

\index{xdeceleration (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.xdeceleration}\pysigline{\bfcode{xdeceleration}}
Like {\hyperref[dsp:sge.dsp.Object.xacceleration]{\emph{\code{xacceleration}}}}, but its sign is ignored and it always
causes the absolute value of {\hyperref[dsp:sge.dsp.Object.xvelocity]{\emph{\code{xvelocity}}}} to decrease.

\end{fulllineitems}

\index{ydeceleration (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.ydeceleration}\pysigline{\bfcode{ydeceleration}}
Like {\hyperref[dsp:sge.dsp.Object.yacceleration]{\emph{\code{yacceleration}}}}, but its sign is ignored and it always
causes the absolute value of {\hyperref[dsp:sge.dsp.Object.yvelocity]{\emph{\code{yvelocity}}}} to decrease.

\end{fulllineitems}

\index{image\_index (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_index}\pysigline{\bfcode{image\_index}}
The animation frame currently being displayed, with \code{0} being
the first one.

\end{fulllineitems}

\index{image\_origin\_x (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_origin_x}\pysigline{\bfcode{image\_origin\_x}}
The horizontal location of the origin relative to the left edge
of the images.  If set to \code{None}, the value recommended by
the sprite is used.

\end{fulllineitems}

\index{image\_origin\_y (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_origin_y}\pysigline{\bfcode{image\_origin\_y}}
The vertical location of the origin relative to the top edge of
the images.  If set to \code{None}, the value recommended by
the sprite is used.

\end{fulllineitems}

\index{image\_fps (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_fps}\pysigline{\bfcode{image\_fps}}
The animation rate in frames per second.  Can be negative, in
which case animation will be reversed.  If set to \code{None},
the value recommended by the sprite is used.

\end{fulllineitems}

\index{image\_speed (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_speed}\pysigline{\bfcode{image\_speed}}
The animation rate as a factor of \code{sge.game.fps}.  Can be
negative, in which case animation will be reversed.  If set to
\code{None}, the value recommended by the sprite is used.

\end{fulllineitems}

\index{image\_xscale (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_xscale}\pysigline{\bfcode{image\_xscale}}
The horizontal scale factor of the sprite.  If this is negative,
the sprite will also be mirrored horizontally.

\end{fulllineitems}

\index{image\_yscale (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_yscale}\pysigline{\bfcode{image\_yscale}}
The vertical scale factor of the sprite.  If this is negative,
the sprite will also be flipped vertically.

\end{fulllineitems}

\index{image\_rotation (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_rotation}\pysigline{\bfcode{image\_rotation}}
The rotation of the sprite in degrees, with rotation in a
positive direction being clockwise.

If {\hyperref[dsp:sge.dsp.Object.regulate_origin]{\emph{\code{regulate\_origin}}}} is \code{True}, the image is rotated
about the origin.  Otherwise, the image is rotated about its
center.

\end{fulllineitems}

\index{image\_alpha (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_alpha}\pysigline{\bfcode{image\_alpha}}
The alpha value applied to the entire image, where \code{255} is the
original image, \code{128} is half the opacity of the original
image, \code{0} is fully transparent, etc.

\end{fulllineitems}

\index{image\_blend (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_blend}\pysigline{\bfcode{image\_blend}}
A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object representing the color to blend
with the sprite (using RGBA Multiply blending).  Set to
\code{None} for no color blending.

\end{fulllineitems}

\index{image\_blend\_mode (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_blend_mode}\pysigline{\bfcode{image\_blend\_mode}}
The blend mode to use with {\hyperref[dsp:sge.dsp.Object.image_blend]{\emph{\code{image\_blend}}}}.  Possible blend
modes are:
\begin{itemize}
\item {} 
\code{sge.BLEND\_NORMAL}

\item {} 
\code{sge.BLEND\_RGBA\_ADD}

\item {} 
\code{sge.BLEND\_RGBA\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGBA\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGBA\_SCREEN}

\item {} 
\code{sge.BLEND\_RGBA\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGBA\_MAXIMUM}

\item {} 
\code{sge.BLEND\_RGB\_ADD}

\item {} 
\code{sge.BLEND\_RGB\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGB\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGB\_SCREEN}

\item {} 
\code{sge.BLEND\_RGB\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGB\_MAXIMUM}

\end{itemize}

\code{None} is treated as \code{sge.BLEND\_RGB\_MULTIPLY}.

\end{fulllineitems}

\index{image\_left (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_left}\pysigline{\bfcode{image\_left}}
The horizontal position of the left edge of the object's sprite
in the room.

\end{fulllineitems}

\index{image\_right (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_right}\pysigline{\bfcode{image\_right}}
The horizontal position of the right edge of the object's sprite
in the room.

\end{fulllineitems}

\index{image\_xcenter (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_xcenter}\pysigline{\bfcode{image\_xcenter}}
The horizontal position of the center of the object's sprite in
the room.

\end{fulllineitems}

\index{image\_top (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_top}\pysigline{\bfcode{image\_top}}
The vertical position of the top edge of the object's sprite in
the room.

\end{fulllineitems}

\index{image\_bottom (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_bottom}\pysigline{\bfcode{image\_bottom}}
The vertical position of the bottom edge of the object's sprite
in the room.

\end{fulllineitems}

\index{image\_ycenter (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_ycenter}\pysigline{\bfcode{image\_ycenter}}
The vertical position of the center of the object's sprite in the
room.

\end{fulllineitems}

\index{alarms (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.alarms}\pysigline{\bfcode{alarms}}
A dictionary containing the alarms of the object.  Each value
decreases by 1 each frame (adjusted for delta timing if it is
enabled).  When a value is at or below 0, {\hyperref[dsp:sge.dsp.Object.event_alarm]{\emph{\code{event\_alarm()}}}} is
executed with \code{alarm\_id} set to the respective key, and the
item is deleted from this dictionary.

\end{fulllineitems}

\index{image\_width (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_width}\pysigline{\bfcode{image\_width}}
The total width of the object's displayed image as it appears on
the screen, including the effects of scaling and rotation.
(Read-only)

\end{fulllineitems}

\index{image\_height (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.image_height}\pysigline{\bfcode{image\_height}}
The total height of the object's displayed image as it appears on
the screen, including the effects of scaling and rotation.
(Read-only)

\end{fulllineitems}

\index{mask (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.mask}\pysigline{\bfcode{mask}}
The current mask used for non-rectangular collision detection.
See the documentation for {\hyperref[collision:sge.collision.masks_collide]{\emph{\code{sge.collision.masks\_collide()}}}} for
more information.  (Read-only)

\end{fulllineitems}

\index{xstart (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.xstart}\pysigline{\bfcode{xstart}}
The initial value of {\hyperref[dsp:sge.dsp.Object.x]{\emph{\code{x}}}} when the object was created.
(Read-only)

\end{fulllineitems}

\index{ystart (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.ystart}\pysigline{\bfcode{ystart}}
The initial value of {\hyperref[dsp:sge.dsp.Object.y]{\emph{\code{y}}}} when the object was created.
(Read-only)

\end{fulllineitems}

\index{xprevious (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.xprevious}\pysigline{\bfcode{xprevious}}
The value of {\hyperref[dsp:sge.dsp.Object.x]{\emph{\code{x}}}} at the end of the previous frame.
(Read-only)

\end{fulllineitems}

\index{yprevious (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.yprevious}\pysigline{\bfcode{yprevious}}
The value of {\hyperref[dsp:sge.dsp.Object.y]{\emph{\code{y}}}} at the end of the previous frame.
(Read-only)

\end{fulllineitems}

\index{mask\_x (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.mask_x}\pysigline{\bfcode{mask\_x}}
The horizontal location of the mask in the room.  (Read-only)

\end{fulllineitems}

\index{mask\_y (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.mask_y}\pysigline{\bfcode{mask\_y}}
The vertical location of the mask in the room.  (Read-only)

\end{fulllineitems}

\index{rd (sge.dsp.Object attribute)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.rd}\pysigline{\bfcode{rd}}
Reserved dictionary for internal use by the SGE.  (Read-only)

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{sge.dsp.Object Methods}
\label{dsp:sge-dsp-object-methods}\index{\_\_init\_\_() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.__init__}\pysiglinewithargsret{\code{Object.}\bfcode{\_\_init\_\_}}{\emph{x}, \emph{y}, \emph{z=0}, \emph{sprite=None}, \emph{visible=True}, \emph{active=True}, \emph{checks\_collisions=True}, \emph{tangible=True}, \emph{bbox\_x=None}, \emph{bbox\_y=None}, \emph{bbox\_width=None}, \emph{bbox\_height=None}, \emph{regulate\_origin=False}, \emph{collision\_ellipse=False}, \emph{collision\_precise=False}, \emph{xvelocity=0}, \emph{yvelocity=0}, \emph{xacceleration=0}, \emph{yacceleration=0}, \emph{xdeceleration=0}, \emph{ydeceleration=0}, \emph{image\_index=0}, \emph{image\_origin\_x=None}, \emph{image\_origin\_y=None}, \emph{image\_fps=None}, \emph{image\_xscale=1}, \emph{image\_yscale=1}, \emph{image\_rotation=0}, \emph{image\_alpha=255}, \emph{image\_blend=None}, \emph{image\_blend\_mode=None}}{}
Arugments set the respective initial attributes of the object.
See the documentation for {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} for more
information.

\end{fulllineitems}

\index{move\_x() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.move_x}\pysiglinewithargsret{\code{Object.}\bfcode{move\_x}}{\emph{move}}{}
Move the object horizontally.  This method can be overridden to
conveniently define a particular way movement should be handled.
Currently, it is used in the default implementation of
{\hyperref[dsp:sge.dsp.Object.event_update_position]{\emph{\code{event\_update\_position()}}}}.

Arguments:
\begin{itemize}
\item {} 
\code{move} -- The amount to add to {\hyperref[dsp:sge.dsp.Object.x]{\emph{\code{x}}}}.

\end{itemize}

The default behavior of this method is the following code:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{x} \PYG{o}{+}\PYG{o}{=} \PYG{n}{move}
\end{Verbatim}

\end{fulllineitems}

\index{move\_y() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.move_y}\pysiglinewithargsret{\code{Object.}\bfcode{move\_y}}{\emph{move}}{}
Move the object vertically.  This method can be overridden to
conveniently define a particular way movement should be handled.
Currently, it is used in the default implementation of
{\hyperref[dsp:sge.dsp.Object.event_update_position]{\emph{\code{event\_update\_position()}}}}.

Arguments:
\begin{itemize}
\item {} 
\code{move} -- The amount to add to {\hyperref[dsp:sge.dsp.Object.y]{\emph{\code{y}}}}.

\end{itemize}

The default behavior of this method is the following code:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{y} \PYG{o}{+}\PYG{o}{=} \PYG{n}{move}
\end{Verbatim}

\end{fulllineitems}

\index{collision() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.collision}\pysiglinewithargsret{\code{Object.}\bfcode{collision}}{\emph{other=None}, \emph{x=None}, \emph{y=None}}{}
Return a list of objects colliding with this object.

Arguments:
\begin{itemize}
\item {} 
\code{other} -- What to check for collisions with.  Can be one of
the following:
\begin{itemize}
\item {} 
A {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} object.

\item {} 
A list of {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} objects.

\item {} 
A class derived from {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}}.

\item {} 
\code{None}: Check for collisions with all objects.

\end{itemize}

\item {} 
\code{x} -- The horizontal position to pretend this object is at
for the purpose of the collision detection.  If set to
\code{None}, {\hyperref[dsp:sge.dsp.Object.x]{\emph{\code{x}}}} will be used.

\item {} 
\code{y} -- The vertical position to pretend this object is at
for the purpose of the collision detection.  If set to
\code{None}, {\hyperref[dsp:sge.dsp.Object.y]{\emph{\code{y}}}} will be used.

\end{itemize}

\end{fulllineitems}

\index{destroy() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.destroy}\pysiglinewithargsret{\code{Object.}\bfcode{destroy}}{}{}
Remove the object from the current room.  \code{foo.destroy()} is
identical to \code{sge.game.current\_room.remove(foo)}.

\end{fulllineitems}

\index{create() (sge.dsp.Object class method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.create}\pysiglinewithargsret{\strong{classmethod }\code{Object.}\bfcode{create}}{\emph{*args}, \emph{**kwargs}}{}
Create an object of this class and add it to the current room.

\code{args} and \code{kwargs} are passed to the constructor method of
\code{cls} as arguments.  Calling
\code{obj = cls.create(*args, **kwargs)} is the same as:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{obj} \PYG{o}{=} \PYG{n}{cls}\PYG{p}{(}\PYG{o}{*}\PYG{n}{args}\PYG{p}{,} \PYG{o}{*}\PYG{o}{*}\PYG{n}{kwargs}\PYG{p}{)}
\PYG{n}{sge}\PYG{o}{.}\PYG{n}{game}\PYG{o}{.}\PYG{n}{current\PYGZus{}room}\PYG{o}{.}\PYG{n}{add}\PYG{p}{(}\PYG{n}{obj}\PYG{p}{)}
\end{Verbatim}

\end{fulllineitems}



\subsubsection{sge.dsp.Object Event Methods}
\label{dsp:sge-dsp-object-event-methods}\index{event\_create() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_create}\pysiglinewithargsret{\code{Object.}\bfcode{event\_create}}{}{}
Called in the following cases:
\begin{itemize}
\item {} 
Right after the object is added to the current room.

\item {} 
Right after a room starts for the first time after the object
was added to it, if and only if the object was added to the
room while it was not the current room.  In this case, this
event is called for each appropriate object after the
respective room start event or room resume event, in the same
order that the objects were added to the room.

\end{itemize}

\end{fulllineitems}

\index{event\_destroy() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_destroy}\pysiglinewithargsret{\code{Object.}\bfcode{event\_destroy}}{}{}
Called right after the object is removed from the current room.

\begin{notice}{note}{Note:}
If the object is removed from a room while it is not the
current room, this method will not be called.
\end{notice}

\end{fulllineitems}

\index{event\_step() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_step}\pysiglinewithargsret{\code{Object.}\bfcode{event\_step}}{\emph{time\_passed}, \emph{delta\_mult}}{}
Called each frame after automatic updates to objects (such as
the effects of the speed variables), but before collision
events.

See the documentation for {\hyperref[dsp:sge.dsp.Game.event_step]{\emph{\code{sge.dsp.Game.event\_step()}}}} for
more information.

\end{fulllineitems}

\index{event\_alarm() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_alarm}\pysiglinewithargsret{\code{Object.}\bfcode{event\_alarm}}{\emph{alarm\_id}}{}
See the documentation for {\hyperref[dsp:sge.dsp.Object.alarms]{\emph{\code{sge.dsp.Object.alarms}}}} for more
information.

\end{fulllineitems}

\index{event\_animation\_end() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_animation_end}\pysiglinewithargsret{\code{Object.}\bfcode{event\_animation\_end}}{}{}
Called when an animation cycle ends.

\end{fulllineitems}

\index{event\_key\_press() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_key_press}\pysiglinewithargsret{\code{Object.}\bfcode{event\_key\_press}}{\emph{key}, \emph{char}}{}
See the documentation for {\hyperref[input:sge.input.KeyPress]{\emph{\code{sge.input.KeyPress}}}} for more
information.

\end{fulllineitems}

\index{event\_key\_release() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_key_release}\pysiglinewithargsret{\code{Object.}\bfcode{event\_key\_release}}{\emph{key}}{}
See the documentation for {\hyperref[input:sge.input.KeyRelease]{\emph{\code{sge.input.KeyRelease}}}} for more
information.

\end{fulllineitems}

\index{event\_mouse\_move() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_mouse_move}\pysiglinewithargsret{\code{Object.}\bfcode{event\_mouse\_move}}{\emph{x}, \emph{y}}{}
See the documentation for {\hyperref[input:sge.input.MouseMove]{\emph{\code{sge.input.MouseMove}}}} for more
information.

\end{fulllineitems}

\index{event\_mouse\_button\_press() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_mouse_button_press}\pysiglinewithargsret{\code{Object.}\bfcode{event\_mouse\_button\_press}}{\emph{button}}{}
See the documentation for {\hyperref[input:sge.input.MouseButtonPress]{\emph{\code{sge.input.MouseButtonPress}}}}
for more information.

\end{fulllineitems}

\index{event\_mouse\_button\_release() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_mouse_button_release}\pysiglinewithargsret{\code{Object.}\bfcode{event\_mouse\_button\_release}}{\emph{button}}{}
See the documentation for {\hyperref[input:sge.input.MouseButtonRelease]{\emph{\code{sge.input.MouseButtonRelease}}}}
for more information.

\end{fulllineitems}

\index{event\_joystick() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_joystick}\pysiglinewithargsret{\code{Object.}\bfcode{event\_joystick}}{\emph{js\_name}, \emph{js\_id}, \emph{input\_type}, \emph{input\_id}, \emph{value}}{}
See the documentation for \code{sge.input.JoystickEvent} for
more information.

\end{fulllineitems}

\index{event\_joystick\_axis\_move() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_joystick_axis_move}\pysiglinewithargsret{\code{Object.}\bfcode{event\_joystick\_axis\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{axis}, \emph{value}}{}
See the documentation for {\hyperref[input:sge.input.JoystickAxisMove]{\emph{\code{sge.input.JoystickAxisMove}}}}
for more information.

\end{fulllineitems}

\index{event\_joystick\_hat\_move() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_joystick_hat_move}\pysiglinewithargsret{\code{Object.}\bfcode{event\_joystick\_hat\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{hat}, \emph{x}, \emph{y}}{}
See the documentation for {\hyperref[input:sge.input.JoystickHatMove]{\emph{\code{sge.input.JoystickHatMove}}}} for
more information.

\end{fulllineitems}

\index{event\_joystick\_trackball\_move() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_joystick_trackball_move}\pysiglinewithargsret{\code{Object.}\bfcode{event\_joystick\_trackball\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{ball}, \emph{x}, \emph{y}}{}
See the documentation for
{\hyperref[input:sge.input.JoystickTrackballMove]{\emph{\code{sge.input.JoystickTrackballMove}}}} for more information.

\end{fulllineitems}

\index{event\_joystick\_button\_press() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_joystick_button_press}\pysiglinewithargsret{\code{Object.}\bfcode{event\_joystick\_button\_press}}{\emph{js\_name}, \emph{js\_id}, \emph{button}}{}
See the documentation for {\hyperref[input:sge.input.JoystickButtonPress]{\emph{\code{sge.input.JoystickButtonPress}}}}
for more information.

\end{fulllineitems}

\index{event\_joystick\_button\_release() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_joystick_button_release}\pysiglinewithargsret{\code{Object.}\bfcode{event\_joystick\_button\_release}}{\emph{js\_name}, \emph{js\_id}, \emph{button}}{}
See the documentation for
{\hyperref[input:sge.input.JoystickButtonRelease]{\emph{\code{sge.input.JoystickButtonRelease}}}} for more information.

\end{fulllineitems}

\index{event\_update\_position() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_update_position}\pysiglinewithargsret{\code{Object.}\bfcode{event\_update\_position}}{\emph{delta\_mult}}{}
Called when it's time to update the position of the object.
This method handles this functionality, so defining this will
override the default behavior and allow you to handle the speed
variables in a special way.

The default behavior of this method is the following code:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{k}{if} \PYG{n}{delta\PYGZus{}mult}\PYG{p}{:}
    \PYG{n}{vi} \PYG{o}{=} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xvelocity}
    \PYG{n}{vf} \PYG{o}{=} \PYG{n}{vi} \PYG{o}{+} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xacceleration} \PYG{o}{*} \PYG{n}{delta\PYGZus{}mult}
    \PYG{n}{dc} \PYG{o}{=} \PYG{n+nb}{abs}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xdeceleration}\PYG{p}{)} \PYG{o}{*} \PYG{n}{delta\PYGZus{}mult}
    \PYG{k}{if} \PYG{n+nb}{abs}\PYG{p}{(}\PYG{n}{vf}\PYG{p}{)} \PYG{o}{\PYGZgt{}} \PYG{n}{dc}\PYG{p}{:}
        \PYG{n}{vf} \PYG{o}{\PYGZhy{}}\PYG{o}{=} \PYG{n}{math}\PYG{o}{.}\PYG{n}{copysign}\PYG{p}{(}\PYG{n}{dc}\PYG{p}{,} \PYG{n}{vf}\PYG{p}{)}
    \PYG{k}{else}\PYG{p}{:}
        \PYG{n}{vf} \PYG{o}{=} \PYG{l+m+mi}{0}
    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{xvelocity} \PYG{o}{=} \PYG{n}{vf}
    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{move\PYGZus{}x}\PYG{p}{(}\PYG{p}{(}\PYG{p}{(}\PYG{n}{vi} \PYG{o}{+} \PYG{n}{vf}\PYG{p}{)} \PYG{o}{/} \PYG{l+m+mi}{2}\PYG{p}{)} \PYG{o}{*} \PYG{n}{delta\PYGZus{}mult}\PYG{p}{)}

    \PYG{n}{vi} \PYG{o}{=} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity}
    \PYG{n}{vf} \PYG{o}{=} \PYG{n}{vi} \PYG{o}{+} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yacceleration} \PYG{o}{*} \PYG{n}{delta\PYGZus{}mult}
    \PYG{n}{dc} \PYG{o}{=} \PYG{n+nb}{abs}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{ydeceleration}\PYG{p}{)} \PYG{o}{*} \PYG{n}{delta\PYGZus{}mult}
    \PYG{k}{if} \PYG{n+nb}{abs}\PYG{p}{(}\PYG{n}{vf}\PYG{p}{)} \PYG{o}{\PYGZgt{}} \PYG{n}{dc}\PYG{p}{:}
        \PYG{n}{vf} \PYG{o}{\PYGZhy{}}\PYG{o}{=} \PYG{n}{math}\PYG{o}{.}\PYG{n}{copysign}\PYG{p}{(}\PYG{n}{dc}\PYG{p}{,} \PYG{n}{vf}\PYG{p}{)}
    \PYG{k}{else}\PYG{p}{:}
        \PYG{n}{vf} \PYG{o}{=} \PYG{l+m+mi}{0}
    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{yvelocity} \PYG{o}{=} \PYG{n}{vf}
    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{move\PYGZus{}y}\PYG{p}{(}\PYG{p}{(}\PYG{p}{(}\PYG{n}{vi} \PYG{o}{+} \PYG{n}{vf}\PYG{p}{)} \PYG{o}{/} \PYG{l+m+mi}{2}\PYG{p}{)} \PYG{o}{*} \PYG{n}{delta\PYGZus{}mult}\PYG{p}{)}
\end{Verbatim}

See the documentation for {\hyperref[dsp:sge.dsp.Game.event_step]{\emph{\code{sge.dsp.Game.event\_step()}}}} for
more information.

\end{fulllineitems}

\index{event\_collision() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_collision}\pysiglinewithargsret{\code{Object.}\bfcode{event\_collision}}{\emph{other}, \emph{xdirection}, \emph{ydirection}}{}
Called when this object collides with another object.

Arguments:
\begin{itemize}
\item {} 
\code{other} -- The other object which was collided with.

\item {} 
\code{xdirection} -- The horizontal direction of the collision
from the perspective of this object.  Can be \code{-1} (left),
\code{1} (right), or \code{0} (no horizontal direction).

\item {} 
\code{ydirection} -- The vertical direction of the collision from
the perspective of this object.  Can be \code{-1} (up), \code{1}
(down), or \code{0} (no vertical direction).

\end{itemize}

Directionless ``collisions'' (ones with both an xdirection and
ydirection of \code{0}) are possible.  These are typically
collisions which were already occurring in the previous frame
(continuous collisions).

\end{fulllineitems}

\index{event\_paused\_step() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_paused_step}\pysiglinewithargsret{\code{Object.}\bfcode{event\_paused\_step}}{\emph{time\_passed}, \emph{delta\_mult}}{}
See the documentation for {\hyperref[dsp:sge.dsp.Game.event_step]{\emph{\code{sge.dsp.Game.event\_step()}}}} for
more information.

\end{fulllineitems}

\index{event\_paused\_key\_press() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_paused_key_press}\pysiglinewithargsret{\code{Object.}\bfcode{event\_paused\_key\_press}}{\emph{key}, \emph{char}}{}
See the documentation for {\hyperref[input:sge.input.KeyPress]{\emph{\code{sge.input.KeyPress}}}} for more
information.

\end{fulllineitems}

\index{event\_paused\_key\_release() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_paused_key_release}\pysiglinewithargsret{\code{Object.}\bfcode{event\_paused\_key\_release}}{\emph{key}}{}
See the documentation for {\hyperref[input:sge.input.KeyRelease]{\emph{\code{sge.input.KeyRelease}}}} for more
information.

\end{fulllineitems}

\index{event\_paused\_mouse\_move() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_paused_mouse_move}\pysiglinewithargsret{\code{Object.}\bfcode{event\_paused\_mouse\_move}}{\emph{x}, \emph{y}}{}
See the documentation for {\hyperref[input:sge.input.MouseMove]{\emph{\code{sge.input.MouseMove}}}} for more
information.

\end{fulllineitems}

\index{event\_paused\_mouse\_button\_press() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_paused_mouse_button_press}\pysiglinewithargsret{\code{Object.}\bfcode{event\_paused\_mouse\_button\_press}}{\emph{button}}{}
See the documentation for {\hyperref[input:sge.input.MouseButtonPress]{\emph{\code{sge.input.MouseButtonPress}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_mouse\_button\_release() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_paused_mouse_button_release}\pysiglinewithargsret{\code{Object.}\bfcode{event\_paused\_mouse\_button\_release}}{\emph{button}}{}
See the documentation for {\hyperref[input:sge.input.MouseButtonRelease]{\emph{\code{sge.input.MouseButtonRelease}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_joystick() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_paused_joystick}\pysiglinewithargsret{\code{Object.}\bfcode{event\_paused\_joystick}}{\emph{js\_name}, \emph{js\_id}, \emph{input\_type}, \emph{input\_id}, \emph{value}}{}
See the documentation for \code{sge.input.JoystickEvent} for
more information.

\end{fulllineitems}

\index{event\_paused\_joystick\_axis\_move() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_paused_joystick_axis_move}\pysiglinewithargsret{\code{Object.}\bfcode{event\_paused\_joystick\_axis\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{axis}, \emph{value}}{}
See the documentation for {\hyperref[input:sge.input.JoystickAxisMove]{\emph{\code{sge.input.JoystickAxisMove}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_joystick\_hat\_move() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_paused_joystick_hat_move}\pysiglinewithargsret{\code{Object.}\bfcode{event\_paused\_joystick\_hat\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{hat}, \emph{x}, \emph{y}}{}
See the documentation for {\hyperref[input:sge.input.JoystickHatMove]{\emph{\code{sge.input.JoystickHatMove}}}} for
more information.

\end{fulllineitems}

\index{event\_paused\_joystick\_trackball\_move() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_paused_joystick_trackball_move}\pysiglinewithargsret{\code{Object.}\bfcode{event\_paused\_joystick\_trackball\_move}}{\emph{js\_name}, \emph{js\_id}, \emph{ball}, \emph{x}, \emph{y}}{}
See the documentation for
{\hyperref[input:sge.input.JoystickTrackballMove]{\emph{\code{sge.input.JoystickTrackballMove}}}} for more information.

\end{fulllineitems}

\index{event\_paused\_joystick\_button\_press() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_paused_joystick_button_press}\pysiglinewithargsret{\code{Object.}\bfcode{event\_paused\_joystick\_button\_press}}{\emph{js\_name}, \emph{js\_id}, \emph{button}}{}
See the documentation for {\hyperref[input:sge.input.JoystickButtonPress]{\emph{\code{sge.input.JoystickButtonPress}}}}
for more information.

\end{fulllineitems}

\index{event\_paused\_joystick\_button\_release() (sge.dsp.Object method)}

\begin{fulllineitems}
\phantomsection\label{dsp:sge.dsp.Object.event_paused_joystick_button_release}\pysiglinewithargsret{\code{Object.}\bfcode{event\_paused\_joystick\_button\_release}}{\emph{js\_name}, \emph{js\_id}, \emph{button}}{}
See the documentation for
{\hyperref[input:sge.input.JoystickButtonRelease]{\emph{\code{sge.input.JoystickButtonRelease}}}} for more information.

\end{fulllineitems}



\chapter{sge.gfx}
\label{gfx::doc}\label{gfx:sge-gfx}\setbox0\vbox{
\begin{minipage}{0.95\linewidth}
\textbf{Contents}

\medskip

\begin{itemize}
\item {} 
\phantomsection\label{gfx:id1}{\hyperref[gfx:sge\string-gfx]{\emph{sge.gfx}}}
\begin{itemize}
\item {} 
\phantomsection\label{gfx:id2}{\hyperref[gfx:sge\string-gfx\string-classes]{\emph{sge.gfx Classes}}}
\begin{itemize}
\item {} 
\phantomsection\label{gfx:id3}{\hyperref[gfx:sge\string-gfx\string-color]{\emph{sge.gfx.Color}}}

\item {} 
\phantomsection\label{gfx:id4}{\hyperref[gfx:sge\string-gfx\string-sprite]{\emph{sge.gfx.Sprite}}}
\begin{itemize}
\item {} 
\phantomsection\label{gfx:id5}{\hyperref[gfx:sge\string-gfx\string-sprite\string-methods]{\emph{sge.gfx.Sprite Methods}}}

\end{itemize}

\item {} 
\phantomsection\label{gfx:id6}{\hyperref[gfx:sge\string-gfx\string-font]{\emph{sge.gfx.Font}}}
\begin{itemize}
\item {} 
\phantomsection\label{gfx:id7}{\hyperref[gfx:sge\string-gfx\string-font\string-methods]{\emph{sge.gfx.Font Methods}}}

\end{itemize}

\item {} 
\phantomsection\label{gfx:id8}{\hyperref[gfx:sge\string-gfx\string-backgroundlayer]{\emph{sge.gfx.BackgroundLayer}}}
\begin{itemize}
\item {} 
\phantomsection\label{gfx:id9}{\hyperref[gfx:sge\string-gfx\string-backgroundlayer\string-methods]{\emph{sge.gfx.BackgroundLayer Methods}}}

\end{itemize}

\item {} 
\phantomsection\label{gfx:id10}{\hyperref[gfx:sge\string-gfx\string-background]{\emph{sge.gfx.Background}}}
\begin{itemize}
\item {} 
\phantomsection\label{gfx:id11}{\hyperref[gfx:sge\string-gfx\string-background\string-methods]{\emph{sge.gfx.Background Methods}}}

\end{itemize}

\end{itemize}

\end{itemize}

\end{itemize}
\end{minipage}}
\begin{center}\setlength{\fboxsep}{5pt}\shadowbox{\box0}\end{center}
\phantomsection\label{gfx:module-sge.gfx}\index{sge.gfx (module)}
This module provides classes related to rendering graphics.


\section{sge.gfx Classes}
\label{gfx:sge-gfx-classes}

\subsection{sge.gfx.Color}
\label{gfx:sge-gfx-color}\index{Color (class in sge.gfx)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Color}\pysiglinewithargsret{\strong{class }\code{sge.gfx.}\bfcode{Color}}{\emph{value}}{}
This class stores color information.

Objects of this class can be converted to iterables indicating the
object's {\hyperref[gfx:sge.gfx.Color.red]{\emph{\code{red}}}}, {\hyperref[gfx:sge.gfx.Color.green]{\emph{\code{green}}}}, {\hyperref[gfx:sge.gfx.Color.blue]{\emph{\code{blue}}}}, and {\hyperref[gfx:sge.gfx.Color.alpha]{\emph{\code{alpha}}}}
values, respectively; to integers which can be interpreted as a
hexadecimal representation of the color, excluding alpha
transparency; and to strings which indicate the English name of the
color (in all lowercase) if possible, and {\hyperref[gfx:sge.gfx.Color.hex_string]{\emph{\code{hex\_string}}}}
otherwise.
\index{red (sge.gfx.Color attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Color.red}\pysigline{\bfcode{red}}
The red component of the color as an integer, where \code{0}
indicates no red intensity and \code{255} indicates full red
intensity.

\end{fulllineitems}

\index{green (sge.gfx.Color attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Color.green}\pysigline{\bfcode{green}}
The green component of the color as an integer, where \code{0}
indicates no green intensity and \code{255} indicates full green
intensity.

\end{fulllineitems}

\index{blue (sge.gfx.Color attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Color.blue}\pysigline{\bfcode{blue}}
The blue component of the color as an integer, where \code{0}
indicates no blue intensity and \code{255} indicates full blue
intensity.

\end{fulllineitems}

\index{alpha (sge.gfx.Color attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Color.alpha}\pysigline{\bfcode{alpha}}
The alpha transparency of the color as an integer, where \code{0}
indicates full transparency and \code{255} indicates full opacity.

\end{fulllineitems}

\index{hex\_string (sge.gfx.Color attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Color.hex_string}\pysigline{\bfcode{hex\_string}}
An HTML hex string representation of the color.  (Read-only)

\end{fulllineitems}


\end{fulllineitems}



\subsection{sge.gfx.Sprite}
\label{gfx:sge-gfx-sprite}\index{Sprite (class in sge.gfx)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite}\pysiglinewithargsret{\strong{class }\code{sge.gfx.}\bfcode{Sprite}}{\emph{name=None}, \emph{directory='`}, \emph{width=None}, \emph{height=None}, \emph{transparent=True}, \emph{origin\_x=0}, \emph{origin\_y=0}, \emph{fps=60}, \emph{bbox\_x=None}, \emph{bbox\_y=None}, \emph{bbox\_width=None}, \emph{bbox\_height=None}}{}
This class stores images and information about how the SGE is to use
those images.

What image formats are supported depends on the implementation of
the SGE, but image formats that are generally a good choice are PNG
and JPEG.  See the implementation-specific information for a full
list of supported formats.
\index{width (sge.gfx.Sprite attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.width}\pysigline{\bfcode{width}}
The width of the sprite.

\begin{notice}{note}{Note:}
Changing this attribute will cause the sprite to be scaled
horizontally.  This is a destructive transformation: it can
result in loss of pixel information, especially if it is done
repeatedly.  Because of this, it is advised that you do not
adjust this value for routine scaling.  Use the
\code{image\_xscale} attribute of a {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}}
object instead.
\end{notice}

\end{fulllineitems}

\index{height (sge.gfx.Sprite attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.height}\pysigline{\bfcode{height}}
The height of the sprite.

\begin{notice}{note}{Note:}
Changing this attribute will cause the sprite to be scaled
vertically.  This is a destructive transformation: it can
result in loss of pixel information, especially if it is done
repeatedly.  Because of this, it is advised that you do not
adjust this value for routine scaling.  Use the
\code{image\_yscale} attribute of a {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}}
object instead.
\end{notice}

\end{fulllineitems}

\index{transparent (sge.gfx.Sprite attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.transparent}\pysigline{\bfcode{transparent}}
Whether or not the image should be partially transparent, based
on the image's alpha channel.  If this is \code{False}, all
pixels in the image will be treated as fully opaque regardless
of what the image file says their opacity should be.

This can also be set to a {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object, which
will cause the indicated color to be used as a colorkey.

\end{fulllineitems}

\index{origin\_x (sge.gfx.Sprite attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.origin_x}\pysigline{\bfcode{origin\_x}}
The suggested horizontal location of the origin relative to the
left edge of the images.

\end{fulllineitems}

\index{origin\_y (sge.gfx.Sprite attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.origin_y}\pysigline{\bfcode{origin\_y}}
The suggested vertical location of the origin relative to the top
edge of the images.

\end{fulllineitems}

\index{fps (sge.gfx.Sprite attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.fps}\pysigline{\bfcode{fps}}
The suggested rate in frames per second to animate the image at.
Can be negative, in which case animation will be reversed.

\end{fulllineitems}

\index{speed (sge.gfx.Sprite attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.speed}\pysigline{\bfcode{speed}}
The suggested rate to animate the image at as a factor of
\code{sge.game.fps}.  Can be negative, in which case animation
will be reversed.

\end{fulllineitems}

\index{bbox\_x (sge.gfx.Sprite attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.bbox_x}\pysigline{\bfcode{bbox\_x}}
The horizontal location relative to the sprite of the suggested
bounding box to use with it.  If set to \code{None}, it will
become equal to \code{-origin\_x} (which is always the left edge of
the image).

\end{fulllineitems}

\index{bbox\_y (sge.gfx.Sprite attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.bbox_y}\pysigline{\bfcode{bbox\_y}}
The vertical location relative to the sprite of the suggested
bounding box to use with it.  If set to \code{None}, it will
become equal to \code{-origin\_y} (which is always the top edge of
the image).

\end{fulllineitems}

\index{bbox\_width (sge.gfx.Sprite attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.bbox_width}\pysigline{\bfcode{bbox\_width}}
The width of the suggested bounding box.  If set to
\code{None}, it will become equal to \code{width - bbox\_x}
(which is always everything on the image to the right of
{\hyperref[gfx:sge.gfx.Sprite.bbox_x]{\emph{\code{bbox\_x}}}}).

\end{fulllineitems}

\index{bbox\_height (sge.gfx.Sprite attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.bbox_height}\pysigline{\bfcode{bbox\_height}}
The height of the suggested bounding box.  If set to
\code{None}, it will become equal to \code{height - bbox\_y}
(which is always everything on the image below {\hyperref[gfx:sge.gfx.Sprite.bbox_y]{\emph{\code{bbox\_y}}}}).

\end{fulllineitems}

\index{name (sge.gfx.Sprite attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.name}\pysigline{\bfcode{name}}
The name of the sprite given when it was created.  (Read-only)

\end{fulllineitems}

\index{frames (sge.gfx.Sprite attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.frames}\pysigline{\bfcode{frames}}
The number of animation frames in the sprite.  (Read-only)

\end{fulllineitems}

\index{rd (sge.gfx.Sprite attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.rd}\pysigline{\bfcode{rd}}
Reserved dictionary for internal use by the SGE.  (Read-only)

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{sge.gfx.Sprite Methods}
\label{gfx:sge-gfx-sprite-methods}\index{\_\_init\_\_() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.__init__}\pysiglinewithargsret{\code{Sprite.}\bfcode{\_\_init\_\_}}{\emph{name=None}, \emph{directory='`}, \emph{width=None}, \emph{height=None}, \emph{transparent=True}, \emph{origin\_x=0}, \emph{origin\_y=0}, \emph{fps=60}, \emph{bbox\_x=None}, \emph{bbox\_y=None}, \emph{bbox\_width=None}, \emph{bbox\_height=None}}{}
Arguments:
\begin{itemize}
\item {} 
\code{name} -- The base name of the image files, used to find all
individual image files that make up the sprite's animation{}`.
One of the following rules will be used to find the images:
\begin{itemize}
\item {} 
The base name plus a valid image extension.  If this rule is
used, the image will be loaded as a single-frame sprite.

\item {} 
The base name and an integer separated by either a hyphen
(\code{-}) or an underscore (\code{\_}) and followed by a valid
image extension.  If this rule is used, all images with
names like this are loaded and treated as an animation, with
the lower-numbered images being earlier frames.

\item {} 
The base name and an integer separated by either \code{-strip}
or \code{\_strip} and followed by a valid image extension.  If
this rule is used, the image will be treated as an animation
read as a horizontal reel from left to right, split into the
number of frames indicated by the integer.

\item {} 
If the base name is \code{None}, the sprite will be a
fully transparent rectangle at the specified size (with both
\code{width} and \code{height} defaulting to 32 if they are set to
\code{None}).  The SGE decides what to assign to the
sprite's {\hyperref[gfx:sge.gfx.Sprite.name]{\emph{\code{name}}}} attribute in this case, but it will
always be a string.

\end{itemize}

If none of the above rules can be used, \code{OSError} is
raised.

\item {} 
\code{directory} -- The directory to search for image files in.

\end{itemize}

All other arguments set the respective initial attributes of the
sprite.  See the documentation for {\hyperref[gfx:sge.gfx.Sprite]{\emph{\code{Sprite}}}} for more
information.

\end{fulllineitems}

\index{append\_frame() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.append_frame}\pysiglinewithargsret{\code{Sprite.}\bfcode{append\_frame}}{}{}
Append a new blank frame to the end of the sprite.

\end{fulllineitems}

\index{insert\_frame() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.insert_frame}\pysiglinewithargsret{\code{Sprite.}\bfcode{insert\_frame}}{\emph{frame}}{}
Insert a new blank frame into the sprite.

Arguments:
\begin{itemize}
\item {} 
\code{frame} -- The frame of the sprite to insert the new frame
in front of, where \code{0} is the first frame.

\end{itemize}

\end{fulllineitems}

\index{extend() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.extend}\pysiglinewithargsret{\code{Sprite.}\bfcode{extend}}{\emph{sprite}}{}
Extend this sprite with the frames of another sprite.

If the size of the frames added is different from the size of
this sprite, they are scaled to this sprite's size.

Arguments:
\begin{itemize}
\item {} 
\code{sprite} -- The sprite to add the frames of to this sprite.

\end{itemize}

\end{fulllineitems}

\index{delete\_frame() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.delete_frame}\pysiglinewithargsret{\code{Sprite.}\bfcode{delete\_frame}}{\emph{frame}}{}
Delete a frame from the sprite.

Arguments:
\begin{itemize}
\item {} 
\code{frame} -- The frame of the sprite to delete, where \code{0} is
the first frame.

\end{itemize}

\end{fulllineitems}

\index{get\_pixel() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.get_pixel}\pysiglinewithargsret{\code{Sprite.}\bfcode{get\_pixel}}{\emph{x}, \emph{y}, \emph{frame=0}}{}
Return a {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object indicating the color of a
particular pixel on the sprite.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the sprite of the
pixel to check.

\item {} 
\code{y} -- The vertical location relative to the sprite of the
pixel to check.

\item {} 
\code{frame} -- The frame of the sprite to check, where \code{0} is
the first frame.

\end{itemize}

\end{fulllineitems}

\index{get\_pixels() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.get_pixels}\pysiglinewithargsret{\code{Sprite.}\bfcode{get\_pixels}}{\emph{frame=0}}{}
Return a two-dimensional list of :class{}`sge.gfx.Color{}` objects
indicating the colors of a particular frame's pixels.

A returned list given the name \code{pixels} is indexed as
\code{pixels{[}x{]}{[}y{]}}, where \code{x} is the horizontal location of the
pixel and \code{y} is the vertical location of the pixel.

Arguments:
\begin{itemize}
\item {} 
\code{frame} -- The frame of the sprite to check, where \code{0} is
the first frame.

\end{itemize}

\end{fulllineitems}

\index{draw\_dot() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.draw_dot}\pysiglinewithargsret{\code{Sprite.}\bfcode{draw\_dot}}{\emph{x}, \emph{y}, \emph{color}, \emph{frame=None}, \emph{blend\_mode=None}}{}
Draw a single-pixel dot on the sprite.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the sprite to
draw the dot.

\item {} 
\code{y} -- The vertical location relative to the sprite to draw
the dot.

\item {} 
\code{color} -- A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object representing the
color of the dot.

\item {} 
\code{frame} -- The frame of the sprite to draw on, where \code{0}
is the first frame; set to \code{None} to draw on all
frames.

\item {} 
\code{blend\_mode} -- The blend mode to use.  Possible blend modes
are:
\begin{itemize}
\item {} 
\code{sge.BLEND\_NORMAL}

\item {} 
\code{sge.BLEND\_RGBA\_ADD}

\item {} 
\code{sge.BLEND\_RGBA\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGBA\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGBA\_SCREEN}

\item {} 
\code{sge.BLEND\_RGBA\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGBA\_MAXIMUM}

\item {} 
\code{sge.BLEND\_RGB\_ADD}

\item {} 
\code{sge.BLEND\_RGB\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGB\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGB\_SCREEN}

\item {} 
\code{sge.BLEND\_RGB\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGB\_MAXIMUM}

\end{itemize}

\code{None} is treated as \code{sge.BLEND\_NORMAL}.

\end{itemize}

\end{fulllineitems}

\index{draw\_line() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.draw_line}\pysiglinewithargsret{\code{Sprite.}\bfcode{draw\_line}}{\emph{x1}, \emph{y1}, \emph{x2}, \emph{y2}, \emph{color}, \emph{thickness=1}, \emph{anti\_alias=False}, \emph{frame=None}, \emph{blend\_mode=None}}{}
Draw a line segment on the sprite.

Arguments:
\begin{itemize}
\item {} 
\code{x1} -- The horizontal location relative to the sprite of
the first end point of the line segment.

\item {} 
\code{y1} -- The vertical location relative to the sprite of the
first end point of the line segment.

\item {} 
\code{x2} -- The horizontal location relative to the sprite of
the second end point of the line segment.

\item {} 
\code{y2} -- The vertical location relative to the sprite of the
second end point of the line segment.

\item {} 
\code{color} -- A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object representing the
color of the line segment.

\item {} 
\code{thickness} -- The thickness of the line segment.

\item {} 
\code{anti\_alias} -- Whether or not anti-aliasing should be used.

\item {} 
\code{frame} -- The frame of the sprite to draw on, where \code{0}
is the first frame; set to \code{None} to draw on all
frames.

\item {} 
\code{blend\_mode} -- The blend mode to use.  Possible blend modes
are:
\begin{itemize}
\item {} 
\code{sge.BLEND\_NORMAL}

\item {} 
\code{sge.BLEND\_RGBA\_ADD}

\item {} 
\code{sge.BLEND\_RGBA\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGBA\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGBA\_SCREEN}

\item {} 
\code{sge.BLEND\_RGBA\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGBA\_MAXIMUM}

\item {} 
\code{sge.BLEND\_RGB\_ADD}

\item {} 
\code{sge.BLEND\_RGB\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGB\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGB\_SCREEN}

\item {} 
\code{sge.BLEND\_RGB\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGB\_MAXIMUM}

\end{itemize}

\code{None} is treated as \code{sge.BLEND\_NORMAL}.

\end{itemize}

\end{fulllineitems}

\index{draw\_rectangle() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.draw_rectangle}\pysiglinewithargsret{\code{Sprite.}\bfcode{draw\_rectangle}}{\emph{x}, \emph{y}, \emph{width}, \emph{height}, \emph{fill=None}, \emph{outline=None}, \emph{outline\_thickness=1}, \emph{frame=None}, \emph{blend\_mode=None}}{}
Draw a rectangle on the sprite.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the sprite to
draw the rectangle.

\item {} 
\code{y} -- The vertical location relative to the sprite to draw
the rectangle.

\item {} 
\code{width} -- The width of the rectangle.

\item {} 
\code{height} -- The height of the rectangle.

\item {} 
\code{fill} -- A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object representing the
color of the fill of the rectangle.

\item {} 
\code{outline} -- A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object representing
the color of the outline of the rectangle.

\item {} 
\code{outline\_thickness} -- The thickness of the outline of the
rectangle.

\item {} 
\code{frame} -- The frame of the sprite to draw on, where \code{0}
is the first frame; set to \code{None} to draw on all
frames.

\item {} 
\code{blend\_mode} -- The blend mode to use.  Possible blend modes
are:
\begin{itemize}
\item {} 
\code{sge.BLEND\_NORMAL}

\item {} 
\code{sge.BLEND\_RGBA\_ADD}

\item {} 
\code{sge.BLEND\_RGBA\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGBA\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGBA\_SCREEN}

\item {} 
\code{sge.BLEND\_RGBA\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGBA\_MAXIMUM}

\item {} 
\code{sge.BLEND\_RGB\_ADD}

\item {} 
\code{sge.BLEND\_RGB\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGB\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGB\_SCREEN}

\item {} 
\code{sge.BLEND\_RGB\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGB\_MAXIMUM}

\end{itemize}

\code{None} is treated as \code{sge.BLEND\_NORMAL}.

\end{itemize}

\end{fulllineitems}

\index{draw\_ellipse() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.draw_ellipse}\pysiglinewithargsret{\code{Sprite.}\bfcode{draw\_ellipse}}{\emph{x}, \emph{y}, \emph{width}, \emph{height}, \emph{fill=None}, \emph{outline=None}, \emph{outline\_thickness=1}, \emph{anti\_alias=False}, \emph{frame=None}, \emph{blend\_mode=None}}{}
Draw an ellipse on the sprite.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the sprite to
position the imaginary rectangle containing the ellipse.

\item {} 
\code{y} -- The vertical location relative to the sprite to
position the imaginary rectangle containing the ellipse.

\item {} 
\code{width} -- The width of the ellipse.

\item {} 
\code{height} -- The height of the ellipse.

\item {} 
\code{fill} -- A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object representing the
color of the fill of the ellipse.

\item {} 
\code{outline} -- A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object representing
the color of the outline of the ellipse.

\item {} 
\code{outline\_thickness} -- The thickness of the outline of the
ellipse.

\item {} 
\code{anti\_alias} -- Whether or not anti-aliasing should be used.

\item {} 
\code{frame} -- The frame of the sprite to draw on, where \code{0}
is the first frame; set to \code{None} to draw on all
frames.

\item {} 
\code{blend\_mode} -- The blend mode to use.  Possible blend modes
are:
\begin{itemize}
\item {} 
\code{sge.BLEND\_NORMAL}

\item {} 
\code{sge.BLEND\_RGBA\_ADD}

\item {} 
\code{sge.BLEND\_RGBA\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGBA\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGBA\_SCREEN}

\item {} 
\code{sge.BLEND\_RGBA\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGBA\_MAXIMUM}

\item {} 
\code{sge.BLEND\_RGB\_ADD}

\item {} 
\code{sge.BLEND\_RGB\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGB\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGB\_SCREEN}

\item {} 
\code{sge.BLEND\_RGB\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGB\_MAXIMUM}

\end{itemize}

\code{None} is treated as \code{sge.BLEND\_NORMAL}.

\end{itemize}

\end{fulllineitems}

\index{draw\_circle() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.draw_circle}\pysiglinewithargsret{\code{Sprite.}\bfcode{draw\_circle}}{\emph{x}, \emph{y}, \emph{radius}, \emph{fill=None}, \emph{outline=None}, \emph{outline\_thickness=1}, \emph{anti\_alias=False}, \emph{frame=None}, \emph{blend\_mode=None}}{}
Draw a circle on the sprite.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the sprite to
position the center of the circle.

\item {} 
\code{y} -- The vertical location relative to the sprite to
position the center of the circle.

\item {} 
\code{radius} -- The radius of the circle.

\item {} 
\code{fill} -- A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object representing the
color of the fill of the circle.

\item {} 
\code{outline} -- A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object representing
the color of the outline of the circle.

\item {} 
\code{outline\_thickness} -- The thickness of the outline of the
circle.

\item {} 
\code{anti\_alias} -- Whether or not anti-aliasing should be used.

\item {} 
\code{frame} -- The frame of the sprite to draw on, where \code{0}
is the first frame; set to \code{None} to draw on all
frames.

\item {} 
\code{blend\_mode} -- The blend mode to use.  Possible blend modes
are:
\begin{itemize}
\item {} 
\code{sge.BLEND\_NORMAL}

\item {} 
\code{sge.BLEND\_RGBA\_ADD}

\item {} 
\code{sge.BLEND\_RGBA\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGBA\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGBA\_SCREEN}

\item {} 
\code{sge.BLEND\_RGBA\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGBA\_MAXIMUM}

\item {} 
\code{sge.BLEND\_RGB\_ADD}

\item {} 
\code{sge.BLEND\_RGB\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGB\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGB\_SCREEN}

\item {} 
\code{sge.BLEND\_RGB\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGB\_MAXIMUM}

\end{itemize}

\code{None} is treated as \code{sge.BLEND\_NORMAL}.

\end{itemize}

\end{fulllineitems}

\index{draw\_polygon() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.draw_polygon}\pysiglinewithargsret{\code{Sprite.}\bfcode{draw\_polygon}}{\emph{points}, \emph{fill=None}, \emph{outline=None}, \emph{outline\_thickness=1}, \emph{anti\_alias=False}, \emph{frame=None}, \emph{blend\_mode=None}}{}
Draw a polygon on the sprite.

Arguments:
\begin{itemize}
\item {} 
\code{points} -- A list of points relative to the sprite to
position each of the polygon's angles.  Each point should be a
tuple in the form \code{(x, y)}, where x is the horizontal
location and y is the vertical location.

\item {} 
\code{fill} -- A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object representing the
color of the fill of the polygon.

\item {} 
\code{outline} -- A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object representing
the color of the outline of the polygon.

\item {} 
\code{outline\_thickness} -- The thickness of the outline of the
polygon.

\item {} 
\code{anti\_alias} -- Whether or not anti-aliasing should be used.

\item {} 
\code{frame} -- The frame of the sprite to draw on, where \code{0}
is the first frame; set to \code{None} to draw on all
frames.

\item {} 
\code{blend\_mode} -- The blend mode to use.  Possible blend modes
are:
\begin{itemize}
\item {} 
\code{sge.BLEND\_NORMAL}

\item {} 
\code{sge.BLEND\_RGBA\_ADD}

\item {} 
\code{sge.BLEND\_RGBA\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGBA\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGBA\_SCREEN}

\item {} 
\code{sge.BLEND\_RGBA\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGBA\_MAXIMUM}

\item {} 
\code{sge.BLEND\_RGB\_ADD}

\item {} 
\code{sge.BLEND\_RGB\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGB\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGB\_SCREEN}

\item {} 
\code{sge.BLEND\_RGB\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGB\_MAXIMUM}

\end{itemize}

\code{None} is treated as \code{sge.BLEND\_NORMAL}.

\end{itemize}

\end{fulllineitems}

\index{draw\_sprite() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.draw_sprite}\pysiglinewithargsret{\code{Sprite.}\bfcode{draw\_sprite}}{\emph{sprite}, \emph{image}, \emph{x}, \emph{y}, \emph{frame=None}, \emph{blend\_mode=None}}{}
Draw another sprite on the sprite.

Arguments:
\begin{itemize}
\item {} 
\code{sprite} -- The {\hyperref[gfx:sge.gfx.Sprite]{\emph{\code{sge.gfx.Sprite}}}} or
\code{sge.gfx.TileGrid} object to draw with.

\item {} 
\code{image} -- The frame of \code{sprite} to draw with, where \code{0}
is the first frame.

\item {} 
\code{x} -- The horizontal location relative to \code{self} to
position the origin of \code{sprite}.

\item {} 
\code{y} -- The vertical location relative to \code{self} to
position the origin of \code{sprite}.

\item {} 
\code{frame} -- The frame of the sprite to draw on, where \code{0}
is the first frame; set to \code{None} to draw on all
frames.

\item {} 
\code{blend\_mode} -- The blend mode to use.  Possible blend modes
are:
\begin{itemize}
\item {} 
\code{sge.BLEND\_NORMAL}

\item {} 
\code{sge.BLEND\_RGBA\_ADD}

\item {} 
\code{sge.BLEND\_RGBA\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGBA\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGBA\_SCREEN}

\item {} 
\code{sge.BLEND\_RGBA\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGBA\_MAXIMUM}

\item {} 
\code{sge.BLEND\_RGB\_ADD}

\item {} 
\code{sge.BLEND\_RGB\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGB\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGB\_SCREEN}

\item {} 
\code{sge.BLEND\_RGB\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGB\_MAXIMUM}

\end{itemize}

\code{None} is treated as \code{sge.BLEND\_NORMAL}.

\end{itemize}

\end{fulllineitems}

\index{draw\_text() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.draw_text}\pysiglinewithargsret{\code{Sprite.}\bfcode{draw\_text}}{\emph{font}, \emph{text}, \emph{x}, \emph{y}, \emph{width=None}, \emph{height=None}, \emph{color=sge.gfx.Color(``white'')}, \emph{halign='left'}, \emph{valign='top'}, \emph{anti\_alias=True}, \emph{frame=None}, \emph{blend\_mode=None}}{}
Draw text on the sprite.

Arguments:
\begin{itemize}
\item {} 
\code{font} -- The font to use to draw the text.

\item {} 
\code{text} -- The text (as a string) to draw.

\item {} 
\code{x} -- The horizontal location relative to the sprite to
draw the text.

\item {} 
\code{y} -- The vertical location relative to the sprite to draw
the text.

\item {} 
\code{width} -- The width of the imaginary rectangle the text is
drawn in; set to \code{None} to make the rectangle as wide
as needed to contain the text without additional line breaks.
If set to something other than \code{None}, a line which
does not fit will be automatically split into multiple lines
that do fit.

\item {} 
\code{height} -- The height of the imaginary rectangle the text
is drawn in; set to \code{None} to make the rectangle as
tall as needed to contain the text.

\item {} 
\code{color} -- A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object representing the
color of the text.

\item {} 
\code{halign} -- The horizontal alignment of the text and the
horizontal location of the origin of the imaginary rectangle
the text is drawn in.  Can be set to one of the following:
\begin{itemize}
\item {} 
\code{"left"} -- Align the text to the left of the imaginary
rectangle the text is drawn in.  Set the origin of the
imaginary rectangle to its left edge.

\item {} 
\code{"center"} -- Align the text to the center of the
imaginary rectangle the text is drawn in.  Set the origin of
the imaginary rectangle to its center.

\item {} 
\code{"right"} -- Align the text to the right of the imaginary
rectangle the text is drawn in.  Set the origin of the
imaginary rectangle to its right edge.

\end{itemize}

\item {} 
\code{valign} -- The vertical alignment of the text and the
vertical location of the origin of the imaginary rectangle the
text is drawn in.  Can be set to one of the following:
\begin{itemize}
\item {} 
\code{"top"} -- Align the text to the top of the imaginary
rectangle the text is drawn in.  Set the origin of the
imaginary rectangle to its top edge.  If the imaginary
rectangle is not tall enough to contain all of the text, cut
text off from the bottom.

\item {} 
\code{"middle"} -- Align the the text to the middle of the
imaginary rectangle the text is drawn in.  Set the origin of
the imaginary rectangle to its middle.  If the imaginary
rectangle is not tall enough to contain all of the text, cut
text off equally from the top and bottom.

\item {} 
\code{"bottom"} -- Align the text  to the bottom of the
imaginary rectangle the text is drawn in.  Set the origin of
the imaginary rectangle to its top edge.  If the imaginary
rectangle is not tall enough to contain all of the text, cut
text off from the top.

\end{itemize}

\item {} 
\code{anti\_alias} -- Whether or not anti-aliasing should be used.

\item {} 
\code{frame} -- The frame of the sprite to draw on, where \code{0}
is the first frame; set to \code{None} to draw on all
frames.

\item {} 
\code{blend\_mode} -- The blend mode to use.  Possible blend modes
are:
\begin{itemize}
\item {} 
\code{sge.BLEND\_NORMAL}

\item {} 
\code{sge.BLEND\_RGBA\_ADD}

\item {} 
\code{sge.BLEND\_RGBA\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGBA\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGBA\_SCREEN}

\item {} 
\code{sge.BLEND\_RGBA\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGBA\_MAXIMUM}

\item {} 
\code{sge.BLEND\_RGB\_ADD}

\item {} 
\code{sge.BLEND\_RGB\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGB\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGB\_SCREEN}

\item {} 
\code{sge.BLEND\_RGB\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGB\_MAXIMUM}

\end{itemize}

\code{None} is treated as \code{sge.BLEND\_NORMAL}.

\end{itemize}

\end{fulllineitems}

\index{draw\_erase() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.draw_erase}\pysiglinewithargsret{\code{Sprite.}\bfcode{draw\_erase}}{\emph{x}, \emph{y}, \emph{width}, \emph{height}, \emph{frame=None}}{}
Erase part of the sprite.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location relative to the sprite of the
area to erase.

\item {} 
\code{y} -- The vertical location relative to the sprite of the
area to erase.

\item {} 
\code{width} -- The width of the area to erase.

\item {} 
\code{height} -- The height of the area to erase.

\item {} 
\code{frame} -- The frame of the sprite to erase from, where
\code{0} is the first frame; set to \code{None} to erase from
all frames.

\end{itemize}

\end{fulllineitems}

\index{draw\_clear() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.draw_clear}\pysiglinewithargsret{\code{Sprite.}\bfcode{draw\_clear}}{\emph{frame=None}}{}
Erase everything from the sprite.

Arguments:
\begin{itemize}
\item {} 
\code{frame} -- The frame of the sprite to clear, where \code{0} is
the first frame; set to \code{None} to clear all frames.

\end{itemize}

\end{fulllineitems}

\index{draw\_lock() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.draw_lock}\pysiglinewithargsret{\code{Sprite.}\bfcode{draw\_lock}}{}{}
Lock the sprite for continuous drawing.

Use this method to ``lock'' the sprite for being drawn on several
times in a row.  What exactly this does depends on the
implementation and it may even do nothing at all, but calling
this method before doing several draw actions on the sprite in a
row gives the SGE a chance to make the drawing more efficient.

After you are done with continuous drawing, call
{\hyperref[gfx:sge.gfx.Sprite.draw_unlock]{\emph{\code{draw\_unlock()}}}} to let the SGE know that you are done
drawing.

\begin{notice}{warning}{Warning:}
Do not cause a sprite to be used while it's locked.  For
example, don't leave it locked for the duration of a frame,
and don't draw it or project it on anything.  The effect of
using a locked sprite could be as minor as graphical errors
and as severe as crashing the program, depending on the SGE
implementation.  Always call {\hyperref[gfx:sge.gfx.Sprite.draw_unlock]{\emph{\code{draw\_unlock()}}}} immediately
after you're done drawing for a while.
\end{notice}

\end{fulllineitems}

\index{draw\_unlock() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.draw_unlock}\pysiglinewithargsret{\code{Sprite.}\bfcode{draw\_unlock}}{}{}
Unlock the sprite.

Use this method to ``unlock'' the sprite after it has been
``locked'' for continuous drawing by {\hyperref[gfx:sge.gfx.Sprite.draw_lock]{\emph{\code{draw\_lock()}}}}.

\end{fulllineitems}

\index{mirror() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.mirror}\pysiglinewithargsret{\code{Sprite.}\bfcode{mirror}}{\emph{frame=None}}{}
Mirror the sprite horizontally.

Arguments:
\begin{itemize}
\item {} 
\code{frame} -- The frame of the sprite to mirror, where \code{0} is
the first frame; set to \code{None} to mirror all frames.

\end{itemize}

\end{fulllineitems}

\index{flip() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.flip}\pysiglinewithargsret{\code{Sprite.}\bfcode{flip}}{\emph{frame=None}}{}
Flip the sprite vertically.

Arguments:
\begin{itemize}
\item {} 
\code{frame} -- The frame of the sprite to flip, where \code{0} is
the first frame; set to \code{None} to flip all frames.

\end{itemize}

\end{fulllineitems}

\index{resize\_canvas() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.resize_canvas}\pysiglinewithargsret{\code{Sprite.}\bfcode{resize\_canvas}}{\emph{width}, \emph{height}}{}
Resize the sprite by adding empty space instead of scaling.

After resizing the canvas:
\begin{enumerate}
\item {} 
The horizontal location of the origin is multiplied by the
new width divided by the old width.

\item {} 
The vertical location of the origin is multiplied by the new
height divided by the old height.

\item {} 
All frames are repositioned within the sprite such that their
position relative to the origin is the same as before.

\end{enumerate}

Arguments:
\begin{itemize}
\item {} 
\code{width} -- The width to set the sprite to.

\item {} 
\code{height} -- The height to set the sprite to.

\end{itemize}

\end{fulllineitems}

\index{scale() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.scale}\pysiglinewithargsret{\code{Sprite.}\bfcode{scale}}{\emph{xscale=1}, \emph{yscale=1}, \emph{frame=None}}{}
Scale the sprite to a different size.

Unlike changing {\hyperref[gfx:sge.gfx.Sprite.width]{\emph{\code{width}}}} and {\hyperref[gfx:sge.gfx.Sprite.height]{\emph{\code{height}}}}, this function
does not result in the actual size of the sprite changing.
Instead, any scaled frames are repositioned so that the pixel
which was at the origin before scaling remains at the origin.

Arguments:
\begin{itemize}
\item {} 
\code{xscale} -- The horizontal scale factor.

\item {} 
\code{yscale} -- The vertical scale factor.

\item {} 
\code{frame} -- The frame of the sprite to rotate, where \code{0} is
the first frame; set to \code{None} to rotate all frames.

\end{itemize}

\begin{notice}{note}{Note:}
This is a destructive transformation: it can result in loss
of pixel information, especially if it is done repeatedly.
Because of this, it is advised that you do not adjust this
value for routine scaling.  Use the \code{image\_xscale} and
\code{image\_yscale} attributes of a {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}}
object instead.
\end{notice}

\begin{notice}{note}{Note:}
Because this function does not alter the actual size of the
sprite, scaling up may result in some parts of the image
being cropped off.
\end{notice}

\end{fulllineitems}

\index{rotate() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.rotate}\pysiglinewithargsret{\code{Sprite.}\bfcode{rotate}}{\emph{x}, \emph{adaptive\_resize=True}, \emph{frame=None}}{}
Rotate the sprite about the center.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The rotation amount in degrees, with rotation in a
positive direction being clockwise.

\item {} 
\code{adaptive\_resize} -- Whether or not the sprite should be
resized to accomodate rotation.  If this is \code{True},
rotation amounts other than multiples of 180 will result in
the size of the sprite being adapted to fit the whole rotated
image.  The origin and any frames which have not been rotated
will also be moved so that their location relative to the
rotated image(s) is the same.

\item {} 
\code{frame} -- The frame of the sprite to rotate, where \code{0} is
the first frame; set to \code{None} to rotate all frames.

\end{itemize}

\begin{notice}{note}{Note:}
This is a destructive transformation: it can result in loss
of pixel information, especially if it is done repeatedly.
Because of this, it is advised that you do not adjust this
value for routine rotation.  Use the \code{image\_rotation}
attribute of a {\hyperref[dsp:sge.dsp.Object]{\emph{\code{sge.dsp.Object}}}} object instead.
\end{notice}

\end{fulllineitems}

\index{swap\_color() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.swap_color}\pysiglinewithargsret{\code{Sprite.}\bfcode{swap\_color}}{\emph{old\_color}, \emph{new\_color}, \emph{frame=None}}{}
Change all pixels of one color to another color.

Arguments:
\begin{itemize}
\item {} 
\code{old\_color} -- A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object indicating
the color of pixels to change.

\item {} 
\code{new\_color} -- A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object indicating
the color to change the pixels to.

\item {} 
\code{frame} -- The frame of the sprite to rotate, where \code{0} is
the first frame; set to \code{None} to rotate all frames.

\end{itemize}

\begin{notice}{note}{Note:}
While this method can be used on any image, it is likely to
be most efficient when used on images based on palettes
(such as 8-bit images).  The SGE cannot implicitly convert
high bit depth images to low bit depths, so if you plan on
using this method frequently, you should ensure that you
save your images in a low bit depth.
\end{notice}

\end{fulllineitems}

\index{copy() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.copy}\pysiglinewithargsret{\code{Sprite.}\bfcode{copy}}{}{}
Return a copy of the sprite.

\end{fulllineitems}

\index{save() (sge.gfx.Sprite method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.save}\pysiglinewithargsret{\code{Sprite.}\bfcode{save}}{\emph{fname}}{}
Save the sprite to an image file.

Arguments:
\begin{itemize}
\item {} 
\code{fname} -- The path of the file to save the sprite to.  If
it is not a path that can be saved to, \code{OSError} is
raised.

\end{itemize}

If the sprite has multiple frames, the image file saved will be
a horizontal reel of each of the frames from left to right with
no space in between the frames.

\end{fulllineitems}

\index{from\_tween() (sge.gfx.Sprite class method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.from_tween}\pysiglinewithargsret{\strong{classmethod }\code{Sprite.}\bfcode{from\_tween}}{\emph{sprite}, \emph{frames}, \emph{fps=None}, \emph{xscale=None}, \emph{yscale=None}, \emph{rotation=None}, \emph{blend=None}, \emph{bbox\_x=None}, \emph{bbox\_y=None}, \emph{bbox\_width=None}, \emph{bbox\_height=None}, \emph{blend\_mode=None}}{}
Create a sprite based on tweening an existing sprite.

``Tweening'' refers to creating an animation from gradual
transformations to an image.  For example, this can be used to
generate an animation of an object growing to a particular size.
The animation generated is called a ``tween''.

Arguments:
\begin{itemize}
\item {} 
\code{sprite} -- The sprite to base the tween on.  If the sprite
includes multiple frames, all frames will be used in sequence
until the end of the tween.

The tween's origin is derived from this sprite's origin,
adjusted appropriately to accomodate any size changes made.
Whether or not the tween is transparent is also determined by
whether or not this sprite is transparent.

\item {} 
\code{frames} -- The number of frames the to make the tween take
up.

\item {} 
\code{fps} -- The suggested rate of animation for the tween in
frames per second.  If set to \code{None}, the suggested
animation rate of the base sprite is used.

\item {} 
\code{xscale} -- The horizontal scale factor at the end of the
tween.  If set to \code{None}, horizontal scaling will not
be included in the tweening process.

\item {} 
\code{yscale} -- The vertical scale factor at the end of the
tween.  If set to \code{None}, vertical scaling will not be
included in the tweening process.

\item {} 
\code{rotation} -- The total clockwise rotation amount in degrees
at the end of the tween.  Can be negative to indicate
counter-clockwise rotation instead.  If set to \code{None},
rotation will not be included in the tweening process.

\item {} 
\code{blend} -- A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object representing the
color to blend with the sprite at the end of the tween.  If
set to \code{None}, color blending will not be included in
the tweening process.

\item {} 
\code{blend\_mode} -- The blend mode to use with \code{blend}.
Possible blend modes are:
\begin{itemize}
\item {} 
\code{sge.BLEND\_NORMAL}

\item {} 
\code{sge.BLEND\_RGBA\_ADD}

\item {} 
\code{sge.BLEND\_RGBA\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGBA\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGBA\_SCREEN}

\item {} 
\code{sge.BLEND\_RGBA\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGBA\_MAXIMUM}

\item {} 
\code{sge.BLEND\_RGB\_ADD}

\item {} 
\code{sge.BLEND\_RGB\_SUBTRACT}

\item {} 
\code{sge.BLEND\_RGB\_MULTIPLY}

\item {} 
\code{sge.BLEND\_RGB\_SCREEN}

\item {} 
\code{sge.BLEND\_RGB\_MINIMUM}

\item {} 
\code{sge.BLEND\_RGB\_MAXIMUM}

\end{itemize}

\code{None} is treated as \code{sge.BLEND\_RGBA\_MULTIPLY}.

\end{itemize}

All other arguments set the respective initial attributes of the
tween.  See the documentation for {\hyperref[gfx:sge.gfx.Sprite]{\emph{\code{sge.gfx.Sprite}}}} for
more information.

\end{fulllineitems}

\index{from\_text() (sge.gfx.Sprite class method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.from_text}\pysiglinewithargsret{\strong{classmethod }\code{Sprite.}\bfcode{from\_text}}{\emph{font}, \emph{text}, \emph{width=None}, \emph{height=None}, \emph{color=sge.gfx.Color(``white'')}, \emph{halign='left'}, \emph{valign='top'}, \emph{anti\_alias=True}}{}
Create a sprite, draw the given text on it, and return the
sprite.  See the documentation for
{\hyperref[gfx:sge.gfx.Sprite.draw_text]{\emph{\code{sge.gfx.Sprite.draw\_text()}}}} for more information.

The sprite's origin is set based on \code{halign} and \code{valign}.

\end{fulllineitems}

\index{from\_tileset() (sge.gfx.Sprite class method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.from_tileset}\pysiglinewithargsret{\strong{classmethod }\code{Sprite.}\bfcode{from\_tileset}}{\emph{fname}, \emph{x=0}, \emph{y=0}, \emph{columns=1}, \emph{rows=1}, \emph{xsep=0}, \emph{ysep=0}, \emph{width=1}, \emph{height=1}, \emph{origin\_x=0}, \emph{origin\_y=0}, \emph{transparent=True}, \emph{fps=0}, \emph{bbox\_x=None}, \emph{bbox\_y=None}, \emph{bbox\_width=None}, \emph{bbox\_height=None}}{}
Return a sprite based on the tiles in a tileset.

Arguments:
\begin{itemize}
\item {} 
\code{fname} -- The path to the image file containing the
tileset.

\item {} 
\code{x} -- The horizontal location relative to the image of the
top-leftmost tile in the tileset.

\item {} 
\code{y} -- The vertical location relative to the image of the
top-leftmost tile in the tileset.

\item {} 
\code{columns} -- The number of columns in the tileset.

\item {} 
\code{rows} -- The number of rows in the tileset.

\item {} 
\code{xsep} -- The spacing between columns in the tileset.

\item {} 
\code{ysep} -- The spacing between rows in the tileset.

\item {} 
\code{width} -- The width of the tiles.

\item {} 
\code{height} -- The height of the tiles.

\end{itemize}

For all other arguments, see the documentation for
{\hyperref[gfx:sge.gfx.Sprite.__init__]{\emph{\code{Sprite.\_\_init\_\_()}}}}.

Each tile in the tileset becomes a subimage of the returned
sprite, ordered first from left to right and then from top to
bottom.

\end{fulllineitems}

\index{from\_screenshot() (sge.gfx.Sprite class method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Sprite.from_screenshot}\pysiglinewithargsret{\strong{classmethod }\code{Sprite.}\bfcode{from\_screenshot}}{\emph{x=0}, \emph{y=0}, \emph{width=None}, \emph{height=None}}{}
Return the current display on the screen as a sprite.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal location of the rectangular area to
take a screenshot of.

\item {} 
\code{y} -- The vertical location of the rectangular area to take
a screenshot of.

\item {} 
\code{width} -- The width of the area to take a screenshot of;
set to None for all of the area to the right of \code{x} to be
included.

\item {} 
\code{height} -- The height of the area to take a screenshot of;
set to \code{None} for all of the area below \code{y} to be
included.

\end{itemize}

If you only wish to save a screenshot (of the entire screen) to
a file, the easiest way to do that is:

\begin{Verbatim}[commandchars=\\\{\}]
\PYG{n}{sge}\PYG{o}{.}\PYG{n}{gfx}\PYG{o}{.}\PYG{n}{Sprite}\PYG{o}{.}\PYG{n}{from\PYGZus{}screenshot}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{save}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{foo.png}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}
\end{Verbatim}

\end{fulllineitems}



\subsection{sge.gfx.Font}
\label{gfx:sge-gfx-font}\index{Font (class in sge.gfx)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Font}\pysiglinewithargsret{\strong{class }\code{sge.gfx.}\bfcode{Font}}{\emph{name=None}, \emph{size=12}, \emph{underline=False}, \emph{bold=False}, \emph{italic=False}}{}
This class stores a font for use by text drawing methods.

Note that bold and italic rendering could be ugly.  It is better to
choose a bold or italic font rather than enabling bold or italic
rendering, if possible.
\index{size (sge.gfx.Font attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Font.size}\pysigline{\bfcode{size}}
The height of the font in pixels.

\end{fulllineitems}

\index{underline (sge.gfx.Font attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Font.underline}\pysigline{\bfcode{underline}}
Whether or not underlined rendering is enabled.

\end{fulllineitems}

\index{bold (sge.gfx.Font attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Font.bold}\pysigline{\bfcode{bold}}
Whether or not bold rendering is enabled.

\begin{notice}{note}{Note:}
Using this option can be ugly.  It is better to choose a bold
font rather than enabling bold rendering, if possible.
\end{notice}

\end{fulllineitems}

\index{italic (sge.gfx.Font attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Font.italic}\pysigline{\bfcode{italic}}
Whether or not italic rendering is enabled.

\begin{notice}{note}{Note:}
Using this option can be ugly.  It is better to choose an
italic font rather than enabling italic rendering, if
possible.
\end{notice}

\end{fulllineitems}

\index{name (sge.gfx.Font attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Font.name}\pysigline{\bfcode{name}}
The name of the font as specified when it was created.
(Read-only)

\end{fulllineitems}

\index{rd (sge.gfx.Font attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Font.rd}\pysigline{\bfcode{rd}}
Reserved dictionary for internal use by the SGE.  (Read-only)

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{sge.gfx.Font Methods}
\label{gfx:sge-gfx-font-methods}\index{\_\_init\_\_() (sge.gfx.Font method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Font.__init__}\pysiglinewithargsret{\code{Font.}\bfcode{\_\_init\_\_}}{\emph{name=None}, \emph{size=12}, \emph{underline=False}, \emph{bold=False}, \emph{italic=False}}{}
Arguments:
\begin{itemize}
\item {} 
\code{name} -- The name of the font.  Can be one of the
following:
\begin{itemize}
\item {} 
A string indicating the path to the font file.

\item {} 
A string indicating the case-insensitive name of a system
font, e.g. \code{"Liberation Serif"}.

\item {} 
A list or tuple of strings indicating either a font file or
a system font to choose from in order of preference.

\end{itemize}

If none of the above methods return a valid font, the SGE will
choose the font.

\end{itemize}

All other arguments set the respective initial attributes of the
font.  See the documentation for {\hyperref[gfx:sge.gfx.Font]{\emph{\code{sge.gfx.Font}}}} for more
information.

\begin{notice}{note}{Note:}
It is generally not a good practice to rely on system fonts.
There are no standard fonts; a font which you have on your
system is probably not on everyone's system.  Rather than
relying on system fonts, choose a font which is under a libre
license (such as the GNU General Public License or the SIL
Open Font License) and distribute it with your game; this
will ensure that everyone sees text rendered the same way you
do.
\end{notice}

\end{fulllineitems}

\index{get\_width() (sge.gfx.Font method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Font.get_width}\pysiglinewithargsret{\code{Font.}\bfcode{get\_width}}{\emph{text}, \emph{width=None}, \emph{height=None}}{}
Return the width of a certain string of text when rendered.

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_text]{\emph{\code{sge.gfx.Sprite.draw\_text()}}}} for
more information.

\end{fulllineitems}

\index{get\_height() (sge.gfx.Font method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Font.get_height}\pysiglinewithargsret{\code{Font.}\bfcode{get\_height}}{\emph{text}, \emph{width=None}, \emph{height=None}}{}
Return the height of a certain string of text when rendered.

See the documentation for {\hyperref[gfx:sge.gfx.Sprite.draw_text]{\emph{\code{sge.gfx.Sprite.draw\_text()}}}} for
more information.

\end{fulllineitems}

\index{from\_sprite() (sge.gfx.Font class method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Font.from_sprite}\pysiglinewithargsret{\strong{classmethod }\code{Font.}\bfcode{from\_sprite}}{\emph{sprite}, \emph{chars}, \emph{hsep=0}, \emph{vsep=0}, \emph{size=12}, \emph{underline=False}, \emph{bold=False}, \emph{italic=False}}{}
Return a font derived from a sprite.

Arguments:
\begin{itemize}
\item {} 
\code{sprite} -- The {\hyperref[gfx:sge.gfx.Sprite]{\emph{\code{sge.gfx.Sprite}}}} object to derive the
font from.

\item {} 
\code{chars} -- A dictionary mapping each supported text
character to the corresponding frame of the sprite.  For
example, \code{\{'A': 0, 'B': 1, 'C': 2\}} would assign the letter
``A' to the first frame, the letter ``B'' to the second frame,
and the letter ``C'' to the third frame.

Alternatively, this can be given as a list of characters to
assign to the frames corresponding to the characters' indexes
within the list.  For example, \code{{[}'A', 'B', 'C'{]}} would
assign the letter ``A'' to the first frame, the letter ``B'' to
the second frame, and the letter ``C'' to the third frame.

Any character not explicitly mapped to a frame will be
rendered as its differently-cased counterpart if possible
(e.g. ``A'' as ``a''). Otherwise, it will be rendered using the
frame mapped to \code{None}.  If \code{None} has not been
explicitly mapped to a frame, it is implied to be a blank
space.

\item {} 
\code{hsep} -- The amount of horizontal space to place between
characters when text is rendered.

\item {} 
\code{vsep} -- The amount of vertical space to place between
lines when text is rendered.

\end{itemize}

All other arguments set the respective initial attributes of the
font.  See the documentation for {\hyperref[gfx:sge.gfx.Font]{\emph{\code{sge.gfx.Font}}}} for more
information.

The font's {\hyperref[gfx:sge.gfx.Font.name]{\emph{\code{name}}}} attribute will be set to the name of the
sprite the font is derived from.

The font's {\hyperref[gfx:sge.gfx.Font.size]{\emph{\code{size}}}} attribute will indicate the height of
the characters in pixels.  The width of the characters will be
adjusted proportionally.

\end{fulllineitems}



\subsection{sge.gfx.BackgroundLayer}
\label{gfx:sge-gfx-backgroundlayer}\index{BackgroundLayer (class in sge.gfx)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.BackgroundLayer}\pysiglinewithargsret{\strong{class }\code{sge.gfx.}\bfcode{BackgroundLayer}}{\emph{sprite}, \emph{x}, \emph{y}, \emph{z=0}, \emph{xscroll\_rate=1}, \emph{yscroll\_rate=1}, \emph{repeat\_left=False}, \emph{repeat\_right=False}, \emph{repeat\_up=False}, \emph{repeat\_down=False}}{}
This class stores a sprite and certain information for a layer of a
background.  In particular, it stores the location of the layer,
whether the layer tiles horizontally, vertically, or both, and the
rate at which it scrolls.
\index{sprite (sge.gfx.BackgroundLayer attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.BackgroundLayer.sprite}\pysigline{\bfcode{sprite}}
The sprite used for this layer.  It will be animated normally if
it contains multiple frames.

\end{fulllineitems}

\index{x (sge.gfx.BackgroundLayer attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.BackgroundLayer.x}\pysigline{\bfcode{x}}
The horizontal location of the layer relative to the background.

\end{fulllineitems}

\index{y (sge.gfx.BackgroundLayer attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.BackgroundLayer.y}\pysigline{\bfcode{y}}
The vertical location of the layer relative to the background.

\end{fulllineitems}

\index{z (sge.gfx.BackgroundLayer attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.BackgroundLayer.z}\pysigline{\bfcode{z}}
The Z-axis position of the layer in the room.

\end{fulllineitems}

\index{xscroll\_rate (sge.gfx.BackgroundLayer attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.BackgroundLayer.xscroll_rate}\pysigline{\bfcode{xscroll\_rate}}
The horizontal rate that the layer scrolls as a factor of the
additive inverse of the horizontal movement of the view.

\end{fulllineitems}

\index{yscroll\_rate (sge.gfx.BackgroundLayer attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.BackgroundLayer.yscroll_rate}\pysigline{\bfcode{yscroll\_rate}}
The vertical rate that the layer scrolls as a factor of the
additive inverse of the vertical movement of the view.

\end{fulllineitems}

\index{repeat\_left (sge.gfx.BackgroundLayer attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.BackgroundLayer.repeat_left}\pysigline{\bfcode{repeat\_left}}
Whether or not the layer should be repeated (tiled) to the left.

\end{fulllineitems}

\index{repeat\_right (sge.gfx.BackgroundLayer attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.BackgroundLayer.repeat_right}\pysigline{\bfcode{repeat\_right}}
Whether or not the layer should be repeated (tiled) to the right.

\end{fulllineitems}

\index{repeat\_up (sge.gfx.BackgroundLayer attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.BackgroundLayer.repeat_up}\pysigline{\bfcode{repeat\_up}}
Whether or not the layer should be repeated (tiled) upwards.

\end{fulllineitems}

\index{repeat\_down (sge.gfx.BackgroundLayer attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.BackgroundLayer.repeat_down}\pysigline{\bfcode{repeat\_down}}
Whether or not the layer should be repeated (tiled) downwards.

\end{fulllineitems}

\index{rd (sge.gfx.BackgroundLayer attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.BackgroundLayer.rd}\pysigline{\bfcode{rd}}
Reserved dictionary for internal use by the SGE.  (Read-only)

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{sge.gfx.BackgroundLayer Methods}
\label{gfx:sge-gfx-backgroundlayer-methods}\index{\_\_init\_\_() (sge.gfx.BackgroundLayer method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.BackgroundLayer.__init__}\pysiglinewithargsret{\code{BackgroundLayer.}\bfcode{\_\_init\_\_}}{\emph{sprite}, \emph{x}, \emph{y}, \emph{z=0}, \emph{xscroll\_rate=1}, \emph{yscroll\_rate=1}, \emph{repeat\_left=False}, \emph{repeat\_right=False}, \emph{repeat\_up=False}, \emph{repeat\_down=False}}{}
Arguments set the respective initial attributes of the layer.
See the documentation for {\hyperref[gfx:sge.gfx.BackgroundLayer]{\emph{\code{sge.gfx.BackgroundLayer}}}} for
more information.

\end{fulllineitems}



\subsection{sge.gfx.Background}
\label{gfx:sge-gfx-background}\index{Background (class in sge.gfx)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Background}\pysiglinewithargsret{\strong{class }\code{sge.gfx.}\bfcode{Background}}{\emph{layers}, \emph{color}}{}
This class stores the layers that make up the background (which
contain the information about what images to use and where) as well
as the color to use where no image is shown.
\index{layers (sge.gfx.Background attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Background.layers}\pysigline{\bfcode{layers}}
A list containing all {\hyperref[gfx:sge.gfx.BackgroundLayer]{\emph{\code{sge.gfx.BackgroundLayer}}}} objects
used in this background.  (Read-only)

\end{fulllineitems}

\index{color (sge.gfx.Background attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Background.color}\pysigline{\bfcode{color}}
A {\hyperref[gfx:sge.gfx.Color]{\emph{\code{sge.gfx.Color}}}} object representing the color used in
parts of the background where no layer is shown.

\end{fulllineitems}

\index{rd (sge.gfx.Background attribute)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Background.rd}\pysigline{\bfcode{rd}}
Reserved dictionary for internal use by the SGE.  (Read-only)

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{sge.gfx.Background Methods}
\label{gfx:sge-gfx-background-methods}\index{\_\_init\_\_() (sge.gfx.Background method)}

\begin{fulllineitems}
\phantomsection\label{gfx:sge.gfx.Background.__init__}\pysiglinewithargsret{\code{Background.}\bfcode{\_\_init\_\_}}{\emph{layers}, \emph{color}}{}
Arguments set the respective initial attributes of the
background.  See the documentation for
{\hyperref[gfx:sge.gfx.Background]{\emph{\code{sge.gfx.Background}}}} for more information.

\end{fulllineitems}



\chapter{sge.snd}
\label{snd::doc}\label{snd:sge-snd}\setbox0\vbox{
\begin{minipage}{0.95\linewidth}
\textbf{Contents}

\medskip

\begin{itemize}
\item {} 
\phantomsection\label{snd:id1}{\hyperref[snd:sge\string-snd]{\emph{sge.snd}}}
\begin{itemize}
\item {} 
\phantomsection\label{snd:id2}{\hyperref[snd:sge\string-snd\string-classes]{\emph{sge.snd Classes}}}
\begin{itemize}
\item {} 
\phantomsection\label{snd:id3}{\hyperref[snd:sge\string-snd\string-sound]{\emph{sge.snd.Sound}}}
\begin{itemize}
\item {} 
\phantomsection\label{snd:id4}{\hyperref[snd:sge\string-snd\string-sound\string-methods]{\emph{sge.snd.Sound Methods}}}

\end{itemize}

\item {} 
\phantomsection\label{snd:id5}{\hyperref[snd:sge\string-snd\string-music]{\emph{sge.snd.Music}}}
\begin{itemize}
\item {} 
\phantomsection\label{snd:id6}{\hyperref[snd:sge\string-snd\string-music\string-methods]{\emph{sge.snd.Music Methods}}}

\end{itemize}

\end{itemize}

\item {} 
\phantomsection\label{snd:id7}{\hyperref[snd:sge\string-snd\string-functions]{\emph{sge.snd Functions}}}
\begin{itemize}
\item {} 
\phantomsection\label{snd:id8}{\hyperref[snd:sge\string-snd\string-stop\string-all]{\emph{sge.snd.stop\_all}}}

\end{itemize}

\end{itemize}

\end{itemize}
\end{minipage}}
\begin{center}\setlength{\fboxsep}{5pt}\shadowbox{\box0}\end{center}
\phantomsection\label{snd:module-sge.snd}\index{sge.snd (module)}
This module provides classes related to the sound system.


\section{sge.snd Classes}
\label{snd:sge-snd-classes}

\subsection{sge.snd.Sound}
\label{snd:sge-snd-sound}\index{Sound (class in sge.snd)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Sound}\pysiglinewithargsret{\strong{class }\code{sge.snd.}\bfcode{Sound}}{\emph{fname}, \emph{volume=1}, \emph{max\_play=1}, \emph{parent=None}}{}
This class stores and plays sound effects.  Note that this is
inefficient for large music files; for those, use
{\hyperref[snd:sge.snd.Music]{\emph{\code{sge.snd.Music}}}} instead.

What sound formats are supported depends on the implementation of
the SGE, but sound formats that are generally a good choice are Ogg
Vorbis and uncompressed WAV.  See the implementation-specific
information for a full list of supported formats.
\index{volume (sge.snd.Sound attribute)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Sound.volume}\pysigline{\bfcode{volume}}
The volume of the sound as a value from \code{0} to \code{1} (\code{0} for
no sound, \code{1} for maximum volume).

\end{fulllineitems}

\index{max\_play (sge.snd.Sound attribute)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Sound.max_play}\pysigline{\bfcode{max\_play}}
The maximum number of instances of this sound playing permitted.
If a sound is played while this number of the instances of the
same sound are already playing, one of the already playing sounds
will be stopped before playing the new instance.  Set to
\code{None} for no limit.

\end{fulllineitems}

\index{parent (sge.snd.Sound attribute)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Sound.parent}\pysigline{\bfcode{parent}}
Indicates another sound which is treated as being the same sound
as this one for the purpose of determining whether or not, and
how many times, the sound is playing.  Set to \code{None} for
no parent.

If the sound has a parent, {\hyperref[snd:sge.snd.Sound.max_play]{\emph{\code{max\_play}}}} will have no effect
and instead the parent sound's {\hyperref[snd:sge.snd.Sound.max_play]{\emph{\code{max\_play}}}} will apply to
both the parent sound and this sound.

\begin{notice}{warning}{Warning:}
It is acceptable for a sound to both be a parent and have a
parent.  However, there MUST be a parent at the top which has
no parent.  The behavior of circular parenting, such as making
two sounds parents of each other, is undefined.
\end{notice}

\end{fulllineitems}

\index{fname (sge.snd.Sound attribute)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Sound.fname}\pysigline{\bfcode{fname}}
The file name of the sound given when it was created.
(Read-only)

\end{fulllineitems}

\index{length (sge.snd.Sound attribute)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Sound.length}\pysigline{\bfcode{length}}
The length of the sound in milliseconds.  (Read-only)

\end{fulllineitems}

\index{playing (sge.snd.Sound attribute)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Sound.playing}\pysigline{\bfcode{playing}}
The number of instances of this sound playing.  (Read-only)

\end{fulllineitems}

\index{rd (sge.snd.Sound attribute)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Sound.rd}\pysigline{\bfcode{rd}}
Reserved dictionary for internal use by the SGE.  (Read-only)

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{sge.snd.Sound Methods}
\label{snd:sge-snd-sound-methods}\index{\_\_init\_\_() (sge.snd.Sound method)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Sound.__init__}\pysiglinewithargsret{\code{Sound.}\bfcode{\_\_init\_\_}}{\emph{fname}, \emph{volume=1}, \emph{max\_play=1}, \emph{parent=None}}{}
Arguments:
\begin{itemize}
\item {} 
\code{fname} -- The path to the sound file.  If set to
\code{None}, this object will not actually play any sound.
If this is neither a valid sound file nor \code{None},
\code{OSError} is raised.

\end{itemize}

All other arguments set the respective initial attributes of the
sound.  See the documentation for {\hyperref[snd:sge.snd.Sound]{\emph{\code{sge.snd.Sound}}}} for
more information.

\end{fulllineitems}

\index{play() (sge.snd.Sound method)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Sound.play}\pysiglinewithargsret{\code{Sound.}\bfcode{play}}{\emph{loops=1}, \emph{volume=1}, \emph{balance=0}, \emph{maxtime=None}, \emph{fade\_time=None}, \emph{force=True}}{}
Play the sound.

Arguments:
\begin{itemize}
\item {} 
\code{loops} -- The number of times to play the sound; set to
\code{None} or \code{0} to loop indefinitely.

\item {} 
\code{volume} -- The volume to play the sound at as a factor
of \code{self.volume} (\code{0} for no sound, \code{1} for
\code{self.volume}).

\item {} 
\code{balance} -- The balance of the sound effect on stereo
speakers as a float from \code{-1} to \code{1}, where \code{0} is
centered (full volume in both speakers), \code{1} is entirely in
the right speaker, and \code{-1} is entirely in the left speaker.

\item {} 
\code{maxtime} -- The maximum amount of time to play the sound in
milliseconds; set to \code{None} for no limit.

\item {} 
\code{fade\_time} -- The time in milliseconds over which to fade
the sound in; set to \code{None} or \code{0} to immediately
play the sound at full volume.

\item {} 
\code{force} -- Whether or not the sound should be played even if
it is already playing the maximum number of times.  If set to
\code{True} and the sound is already playing the maximum
number of times, one of the instances of the sound already
playing will be stopped.

\end{itemize}

\end{fulllineitems}

\index{stop() (sge.snd.Sound method)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Sound.stop}\pysiglinewithargsret{\code{Sound.}\bfcode{stop}}{\emph{fade\_time=None}}{}
Stop the sound.

Arguments:
\begin{itemize}
\item {} 
\code{fade\_time} -- The time in milliseconds over which to fade
the sound out before stopping; set to \code{None} or \code{0}
to immediately stop the sound.

\end{itemize}

\end{fulllineitems}

\index{pause() (sge.snd.Sound method)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Sound.pause}\pysiglinewithargsret{\code{Sound.}\bfcode{pause}}{}{}
Pause playback of the sound.

\end{fulllineitems}

\index{unpause() (sge.snd.Sound method)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Sound.unpause}\pysiglinewithargsret{\code{Sound.}\bfcode{unpause}}{}{}
Resume playback of the sound if paused.

\end{fulllineitems}



\subsection{sge.snd.Music}
\label{snd:sge-snd-music}\index{Music (class in sge.snd)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Music}\pysiglinewithargsret{\strong{class }\code{sge.snd.}\bfcode{Music}}{\emph{fname}, \emph{volume=1}}{}
This class stores and plays music.  Music is very similar to sound
effects, but only one music file can be played at a time, and it is
more efficient for larger files than {\hyperref[snd:sge.snd.Sound]{\emph{\code{sge.snd.Sound}}}}.

What music formats are supported depends on the implementation of
the SGE, but Ogg Vorbis is generally a good choice.  See the
implementation-specific information for a full list of supported
formats.

\begin{notice}{note}{Note:}
You should avoid the temptation to use MP3 files; MP3 is a
patent-encumbered format, so many systems do not support it and
royalties to the patent holders may be required for commercial
use.  There are many programs which can convert your MP3 files to
the free Ogg Vorbis format.
\end{notice}
\index{volume (sge.snd.Music attribute)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Music.volume}\pysigline{\bfcode{volume}}
The volume of the music as a value from \code{0} to \code{1} (\code{0} for
no sound, \code{1} for maximum volume).

\end{fulllineitems}

\index{fname (sge.snd.Music attribute)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Music.fname}\pysigline{\bfcode{fname}}
The file name of the music given when it was created.
(Read-only)

\end{fulllineitems}

\index{length (sge.snd.Music attribute)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Music.length}\pysigline{\bfcode{length}}
The length of the music in milliseconds.  (Read-only)

\end{fulllineitems}

\index{playing (sge.snd.Music attribute)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Music.playing}\pysigline{\bfcode{playing}}
Whether or not the music is playing.  (Read-only)

\end{fulllineitems}

\index{position (sge.snd.Music attribute)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Music.position}\pysigline{\bfcode{position}}
The current position (time) playback of the music is at in
milliseconds.  (Read-only)

\end{fulllineitems}

\index{rd (sge.snd.Music attribute)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Music.rd}\pysigline{\bfcode{rd}}
Reserved dictionary for internal use by the SGE.  (Read-only)

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{sge.snd.Music Methods}
\label{snd:sge-snd-music-methods}\index{\_\_init\_\_() (sge.snd.Music method)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Music.__init__}\pysiglinewithargsret{\code{Music.}\bfcode{\_\_init\_\_}}{\emph{fname}, \emph{volume=1}}{}
Arguments:
\begin{itemize}
\item {} 
\code{fname} -- The path to the sound file.  If set to
\code{None}, this object will not actually play any music.
If this is neither a valid sound file nor \code{None},
\code{OSError} is raised.

\end{itemize}

All other arguments set the respective initial attributes of the
music.  See the documentation for {\hyperref[snd:sge.snd.Music]{\emph{\code{sge.snd.Music}}}} for
more information.

\end{fulllineitems}

\index{play() (sge.snd.Music method)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Music.play}\pysiglinewithargsret{\code{Music.}\bfcode{play}}{\emph{start=0}, \emph{loops=1}, \emph{maxtime=None}, \emph{fade\_time=None}}{}
Play the music.

Arguments:
\begin{itemize}
\item {} 
\code{start} -- The number of milliseconds from the beginning to
start playing at.

\end{itemize}

See the documentation for {\hyperref[snd:sge.snd.Sound.play]{\emph{\code{sge.snd.Sound.play()}}}} for more
information.

\end{fulllineitems}

\index{queue() (sge.snd.Music method)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Music.queue}\pysiglinewithargsret{\code{Music.}\bfcode{queue}}{\emph{start=0}, \emph{loops=1}, \emph{maxtime=None}, \emph{fade\_time=None}}{}
Queue the music for playback.

This will cause the music to be added to a list of music to play
in order, after the previous music has finished playing.

See the documentation for {\hyperref[snd:sge.snd.Music.play]{\emph{\code{sge.snd.Music.play()}}}} for more
information.

\end{fulllineitems}

\index{stop() (sge.snd.Music static method)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Music.stop}\pysiglinewithargsret{\strong{static }\code{Music.}\bfcode{stop}}{\emph{fade\_time=None}}{}
Stop the currently playing music.

See the documentation for {\hyperref[snd:sge.snd.Sound.stop]{\emph{\code{sge.snd.Sound.stop()}}}} for more
information.

\end{fulllineitems}

\index{pause() (sge.snd.Music static method)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Music.pause}\pysiglinewithargsret{\strong{static }\code{Music.}\bfcode{pause}}{}{}
Pause playback of the currently playing music.

\end{fulllineitems}

\index{unpause() (sge.snd.Music static method)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Music.unpause}\pysiglinewithargsret{\strong{static }\code{Music.}\bfcode{unpause}}{}{}
Resume playback of the currently playing music if paused.

\end{fulllineitems}

\index{clear\_queue() (sge.snd.Music static method)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.Music.clear_queue}\pysiglinewithargsret{\strong{static }\code{Music.}\bfcode{clear\_queue}}{}{}
Clear the music queue.

\end{fulllineitems}



\section{sge.snd Functions}
\label{snd:sge-snd-functions}

\subsection{sge.snd.stop\_all}
\label{snd:sge-snd-stop-all}\index{stop\_all() (in module sge.snd)}

\begin{fulllineitems}
\phantomsection\label{snd:sge.snd.stop_all}\pysiglinewithargsret{\code{sge.snd.}\bfcode{stop\_all}}{}{}
Stop playback of all sounds.

\end{fulllineitems}



\chapter{sge.collision}
\label{collision::doc}\label{collision:sge-collision}\setbox0\vbox{
\begin{minipage}{0.95\linewidth}
\textbf{Contents}

\medskip

\begin{itemize}
\item {} 
\phantomsection\label{collision:id1}{\hyperref[collision:sge\string-collision]{\emph{sge.collision}}}
\begin{itemize}
\item {} 
\phantomsection\label{collision:id2}{\hyperref[collision:sge\string-collision\string-functions]{\emph{sge.collision Functions}}}

\end{itemize}

\end{itemize}
\end{minipage}}
\begin{center}\setlength{\fboxsep}{5pt}\shadowbox{\box0}\end{center}
\phantomsection\label{collision:module-sge.collision}\index{sge.collision (module)}
This module provides easy-to-use collision detection functions, from
basic rectangle-based collision detection to shape-based collision
detection.


\section{sge.collision Functions}
\label{collision:sge-collision-functions}\index{rectangles\_collide() (in module sge.collision)}

\begin{fulllineitems}
\phantomsection\label{collision:sge.collision.rectangles_collide}\pysiglinewithargsret{\code{sge.collision.}\bfcode{rectangles\_collide}}{\emph{x1}, \emph{y1}, \emph{w1}, \emph{h1}, \emph{x2}, \emph{y2}, \emph{w2}, \emph{h2}}{}
Return whether or not two rectangles collide.

Arguments:
\begin{itemize}
\item {} 
\code{x1} -- The horizontal position of the first rectangle.

\item {} 
\code{y1} -- The vertical position of the first rectangle.

\item {} 
\code{w1} -- The width of the first rectangle.

\item {} 
\code{h1} -- The height of the first rectangle.

\item {} 
\code{x2} -- The horizontal position of the second rectangle.

\item {} 
\code{y2} -- The vertical position of the second rectangle.

\item {} 
\code{w2} -- The width of the second rectangle.

\item {} 
\code{h2} -- The height of the second rectangle.

\end{itemize}

\end{fulllineitems}

\index{masks\_collide() (in module sge.collision)}

\begin{fulllineitems}
\phantomsection\label{collision:sge.collision.masks_collide}\pysiglinewithargsret{\code{sge.collision.}\bfcode{masks\_collide}}{\emph{x1}, \emph{y1}, \emph{mask1}, \emph{x2}, \emph{y2}, \emph{mask2}}{}
Return whether or not two masks collide.

Arguments:
\begin{itemize}
\item {} 
\code{x1} -- The horizontal position of the first mask.

\item {} 
\code{y1} -- The vertical position of the first mask.

\item {} 
\code{mask1} -- The first mask (see below).

\item {} 
\code{x2} -- The horizontal position of the second mask.

\item {} 
\code{y2} -- The vertical position of the second mask.

\item {} 
\code{mask2} -- The second mask (see below).

\end{itemize}

\code{mask1} and \code{mask2} are both lists of lists of boolean values.
Each value in the mask indicates whether or not a pixel is counted
as a collision; the masks collide if at least one pixel at the same
location is \code{True} for both masks.

Masks are indexed as \code{mask{[}x{]}{[}y{]}}, where \code{x} is the column and
\code{y} is the row.

\end{fulllineitems}

\index{rectangle() (in module sge.collision)}

\begin{fulllineitems}
\phantomsection\label{collision:sge.collision.rectangle}\pysiglinewithargsret{\code{sge.collision.}\bfcode{rectangle}}{\emph{x}, \emph{y}, \emph{w}, \emph{h}, \emph{other=None}}{}
Return a list of objects colliding with a rectangle.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal position of the rectangle.

\item {} 
\code{y} -- The vertical position of the rectangle.

\item {} 
\code{w} -- The width of the rectangle.

\item {} 
\code{h} -- The height of the rectangle.

\item {} 
\code{other} -- What to check for collisions with.  See the
documentation for {\hyperref[dsp:sge.dsp.Object.collision]{\emph{\code{sge.dsp.Object.collision()}}}} for more
information.

\end{itemize}

\end{fulllineitems}

\index{ellipse() (in module sge.collision)}

\begin{fulllineitems}
\phantomsection\label{collision:sge.collision.ellipse}\pysiglinewithargsret{\code{sge.collision.}\bfcode{ellipse}}{\emph{x}, \emph{y}, \emph{w}, \emph{h}, \emph{other=None}}{}
Return a list of objects colliding with an ellipse.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal position of the imaginary rectangle
containing the ellipse.

\item {} 
\code{y} -- The vertical position of the imaginary rectangle
containing the ellipse.

\item {} 
\code{w} -- The width of the ellipse.

\item {} 
\code{h} -- The height of the ellipse.

\item {} 
\code{other} -- What to check for collisions with.  See the
documentation for {\hyperref[dsp:sge.dsp.Object.collision]{\emph{\code{sge.dsp.Object.collision()}}}} for more
information.

\end{itemize}

\end{fulllineitems}

\index{circle() (in module sge.collision)}

\begin{fulllineitems}
\phantomsection\label{collision:sge.collision.circle}\pysiglinewithargsret{\code{sge.collision.}\bfcode{circle}}{\emph{x}, \emph{y}, \emph{radius}, \emph{other=None}}{}
Return a list of objects colliding with a circle.

Arguments:
\begin{itemize}
\item {} 
\code{x} -- The horizontal position of the center of the circle.

\item {} 
\code{y} -- The vertical position of the center of the circle.

\item {} 
\code{radius} -- The radius of the circle.

\item {} 
\code{other} -- What to check for collisions with.  See the
documentation for {\hyperref[dsp:sge.dsp.Object.collision]{\emph{\code{sge.dsp.Object.collision()}}}} for more
information.

\end{itemize}

\end{fulllineitems}

\index{line() (in module sge.collision)}

\begin{fulllineitems}
\phantomsection\label{collision:sge.collision.line}\pysiglinewithargsret{\code{sge.collision.}\bfcode{line}}{\emph{x1}, \emph{y1}, \emph{x2}, \emph{y2}, \emph{other=None}}{}
Return a list of objects colliding with a line segment.

Arguments:
\begin{itemize}
\item {} 
\code{x1} -- The horizontal position of the first endpoint of the
line segment.

\item {} 
\code{y1} -- The vertical position of the first endpoint of the line
segment.

\item {} 
\code{x2} -- The horizontal position of the second endpoint of the
line segment.

\item {} 
\code{y2} -- The vertical position of the second endpoint of the line
segment.

\item {} 
\code{other} -- What to check for collisions with.  See the
documentation for {\hyperref[dsp:sge.dsp.Object.collision]{\emph{\code{sge.dsp.Object.collision()}}}} for more
information.

\end{itemize}

\end{fulllineitems}



\chapter{sge.joystick}
\label{joystick::doc}\label{joystick:sge-joystick}\setbox0\vbox{
\begin{minipage}{0.95\linewidth}
\textbf{Contents}

\medskip

\begin{itemize}
\item {} 
\phantomsection\label{joystick:id1}{\hyperref[joystick:sge\string-joystick]{\emph{sge.joystick}}}
\begin{itemize}
\item {} 
\phantomsection\label{joystick:id2}{\hyperref[joystick:sge\string-joystick\string-functions]{\emph{sge.joystick Functions}}}

\end{itemize}

\end{itemize}
\end{minipage}}
\begin{center}\setlength{\fboxsep}{5pt}\shadowbox{\box0}\end{center}
\phantomsection\label{joystick:module-sge.joystick}\index{sge.joystick (module)}
This module provides functions related to joystick input.


\section{sge.joystick Functions}
\label{joystick:sge-joystick-functions}\index{refresh() (in module sge.joystick)}

\begin{fulllineitems}
\phantomsection\label{joystick:sge.joystick.refresh}\pysiglinewithargsret{\code{sge.joystick.}\bfcode{refresh}}{}{}
Refresh the SGE's knowledge of joysticks.

Call this method to allow the SGE to use joysticks that were plugged
in while the game was running.

\end{fulllineitems}

\index{get\_axis() (in module sge.joystick)}

\begin{fulllineitems}
\phantomsection\label{joystick:sge.joystick.get_axis}\pysiglinewithargsret{\code{sge.joystick.}\bfcode{get\_axis}}{\emph{joystick}, \emph{axis}}{}
Return the position of a joystick axis as a float from \code{-1} to
\code{1}, where \code{0} is centered, \code{-1} is all the way to the left or
up, and \code{1} is all the way to the right or down.  Return \code{0} if
the requested joystick or axis does not exist.

Arguments:
\begin{itemize}
\item {} 
\code{joystick} -- The number of the joystick to check, where \code{0}
is the first joystick, or the name of the joystick to check.

\item {} 
\code{axis} -- The number of the axis to check, where \code{0} is the
first axis of the joystick.

\end{itemize}

\end{fulllineitems}

\index{get\_hat\_x() (in module sge.joystick)}

\begin{fulllineitems}
\phantomsection\label{joystick:sge.joystick.get_hat_x}\pysiglinewithargsret{\code{sge.joystick.}\bfcode{get\_hat\_x}}{\emph{joystick}, \emph{hat}}{}
Return the horizontal position of a joystick hat (d-pad).  Can be
\code{-1} (left), \code{0} (centered), or \code{1} (right).  Return \code{0} if
the requested joystick or hat does not exist.

Arguments:
\begin{itemize}
\item {} 
\code{joystick} -- The number of the joystick to check, where \code{0}
is the first joystick, or the name of the joystick to check.

\item {} 
\code{hat} -- The number of the hat to check, where \code{0} is the
first hat of the joystick.

\end{itemize}

\end{fulllineitems}

\index{get\_hat\_y() (in module sge.joystick)}

\begin{fulllineitems}
\phantomsection\label{joystick:sge.joystick.get_hat_y}\pysiglinewithargsret{\code{sge.joystick.}\bfcode{get\_hat\_y}}{\emph{joystick}, \emph{hat}}{}
Return the vertical position of a joystick hat (d-pad).  Can be
\code{-1} (up), \code{0} (centered), or \code{1} (down).  Return \code{0} if the
requested joystick or hat does not exist.

Arguments:
\begin{itemize}
\item {} 
\code{joystick} -- The number of the joystick to check, where \code{0}
is the first joystick, or the name of the joystick to check.

\item {} 
\code{hat} -- The number of the hat to check, where \code{0} is the
first hat of the joystick.

\end{itemize}

\end{fulllineitems}

\index{get\_pressed() (in module sge.joystick)}

\begin{fulllineitems}
\phantomsection\label{joystick:sge.joystick.get_pressed}\pysiglinewithargsret{\code{sge.joystick.}\bfcode{get\_pressed}}{\emph{joystick}, \emph{button}}{}
Return whether or not a joystick button is pressed, or
\code{False} if the requested joystick or button does not exist.

Arguments:
\begin{itemize}
\item {} 
\code{joystick} -- The number of the joystick to check, where \code{0}
is the first joystick, or the name of the joystick to check.

\item {} 
\code{button} -- The number of the button to check, where \code{0} is
the first button of the joystick.

\end{itemize}

\end{fulllineitems}

\index{get\_joysticks() (in module sge.joystick)}

\begin{fulllineitems}
\phantomsection\label{joystick:sge.joystick.get_joysticks}\pysiglinewithargsret{\code{sge.joystick.}\bfcode{get\_joysticks}}{}{}
Return the number of joysticks available.

\end{fulllineitems}

\index{get\_name() (in module sge.joystick)}

\begin{fulllineitems}
\phantomsection\label{joystick:sge.joystick.get_name}\pysiglinewithargsret{\code{sge.joystick.}\bfcode{get\_name}}{\emph{joystick}}{}
Return the name of a joystick, or \code{None} if the requested
joystick does not exist.

Arguments:
\begin{itemize}
\item {} 
\code{joystick} -- The number of the joystick to check, where \code{0}
is the first joystick, or the name of the joystick to check.

\end{itemize}

\end{fulllineitems}

\index{get\_id() (in module sge.joystick)}

\begin{fulllineitems}
\phantomsection\label{joystick:sge.joystick.get_id}\pysiglinewithargsret{\code{sge.joystick.}\bfcode{get\_id}}{\emph{joystick}}{}
Return the number of a joystick, where \code{0} is the first joystick,
or \code{None} if the requested joystick does not exist.

Arguments:
\begin{itemize}
\item {} 
\code{joystick} -- The number of the joystick to check, where \code{0}
is the first joystick, or the name of the joystick to check.

\end{itemize}

\end{fulllineitems}

\index{get\_axes() (in module sge.joystick)}

\begin{fulllineitems}
\phantomsection\label{joystick:sge.joystick.get_axes}\pysiglinewithargsret{\code{sge.joystick.}\bfcode{get\_axes}}{\emph{joystick}}{}
Return the number of axes available on a joystick, or \code{0} if the
requested joystick does not exist.

Arguments:
\begin{itemize}
\item {} 
\code{joystick} -- The number of the joystick to check, where \code{0}
is the first joystick, or the name of the joystick to check.

\end{itemize}

\end{fulllineitems}

\index{get\_hats() (in module sge.joystick)}

\begin{fulllineitems}
\phantomsection\label{joystick:sge.joystick.get_hats}\pysiglinewithargsret{\code{sge.joystick.}\bfcode{get\_hats}}{\emph{joystick}}{}
Return the number of hats (d-pads) available on a joystick, or \code{0}
if the requested joystick does not exist.

Arguments:
\begin{itemize}
\item {} 
\code{joystick} -- The number of the joystick to check, where \code{0}
is the first joystick, or the name of the joystick to check.

\end{itemize}

\end{fulllineitems}

\index{get\_trackballs() (in module sge.joystick)}

\begin{fulllineitems}
\phantomsection\label{joystick:sge.joystick.get_trackballs}\pysiglinewithargsret{\code{sge.joystick.}\bfcode{get\_trackballs}}{\emph{joystick}}{}
Return the number of trackballs available on a joystick, or \code{0} if
the requested joystick does not exist.

Arguments:
\begin{itemize}
\item {} 
\code{joystick} -- The number of the joystick to check, where \code{0}
is the first joystick, or the name of the joystick to check.

\end{itemize}

\end{fulllineitems}

\index{get\_buttons() (in module sge.joystick)}

\begin{fulllineitems}
\phantomsection\label{joystick:sge.joystick.get_buttons}\pysiglinewithargsret{\code{sge.joystick.}\bfcode{get\_buttons}}{\emph{joystick}}{}
Return the number of buttons available on a joystick, or \code{0} if
the requested joystick does not exist.

Arguments:
\begin{itemize}
\item {} 
\code{joystick} -- The number of the joystick to check, where \code{0}
is the first joystick, or the name of the joystick to check.

\end{itemize}

\end{fulllineitems}



\chapter{sge.keyboard}
\label{keyboard::doc}\label{keyboard:sge-keyboard}\setbox0\vbox{
\begin{minipage}{0.95\linewidth}
\textbf{Contents}

\medskip

\begin{itemize}
\item {} 
\phantomsection\label{keyboard:id1}{\hyperref[keyboard:sge\string-keyboard]{\emph{sge.keyboard}}}
\begin{itemize}
\item {} 
\phantomsection\label{keyboard:id2}{\hyperref[keyboard:sge\string-keyboard\string-functions]{\emph{sge.keyboard Functions}}}

\end{itemize}

\end{itemize}
\end{minipage}}
\begin{center}\setlength{\fboxsep}{5pt}\shadowbox{\box0}\end{center}
\phantomsection\label{keyboard:module-sge.keyboard}\index{sge.keyboard (module)}
This module provides functions related to keyboard input.


\section{sge.keyboard Functions}
\label{keyboard:sge-keyboard-functions}\index{get\_pressed() (in module sge.keyboard)}

\begin{fulllineitems}
\phantomsection\label{keyboard:sge.keyboard.get_pressed}\pysiglinewithargsret{\code{sge.keyboard.}\bfcode{get\_pressed}}{\emph{key}}{}
Return whether or not a key is pressed.

See the documentation for {\hyperref[input:sge.input.KeyPress]{\emph{\code{sge.input.KeyPress}}}} for more
information.

\end{fulllineitems}

\index{get\_modifier() (in module sge.keyboard)}

\begin{fulllineitems}
\phantomsection\label{keyboard:sge.keyboard.get_modifier}\pysiglinewithargsret{\code{sge.keyboard.}\bfcode{get\_modifier}}{\emph{key}}{}
Return whether or not a modifier key is being held.

Arguments:
\begin{itemize}
\item {} 
\code{key} -- The identifier string of the modifier key to check; see
the table below.

\end{itemize}

\begin{tabulary}{\linewidth}{|L|L|}
\hline
\textsf{\relax 
Modifier Key Name
} & \textsf{\relax 
Identifier String
}\\
\hline
Alt
 & 
\code{"alt"}
\\
\hline
Left Alt
 & 
\code{"alt\_left"}
\\
\hline
Right Alt
 & 
\code{"alt\_right"}
\\
\hline
Ctrl
 & 
\code{"ctrl"}
\\
\hline
Left Ctrl
 & 
\code{"ctrl\_left"}
\\
\hline
Right Ctrl
 & 
\code{"ctrl\_right"}
\\
\hline
Meta
 & 
\code{"meta"}
\\
\hline
Left Meta
 & 
\code{"meta\_left"}
\\
\hline
Right Meta
 & 
\code{"meta\_right"}
\\
\hline
Shift
 & 
\code{"shift"}
\\
\hline
Left Shift
 & 
\code{"shift\_left"}
\\
\hline
Right Shift
 & 
\code{"shift\_right"}
\\
\hline
Mode
 & 
\code{"mode"}
\\
\hline
Caps Lock
 & 
\code{"caps\_lock"}
\\
\hline
Num Lock
 & 
\code{"num\_lock"}
\\
\hline\end{tabulary}


\end{fulllineitems}

\index{get\_focused() (in module sge.keyboard)}

\begin{fulllineitems}
\phantomsection\label{keyboard:sge.keyboard.get_focused}\pysiglinewithargsret{\code{sge.keyboard.}\bfcode{get\_focused}}{}{}
Return whether or not the game has keyboard focus.

\end{fulllineitems}

\index{set\_repeat() (in module sge.keyboard)}

\begin{fulllineitems}
\phantomsection\label{keyboard:sge.keyboard.set_repeat}\pysiglinewithargsret{\code{sge.keyboard.}\bfcode{set\_repeat}}{\emph{enabled=True}, \emph{interval=0}, \emph{delay=0}}{}
Set repetition of key press events.

Arguments:
\begin{itemize}
\item {} 
\code{enabled} -- Whether or not to enable repetition of key press
events.

\item {} 
\code{interval} -- The time in milliseconds in between each repeated
key press event.

\item {} 
\code{delay} -- The time in milliseconds to wait after the first key
press event before repeating key press events.

\end{itemize}

If \code{enabled} is set to true, this causes a key being held down to
generate additional key press events as long as it remains held
down.

\end{fulllineitems}

\index{get\_repeat\_enabled() (in module sge.keyboard)}

\begin{fulllineitems}
\phantomsection\label{keyboard:sge.keyboard.get_repeat_enabled}\pysiglinewithargsret{\code{sge.keyboard.}\bfcode{get\_repeat\_enabled}}{}{}
Return whether or not repetition of key press events is enabled.

See the documentation for {\hyperref[keyboard:sge.keyboard.set_repeat]{\emph{\code{sge.keyboard.set\_repeat()}}}} for more
information.

\end{fulllineitems}

\index{get\_repeat\_interval() (in module sge.keyboard)}

\begin{fulllineitems}
\phantomsection\label{keyboard:sge.keyboard.get_repeat_interval}\pysiglinewithargsret{\code{sge.keyboard.}\bfcode{get\_repeat\_interval}}{}{}
Return the interval in between each repeated key press event.

See the documentation for {\hyperref[keyboard:sge.keyboard.set_repeat]{\emph{\code{sge.keyboard.set\_repeat()}}}} for more
information.

\end{fulllineitems}

\index{get\_repeat\_delay() (in module sge.keyboard)}

\begin{fulllineitems}
\phantomsection\label{keyboard:sge.keyboard.get_repeat_delay}\pysiglinewithargsret{\code{sge.keyboard.}\bfcode{get\_repeat\_delay}}{}{}
Return the delay before repeating key press events.

See the documentation for {\hyperref[keyboard:sge.keyboard.set_repeat]{\emph{\code{sge.keyboard.set\_repeat()}}}} for more
information.

\end{fulllineitems}



\chapter{sge.mouse}
\label{mouse::doc}\label{mouse:sge-mouse}\setbox0\vbox{
\begin{minipage}{0.95\linewidth}
\textbf{Contents}

\medskip

\begin{itemize}
\item {} 
\phantomsection\label{mouse:id1}{\hyperref[mouse:sge\string-mouse]{\emph{sge.mouse}}}
\begin{itemize}
\item {} 
\phantomsection\label{mouse:id2}{\hyperref[mouse:sge\string-mouse\string-functions]{\emph{sge.mouse Functions}}}

\end{itemize}

\end{itemize}
\end{minipage}}
\begin{center}\setlength{\fboxsep}{5pt}\shadowbox{\box0}\end{center}
\phantomsection\label{mouse:module-sge.mouse}\index{sge.mouse (module)}
This module provides functions related to the mouse input.

Some other mouse functionalities are provided through attributes of
\code{sge.game.mouse}.  These attributes are listed below.

The mouse can be in either absolute or relative mode.  In absolute mode,
the mouse has a position.  In relative mode, the mouse only moves.
Which mode the mouse is in depends on the values of
\code{sge.game.grab\_input} and {\hyperref[mouse:sge.mouse.sge.game.mouse.visible]{\emph{\code{sge.game.mouse.visible}}}}.
\index{x (sge.mouse.sge.game.mouse attribute)}\index{y (sge.mouse.sge.game.mouse attribute)}

\begin{fulllineitems}
\phantomsection\label{mouse:sge.mouse.sge.game.mouse.x}\pysigline{\code{sge.game.mouse.}\bfcode{x}}\phantomsection\label{mouse:sge.mouse.sge.game.mouse.y}\pysigline{\code{sge.game.mouse.}\bfcode{y}}
If the mouse is in absolute mode and within a view port, these
attributes indicate the
position of the mouse in the room, based on its proximity to the view
it is in.  Otherwise, they will return \code{-1}.

These attributes can be assigned to safely, but doing so will not
have any effect.

\end{fulllineitems}

\index{z (sge.mouse.sge.game.mouse attribute)}

\begin{fulllineitems}
\phantomsection\label{mouse:sge.mouse.sge.game.mouse.z}\pysigline{\code{sge.game.mouse.}\bfcode{z}}
The Z-axis position of the mouse cursor's projection in relation to
other window projections.  The default value is \code{10000}.

\end{fulllineitems}

\index{sprite (sge.mouse.sge.game.mouse attribute)}

\begin{fulllineitems}
\phantomsection\label{mouse:sge.mouse.sge.game.mouse.sprite}\pysigline{\code{sge.game.mouse.}\bfcode{sprite}}
Determines what sprite will be used to represent the mouse cursor.
Set to \code{None} for the default mouse cursor.

\end{fulllineitems}

\index{visible (sge.mouse.sge.game.mouse attribute)}

\begin{fulllineitems}
\phantomsection\label{mouse:sge.mouse.sge.game.mouse.visible}\pysigline{\code{sge.game.mouse.}\bfcode{visible}}
Controls whether or not the mouse cursor is visible.  If this is
\code{False} and \code{sge.game.grab\_input} is \code{True}, the
mouse will be in relative mode.  Otherwise, the mouse will be in
absolute mode.

\end{fulllineitems}



\section{sge.mouse Functions}
\label{mouse:sge-mouse-functions}\index{get\_pressed() (in module sge.mouse)}

\begin{fulllineitems}
\phantomsection\label{mouse:sge.mouse.get_pressed}\pysiglinewithargsret{\code{sge.mouse.}\bfcode{get\_pressed}}{\emph{button}}{}
Return whether or not a mouse button is pressed.

See the documentation for {\hyperref[input:sge.input.MouseButtonPress]{\emph{\code{sge.input.MouseButtonPress}}}} for
more information.

\end{fulllineitems}

\index{get\_x() (in module sge.mouse)}

\begin{fulllineitems}
\phantomsection\label{mouse:sge.mouse.get_x}\pysiglinewithargsret{\code{sge.mouse.}\bfcode{get\_x}}{}{}
Return the horizontal location of the mouse cursor.

The location returned is relative to the window, excluding any
scaling, pillarboxes, and letterboxes.  If the mouse is in
relative mode, this function returns \code{None}.

\end{fulllineitems}

\index{get\_y() (in module sge.mouse)}

\begin{fulllineitems}
\phantomsection\label{mouse:sge.mouse.get_y}\pysiglinewithargsret{\code{sge.mouse.}\bfcode{get\_y}}{}{}
Return the vertical location of the mouse cursor.

The location returned is relative to the window, excluding any
scaling, pillarboxes, and letterboxes.  If the mouse is in
relative mode, this function returns \code{None}.

\end{fulllineitems}

\index{set\_x() (in module sge.mouse)}

\begin{fulllineitems}
\phantomsection\label{mouse:sge.mouse.set_x}\pysiglinewithargsret{\code{sge.mouse.}\bfcode{set\_x}}{\emph{value}}{}
Set the horizontal location of the mouse cursor.

The location returned is relative to the window, excluding any
scaling, pillarboxes, and letterboxes.  If the mouse is in
relative mode, this function has no effect.

\end{fulllineitems}

\index{set\_y() (in module sge.mouse)}

\begin{fulllineitems}
\phantomsection\label{mouse:sge.mouse.set_y}\pysiglinewithargsret{\code{sge.mouse.}\bfcode{set\_y}}{\emph{value}}{}
Set the vertical location of the mouse cursor.

The location returned is relative to the window, excluding any
scaling, pillarboxes, and letterboxes.  If the mouse is in
relative mode, this function has no effect.

\end{fulllineitems}



\chapter{sge.s}
\label{s::doc}\label{s:sge-s}\setbox0\vbox{
\begin{minipage}{0.95\linewidth}
\textbf{Contents}

\medskip

\begin{itemize}
\item {} 
\phantomsection\label{s:id1}{\hyperref[s:sge\string-s]{\emph{sge.s}}}

\end{itemize}
\end{minipage}}
\begin{center}\setlength{\fboxsep}{5pt}\shadowbox{\box0}\end{center}
\phantomsection\label{s:module-sge.s}\index{sge.s (module)}
This module provides several variables which represent particular
important strings.  The purpose of these variables (listed below) is to
make typos more obvious.

The values of all of these variables are their names as strings.  If a
variable name starts with an underscore, its value excludes this
preceding underscore.  For example, a variable called \code{spam} would
have a value of \code{"spam"}, and a variable called \code{\_1984} would have a
value of \code{"1984"}.
\index{sge.s.\_0 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s._0}\pysigline{\code{sge.s.}\bfcode{\_0}}
\end{fulllineitems}

\index{sge.s.\_1 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s._1}\pysigline{\code{sge.s.}\bfcode{\_1}}
\end{fulllineitems}

\index{sge.s.\_2 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s._2}\pysigline{\code{sge.s.}\bfcode{\_2}}
\end{fulllineitems}

\index{sge.s.\_3 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s._3}\pysigline{\code{sge.s.}\bfcode{\_3}}
\end{fulllineitems}

\index{sge.s.\_4 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s._4}\pysigline{\code{sge.s.}\bfcode{\_4}}
\end{fulllineitems}

\index{sge.s.\_5 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s._5}\pysigline{\code{sge.s.}\bfcode{\_5}}
\end{fulllineitems}

\index{sge.s.\_6 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s._6}\pysigline{\code{sge.s.}\bfcode{\_6}}
\end{fulllineitems}

\index{sge.s.\_7 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s._7}\pysigline{\code{sge.s.}\bfcode{\_7}}
\end{fulllineitems}

\index{sge.s.\_8 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s._8}\pysigline{\code{sge.s.}\bfcode{\_8}}
\end{fulllineitems}

\index{sge.s.\_9 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s._9}\pysigline{\code{sge.s.}\bfcode{\_9}}
\end{fulllineitems}

\index{sge.s.a (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.a}\pysigline{\code{sge.s.}\bfcode{a}}
\end{fulllineitems}

\index{sge.s.b (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.b}\pysigline{\code{sge.s.}\bfcode{b}}
\end{fulllineitems}

\index{sge.s.c (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.c}\pysigline{\code{sge.s.}\bfcode{c}}
\end{fulllineitems}

\index{sge.s.d (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.d}\pysigline{\code{sge.s.}\bfcode{d}}
\end{fulllineitems}

\index{sge.s.e (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.e}\pysigline{\code{sge.s.}\bfcode{e}}
\end{fulllineitems}

\index{sge.s.f (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.f}\pysigline{\code{sge.s.}\bfcode{f}}
\end{fulllineitems}

\index{sge.s.g (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.g}\pysigline{\code{sge.s.}\bfcode{g}}
\end{fulllineitems}

\index{sge.s.h (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.h}\pysigline{\code{sge.s.}\bfcode{h}}
\end{fulllineitems}

\index{sge.s.i (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.i}\pysigline{\code{sge.s.}\bfcode{i}}
\end{fulllineitems}

\index{sge.s.j (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.j}\pysigline{\code{sge.s.}\bfcode{j}}
\end{fulllineitems}

\index{sge.s.k (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.k}\pysigline{\code{sge.s.}\bfcode{k}}
\end{fulllineitems}

\index{sge.s.l (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.l}\pysigline{\code{sge.s.}\bfcode{l}}
\end{fulllineitems}

\index{sge.s.m (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.m}\pysigline{\code{sge.s.}\bfcode{m}}
\end{fulllineitems}

\index{sge.s.n (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.n}\pysigline{\code{sge.s.}\bfcode{n}}
\end{fulllineitems}

\index{sge.s.o (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.o}\pysigline{\code{sge.s.}\bfcode{o}}
\end{fulllineitems}

\index{sge.s.p (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.p}\pysigline{\code{sge.s.}\bfcode{p}}
\end{fulllineitems}

\index{sge.s.q (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.q}\pysigline{\code{sge.s.}\bfcode{q}}
\end{fulllineitems}

\index{sge.s.r (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.r}\pysigline{\code{sge.s.}\bfcode{r}}
\end{fulllineitems}

\index{sge.s.s (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.s}\pysigline{\code{sge.s.}\bfcode{s}}
\end{fulllineitems}

\index{sge.s.t (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.t}\pysigline{\code{sge.s.}\bfcode{t}}
\end{fulllineitems}

\index{sge.s.u (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.u}\pysigline{\code{sge.s.}\bfcode{u}}
\end{fulllineitems}

\index{sge.s.v (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.v}\pysigline{\code{sge.s.}\bfcode{v}}
\end{fulllineitems}

\index{sge.s.w (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.w}\pysigline{\code{sge.s.}\bfcode{w}}
\end{fulllineitems}

\index{sge.s.x (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.x}\pysigline{\code{sge.s.}\bfcode{x}}
\end{fulllineitems}

\index{sge.s.y (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.y}\pysigline{\code{sge.s.}\bfcode{y}}
\end{fulllineitems}

\index{sge.s.z (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.z}\pysigline{\code{sge.s.}\bfcode{z}}
\end{fulllineitems}

\index{sge.s.\_break (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s._break}\pysigline{\code{sge.s.}\bfcode{\_break}}
\end{fulllineitems}

\index{sge.s.alt\_left (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.alt_left}\pysigline{\code{sge.s.}\bfcode{alt\_left}}
\end{fulllineitems}

\index{sge.s.alt\_right (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.alt_right}\pysigline{\code{sge.s.}\bfcode{alt\_right}}
\end{fulllineitems}

\index{sge.s.ampersand (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.ampersand}\pysigline{\code{sge.s.}\bfcode{ampersand}}
\end{fulllineitems}

\index{sge.s.apostrophe (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.apostrophe}\pysigline{\code{sge.s.}\bfcode{apostrophe}}
\end{fulllineitems}

\index{sge.s.aqua (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.aqua}\pysigline{\code{sge.s.}\bfcode{aqua}}
\end{fulllineitems}

\index{sge.s.asterisk (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.asterisk}\pysigline{\code{sge.s.}\bfcode{asterisk}}
\end{fulllineitems}

\index{sge.s.at (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.at}\pysigline{\code{sge.s.}\bfcode{at}}
\end{fulllineitems}

\index{sge.s.axis0 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.axis0}\pysigline{\code{sge.s.}\bfcode{axis0}}
\end{fulllineitems}

\index{sge.s.backslash (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.backslash}\pysigline{\code{sge.s.}\bfcode{backslash}}
\end{fulllineitems}

\index{sge.s.backspace (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.backspace}\pysigline{\code{sge.s.}\bfcode{backspace}}
\end{fulllineitems}

\index{sge.s.backtick (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.backtick}\pysigline{\code{sge.s.}\bfcode{backtick}}
\end{fulllineitems}

\index{sge.s.black (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.black}\pysigline{\code{sge.s.}\bfcode{black}}
\end{fulllineitems}

\index{sge.s.blue (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.blue}\pysigline{\code{sge.s.}\bfcode{blue}}
\end{fulllineitems}

\index{sge.s.bottom (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.bottom}\pysigline{\code{sge.s.}\bfcode{bottom}}
\end{fulllineitems}

\index{sge.s.bracket\_left (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.bracket_left}\pysigline{\code{sge.s.}\bfcode{bracket\_left}}
\end{fulllineitems}

\index{sge.s.bracket\_right (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.bracket_right}\pysigline{\code{sge.s.}\bfcode{bracket\_right}}
\end{fulllineitems}

\index{sge.s.button (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.button}\pysigline{\code{sge.s.}\bfcode{button}}
\end{fulllineitems}

\index{sge.s.caps\_lock (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.caps_lock}\pysigline{\code{sge.s.}\bfcode{caps\_lock}}
\end{fulllineitems}

\index{sge.s.carat (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.carat}\pysigline{\code{sge.s.}\bfcode{carat}}
\end{fulllineitems}

\index{sge.s.center (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.center}\pysigline{\code{sge.s.}\bfcode{center}}
\end{fulllineitems}

\index{sge.s.clear (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.clear}\pysigline{\code{sge.s.}\bfcode{clear}}
\end{fulllineitems}

\index{sge.s.colon (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.colon}\pysigline{\code{sge.s.}\bfcode{colon}}
\end{fulllineitems}

\index{sge.s.comma (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.comma}\pysigline{\code{sge.s.}\bfcode{comma}}
\end{fulllineitems}

\index{sge.s.ctrl\_left (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.ctrl_left}\pysigline{\code{sge.s.}\bfcode{ctrl\_left}}
\end{fulllineitems}

\index{sge.s.ctrl\_right (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.ctrl_right}\pysigline{\code{sge.s.}\bfcode{ctrl\_right}}
\end{fulllineitems}

\index{sge.s.delete (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.delete}\pysigline{\code{sge.s.}\bfcode{delete}}
\end{fulllineitems}

\index{sge.s.dissolve (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.dissolve}\pysigline{\code{sge.s.}\bfcode{dissolve}}
\end{fulllineitems}

\index{sge.s.dollar (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.dollar}\pysigline{\code{sge.s.}\bfcode{dollar}}
\end{fulllineitems}

\index{sge.s.down (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.down}\pysigline{\code{sge.s.}\bfcode{down}}
\end{fulllineitems}

\index{sge.s.end (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.end}\pysigline{\code{sge.s.}\bfcode{end}}
\end{fulllineitems}

\index{sge.s.enter (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.enter}\pysigline{\code{sge.s.}\bfcode{enter}}
\end{fulllineitems}

\index{sge.s.equals (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.equals}\pysigline{\code{sge.s.}\bfcode{equals}}
\end{fulllineitems}

\index{sge.s.escape (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.escape}\pysigline{\code{sge.s.}\bfcode{escape}}
\end{fulllineitems}

\index{sge.s.euro (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.euro}\pysigline{\code{sge.s.}\bfcode{euro}}
\end{fulllineitems}

\index{sge.s.exclamation (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.exclamation}\pysigline{\code{sge.s.}\bfcode{exclamation}}
\end{fulllineitems}

\index{sge.s.f0 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.f0}\pysigline{\code{sge.s.}\bfcode{f0}}
\end{fulllineitems}

\index{sge.s.f1 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.f1}\pysigline{\code{sge.s.}\bfcode{f1}}
\end{fulllineitems}

\index{sge.s.f2 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.f2}\pysigline{\code{sge.s.}\bfcode{f2}}
\end{fulllineitems}

\index{sge.s.f3 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.f3}\pysigline{\code{sge.s.}\bfcode{f3}}
\end{fulllineitems}

\index{sge.s.f4 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.f4}\pysigline{\code{sge.s.}\bfcode{f4}}
\end{fulllineitems}

\index{sge.s.f5 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.f5}\pysigline{\code{sge.s.}\bfcode{f5}}
\end{fulllineitems}

\index{sge.s.f6 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.f6}\pysigline{\code{sge.s.}\bfcode{f6}}
\end{fulllineitems}

\index{sge.s.f7 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.f7}\pysigline{\code{sge.s.}\bfcode{f7}}
\end{fulllineitems}

\index{sge.s.f8 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.f8}\pysigline{\code{sge.s.}\bfcode{f8}}
\end{fulllineitems}

\index{sge.s.f9 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.f9}\pysigline{\code{sge.s.}\bfcode{f9}}
\end{fulllineitems}

\index{sge.s.f10 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.f10}\pysigline{\code{sge.s.}\bfcode{f10}}
\end{fulllineitems}

\index{sge.s.f11 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.f11}\pysigline{\code{sge.s.}\bfcode{f11}}
\end{fulllineitems}

\index{sge.s.f12 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.f12}\pysigline{\code{sge.s.}\bfcode{f12}}
\end{fulllineitems}

\index{sge.s.fade (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.fade}\pysigline{\code{sge.s.}\bfcode{fade}}
\end{fulllineitems}

\index{sge.s.fuchsia (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.fuchsia}\pysigline{\code{sge.s.}\bfcode{fuchsia}}
\end{fulllineitems}

\index{sge.s.gray (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.gray}\pysigline{\code{sge.s.}\bfcode{gray}}
\end{fulllineitems}

\index{sge.s.greater\_than (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.greater_than}\pysigline{\code{sge.s.}\bfcode{greater\_than}}
\end{fulllineitems}

\index{sge.s.green (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.green}\pysigline{\code{sge.s.}\bfcode{green}}
\end{fulllineitems}

\index{sge.s.hash (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.hash}\pysigline{\code{sge.s.}\bfcode{hash}}
\end{fulllineitems}

\index{sge.s.hat\_center\_x (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.hat_center_x}\pysigline{\code{sge.s.}\bfcode{hat\_center\_x}}
\end{fulllineitems}

\index{sge.s.hat\_center\_y (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.hat_center_y}\pysigline{\code{sge.s.}\bfcode{hat\_center\_y}}
\end{fulllineitems}

\index{sge.s.hat\_down (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.hat_down}\pysigline{\code{sge.s.}\bfcode{hat\_down}}
\end{fulllineitems}

\index{sge.s.hat\_left (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.hat_left}\pysigline{\code{sge.s.}\bfcode{hat\_left}}
\end{fulllineitems}

\index{sge.s.hat\_right (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.hat_right}\pysigline{\code{sge.s.}\bfcode{hat\_right}}
\end{fulllineitems}

\index{sge.s.hat\_up (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.hat_up}\pysigline{\code{sge.s.}\bfcode{hat\_up}}
\end{fulllineitems}

\index{sge.s.home (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.home}\pysigline{\code{sge.s.}\bfcode{home}}
\end{fulllineitems}

\index{sge.s.hyphen (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.hyphen}\pysigline{\code{sge.s.}\bfcode{hyphen}}
\end{fulllineitems}

\index{sge.s.insert (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.insert}\pysigline{\code{sge.s.}\bfcode{insert}}
\end{fulllineitems}

\index{sge.s.iris\_in (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.iris_in}\pysigline{\code{sge.s.}\bfcode{iris\_in}}
\end{fulllineitems}

\index{sge.s.iris\_out (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.iris_out}\pysigline{\code{sge.s.}\bfcode{iris\_out}}
\end{fulllineitems}

\index{sge.s.kp\_0 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_0}\pysigline{\code{sge.s.}\bfcode{kp\_0}}
\end{fulllineitems}

\index{sge.s.kp\_1 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_1}\pysigline{\code{sge.s.}\bfcode{kp\_1}}
\end{fulllineitems}

\index{sge.s.kp\_2 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_2}\pysigline{\code{sge.s.}\bfcode{kp\_2}}
\end{fulllineitems}

\index{sge.s.kp\_3 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_3}\pysigline{\code{sge.s.}\bfcode{kp\_3}}
\end{fulllineitems}

\index{sge.s.kp\_4 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_4}\pysigline{\code{sge.s.}\bfcode{kp\_4}}
\end{fulllineitems}

\index{sge.s.kp\_5 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_5}\pysigline{\code{sge.s.}\bfcode{kp\_5}}
\end{fulllineitems}

\index{sge.s.kp\_6 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_6}\pysigline{\code{sge.s.}\bfcode{kp\_6}}
\end{fulllineitems}

\index{sge.s.kp\_7 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_7}\pysigline{\code{sge.s.}\bfcode{kp\_7}}
\end{fulllineitems}

\index{sge.s.kp\_8 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_8}\pysigline{\code{sge.s.}\bfcode{kp\_8}}
\end{fulllineitems}

\index{sge.s.kp\_9 (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_9}\pysigline{\code{sge.s.}\bfcode{kp\_9}}
\end{fulllineitems}

\index{sge.s.kp\_divide (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_divide}\pysigline{\code{sge.s.}\bfcode{kp\_divide}}
\end{fulllineitems}

\index{sge.s.kp\_enter (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_enter}\pysigline{\code{sge.s.}\bfcode{kp\_enter}}
\end{fulllineitems}

\index{sge.s.kp\_equals (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_equals}\pysigline{\code{sge.s.}\bfcode{kp\_equals}}
\end{fulllineitems}

\index{sge.s.kp\_minus (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_minus}\pysigline{\code{sge.s.}\bfcode{kp\_minus}}
\end{fulllineitems}

\index{sge.s.kp\_multiply (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_multiply}\pysigline{\code{sge.s.}\bfcode{kp\_multiply}}
\end{fulllineitems}

\index{sge.s.kp\_plus (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_plus}\pysigline{\code{sge.s.}\bfcode{kp\_plus}}
\end{fulllineitems}

\index{sge.s.kp\_point (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.kp_point}\pysigline{\code{sge.s.}\bfcode{kp\_point}}
\end{fulllineitems}

\index{sge.s.left (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.left}\pysigline{\code{sge.s.}\bfcode{left}}
\end{fulllineitems}

\index{sge.s.less\_than (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.less_than}\pysigline{\code{sge.s.}\bfcode{less\_than}}
\end{fulllineitems}

\index{sge.s.lime (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.lime}\pysigline{\code{sge.s.}\bfcode{lime}}
\end{fulllineitems}

\index{sge.s.maroon (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.maroon}\pysigline{\code{sge.s.}\bfcode{maroon}}
\end{fulllineitems}

\index{sge.s.menu (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.menu}\pysigline{\code{sge.s.}\bfcode{menu}}
\end{fulllineitems}

\index{sge.s.middle (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.middle}\pysigline{\code{sge.s.}\bfcode{middle}}
\end{fulllineitems}

\index{sge.s.mode (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.mode}\pysigline{\code{sge.s.}\bfcode{mode}}
\end{fulllineitems}

\index{sge.s.navy (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.navy}\pysigline{\code{sge.s.}\bfcode{navy}}
\end{fulllineitems}

\index{sge.s.noblur (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.noblur}\pysigline{\code{sge.s.}\bfcode{noblur}}
\end{fulllineitems}

\index{sge.s.num\_lock (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.num_lock}\pysigline{\code{sge.s.}\bfcode{num\_lock}}
\end{fulllineitems}

\index{sge.s.olive (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.olive}\pysigline{\code{sge.s.}\bfcode{olive}}
\end{fulllineitems}

\index{sge.s.pagedown (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.pagedown}\pysigline{\code{sge.s.}\bfcode{pagedown}}
\end{fulllineitems}

\index{sge.s.pageup (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.pageup}\pysigline{\code{sge.s.}\bfcode{pageup}}
\end{fulllineitems}

\index{sge.s.parenthesis\_left (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.parenthesis_left}\pysigline{\code{sge.s.}\bfcode{parenthesis\_left}}
\end{fulllineitems}

\index{sge.s.parenthesis\_right (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.parenthesis_right}\pysigline{\code{sge.s.}\bfcode{parenthesis\_right}}
\end{fulllineitems}

\index{sge.s.pause (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.pause}\pysigline{\code{sge.s.}\bfcode{pause}}
\end{fulllineitems}

\index{sge.s.period (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.period}\pysigline{\code{sge.s.}\bfcode{period}}
\end{fulllineitems}

\index{sge.s.pixelate (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.pixelate}\pysigline{\code{sge.s.}\bfcode{pixelate}}
\end{fulllineitems}

\index{sge.s.plus (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.plus}\pysigline{\code{sge.s.}\bfcode{plus}}
\end{fulllineitems}

\index{sge.s.power (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.power}\pysigline{\code{sge.s.}\bfcode{power}}
\end{fulllineitems}

\index{sge.s.print\_screen (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.print_screen}\pysigline{\code{sge.s.}\bfcode{print\_screen}}
\end{fulllineitems}

\index{sge.s.purple (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.purple}\pysigline{\code{sge.s.}\bfcode{purple}}
\end{fulllineitems}

\index{sge.s.question (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.question}\pysigline{\code{sge.s.}\bfcode{question}}
\end{fulllineitems}

\index{sge.s.quote (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.quote}\pysigline{\code{sge.s.}\bfcode{quote}}
\end{fulllineitems}

\index{sge.s.red (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.red}\pysigline{\code{sge.s.}\bfcode{red}}
\end{fulllineitems}

\index{sge.s.right (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.right}\pysigline{\code{sge.s.}\bfcode{right}}
\end{fulllineitems}

\index{sge.s.scroll\_lock (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.scroll_lock}\pysigline{\code{sge.s.}\bfcode{scroll\_lock}}
\end{fulllineitems}

\index{sge.s.semicolon (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.semicolon}\pysigline{\code{sge.s.}\bfcode{semicolon}}
\end{fulllineitems}

\index{sge.s.shift\_left (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.shift_left}\pysigline{\code{sge.s.}\bfcode{shift\_left}}
\end{fulllineitems}

\index{sge.s.shift\_right (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.shift_right}\pysigline{\code{sge.s.}\bfcode{shift\_right}}
\end{fulllineitems}

\index{sge.s.silver (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.silver}\pysigline{\code{sge.s.}\bfcode{silver}}
\end{fulllineitems}

\index{sge.s.slash (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.slash}\pysigline{\code{sge.s.}\bfcode{slash}}
\end{fulllineitems}

\index{sge.s.smooth (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.smooth}\pysigline{\code{sge.s.}\bfcode{smooth}}
\end{fulllineitems}

\index{sge.s.space (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.space}\pysigline{\code{sge.s.}\bfcode{space}}
\end{fulllineitems}

\index{sge.s.super\_left (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.super_left}\pysigline{\code{sge.s.}\bfcode{super\_left}}
\end{fulllineitems}

\index{sge.s.super\_right (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.super_right}\pysigline{\code{sge.s.}\bfcode{super\_right}}
\end{fulllineitems}

\index{sge.s.sysrq (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.sysrq}\pysigline{\code{sge.s.}\bfcode{sysrq}}
\end{fulllineitems}

\index{sge.s.tab (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.tab}\pysigline{\code{sge.s.}\bfcode{tab}}
\end{fulllineitems}

\index{sge.s.teal (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.teal}\pysigline{\code{sge.s.}\bfcode{teal}}
\end{fulllineitems}

\index{sge.s.top (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.top}\pysigline{\code{sge.s.}\bfcode{top}}
\end{fulllineitems}

\index{sge.s.trackball\_down (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.trackball_down}\pysigline{\code{sge.s.}\bfcode{trackball\_down}}
\end{fulllineitems}

\index{sge.s.trackball\_left (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.trackball_left}\pysigline{\code{sge.s.}\bfcode{trackball\_left}}
\end{fulllineitems}

\index{sge.s.trackball\_right (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.trackball_right}\pysigline{\code{sge.s.}\bfcode{trackball\_right}}
\end{fulllineitems}

\index{sge.s.trackball\_up (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.trackball_up}\pysigline{\code{sge.s.}\bfcode{trackball\_up}}
\end{fulllineitems}

\index{sge.s.underscore (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.underscore}\pysigline{\code{sge.s.}\bfcode{underscore}}
\end{fulllineitems}

\index{sge.s.up (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.up}\pysigline{\code{sge.s.}\bfcode{up}}
\end{fulllineitems}

\index{sge.s.wheel\_down (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.wheel_down}\pysigline{\code{sge.s.}\bfcode{wheel\_down}}
\end{fulllineitems}

\index{sge.s.wheel\_left (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.wheel_left}\pysigline{\code{sge.s.}\bfcode{wheel\_left}}
\end{fulllineitems}

\index{sge.s.wheel\_right (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.wheel_right}\pysigline{\code{sge.s.}\bfcode{wheel\_right}}
\end{fulllineitems}

\index{sge.s.wheel\_up (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.wheel_up}\pysigline{\code{sge.s.}\bfcode{wheel\_up}}
\end{fulllineitems}

\index{sge.s.white (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.white}\pysigline{\code{sge.s.}\bfcode{white}}
\end{fulllineitems}

\index{sge.s.wipe\_down (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.wipe_down}\pysigline{\code{sge.s.}\bfcode{wipe\_down}}
\end{fulllineitems}

\index{sge.s.wipe\_downleft (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.wipe_downleft}\pysigline{\code{sge.s.}\bfcode{wipe\_downleft}}
\end{fulllineitems}

\index{sge.s.wipe\_downright (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.wipe_downright}\pysigline{\code{sge.s.}\bfcode{wipe\_downright}}
\end{fulllineitems}

\index{sge.s.wipe\_left (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.wipe_left}\pysigline{\code{sge.s.}\bfcode{wipe\_left}}
\end{fulllineitems}

\index{sge.s.wipe\_matrix (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.wipe_matrix}\pysigline{\code{sge.s.}\bfcode{wipe\_matrix}}
\end{fulllineitems}

\index{sge.s.wipe\_right (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.wipe_right}\pysigline{\code{sge.s.}\bfcode{wipe\_right}}
\end{fulllineitems}

\index{sge.s.wipe\_up (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.wipe_up}\pysigline{\code{sge.s.}\bfcode{wipe\_up}}
\end{fulllineitems}

\index{sge.s.wipe\_upleft (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.wipe_upleft}\pysigline{\code{sge.s.}\bfcode{wipe\_upleft}}
\end{fulllineitems}

\index{sge.s.wipe\_upright (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.wipe_upright}\pysigline{\code{sge.s.}\bfcode{wipe\_upright}}
\end{fulllineitems}

\index{sge.s.yellow (in module sge.s)}

\begin{fulllineitems}
\phantomsection\label{s:sge.s.sge.s.yellow}\pysigline{\code{sge.s.}\bfcode{yellow}}
\end{fulllineitems}



\chapter{Indices and tables}
\label{index:indices-and-tables}\begin{itemize}
\item {} 
\DUspan{xref,std,std-ref}{genindex}

\item {} 
\DUspan{xref,std,std-ref}{modindex}

\item {} 
\DUspan{xref,std,std-ref}{search}

\end{itemize}


\renewcommand{\indexname}{Python Module Index}
\begin{theindex}
\def\bigletter#1{{\Large\sffamily#1}\nopagebreak\vspace{1mm}}
\bigletter{s}
\item {\texttt{sge}}, \pageref{sge:module-sge}
\item {\texttt{sge.collision}}, \pageref{collision:module-sge.collision}
\item {\texttt{sge.dsp}}, \pageref{dsp:module-sge.dsp}
\item {\texttt{sge.gfx}}, \pageref{gfx:module-sge.gfx}
\item {\texttt{sge.input}}, \pageref{input:module-sge.input}
\item {\texttt{sge.joystick}}, \pageref{joystick:module-sge.joystick}
\item {\texttt{sge.keyboard}}, \pageref{keyboard:module-sge.keyboard}
\item {\texttt{sge.mouse}}, \pageref{mouse:module-sge.mouse}
\item {\texttt{sge.s}}, \pageref{s:module-sge.s}
\item {\texttt{sge.snd}}, \pageref{snd:module-sge.snd}
\end{theindex}

\renewcommand{\indexname}{Index}
\printindex
\end{document}
