Whale Engine is a game engine for Python.
For better documentation look at samples in examples/ folder
Active development project.
Install dependencies:
pip install -r requirements.txtCurrent dependencies:
- cffi==2.0.0
- glfw==2.10.0
- numpy==2.4.2
- pillow==12.1.1
- pycparser==3.0
- PyOpenGL==3.1.10
- PyOpenGL-accelerate==3.1.10
- sounddevice==0.5.2
- soundfile==0.13.1
WhaleEngine/- package source code.examples/- sample programs.requirements.txt- pinned dependencies.
from WhaleEngine import *
app = WhaleEngine(title="Whale Engine App")
# Optional systems: initialize only what your game uses.
app.input = InputSystem()
MouseSystem()
ParentingSystem()
CircleCollisionSystem2D()
BetterCollisionSystem2D()
renderer = Renderer2D()
shapes = LoadShapes()
player = Entity2D(texture=shapes.whale, position=(0, 0), renderer=renderer)
def update(dt):
if app.input.key_pressed(glfw.KEY_SPACE):
print("Space pressed")
app.update = update
app.run()Run:
python AppBase.pyWhaleEngine(...)creates window + engine core.- Plugins are updated before your
app.update(dt)callback in the main loop. - If no renderer exists,
run()creates a defaultRenderer2D()automatically. - World coordinates are centered:
(0, 0)is screen center,+xright,+yup.
Available scripts in examples/:
better_collision.pyboom.pybutton.pyconversation.pydodosmove.pylines.pysound.pytext.pyvisualizecollider.pywhalemoving.py
You still need to move the example file into the same folder as the WhaleEngine package before running it.
Example:
python whalemoving.pyMethods:
run()close_app()
Main loop order:
window.poll()+window.clear()- all plugin updates
- user
app.update(dt) - each renderer:
update(dt) - each renderer:
update_entitys(dt) - each renderer:
render() window.swap()
Methods:
set_size(width, height)set_width(width)set_height(height)set_title(title)set_color(color)setup_2d()clear()poll()swap()should_close()terminate()
Methods:
start()update(dt)add(entity)update_entitys(dt)render()
Entity2D(*, texture, color=Color.white, position=(0, 0), scale=(1, 1), rotation=0.0, update=False, renderer=0)
Notes:
textureis required.- When
update=True, renderer callsentity.update(dt).
Methods:
set_text(new_text)set_font_size(new_font_size)
Button2D(onclick=None, onpress=None, *, density=16, texture, color=Color.white, position=(0, 0), renderer=0)
Important:
- Requires
BetterCollisionSystem2D()to be initialized first. - Uses an internal
MeshCollider2Don layer"mouse".
Methods:
add_message(text)
Features:
- bottom panel text box
- automatic wrapping
- automatic font size fitting
Methods:
key(glfw.KEY_*)key_pressed(glfw.KEY_*)key_released(glfw.KEY_*)
Members:
x,y(world-centered)wx,wy(window cursor position)left_down,right_down
Methods:
get_position()left_pressed()right_pressed()
CircleCollisionSystem2D()CircleCollider2D(size, *, layers=[0], position=(0, 0), visualize=False, visualition_color=Color.cyan, visualition_renderer=0)MeshCircleCollider2D(shape, density=8, size=8, offset_x=50, offset_y=60, *, layers=[0], position=(0, 0), visualize=False, visualition_color=Color.cyan, visualition_renderer=0, load_once=10)
BetterCollisionSystem2D()QuadCollider2D(w=100, h=100, *, position=(0, 0), rotation=0, layers=[0], visualize=False, visualition_color=Color.cyan, visualition_renderer=0)MeshCollider2D(shape, density=16, *, position=(0, 0), scale=(1, 1), rotation=0, layers=[0], visualize=False, visualition_color=Color.cyan, visualition_renderer=0)
ParentingSystem()ParentIn(parent, child, attributes={"x": "set", "y": "set"})
attributes mode values:
"set": child attribute follows parent directly."add": child gets parent delta movement.
Helpers:
Color.rgb(r, g, b)Color.rgba(r, g, b, a)Color.hsv(h, s, v)Color.hex("#RRGGBB")
Includes many presets like white, black, red, green, blue, cyan, orange, purple, gray.
Texture(path)LoadShapes()with built-ins:dodo,whale,square,circle,triangle,grid,dotLoadSounds()with built-ins:music,soundSoundSystem()Sound(name, path)
Sound requires SoundSystem() to be initialized first.
raycast2d(start=(0, 0), end=(0, 0), layers=None)destroy(entity)distance2D(entity1, entity2)distance2D_points(pos1, pos2)angle_to2D(pos1, pos2)forwardPos2D(pos, angle, distance)forwardMove2D(angle, distance)pixel_is_solid(r, g, b, a, alpha_threshold=10)
From WhaleEngine.helpers.fpscounter:
FPS_counter(dt, fps_timer_lenght=1, print_fps=False)get_FPS()summarize_FPS()
Only engine + renderer:
app = WhaleEngine()
renderer = Renderer2D()
app.run()Add keyboard + mouse input:
app = WhaleEngine()
app.input = InputSystem()
MouseSystem()
renderer = Renderer2D()
app.run()Add button support:
app = WhaleEngine()
MouseSystem()
BetterCollisionSystem2D()
renderer = Renderer2D()
button = Button2D(texture=LoadShapes().square, renderer=renderer)
app.run()- The package currently uses the filename
entitys2d.pyinternally; imports are already exposed throughfrom WhaleEngine import *. - API is still evolving.