A python binding for the great C library raylib.
raylib-py uses type annotations in its source, so a Python version that supports it is required.
The easiest way to install raylib-py is by the pip install command:
Depending on you system and python version(s) installed, the command might be:
pip install raylib-py
python -m pip install raylip-py
or (with Python3.7 launcher with multiple versions installed)
py-3.x-32 -m pip install raylib-py
Note that the minimum Python version tested is 3.4. Please, let me know if you're able to run it in Python33.
raylib-py comes with 32bit binaries for Windows, Mac and Linux, but you're not required to use these. If you have a custom raylib dll, dylib or so binary, make sure to set a PATH indicating the directory it is located:
import os # set the path before raylib is imported. os.environ[RAYLIB_LIB_PATH] = "path/to/the/binary" import raylibpy # let the fun begin.
You can set
"__file__" as value to
RAYLIB_LIB_PATH and raylib-py will search for the binary in the package dir:
# bynary file is wherever the package is located. os.environ[RAYLIB_LIB_PATH] = "__file__"
"__main__" can also be set to look for the binary in the project's directory where the starting script is located:
# binary file is in the same dir as this py file. os.environ[RAYLIB_LIB_PATH] = "__main__" # ... if __name__ == "__main__": # run the game # ...
Make sure the bin file name for the respective platform is
raylib-py does not have test code, but you can run the examples in the examples directory.
raylib vs raylib-py
Below are the differences in usage between raylib and raylib-py. Note, though that these differences are being worked to make raylib-py as pythonic as possible, so changes may occur without notification.
#defines got translated to Python 'constants'. Enums got translated to
In general, all structures inherit from
ctypes.Structure class. At the moment, constructors
(except for vectors) require the exact argument types, so
ints can't be passed
floats are expected (although the argument can be omitted).
All structures have
__str__() implemented, so they have a very basic textual representation:
# Define the camera to look into our 3d world >>> camera = Camera() >>> camera.position = Vector3(5., 4., 5.) >>> camera.target = Vector3(0., 2., 0.) >>> camera.up = Vector3(0., 1., 0.) >>> camera.fovy = 45.0 >>> camera.type = CAMERA_PERSPECTIVE >>> camera "(CAMERA3D: position: (5.0, 4.0, 5.0), target: (0.0, 2.0, 0.0), up: (0.0, 1.0, 0.0), fovy: 45.0°, type: PERSPECTIVE)"
Not all information is exposed, though. Mesh objects, for example, exposes only the vertex and triangle count attributes.
Vector2, Vector3 and Vector4 support basic aritmetic operations: addiction, subtraction, multiplication (incluiding scalar multiplication), division and modulo. Augmented assignment is also supported; the right hand side operand can be any sequence of same number of components:
vec_a = Vector3(3., 5., 7.) vec_b = Vector3(4., 2., 0.) vec_a * vec_b # outputs (12.0, 10.0, 0.0) vec_a + (8, 100, -1) # outputs (11.0, 105.0, 6.0) vec_a %= 2 # augmented assignment (modulo) vec_a # outputs (1.0, 1.0, 0.0)
Vectors also support GLSL vector swizzling. Also,
w coordinates maps to
normalized color values (
a; only for
texture coordinates (
# Reading (__getattr__) vec3 = Vector3(123.0, 467.0, 789.0) vec2 = vec3.uv # x and y respectively as u and v vec3 = vec3.bgr # x, y and z respectively as r, g and b ( rgb is not available in Vector 2) vec4 = vec2.rrrg # for attribute reading, is ok to repeat components # Writing (__setattr__) vec3 = Vector3(123.0, 467.0, 789.0) vec4.yxwz = 10, 0, -1, vec3.z # sequences of ints and/or floats are accepted as value vec2.vu = vec3.xy # x and y respectively as u and v vec3.bgr = 12, vec4.x # x, y and z respectively as r, g and b ( rgb is not available in Vector 2) # the following raises an exception: vec3.rrr = vec4.yxw # for attribute writing, is _not_ ok to repeat components vec2.br = vec4.uv # r, g and b is not available in Vector2 vec4.brxy = (0., 0., vec2.x, vec3.z) # can't mix component name groups (rgba, xywz and uv)
Constructors and swizzled attributes now accept any combination of numbers, vectors and sequences, as long as the total number of arguments are preserved:
# all these results in the same Vector4 a = Vector4(3, 4, 5, 6) b = Vector4(a.xy, 5, 6) c = Vector4(b.x, b.yz, 6) d = Vector4(3, c.y, c.zw) e = Vector4(d.xy, (5, 6)) f = Vector4(e.xyz, 6) g = Vector4(3, f.yzw) h = Vector4(g)
Setting attributes also works:
a = Vector4(Vector2(10, 0), 100, 20) b = Vector4.zero() b.rgba = 0.0, vec4.rg, 1.0 a.xyzw = (10, b.uv), 1.0
This became available by dropping a previous feature wich allowed for a very basic swizzling emulation. A feature more similar to GLSL vectors is implemented on top of Python container emulation magic functions:
vec = Vector4(0., 1., 2., 3.) # __len__() print(len(vec)) # outputs 4 # __iter__() for comp in vec: print(comp) # iterates on Vector4 components # __getitem__() x = vec # key as int y = vec['y'] # key as str zw = vec[2:] # key as slice; returns a List[float] # __setitem__() vec = 10 vec['y'] = 20 # vec[2:] = zw # <--- not supported; will raise TypeError
Additional (feature) draw function:
The custom DLL installed by raylib-py includes an not yet official drawing function and
NPatchInfo helper structure:
# draws an 3-patch (vertical, or horizontal) or 9-patch textured that stretches and # shrinks nicely. # Seq means any sequence type def draw_texture_npatch(texture: Texture2D, npatch_info: NPatchInfo, dest_rec: Union[Rectangle, Seq], origin: Union[Vector2, Seq], rotation: float, tint: Union[Color, Seq]) -> None:
At the moment (after raylib v2.0.0), only the x86 custom DLL contains this function
and, to enabled it, an specific
os.environ key must be set:
# set this before importing raylibpy (the value does not matter as long is a str type) os.environ['ENABLE_V2_0_0_FEATURE_DRAWTEXTURENPATCH'] = '1'
Building raylib from source
Please, let me know if you find any strange or unexpected behavior while using raylib-py. If you want to request features or report bugs related to the library (in contrast to this binding), please refer to the author's project repo.
See also the list of contributors who participated in this project.
raylib-py (and raylib) is licensed under an unmodified zlib/libpng license, which is an OSI-certified, BSD-like license that allows static linking with closed source software.