Welcome to sgl’s documentation!¶
Welcome to the documentation for SGL! Soon, this will actually contain, like, useful things.
Until then, please look over the source code to figure out what’s going on. I think I’ve made it logical enough to understand. There’s going to be a lot of this going to change, though. Just warning you.
Contents:
Installing¶
One of these days, you should be able to install SGL by going:
pip install sgl
We’re not quite there yet, though.
Other methods of installing¶
For the record, no, I am not expecting random members of the public actually go through this amount of effort to test a crappy, half completed game development framework. This is mostly here because I’m currently forcing some friends to set the framework for me in an early stage of development, and want them to have some good instructions to follow to do so.
Install in pip’s developer mode¶
First, download the repository in its current state. You can either do this with the git client, or the lazy way–by downloading the zip file Github provides.
Open a command line window, and navigate to the root folder of the repository.
Run the following command:
pip install -e .
Go into the examples folder, and run
sgl-core-demo/demo.py
to make sure SGL is working correctly.
This will make pip add a temporary link to the folder where SGL is located to your Python/Lib/site-packages
directory. If you look in there after doing this, you should find a sgl.egg-link
file that contains the path to the SGL folder.
So, make sure to be careful moving around your SGL folder after this–if you move it without updating this file, SGL will stop in your programs working.
When I update SGL, clear out the contents of this folder, and replace it with the contents of the latest Github zip file of my repository.
When I finally get sgl on the real Python package directory, you will want to uninstall this local copy. To do this, just run the following command in any folder:
pip uninstall sgl
Then reinstall it with the real pip command at the top of the page.
Don’t install it at all¶
If you’re really lazy, download the Github zip file of my repository., and then copy and paste the sgl
folder into any folder in which you want to have access to sgl.
So, for example, to make the example work, you would copy the sgl
folder into the examples/sgl-core-demo/
folder, so you would end up with a examples/sgl-core-demo/sgl/
folder. If you have all the dependencies installed correctly, the example should work like that.
This is, however, a bit inconvenient–you will have to replace this SGL folder whenever it is upgraded. This may be what you’re after, though–this early in development, SGL may change enough that your programs may depend on specific versions, and it may be convenient to be able to use multiple versions simultaneously without dealing with virtualenvs for a package that isn’t even published anywhere.
Dependencies¶
This should be automatically managed, but things may get screwy, so I will say it explicitly.
SGL depends on PyGame 1.9.0+ to work correctly. It may work on earlier versions, but I have not tested this, and some advanced features may behave unexpectedly.
Some functions of SGL depend on NumPy being installed. I think nearly any version will work fine.
To render videos from SGL, you will need to install MoviePy. In my experience, on Windows, this is a fairly smooth, but annoying and long process. You have been warned. Installing MoviePy is not necessary for normal SGL development, though.
To the best of my knowledge, SGL only will work on Python 2.7. I am pretty sure I have done some stuff that will make it broken on Python 3, like using the old-style of print statements. You’re welcome to give it a shot on Python 3, though.
Install these dependencies however you wish. Some of them offer Windows installers–if they do, prefer these. At the moment, this usually works a bit more smoothly than using pip. I know some libraries, such as MoviePy, do not support this, though, and others are slowly moving away from it, so you might have no choice but to use pip in some cases.
Examples¶
Currently there is only one extremely pathetic example.
SGL Core Demo¶

SGL demonstrates its incredible graphic effects.
This is a demo for various features in sgl.core
. It is used internally for me to develop new features and make sure they are working correctly. Anything that does not appear in this demo has not been tested.
This means, for example, that I am still not sure if any of the audio commands work or not.
To navigate through the demos, press the left and right arrow keys. Most of the demos what you alter their parameters by pressing the up and down arrow keys.
The coding style of this demo is not necessarily indicative of what a normal SGL game would look like, as it intentionally avoids using any functions from sgl.lib
. So, it manages things manually that usually SGL would handle for you.
Also, it runs a series of separate demos as different classes, which are pretty much each separate SGL games, which a normal SGL game would have no need to do.
Hopefully even this complicated example showcases SGL’s ability to be simple and easy to understand, though.
SGL Core Reference¶
SGL divided into two components–sgl.lib
and sgl.core
. sgl.core
is the part of the library that provides the low-level drawing commands, similar to what you might find built into BlitzBasic or Processing. While ideally you should be able to spend most of your time in sgl.lib
, it is essential to use sgl.core
to make even the simplest SGL program.
To import sgl.core
, currently this is all that is required:
import sgl
Then, to call any of the functions defined in sgl.core
, simply prefix them with sgl.
, such as this:
sgl.init(640, 480)
graphic = sgl.load_image("smiley.png")
Warning
This may change in the future. I may make it so to import sgl.core
, you must do it like this:
import sgl.core as sgl
The benefits of this approach:
- It will make the internal structure of the library easier to maintain
- It will make it more obvious that
sgl.core
is actually calledsgl.core
.
The detriments of this approach:
- It is more typing for little benefit for the end-user.
- The user must explicitly rename
sgl.core
tosgl
to keep their command invocations short.
I still haven’t made up my mind which approach to take. Keep in mind you may have to change your import statements later. The command invocation will remain the same regardless, though–it is just the importing syntax that may change.
Concepts¶
Philosophy¶
Most of sgl.core
is fairly simple–it is a non-object-oriented module with various functions. This may irritate people who like object-oriented programming, and does create some clumsiness. For example, to get the width of a drawing surface, you cannot do something like this:
graphic = sgl.load_image("smiley.png")
print(graphic.width)
You must instead do this:
graphic = sgl.load_image("smiley.png")
with sgl.with_buffer(graphic):
print(sgl.get_width())
People coming to SGL from non-object-oriented languages, like BlitzBasic, may be used to this, but this will undoubtedly bother Python programmers. I assure you, however, this is an intentional choice. In SGL, you have the freedom to choose how you want to program your game–whether you want to use object-oriented programming or not, and even how you organize the objects and classes of your game. sgl.lib
is but one approach of organizing classes to wrap the internals of SGL. You can easily make your own if you wish, and I encourage you to do so.
I feel like existing Python game development frameworks are a little too dogmatic in how they force a certain structure on your programs, and I want to avoid that at all costs, even if my approach is a bit excessive. If you can wrap your head around this philosophy, most of sgl.core
should make sense to you.
Fake types¶
In the function reference, you may see references to types such as “SGL Surface” or “SGL Sound.” These are not real types, however–whenever a function claims to accept or return values of these types, in reality, they are dealing with classes of whatever the current backend is. So, if you’re using the Pygame backend, and you examine the type of an “SGL Surface”, you will find that it is, in reality, a pygame.Surface.
So, hypothetically, there’s nothing stopping you from calling pygame.Surface
commands on an SGL surface, like this:
graphic = sgl.load_image("smiley.png")
graphic.set_at((3, 3), (255, 0, 0))
Please don’t do this, though. For one, this will obviously not work when different backends are introduced. And also, I may eventually actually wrap SGL Surfaces and such in classes like sglSurface
or something, which will make your code broken on all backends.
Ideally, your code should be completely ignorant of what backend SGL is currently using. This’ll make your game/program more portable, which is one of the main points of SGL existing.
Color arguments¶
Color arguments in SGL are kind of ridiculously flexible, and take some influence from how Processing works.
Whenever you see an argument named *colors
, it can accept the values in the following formats:
number
- If you specify a single value as a color, it will specify shade of gray with that value used for the R, G, and B values of that color.number, number
- If you specify to values as a color, the first number will specify the shade of gray, as it would with a single number, but the second number will specify the transparency of that shade of gray.number, number, number
- If you specify three values, it will be interpreted as a normal RGB color.number, number, number, number
- If you specify for values, it will be interpreted as a normal RGBA color.tuple/list
- If you specify color as a tuple or list, it will be unpacked and interpreted as the arguments would.
In addition, for each number, the following rules apply:
- If the number is an integer, it will be interpreted as a normal RGB value that ranges from 0 to 255.
- If any numbers outside of this range, it will be clamped within that range.
- If the number is a float, it will be interpreted as a percentage of 255. So, for example, 0.5 would be half of 255.
This is perhaps a little complicated, but allows you to do some very convenient things. For example, if you want to clear the screen with 50% gray, it is as simple as doing this:
sgl.clear(0.5)
If you want to make a surface that is black and 75% transparent, you can do this:
surface = sgl.make_surface(320, 32, 0.0, 0.75)
And, if you feel it is confusing that the color data is getting mixed in with the rest of their arguments, you can pass in tuples as well:
surface = sgl.make_surface(320, 32, (0.0, 0.75))
And, of course, you can use plain RGB values for everything:
sgl.clear(100, 175, 93)
Function reference¶
This is a reference of every single function in sgl.core
. It is not complete yet, but all of the most essential functions have been documented in some detail. Hopefully this is helpful.
Base functions¶
These functions have to do with the base functioning of your program, and are essential for nearly everything you’d want to do with SGL.
-
sgl.
init
(width, height, scale=1, fullscreen=False, backend="pygame")¶ Must be called before any other SGL functions to initiate the drawing surface.
Parameters: - width, height (int) – Specifies the size of the display surface.
- scale (int) – Specifies the scaling factor. Width and height will be multiplied by this to form the actual window size. This is useful for working with small resolutions, such as 320x240.
- fullscreen (bool) – On desktop platforms, whether the display
should be windowed or fullscreen.
Parameters: backend (str) – Which backend to use. Currently, the only supported option is “pygame”.
-
sgl.
run
(update=None, draw=None)¶ Starts an SGL program that automatically manages the event loop. SGL will call the specified callbacks every frame, and it is in these that you will specify your game logic.
Parameters: - update (function) – A function to call every frame to update your game’s state.
- draw (function) – A function to call every frame to draw the current frame. Do not put any game logic in this function. No backends currently do this, but in the future, some might take advantage of the difference between update and draw to, for example, pause the game by calling update but not draw.
-
sgl.
make_movie
(file="", update=None, draw=None, duration=0, fps=24, realtime=False, display=True, **extra)¶ Similar to
sgl.run()
, but uses MoviePy to render each frame of your program to a video file or animated GIF.Parameters: - file (str) – The filename of the movie you wish to output.
- update, draw (function) – Works the same as with
sgl.run()
. - duration (number) – The amount of your program’s execution you want to record, in seconds.
- fps (number) – What the frame rate of the resulting video will
be.
make_movie
will force your program’s frame rate to match withsgl.set_fps_limit()
. - realtime (boolean) – If the video renders faster than the frame rate you specify, this will slow down the speed of the video rendering to match. This is useful when you have “display” enabled and you want to, say, use your program while recording it. By default it is false.
- display (boolean) – Whether to draw the current frame to the screen, in addition to rendering into the video file. Useful if you want to interact with your program as it is rendering to video.
- extra (various) – Additional keyword arguments are passed to
MoviePy’s
write_videofile
orwrite_gif
functions. You can use this to specify additional settings about which codecs to use and such.
-
sgl.
set_fps_limit
(fps)¶ Sets the highest frame rate your program will allow. More specifically, it makes your program assume that the frame rate is always this value, as opposed to what it is in reality. This can make programming animation more convenient, but comes with some side effects–such as that, if the frame rate of your program drops, it will start running in slow motion.
Parameters: fps (int) – The desired framerate. Set to 0 to disable framerate limiting.
-
sgl.
get_fps_limit
()¶ Gets the framerate limit. If there is no framerate limiting, will return 0.
Returns: The framerate limit Return type: int
-
sgl.
get_fps
()¶ Gets the current framerate. This will return the actual frame rate, even if the limit has been set with
sgl.set_fps_limit()
.Returns: The current framerate Return type: float
-
sgl.
get_scale
()¶ Gets the window’s scaling factor. SGL automatically takes into account the scaling factor when returning, say, mouse coordinates, so there shouldn’t be any reason to call this–it’s just for completeness sake.
Currently, is no setting the scaling factor–if you want to make a program in which the scaling factor appears to change, use surfaces and end the scaling abilities of
sgl.blit()
to simulate this. This functionality may be added in the future, though.Returns: The current scaling factor Return type: int
-
sgl.
has
(ability)¶ Returns whether the current backend has a given ability. The abilities are specified in the enum-like class sgl.abilities. There are currently only four abilities you can test for:
sgl.abilities.software
: Whether the current backend is powered by software rendering, and thus will be slow at special effects such as rotating and scaling.sgl.abilities.numpy
: Whether the current backend supports exporting and importing surfaces to NumPy arrays.sgl.abilities.save_buffer
: Whether the current backend supports saving surfaces to image files.
The Pygame backend supports all of these.
Parameters: ability (int) – The ability to test Returns: Whether the current backend supports this ability Return type: bool
-
sgl.
set_title
(title)¶ Sets the text in the title bar of the current window.
Parameters: title (str) – The text to put in the title bar
-
sgl.
get_title
(title)¶ Gets the text currently in the title bar of the current window.
Returns: The text in the title bar Return type: str
-
sgl.
get_actual_screen_width
()¶ Gets the width of the current window after applying the scaling factor. You should not need to get this. I should probably get rid of this function.
Returns: The window width Return type: int
-
sgl.
get_actual_screen_height
()¶ Gets the height of the current window after applying the scaling factor. You should not need to get this. I should probably get rid of this function.
Returns: The window height Return type: int
-
sgl.
get_dt
()¶ Gets delta time, or the time that has passed since the last frame is been rendered. If you do not have framerate limiting enabled for your program, you must multiply every animation value by this value if you expect your program to work consistently on different types of computers.
Unlike some other game libraries, this value is returned in seconds, not milliseconds.
Returns: The time that has passed since the last frame in seconds Return type: float
-
sgl.
is_running
()¶ Returns whether your program is running. Useful for when you are manually managing the event loop, and you want your program to end under the same conditions an automatic SGL program would.
Returns: Whether your program is running Return type: Bool
-
sgl.
end
()¶ Halts execution of the program, and closes the window.
Drawing commands¶
These commands have to do with drawing shapes.
-
sgl.
set_smooth
(smooth)¶ Sets whether lines for shapes should be anti-aliased or not. Currently no backend supports this.
Parameters: smooth (bool) – Whether anti-aliasing should be enabled
-
sgl.
get_smooth
()¶ Returns whether anti-aliasing is enabled or not.
Returns: Whether anti-aliasing is enabled Return type: bool
-
sgl.
set_fill
(*color)¶ Sets the color with which shapes are filled. Also affects what color fonts are rendered in.
-
sgl.
get_fill
()¶ Gets the current fill color.
Returns: The current fill color, or None
if fill is disabledReturn type: tuple
-
sgl.
set_stroke
(*color)¶ Sets the color in which shapes are outlined.
-
sgl.
get_stroke
()¶ Gets the current stroke color.
Returns: The current stroke color, or None
if stroke is disabledReturn type: tuple
-
sgl.
set_stroke_weight
(weight)¶ Sets how thick the lines outlining shapes will be. Setting this to 0 will disable stroke rendering.
-
sgl.
get_stroke_weight
()¶ Gets the current stroke weight.
Returns: The current fill weight Return type: int
-
sgl.
no_stroke
()¶ Turns off stroke rendering.
-
sgl.
no_fill
()¶ Turns off fill rendering.
-
sgl.
push
()¶ Pushes the current graphics state to the stack. So, the next time you call
sgl.pop
, it will restore this state. You can use this to change the drawing colors and what current surface is, and reset them later.
-
sgl.
pop
()¶ Pops the current graphics state from the stack. This will make all the drawing settings return to what they were the last time
sgl.push
was called.
-
sgl.
with_state
()¶ A context manager that saves the current drawing state and restores it when the enclosed operations are finished. Useful to avoid manually having to call
sgl.push
andsgl.pop
.
-
sgl.
clear
(*color)¶ Completely fills the current surface with the specified color.
-
sgl.
draw_line
(x1, y1, x2, y2)¶ Draw the line between the specified coordinates.
-
sgl.
draw_rect
(x, y, width, height)¶ Draws a rectangle in the specified area.
-
sgl.
draw_ellipse
(x, y, width, height, from_center=False)¶ Draws an ellipse in the specified area.
-
sgl.
draw_circle
(x, y, radius, from_center=True)¶ Draws a circle in the specified area.
Text commands¶
These commands have to do with rendering text.
-
sgl.
set_font_smooth
(smooth)¶ Specifies whether text is anti-aliased or not.
-
sgl.
get_font_smooth
()¶ Returns whether text is anti-aliased or not.
Returns: Whether font antialiasing is enabled Return type: bool
-
sgl.
load_font
(file, size)¶ Loads a font from a font file in your program folder.
Returns: The loaded font Return type: SGL font object
-
sgl.
load_system_font
(font_name, size)¶ Loads a font from the user’s system via the font’s name.
Returns: The loaded font Return type: SGL font object
-
sgl.
set_font
(font)¶ Sets what font is used for all future drawing operations.
-
sgl.
draw_text
(text, x, y)¶ Draws the specified text at the specified coordinates.
-
sgl.
get_text_width
(text)¶ Gets how wide the specified string will be when rendered in the current font.
Returns: The width of the rendered text Return type: int
-
sgl.
get_text_height
(text="")¶ Gets how tall the specified string will be when rendered in the current font. Usually will just return the height of the current font.
Returns: The height of the text Return type: int
Image commands¶
These commands have to do with loading images and stuff.
-
sgl.
set_transparent_color
(*color)¶ Sets what color will be considered transparent in images without an alpha channel. By default, this color is set to (255, 0, 255), or “magic magenta.”
-
sgl.
load_image
(file, use_transparent_color=True)¶ Loads an image without an alpha channel from the hard drive.
Returns: A surface containing the image loaded Return type: SGL surface
-
sgl.
load_alpha_image
(file)¶ Loads an image with an alpha channel from the hard drive.
Returns: A surface containing the image loaded Return type: SGL surface
Surface commands¶
These commands have to do with using surfaces and changing the current drawing buffer.
-
sgl.
blit
(thing, x, y, alpha=255, flip_v=False, flip_h=False, angle=0, width=None, height=None, scale=1, a_x=0, a_y=0, src_x=0, src_y=0, src_width=None, src_height=None, blend_mode=0, pretty=False)¶ Draws one surface to another. This function is kind of the motherlode of SGL, and provides most of the library’s drawing functionality.
Since this function takes so many arguments, it is recommended you use keyword arguments for everything beyond
x
andy
. For example, a typical call to this function might look like this:sgl.blit(self.player, 16, 16, flip_h=True, angle=45, a_x=0.5, a_y=0.5)
Parameters: - thing (SGL surface) –
The thing that should be drawn (or blitted) to the current surface.
Is an SGL surface value.
- x, y (int/float) –
Specifies the coordinates on the current surface that
thing
should be drawn.Currently, passing in floats will just result in them being rounded to integers.
- alpha (int/float) –
A number specifying how transparent
thing
should be drawn.If it is an integer, this should be a value between 0 and 255, with 0 being invisible and 255 being completely opaque.
If it is a float, this should be a value between 0.0 and 1.0, with zero being invisible and 1.0 being completely opaque.
- flip_v, flip_h (bool) –
Specifies whether
thing
should be horizontally or vertically flipped.Setting
width
orheight
to negative values will also flip a graphic. - angle (int) –
The angle to which
thing
should be rotated. The angle should be in degrees, and should be a value between 0 to 360 (although the code currently does not check this. It probably should).Note that on software renderers, such as Pygame, rotation is fairly slow. You can rotate a few graphics, such as the player graphic, in real time, but it is recommended you cache rotated sprites if you plan to rotate many things at once.
- width, height (int) –
Specifies the width and height to resize
thing
to.If either of these values is not specified, it will be filled in with the original width/height of
thing
.If either of these values is 0,
thing
will not be drawn.If either is negative,
thing
will be drawn backwards in whatever direction resizing it takes. - scale (float) –
Enables you to scale
thing
by a ratio, keeping its aspect ratio. 1.0, the default, will drawthing
at its normal size, 0.5 will draw it half as big, and so on.This can be combined with width and height, and is applied after those values are calculated.
- a_x, a_y (int/float) –
Specifies the anchor point of
thing
–the coordinates of the graphic that is considered (0, 0). Useful in conjunction withangle
to rotate about different points of the graphic than the top left corner.If these values are integers, they will be interpreted as exact coordinates on
thing
.If these values are floats, they will be interpreted as a percentage of the size of
thing
. (As in, setting both anchor points to 0.5 will make the anchor point the center of the image.) - src_x, src_y, src_width, src_height (int) –
Makes the function apply to the specified rectangle of
thing
. This is applied before the other functions are. This is a convenience to avoid having to dosgl.get_chunk
whatever you want to draw a small chunk of a larger image.On hardware accelerated backends, this may be faster than using
sgl.get_chunk
. - blend_mode (int) –
Specifies the blending mode to use when drawing
thing
. Should be a constant fromsgl.blend
.Currently, the only available blending values are:
sgl.blend.add
- Adds the colors ofthing
‘s pixels to the pixels behind it. So, black pixels will become transparent, white pixels will stay white, and everything in between will make the image behind slightly brighter.sgl.blend.subtract
- Subtracts the colors ofthing
‘s pixels from the pixels behind it. So, black pixels will become transparent, and white pixels will invert the background to certain degree.sgl.blend.multiply
- Multiply the colors ofthing
‘s pixels from the pixels behind it. So, white pixels will become transparent, black pixels will stay black, and everything else will be make the image behind slightly darker.
- pretty (boolean) –
Specifies whether the results of scaling and/or rotating
thing
should be smoothed out or not.This will slow down rendering in most cases.
- thing (SGL surface) –
-
sgl.
blitf
(thing, x, y)¶ A lightweight version of
sgl.blit
that does not perform any special effects on the surface being drawn. May be slightly faster.Parameters: - thing (SGL surface) – The thing that should be drawn to the current surface.
- x, y (int) – Specifies the accordance on the current surface
that
thing
should be drawn.
-
sgl.
make_surface
(width, height, *color)¶ Makes a new blank surface of the specified color. If no color specified, the new surface will be blank and transparent.
Returns: The created surface Return type: SGL surface
-
sgl.
get_chunk
(x, y, width, height)¶ Takes a chunk out of the current surface and returns it as a new copy surface. Useful for separating out, say, individual frames from spritesheets.
Parameters: - x, y (int) – The coordinates to start extracting
- width, height (int) – The width and height of the rectangle to extract
Returns: The extracted surface
Return type: SGL surface
-
sgl.
set_clip_rect
(x, y, width, height)¶ Sets the clipping rectangle–makes it so all future rendering operations will only affect the specified rectangle of the current surface.
-
sgl.
get_clip_rect
()¶ Returns the size of the current clipping rectangle.
Returns: A four element tuple, or None Return type: tuple
-
sgl.
no_clip_rect
()¶ Turns off rendering clipping.
-
sgl.
set_buffer
(surface)¶ Sets which surface is the drawing buffer–the surface on which all future drawing operations will take place. You can also think of this as the “current surface,” and many parts of the documentation refer to it like this).
Parameters: surface (SGL surface) – The surface that will become the current surface
-
sgl.
reset_buffer
()¶ Sets the drawing buffer to refer to the screen buffer. If you manage the stack correctly, you shouldn’t need to use this, but this is here just in case.
-
sgl.
with_buffer
(buffer)¶ A context manager that makes all enclosed drawing operations apply to a given buffer. Useful to avoid manually dealing with the stack.
Parameters: buffer (SGL buffer) – The buffer to draw on
-
sgl.
get_width
()¶ Gets the width of the current surface.
Returns: The width of the current surface, in pixels Return type: int
-
sgl.
get_height
()¶ Gets the height of the current surface.
Returns: The height of the current surface, in pixels Return type: int
-
sgl.
save_image
(file)¶ Saves the image in the current surface to the specified filename.
Parameters: file (str) – The filename of the image to save to. The extension will determine the file type.
-
sgl.
to_numpy
()¶ Exports the current surface as a NumPy array. On some back ends, such as Pygame, this might return a “live” NumPy array that is linked the original surface–as in changing the array will instantly change the surface. This is much more efficient than the alternative, but can be unexpected.
Returns: The pixel data of the current surface, in a three-dimensional array Return type: NumPy array
-
sgl.
from_numpy
(array)¶ Creates a new surface from a NumPy array.
Parameters: array (NumPy array) – A three-dimensional array consisting of RGB values. Returns: The surface represented by the array Return type: SGL surface
Special Effect commands¶
These commands do cool special effects.
-
sgl.
invert
(surface=None)¶ Inverts the colors of either the current surface or whatever surface is passed in.
Returns: A new surface, with the effect applied, or nothing Return type: SGL surface
-
sgl.
grayscale
(surface=None)¶ Turns to grayscale either the current surface or whatever surface is passed in.
Returns: A new surface, with the effect applied, or nothing Return type: SGL surface
Audio functions¶
These functions have to do with playing music and sound effects.
-
sgl.
load_sound
(file)¶ Loads a sound file from the hard drive.
Returns: An object representing the loaded sound Return type: SGL sound
-
sgl.
play_sound
(sound, volume=1.0, loops=0)¶ Plays a previously loaded sound.
Parameters: - sound (SGL sound) – The sound object to play
- volume (float) – The volume to play the sound at, specified as a float. (So, 1.0 would be full volume, 0.5 would be half volume, and so on.)
- loops (int) – How many times to loop playback of the sound. If
this is 0, the default, the sound will only play once. If it
is -1, it will play forever, until
sgl.stop_sound
is called on it.
-
sgl.
stop_sound
(sound)¶ Stops the specified sound.
Parameters: sound (SGL sound) – The sound object to stop
-
sgl.
stop_all_sounds
()¶ Stops all currently playing sounds.
-
sgl.
is_sound_playing
(sound)¶ Determines whether the specified sound is currently playing.
Parameters: sound (SGL sound) – The sound object to query Returns: Whether the sound is playing Return type: bool
-
sgl.
play_music
(file, volume=1.0, loops=-1)¶ Plays, by default, infinitely looping background music. Music, unlike sounds, do not need to be loaded in advance. They are loaded when you call this function. Because of this, only one music track can be playing at once.
Parameters: - file (str) – The filename of the music to play
- volume (float) – The volume to play the music at, specified as a float. (So, 1.0 would be full volume, 0.5 would be half volume, and so on.)
- loops (int) – How many times to loop playback of the music.
By default, this is -1, which will look the music forever,
until
sgl.stop_music()
is called.
-
sgl.
pause_music
()¶ Pauses the currently playing piece of music. This is different from
sgl.stop_music()
in that you can later callsgl.resume_music()
to resume the song from the exact point at which you paused it. With stopping, you have no choice but to restart the song.
-
sgl.
resume_music
()¶ Resumes a piece of music that has been paused with
sgl.pause_music()
.
-
sgl.
set_music_volume
(volume)¶ Sets the volume of the currently playing music.
Parameters: volume (float) – The volume to play the music at, specified as a float. (So, 1.0 would be full volume, 0.5 would be half volume, and so on.)
-
sgl.
stop_music
()¶ Stops the currently playing music. This music will not be able to be resumed with
sgl.pause_music()
.
-
sgl.
is_music_playing
()¶ Returns whether any music is currently playing.
Returns: Whether any music is playing Return type: bool
Input commands¶
These commands have to do with getting input.
-
sgl.
add_input
(type)¶ Initializes support for a specified type of input.
Parameters: type (int) – The type of input to add. Should be a constant from sgl.input
.
-
sgl.
supports_input
(type)¶ Returns whether the backend supports the specified input type. Might be integrated into
sgl.has()
later.Parameters: type (int) – The type of input to test. Should be a constant from sgl.input
.Returns: Whether the specified type of input is supported by this backend Return type: bool
-
sgl.
remove_input
(type)¶ Removes support for a specified type of input. It does not matter whether this input is real or fake–it will remove it regardless.
Parameters: type (int) – The type of input to remove. Should be a constant from sgl.input
.
-
sgl.
has_input
(type)¶ Returns whether a specified input type is handled or not. Intentionally does not distinguish between real and fake inputs.
Parameters: type (int) – The type of input to test. Should be a constant from sgl.input
.Returns: Whether the specified type of input is currently handled Return type: bool
-
sgl.
on_key_down
(key)¶ Briefly returns True on the frame a keyboard key is pressed down.
Parameters: key (int) – The key code of the key to test. Should be a constant from sgl.key
.Returns: Whether a key has just been pressed down Return type: bool
-
sgl.
on_key_up
(key)¶ Briefly returns True on the frame a keyboard key is released.
Parameters: key (int) – The key code of the key to test. Should be a constant from sgl.key
.Returns: Whether a key has just been released Return type: bool
-
sgl.
is_key_pressed
(key)¶ Returns True if the specified keyboard key is currently pressed.
Parameters: key (int) – The key code of the key to test. Should be a constant from sgl.key
.Returns: Whether a key is currently down Return type: bool
-
sgl.
get_keys_pressed
()¶ Returns a list of all the keyboard keys currently pressed.
Returns: A list of all pressed keys Return type: list of ints
-
sgl.
get_letters_pressed
()¶ Returns a string containing all the characters typed in the last frame. Handles capitalizing letters and changing characters when shift is pressed.
Returns: The text typed in the last frame Return type: str
-
sgl.
show_mouse
()¶ Shows the system mouse cursor.
-
sgl.
hide_mouse
()¶ Hides the system mouse cursor.
-
sgl.
get_mouse_x
()¶ Returns what the mouse cursor’s x position on the current frame.
Returns: The mouse’s x coordinates Return type: int
-
sgl.
get_mouse_y
()¶ Returns what the mouse cursor’s y position on the current frame.
Returns: The mouse’s y coordinates Return type: int
-
sgl.
get_prev_mouse_x
()¶ Returns what the mouse cursor’s x position was on the previous frame. Exists for convenience and because when managing the event loop automatically, it is impossible for your program to retrieve this value manually.
Returns: The mouse’s x coordinates on the previous frame Return type: int
-
sgl.
get_prev_mouse_y
()¶ Returns what the mouse cursor’s y position was on the previous frame.
Returns: The mouse’s y coordinates on the previous frame Return type: int
-
sgl.
on_mouse_down
(button=1)¶ Briefly returns True on the frame the specified mouse button is pressed down. By default, it tests for the left mouse button–button #1. Does not intelligently determine what the left mouse button is if the user has used their system settings to swap the functions of the mouse buttons.
Parameters: button (int) – The number of the mouse button to test. Is 1 by default. Returns: Whether a mouse button has just been pressed down Return type: bool
-
sgl.
is_mouse_pressed
(button=1)¶ Returns True if the specified mouse button is currently pressed down.
Parameters: button (int) – The number of the mouse button to test. Is 1 by default. Returns: Whether a mouse button is pressed Return type: bool
Returns a list of all the currently pressed mouse buttons.
Returns: A list of all the pressed mouse buttons Return type: list of ints
-
sgl.
on_joy_down
(button)¶ Briefly returns True on the frame the specified joystick button is pressed down.
Parameters: button (int) – The number of the joystick button to test Returns: Whether a joystick button has just been pressed down Return type: bool
-
sgl.
on_joy_up
(button)¶ Briefly returns True on the frame the specified joystick button is released.
Parameters: button (int) – The number of the joystick button to test Returns: Whether a joystick button has just been pressed released Return type: bool
-
sgl.
is_joy_pressed
(button)¶ Returns True if the specified joystick button is currently pressed down.
Parameters: button (int) – The number of the joystick button to test Returns: Whether a joystick button is pressed Return type: bool
-
sgl.
get_joy_axis
(axis)¶ Returns the value of a joystick’s given “axis”. There is usually a separate axis for each direction of each stick. For example, there might be an axis for the horizontal motion of the left stick, the vertical motion of the left stick, and axes for both on right stick. Some joysticks, however, use axes for other things as well, such as pressure sensitive buttons. Experiment to figure out which is which.
Parameters: axis (int) – The axis to get the value from Returns: The value reported by the current axis Return type: float
-
sgl.
get_joy_num_axes
()¶ Returns the amount of axes this joystick reports having.
Returns: The number of axes on this joystick Return type: int
Fake input commands¶
These commands have to do the fake input system, in which on platforms without certain types of input, such as smart phones, you can simulate unavailable input devices with the ones that are available.
Warning
I don’t think this API actually makes any sense. I might remove or change it later.
-
sgl.
add_fake_input
(type)¶ Adds a fake input. There must not be an equivalent real input defined.
-
sgl.
got_key_down
(key)¶ Simulates a key on the keyboard being pressed down.
-
sgl.
got_key_up
(key)¶ Simulates a key on the keyboard being released. If you do not call this function, SGL will think the key has been pressed down forever.
-
sgl.
got_mouse_move
(x, y)¶ Simulates the mouse moving to a new point.
-
sgl.
got_mouse_down
(button=1)¶ Simulates a mouse button being pressed.
-
sgl.
got_mouse_up
(button=1)¶ Simulates a mouse button being released. Similarly to
sgl.got_key_up()
, this is necessary for SGL to ever consider a mouse button released.
SGL Library Reference¶
sgl.lib
is where a lot of the functions useful for making games will live. Not much of it is written right now, and you should probably avoid using most of what’s there, as it might change. Here’s a brief summary of the modules it currently includes, though:
sgl.lib.Script
- Provides a small domain specific markup language for writing in game cut scenes. Is designed to be easy for writers to understand and for programmers to implement support for. The syntax of this language is currently undergoing a great revision. This is the module that you should avoid using the most right now.sgl.lib.Time
- Provides the ability to register functions to happen at specific times or intervals. Useful for making pieces of code happen at a specific frame rate, for animated sprites and such.sgl.lib.Tween
- Provides “tweening” functionality, which lets you specify start and end values for any numerical property of any object, and animate them moving from point A to point B in a given amount of time with the given interpolation. Makes it much easier to add dynamic animations to in game GUIs and game elements.
Sound exciting? Hopefully, because there will be even more in the future! :p
Actual Reference¶
sgl.lib.Sprite¶
This module provides the bulk of the functionality of
sgl.lib. Nearly every other class in sgl.lib inherits from or uses
sgl.lib.Sprite
somehow.
-
class
sgl.lib.Sprite.
AnimatedSprite
¶ A subclass of
Sprite
that provides extra functions useful for managing frame-based animations.-
animation
¶ string: Property containing the name of the currently playing animation. This name should correspond to one of the keys in
animations
.If you set this property, it will immediately switch to the animation of that name. The current playing state (whether this sprite is playing whatever the current animation is, or paused), however, will remain unchanged.
-
pause
()¶ Pauses playment that the current point. You can call
play
to resume playment from this point.
-
play
()¶ Starts playing the active animation.
-
playing
¶ bool: Returns whether this sprite is currently playing whatever the active animation is.
-
preupdate
()¶ Overridden to handle animation logic, in addition to what
Sprite.preupdate
doas.- Todo:
- It might be useful to be able to restrict how many times an animation can loop, so you can, say, only play an animation once. Currently you can simulate this callbacks, but that’s a little cumbersome.
- Maybe make this attempt to make up for lost time, like
sgl.lib.Time
does.
-
-
class
sgl.lib.Sprite.
App
(first_scene)¶ A very simple object that wraps over scenes in order to let you easily switch between multiple scenes.
Parameters: first_scene ( Scene
) – The scene that will be active by default. The scene will be activated byswitch_scene
.
-
class
sgl.lib.Sprite.
Camera
¶ A small object to hold the coordinates of the camera in a given scene.
-
position
¶ tuple: The position of the camera—or, in other words, the coordinates in the scene that will be displayed at the top left corner of the window.
Can also be accessed through the
x
andy
attributes.
-
-
class
sgl.lib.Sprite.
EllipseSprite
¶ A subclass of
ShapeSprite
that draws an ellipse (or circle, ifwidth
andheight
are the same) in the bounding box of the sprite.
-
class
sgl.lib.Sprite.
PerspectiveGroup
¶ A subclass of
SpriteGroup
that disregards the usual sprite rendering order and instead draws every sprite inside in the order of their y coordinates. This means that sprites positioned higher on the screen are drawn below sprites positioned lower on the screen. In most two-dimensional projections of perspective, this provides the illusion that some sprites are positioned “behind” other sprites.By default, it completely flattens the sprite hierarchy inside when drawing sprites. This can be customized with the
max_level
attribute, or by setting ano_perspective
attribute toTrue
on a given sprite instance—this will make it so children of that sprites are not flattened out, and are drawn in their intended order.-
draw_children
()¶ You should not need to deal with this function yourself, but it is useful to note—
PerspectiveGroup
‘s implementation of draw_children reimplements most ofSprite.draw_children
without reusing code. The two method implementations may become the synchronized. If you experience bugs inPerspectiveGroup
that do not occur in normal sprites, this function is likely the cause.
-
-
class
sgl.lib.Sprite.
RectSprite
¶ A subclass of
ShapeSprite
that draws a rectangle in the bounding box of the sprite.
-
class
sgl.lib.Sprite.
Scene
¶ A special kind of
Sprite
designed to provide a few additional functions useful in managing larger game levels.
-
class
sgl.lib.Sprite.
ShapeSprite
¶ A subclass of
Sprite
designed to handle shapes drawn with the SGL drawing commands instead of blitting surfaces to the screen.This will often be faster than drawing the equivalent surface.
-
draw_shape
()¶ Override this function to specify what shape this sprite should draw. The stroke and fill properties will have already been set by the other functions of this class, and will automatically be restored to their previous values after this function has been executed.
-
-
class
sgl.lib.Sprite.
Sprite
(graphic=None)¶ Provides a class to represent drawable objects.
Parameters: graphic (SGL Surface) – A graphic that will be loaded by Sprite.load_surface
during initialization.-
add
(sprite)¶ Adds a child sprite to this end of this sprite’s sprite list.
Parameters: sprite ( Sprite
) – ASprite
instance to add.
-
anchor
¶ tuple: The position of the anchor point of this sprite. This determines the coordinates that is considered (0, 0) for this sprite, and impacts which point it is rotated around if you use that effect.
If either dimension is a floating-point number, they’ll be interpreted as a percentage of the sprite’s width or height. So, setting the anchor point to (0.5, 0.5) will placed in the center of the sprite’s graphic.
Can also be accessed through the
a_x
anda_y
attributes.
-
autosize
()¶ Updates this sprite’s size to match the size of its surface. Automatically called by
Sprite.load_surface
and when sprites are initialized with surfaces.
-
center
()¶ Utility function to place this sprite in the center of its parent sprite. If it has no parent sprite, it will be placed in the center of the screen.
-
collision_rect
¶ sgl.lib.Rect.Rect
: The bounding box that the collision functions will use to determine when this sprite is overlapping with others. If none is specified, it will assume you want the entire sprite to be collidable.
-
draw
()¶ Handle drawing this sprite and its children. Should not be overwritten to define custom drawing logic, unless you want to break drawing child sprites. Instead, override
Sprite.draw_self
.
-
draw_children
()¶ Loops through and draws child sprites. Ideally, should not be called manually.
Currently, this updates each sprite’s screen position one more time, to make them slightly more predictable.
-
draw_self
()¶ Handle drawings this sprite. If you want to customize how sprite drawing works, override this function.
-
fill
()¶ Utility function to make this sprite completely fill its parent sprite. If it has no parent sprite, it will fill the screen.
-
is_being_collided
(other)¶ Returns whether this sprite is colliding with another one.
Parameters: sprite ( Sprite
) – AnotherSprite
instance to test.Returns: Whether this sprite is colliding with the other one. Return type: bool
-
is_colliding_with
(other)¶ Returns whether this sprite is colliding with another one. Currently just passes responsibility to the other sprite by calling its
Sprite.is_being_collided
function.Parameters: sprite ( Sprite
) – AnotherSprite
instance to test.Returns: Whether this sprite is colliding with the other one. Return type: bool
-
is_mouse_over
()¶ Returns whether the mouse cursor is currently inside this sprite’s bounding box.
Returns: Whether the mouse is inside. Return type: bool - Todo:
- Come up with some type of GUI-like event system. Simple functions like these will not help determine whether there’s a sprite above this one that should get the focus first and such.
-
kill
()¶ Marks this sprite to be deleted on the next frame.
-
load_surface
(surface)¶ Sets the graphic for this sprite, and makes the size match the size of this graphic.
Parameters: surface (SGL Surface) – A surface containing the graphic you want this sprite to draw.
-
on_add
()¶ Exectued when a sprite is added. It’s recommended to put initialization code here instead of
__init__
, so that the sprite will have proper access to its parent elements during and after initialization. (Not all the examples have been updated to work like this, though.)
-
position
¶ tuple: The local position of this sprite (before any transformations have been applied).
Can also be accessed through the
x
andy
attributes.
-
preupdate
()¶ Called before this sprite updates. Currently, contains logic to save the previous position and update the screen position.
-
prev_position
¶ tuple: Read-only property returning the local position of this sprite on the previous frame.
Can also be accessed through the
prev_x
andprev_y
attributes.
-
real_anchor
¶ tuple: Read-only property returning the position of the anchor point of this sprite after percentage values (such as 0.5) have been converted to real coordinates.
-
rect
¶ sgl.lib.Rect.Rect
: Read-only property returning the bounding box of this sprite in local coordinates.
-
screen_collision_rect
¶ sgl.lib.Rect.Rect
: Read-only property returning the bounding box of this sprite in screen coordinates (after parent and camera transformations have been applied).
-
screen_position
¶ tuple: Read-only property returning the screen position of this sprite (after parent and camera transformations have been applied). Can also be accessed through the
screen_x
andscreen_y
attributes.
-
screen_rect
¶ sgl.lib.Rect.Rect
: Read-only property returning the bounding box of this sprite in screen coordinates (after camera and parent transformations have been applied).
-
size
¶ tuple: The size of this sprite. Used for positioning the anchor point, determining whether a sprite is visible and should be drawn, and as a default size for the sprite’s collision bounding box.
-
update
()¶ Called every frame to update this sprite and its child sprites’ logic. To define logic for your sprite, override this function. If you want child sprite updating to work properly, though, make sure to call the
Sprite
base classes’ update function before yours.
-
update_screen_positions
()¶ Screen positions are slightly broken. By default, screen coordinates are only updated in the
Sprite.preupdate
function. This means that sometimes they will update a frame late if you change a parent sprite’s position during itsSprite.update
phase. In addition, even when it does update, sometimes position changes will not propagate through the hierarchy correctly.This function can help you work around that by forcing all of this sprite and all of its child sprites to recursively update their screen coordinates to the correct value. If you see child sprites behaving strangely, try adding a call to this in the parent sprite’s code.
I realize this is a bit of a hack, but it is the lesser evil. I tried to update all screen positions on every frame, but that slowed the sprite system down significantly and created new positioning problems that, unlike these, could not be solved with a single extra function call.
-
world_collision_rect
¶ sgl.lib.Rect.Rect
: Read-only property returning the bounding box of this sprite in world coordinates (after parent, but not camera transformations have been applied).- Todo:
- Make this property only disregard camera transformations, instead of all of them.
-
world_to_screen
(x, y)¶ Converts local coordinates in this sprite’s space to screen coordinates.
Parameters: - x (number) – The x coordinates to convert.
- y (number) – The y coordinates to convert.
Returns: The new coordinates.
Return type: tuple
-
-
class
sgl.lib.Sprite.
SpriteGroup
¶ A subclass of
Sprite
designed to do nothing but hold other sprites.Identical to a plain
Sprite
, exceptinfinite_space
is turned on by default.
-
sgl.lib.Sprite.
Spritesheet
(surface, frame_width=0, frame_height=0)¶ Takes a surface containing a spritesheet and extracts each individual frame from it. Often necessary to use
AnimatedSprite
effectively.Parameters: - surface (SGL Surface) – A graphic containing a spritesheet with
equally sized frames starting from (0,0). This function
does not do anything in regards to transparency. You must
load your graphic with
sgl.set_transparent_color
orsgl.load_alpha_image
for transparency to work. - frame_width (int) – How wide each frame is.
- frame_height (int) – How high each frame is.
Returns: A list of each frame in this spritesheet.
Return type: list
- Todo:
- This may eventually be a class, so that spritesheets can blit chunks from a single surface instead of initializing possibly hundreds of tiny little surfaces for each frame. I think that will be more efficient, particularly with hardware accelerated backends. I’ll try to make this class behave identically to a list in most cases, but keep in mind that code depending on modifying the frames of a spritesheet like a list could break when this change happens.
- surface (SGL Surface) – A graphic containing a spritesheet with
equally sized frames starting from (0,0). This function
does not do anything in regards to transparency. You must
load your graphic with
-
class
sgl.lib.Sprite.
Viewport
¶ A
Sprite
that behaves identically to aScene
in most circumstances, except it is only rendered in the bounds of its bounding box.- Todo:
- Make scenes and viewports the same thing. Like, a scene automatically become a viewport if its size does not fill the screen, it will be drawn bigger if at a scale, etc.
- When this happens, force all the examples to run in wiggling (or at least bouncing) viewports. It should be possible to embed scenes in other scenes arbitrarily. The ability to make game anthologies, or browsable demo packages, like the WxPython demo, should be nearly automatic.
sgl.lib.Collision¶
This module provides some functions for working with bounding box based collisions. It is fairly basic, and not very optimized, but for most use cases, it works out of the box and does not let objects randomly get stuck in and fall through each other, something a disturbing amount of game engines lack.
-
class
sgl.lib.Collision.
CollisionChecker
(object1, object2, callback)¶ An object that checks whether sprites are overlapping every frame, and takes user-specified action as a result.
This is mostly used by the backend of
sgl.lib.Collision
. From an end user’s perspective, this class will mostly be used to stop and resume collision checking.-
pause
()¶ Temporarily pauses this collision checker, without deleting it.
-
resume
()¶ Resumes a previously paused collision checker.
-
stop
()¶ Stops a collision checker entirely by deleting the object.
-
-
class
sgl.lib.Collision.
SlidingCollisionChecker
(object1, object2, callback)¶ Identical to a normal
CollisionChecker
, except that its update function provides additional logic to move objects outside of each other.
-
sgl.lib.Collision.
add
(object1, object2, callback)¶ Creates a basic collision checker, which will call a callback on every frame two objects overlap.
Will use a sprite’s visible rectangle for collisions, unless a Sprite has a custom
Sprite.collision_rect
defined.Parameters: - object1 (
Sprite
) – The first object to test. This must be a single sprite—subsprites will not be tested for collision. - object2 (
Sprite
) – The second object to test. This can be any kind of sprite, and subsprites will be tested for collision. - callback (function) –
The function to call when the objects overlap. This function will have different information passed to it depending on how many arguments it accepts.
- If it accepts no arguments, nothing special will be passed to it.
- If it accepts 1 argument, it will be passed a reference
to the subsprite of
object2
thatobject1
collided with on that frame. - If it accepts 2 arguments, it will be passed a
reference to
object1
, and then the subsprite ofobject2
thatobject1
collided with on that frame. - If it accepts 3 arguments, it will be passed all of the
above, and then a
sgl.lib.Rect.Rect
representing the intersected area between the two sprites.
Returns: An object that can be used to pause or stop this collision checking if necessary.
Return type: - object1 (
-
sgl.lib.Collision.
add_sliding
(object1, object2, callback=None)¶ Creates a sliding collision checker, which will prevent
object1
from going inside any of the sprites ofobject2
. It is called a “sliding” collision checker because if an object is moving diagonally, it will continue to move in the free direction even if it collides against a wall. Because the collision algorithms are bounding box based, though, diagonal obstacles are not supported.The sliding collision algorithm checks every pixel position between
object1
‘s position on the current and previous frame to check collision, so object should not be of the slide through each other when they are moving fast or if the frame rate gets low. A consequence of this, however, is that this means manual position updates are subject to collision checking as well–if you want to teleport an object through a wall, you must temporarily turn off sliding collision checking for that to work.Because of this, it’s recommended you always save a reference to the
SlidingCollisionChecker
object this function returns.Will use a sprite’s visible rectangle for collisions, unless a Sprite has a custom
Sprite.collision_rect
defined.Parameters: - object1 (
Sprite
) – The first object to test. This must be a single sprite—subsprites will not be tested for collision. - object2 (
Sprite
) – The second object to test. This can be any kind of sprite, and subsprites will be tested for collision. - callback (function) –
The function to call when the objects overlap. This function will have different information passed to it depending on how many arguments it accepts.
- If it accepts no arguments, nothing special will be passed to it.
- If it accepts 1 argument, it will be passed a list of
strings that can contain various permutations of
"left"
,"right"
,"top"
, and"bottom"
. The strings present in this list will tell you on what sidesobject1
was hit before its position was corrected by the collision checker.
Returns: An object that can be used to pause or stop this collision checking if necessary.
Return type: - object1 (
-
sgl.lib.Collision.
update
()¶ Must be called every frame for any of the collision checkers to work.
- Todo:
- It might be handy to have this and the other continuously executing libraries (tween, time...) automatically inject themselves into the SGL event loop instead of making the user manually call their update functions every frame. Currently it is slightly annoying that one has to plan out a way to make sure these update functions are called exactly once every frame in their entire program. I’m not sure if handling this automatically is too “magic,” though...
sgl.lib.Layout¶
This module mainly provides one class, FlowLayout
, that
lets one arrange sprite similarly to the automatic layout functions of
some GUI frameworks. This can be useful for laying out game GUIs in a
resolution independent way.
-
class
sgl.lib.Layout.
FlowLayout
(horizontal=False)¶ A Sprite that provides similar functionality to wxWidget’s BoxSizer.
Parameters: horizontal (bool) – Whether this layout runs horizontally or not. If this is False, the default, it will run vertically. This can be set later with the horizontal
property.-
add
(sprite, proportion=0.0, proportion_other_way=0.0, align=0.0)¶ Behaves similarly to
Sprite.add
, but with additional parameters to determine how the added sprite will be fit into the layout.Parameters: - sprite (
Sprite
) – ASprite
instance to add. - proportion (float) –
The amount of space this sprite will take up in the direction that the layout flows (which is set by
horizontal
). If this value is 0, this sprite will merely take up its original size. If it is anything else, its size will be calculated relative to the size of the layout and the other sprites.Basically, the way it works is this: take all of the sprites with proportion values, and add those numbers up. That will be the total proportion value. The size of each sprite will be its own proportion value over the total proportion value.
So, if the proportion value is 1 for every sprite in a layout, their sizes will be distributed evenly across the layout.
If one of those sprites has a proportion value of 2, however, it will be twice as large as the other ones, and the other sprites’ sizes will be twice as small. It all balances out in the end.
It would be equally valid to set the larger sprite’s proportion value to 1, and the smaller sprites’ to 0.5 for this—the exact values do not matter as much as how the proportion values relate to each other. This is slightly different from wxWidgets, in which proportion values must be whole numbers.
It may make it easier to understand certain layouts if you specify proportion values as fractions (such as 0.25), and make sure they add up to 1.0 in the end.
It is also important to note that the space taken into account for proportioned sprites is the space left behind by non-proportioned sprites. So, if you have a layout with a few non-proportioned sprites, and add a sprite with a proportion value of 1 to that layout, it will not fill the entire layout—it will take up the entire space left behind by the other sprites.
This gives you many possibilities for positioning non-proportioned sprites. If you have two normal sprites and put a sprites with a proportion value of 1 between them, for example, you will force both normal sprites to be on opposite ends of the layout. If you want to distribute normal sprites equally across an area, you can space them out with proportion 1 spaces. And so on.
Proportion values are slightly difficult to understand, but once you get them, they will open up many possibilities for layout.
- proportion_other_way (float) –
This argument is much easier to understand than the proportion value.
It is a percentage value specifying how much space the sprite will take up on the axis perpendicular to the direction the layout flows. So, if the layout flows vertically, this specifies how a sprite’s horizontal size will be affected by it.
Usually, you will either want this value to be 0, which will leave the sprite’s size in that direction untouched, or 1.0, which will make the sprite completely fill the layout in that direction. Anything in between will leave the sprite somewhere in the middle of that. (Or, more accurately, the size of the layout in that direction times this value.)
- align (float) –
If
proportion_other_way
leaves any breathing room for the sprite, this specifies how that sprite should be positioned in the layout.If this is 0, the sprite will rest along the left or top edge of the layout. If this is 0.5, it will be centered along that direction. If this is 1.0, it will be bottom or right aligned. And other values will be somewhere inbetween.
You will not need to set this argument in most cases. If you do, 0.5 will likely be the most common value you’ll use for it.
- sprite (
-
horizontal
¶ Whether this layout runs horizontally or not. If this is False, the default, it will run vertically.
-
reflow
()¶ Repositions and resizes the elements inside to adhere to the layout rules. Must always be manually called to update the objects inside, even after adding new objects. (I tried having it automatically update the layouts, and the annoyance of having sprites move around at unpredictable times outweighed the benefits.)
Is a potentially expensive function. If there are proportioned sprites in the layout, it must run two passes through the objects inside. In most cases, is recommended to call this function once—after this layout has been positioned and sized correctly, and after all of its items have been added.
If any sprites inside this layout have a
reflow
method, it will call it. This is useful for embedding layouts hierarchically, or specifying custom logic for sprites when they are resized.
-
-
class
sgl.lib.Layout.
Spacer
(width=0, height=0)¶ A dummy object you can add to
FlowLayout
instead of aSprite
when you want to have an invisible spacer sprite to affect the positioning of other sprites.Provides the absolute minimum amount of data required of an object to interact with the sprite system.
Parameters: - width (int) – The width of the spacer, if you do not plan to have it controlled by a proportion value.
- height (int) – The height of the spacer, if you do not plan to have it controlled by a proportion value.
sgl.lib.ScriptParser¶
This module provides the functionality to parse SGLscript. It is
mainly used behind the scenes to provide sgl.lib.Script
with
the data it needs to operate, but you may need to interact with this
module for real-time script manipulation.
An SGLscript file is formatted like follows:
First, there is a header section. The format of this section is documented in
ScriptParser.header
. (Please read that after reading this, though—the documentation for that function assumes some familiarity with the format of commands.)Then, you must specify the beginning of a “label” by having a line that begins with
@
, with the rest of the line consisting of the label name. Any line beginning with a@
starts a new label.Warning
This may be deprecated in favor of just using the normal command syntax to define labels in the future. Even if that happens, though, it will be possible to replicate the current behavior through slightly more configurable macros.
Every line after that is interpreted as the body of a given label.
In the body, two main rules apply:
- Normal text is interpreted as dialogue that will get output to the screen.
- Anything with in square braces (
[
and]
) is interpreted as a command.
Commands can consist of three components:
- All commands must have a command name. This determines what function is used to handle this command when the script is executed.
- Then, after this, they can have positional arguments. These, like positional arguments in Python, or arguments that are specified by order instead of by name.
- Then, after (or instead of) positional arguments, commands can have keyword arguments. These are arguments in which their name is specified, and then their value.
There are two syntaxes of commands:
There are the old-style commands, which behave like HTML tags. In this syntax, the command name is specified at the beginning, and is ended by whitespace. After this whitespace, you can have whitespace separated positional arguments, and then whitespace separated keyword arguments. Keyword arguments are given in a
key=value
form, and any amount of whitespace is accepted before and after the=
.The type of commands look like this:
[show-background "tree.png" transition="fade-in" fade-time=5]
.Warning
These types of commands will be deprecated as soon as possible. Don’t use them. I’m merely documenting them so the source code makes more sense.
There are the new-style commands, or pretty commands. With this syntax, command names are first, but are ended by a colon (
:
). Because of this, command names can have spaces in them. Then, positional arguments can be specified the same way as with the old-style. Then, keyword arguments can be specified, but in akey: value
form. Thus, keyword arguments, like command names, can also have spaces in their names. This creates some ambiguous parsing situations, but these commands are much easier to read.These types of commands look like this:
[show background: "tree.png" transition: "fade-in" fade time: 5]
.With the sense of commands, command and keyword argument names are case insensitive, and can handle arbitrary whitespace in the middle of them. As long as you don’t misspell them, you can mangle their formatting quite a bit and they will parse correctly.
- Todo:
- Okay, we might have to see about that “arbitrary” whitespace... :|
Warning
These types of commands will be what SGLscript uses in the future. Positional arguments may be deprecated in the future, so please stick to using keyword arguments only if you want to play it safe. This will also make your scripts easier to read.
Both styles use identical syntax for values for arguments:
If a value begins with a
"
or'
, it is a string. These behave the same as Python strings—you must escape the other type of quote with backslashes.If a value begins with a digit or
-
, it is a number. Mathematical expressions are not currently allowed—you must just input numbers.Anything else is interpreted as a keyword—or a single word string. This string must have no spaces is in it, and it will be converted to lowercase during parsing. This is a shortcut for specifying short string arguments without having to type quotes.
For example, the earlier example could be inputted as
[show background: tree.png transition: fade-in fade time: 5]
with no information being lost.Warning
Quoteless string values may be deprecated in the future. They can create some annoyingly ambiguous parsing situations with pretty commands, like
[show thing: cool transition: "dissolve"]
. Is “cool” a positional argument or is the name of the keyword argument “cool transition”?
I cannot guarantee the behavior of anything left undescribed here. You have been warned.
In addition, the parser supports some automatic manipulation of
commands during parsing. This is documented more thoroughly in
ParserSettings
.
-
class
sgl.lib.ScriptParser.
Command
(name, pos_arg=[], key_arg={})¶ Represents a single command in a script. Converting this to a string should yield a parsable command.
- Todo:
- Make that yield a parsable pretty command.
-
class
sgl.lib.ScriptParser.
Label
(name, body)¶ A class to represent labels in the script.
-
class
sgl.lib.ScriptParser.
Parser
(text='')¶ A base class for handling recursive descent parsers (possibly badly).
You should definitely not use this class in your own programs, but I need to document it for myself, so there.
Parameters: text (string) – If this argument is specified, it will call load_text
with this text during initialization.-
at_content_beginning
()¶ Returns if we’re at the beginning of the content of the line. (As in, past the whitespace.)
-
at_line_beginning
()¶ Returns if we’re at the beginning of the given line.
-
at_literal
()¶ Returns whether we currently at the beginning of a string or number literal.
-
char
¶ Returns the current character.
-
eat
(char)¶ Eats a character, and if it’s not what you specify, raises an error with
error
.Parameters: char (string) – The character the current character must be equal to.
-
error
(text)¶ Raises an error and prints information about the state of the parser.
Parameters: text (string) – A short description of the error. Raises: ParserError
– Will always raise this.- Todo:
- Maybe I should be using normal exceptions like a normal person? Not really sure how to easily do that while keeping track of the line and column position, though.
-
line_empty
()¶ Peeks ahead to see if the current line has any non-whitespace content or not.
-
literal
()¶ Reads a string or number literal, and returns the parsed value.
-
load_text
(text)¶ Loads text into the parser, and resets all the position counters.
Parameters: text (string) – A string containing the text to load. Should be able to deal fine with Unicode. Should.
-
newline
()¶ Expects a newline at char.
-
next
()¶ Moves the position onwards, keeping track of the current line and column.
-
next_char
¶ Read-only property returning the character after the current one.
-
position_valid
()¶ Returns if we’re in the document.
-
prev_char
¶ Read-only property returning the character before the current one.
-
symbol
()¶ Reads a symbol name.
- Todo:
- Has a bunch of hardcoded values for SGLscript. Factor out.
-
whitespace
(allow_newline=True)¶ Keeps advancing the cursor until reaching non-whitespace characters.
Parameters: allow_newline (bool) – Whether to eat newlines as well.
-
-
exception
sgl.lib.ScriptParser.
ParserError
(text, line, char)¶ This exception handles errors that happened while parsing a script.
-
class
sgl.lib.ScriptParser.
ParserSettings
¶ An object for holding settings on how the SGLscript parser behaves that the user is meant to be able to change.
-
class
sgl.lib.ScriptParser.
ScriptParser
(text='')¶ The object you’ll be interacting with the most if you use this module. This is what actually lets you take a string, parse it, and get back the proper objects.
- Todo:
- Trash a good portion of BodyParser.
- Un-hardcode the concept of labels. Have labels just be commands whose position is tracked so they can be quickly accessed.
Parameters: text (string) – If this argument is specified, it will call load_text
with this text during initialization.-
header
()¶ Parses special commands before the first label. You should not be calling this yourself, but the header is strange enough to warrant additional documentation.
Currently, you can only use two commands here:
define macro
: This takes two positional arguments. The first one is the original text, the second one is what to replace that text with.use pretty commands
: This determines whether to parse all commands as pretty commands or not. It only takes one positional argument, which must be the string or keyword “yes” to activate this.
If you attempt to use any other commands, or normal body text here, it will raise a HeaderError. Comments and all permutations of whitespace are fine.
You can potentially raise a MacroError by defining macros that begin with characters that conflict with SGLscript (currently
\
,[
, and@
). Don’t do this.Both of those types of exceptions only have one parameter,
text
, so I’m not documenting them in detail.
-
parse
()¶ Parses a script loaded by
load_text
and returns a dictionary of labels.Returns: A dictionary in which the keys are the name of a given level, and the value is the corresponding Label
object.Return type: dictionary - Todo:
Label
objects also contains the name of the label. There has to be a less dumb way to do this.
-
reset_settings
()¶ Resets all parser settings to their default values.