pymunk.pygame_util Module

This submodule contains helper functions to help with quick prototyping using pymunk together with pygame.

Intended to help with debugging and prototyping, not for actual production use in a full application. The methods contained in this module is opinionated about your coordinate system and not in any way optimized.

class pymunk.pygame_util.DrawOptions(surface: None.Surface)[source]

Bases: pymunk.space_debug_draw_options.SpaceDebugDrawOptions

DRAW_COLLISION_POINTS

alias of <class ‘CP_SPACE_DEBUG_DRAW_COLLISION_POINTS’>

DRAW_CONSTRAINTS

alias of <class ‘CP_SPACE_DEBUG_DRAW_CONSTRAINTS’>

DRAW_SHAPES

alias of <class ‘CP_SPACE_DEBUG_DRAW_SHAPES’>

__init__(surface: None.Surface) None[source]

Draw a pymunk.Space on a pygame.Surface object.

Typical usage:

>>> import pymunk
>>> surface = pygame.Surface((10,10))
>>> space = pymunk.Space()
>>> options = pymunk.pygame_util.DrawOptions(surface)
>>> space.debug_draw(options)

You can control the color of a shape by setting shape.color to the color you want it drawn in:

>>> c = pymunk.Circle(None, 10)
>>> c.color = pygame.Color("pink")

See pygame_util.demo.py for a full example

Since pygame uses a coordiante system where y points down (in contrast to many other cases), you either have to make the physics simulation with Pymunk also behave in that way, or flip everything when you draw.

The easiest is probably to just make the simulation behave the same way as Pygame does. In that way all coordinates used are in the same orientation and easy to reason about:

>>> space = pymunk.Space()
>>> space.gravity = (0, -1000)
>>> body = pymunk.Body()
>>> body.position = (0, 0) # will be positioned in the top left corner
>>> space.debug_draw(options)

To flip the drawing its possible to set the module property positive_y_is_up to True. Then the pygame drawing will flip the simulation upside down before drawing:

>>> positive_y_is_up = True
>>> body = pymunk.Body()
>>> body.position = (0, 0)
>>> # Body will be position in bottom left corner
Parameters
surfacepygame.Surface

Surface that the objects will be drawn on

property collision_point_color: pymunk.space_debug_draw_options.SpaceDebugColor

The color of collisions.

Should be a tuple of 4 ints between 0 and 255 (r,g,b,a).

Example:

>>> import pymunk
>>> s = pymunk.Space()
>>> b = pymunk.Body(1,10)
>>> c1 = pymunk.Circle(b, 10)
>>> c2 = pymunk.Circle(s.static_body, 10)
>>> s.add(b, c1, c2)
>>> s.step(1)
>>> options = pymunk.SpaceDebugDrawOptions()
>>> s.debug_draw(options)
draw_circle (Vec2d(0.0, 0.0), 0.0, 10.0, SpaceDebugColor(r=44.0, g=62.0, b=80.0, a=255.0), SpaceDebugColor(r=52.0, g=152.0, b=219.0, a=255.0))
draw_circle (Vec2d(0.0, 0.0), 0.0, 10.0, SpaceDebugColor(r=44.0, g=62.0, b=80.0, a=255.0), SpaceDebugColor(r=149.0, g=165.0, b=166.0, a=255.0))
draw_segment (Vec2d(8.0, 0.0), Vec2d(-8.0, 0.0), SpaceDebugColor(r=231.0, g=76.0, b=60.0, a=255.0))
>>> options.collision_point_color = (10,20,30,40)
>>> s.debug_draw(options)
draw_circle (Vec2d(0.0, 0.0), 0.0, 10.0, SpaceDebugColor(r=44.0, g=62.0, b=80.0, a=255.0), SpaceDebugColor(r=52.0, g=152.0, b=219.0, a=255.0))
draw_circle (Vec2d(0.0, 0.0), 0.0, 10.0, SpaceDebugColor(r=44.0, g=62.0, b=80.0, a=255.0), SpaceDebugColor(r=149.0, g=165.0, b=166.0, a=255.0))
draw_segment (Vec2d(8.0, 0.0), Vec2d(-8.0, 0.0), SpaceDebugColor(r=10.0, g=20.0, b=30.0, a=40.0))
color_for_shape(shape: Shape) pymunk.space_debug_draw_options.SpaceDebugColor
property constraint_color: pymunk.space_debug_draw_options.SpaceDebugColor

The color of constraints.

Should be a tuple of 4 ints between 0 and 255 (r,g,b,a).

Example:

>>> import pymunk
>>> s = pymunk.Space()
>>> b = pymunk.Body(1, 10)
>>> j = pymunk.PivotJoint(s.static_body, b, (0,0))
>>> s.add(j)
>>> options = pymunk.SpaceDebugDrawOptions()
>>> s.debug_draw(options)
draw_dot (5.0, Vec2d(0.0, 0.0), SpaceDebugColor(r=142.0, g=68.0, b=173.0, a=255.0))
draw_dot (5.0, Vec2d(0.0, 0.0), SpaceDebugColor(r=142.0, g=68.0, b=173.0, a=255.0))
>>> options.constraint_color = (10,20,30,40)
>>> s.debug_draw(options)
draw_dot (5.0, Vec2d(0.0, 0.0), SpaceDebugColor(r=10.0, g=20.0, b=30.0, a=40.0))
draw_dot (5.0, Vec2d(0.0, 0.0), SpaceDebugColor(r=10.0, g=20.0, b=30.0, a=40.0))
draw_circle(pos: pymunk.vec2d.Vec2d, angle: float, radius: float, outline_color: pymunk.space_debug_draw_options.SpaceDebugColor, fill_color: pymunk.space_debug_draw_options.SpaceDebugColor) None[source]
draw_dot(size: float, pos: Tuple[float, float], color: pymunk.space_debug_draw_options.SpaceDebugColor) None[source]
draw_fat_segment(a: Tuple[float, float], b: Tuple[float, float], radius: float, outline_color: pymunk.space_debug_draw_options.SpaceDebugColor, fill_color: pymunk.space_debug_draw_options.SpaceDebugColor) None[source]
draw_polygon(verts: Sequence[Tuple[float, float]], radius: float, outline_color: pymunk.space_debug_draw_options.SpaceDebugColor, fill_color: pymunk.space_debug_draw_options.SpaceDebugColor) None[source]
draw_segment(a: pymunk.vec2d.Vec2d, b: pymunk.vec2d.Vec2d, color: pymunk.space_debug_draw_options.SpaceDebugColor) None[source]
draw_shape(shape: Shape) None
property flags: int

Bit flags which of shapes, joints and collisions should be drawn.

By default all 3 flags are set, meaning shapes, joints and collisions will be drawn.

Example using the basic text only DebugDraw implementation (normally you would the desired backend instead, such as pygame_util.DrawOptions or pyglet_util.DrawOptions):

>>> import pymunk
>>> s = pymunk.Space()
>>> b = pymunk.Body()
>>> c = pymunk.Circle(b, 10)
>>> c.mass = 3
>>> s.add(b, c)
>>> s.add(pymunk.Circle(s.static_body, 3))
>>> s.step(0.01)
>>> options = pymunk.SpaceDebugDrawOptions() 
>>> # Only draw the shapes, nothing else:
>>> options.flags = pymunk.SpaceDebugDrawOptions.DRAW_SHAPES
>>> s.debug_draw(options) 
draw_circle (Vec2d(0.0, 0.0), 0.0, 10.0, SpaceDebugColor(r=44.0, g=62.0, b=80.0, a=255.0), SpaceDebugColor(r=52.0, g=152.0, b=219.0, a=255.0))
draw_circle (Vec2d(0.0, 0.0), 0.0, 3.0, SpaceDebugColor(r=44.0, g=62.0, b=80.0, a=255.0), SpaceDebugColor(r=149.0, g=165.0, b=166.0, a=255.0))
>>> # Draw the shapes and collision points:
>>> options.flags = pymunk.SpaceDebugDrawOptions.DRAW_SHAPES
>>> options.flags |= pymunk.SpaceDebugDrawOptions.DRAW_COLLISION_POINTS
>>> s.debug_draw(options)
draw_circle (Vec2d(0.0, 0.0), 0.0, 10.0, SpaceDebugColor(r=44.0, g=62.0, b=80.0, a=255.0), SpaceDebugColor(r=52.0, g=152.0, b=219.0, a=255.0))
draw_circle (Vec2d(0.0, 0.0), 0.0, 3.0, SpaceDebugColor(r=44.0, g=62.0, b=80.0, a=255.0), SpaceDebugColor(r=149.0, g=165.0, b=166.0, a=255.0))
draw_segment (Vec2d(1.0, 0.0), Vec2d(-8.0, 0.0), SpaceDebugColor(r=231.0, g=76.0, b=60.0, a=255.0))
shape_dynamic_color: pymunk.space_debug_draw_options.SpaceDebugColor = SpaceDebugColor(r=52, g=152, b=219, a=255)
shape_kinematic_color: pymunk.space_debug_draw_options.SpaceDebugColor = SpaceDebugColor(r=39, g=174, b=96, a=255)
property shape_outline_color: pymunk.space_debug_draw_options.SpaceDebugColor

The outline color of shapes.

Should be a tuple of 4 ints between 0 and 255 (r,g,b,a).

Example:

>>> import pymunk
>>> s = pymunk.Space()
>>> c = pymunk.Circle(s.static_body, 10)
>>> s.add(c)
>>> options = pymunk.SpaceDebugDrawOptions()
>>> s.debug_draw(options)
draw_circle (Vec2d(0.0, 0.0), 0.0, 10.0, SpaceDebugColor(r=44.0, g=62.0, b=80.0, a=255.0), SpaceDebugColor(r=149.0, g=165.0, b=166.0, a=255.0))
>>> options.shape_outline_color = (10,20,30,40)
>>> s.debug_draw(options)
draw_circle (Vec2d(0.0, 0.0), 0.0, 10.0, SpaceDebugColor(r=10.0, g=20.0, b=30.0, a=40.0), SpaceDebugColor(r=149.0, g=165.0, b=166.0, a=255.0))
shape_sleeping_color: pymunk.space_debug_draw_options.SpaceDebugColor = SpaceDebugColor(r=114, g=148, b=168, a=255)
shape_static_color: pymunk.space_debug_draw_options.SpaceDebugColor = SpaceDebugColor(r=149, g=165, b=166, a=255)
property transform: pymunk.transform.Transform

The transform is applied before drawing, e.g for scaling or translation.

Example:

>>> import pymunk
>>> s = pymunk.Space()
>>> c = pymunk.Circle(s.static_body, 10)
>>> s.add(c)
>>> options = pymunk.SpaceDebugDrawOptions() 
>>> s.debug_draw(options) 
draw_circle (Vec2d(0.0, 0.0), 0.0, 10.0, SpaceDebugColor(r=44.0, g=62.0, b=80.0, a=255.0), SpaceDebugColor(r=149.0, g=165.0, b=166.0, a=255.0))
>>> options.transform = pymunk.Transform.scaling(2)
>>> s.debug_draw(options)
draw_circle (Vec2d(0.0, 0.0), 0.0, 20.0, SpaceDebugColor(r=44.0, g=62.0, b=80.0, a=255.0), SpaceDebugColor(r=149.0, g=165.0, b=166.0, a=255.0))
>>> options.transform = pymunk.Transform.translation(2,3)
>>> s.debug_draw(options)
draw_circle (Vec2d(2.0, 3.0), 0.0, 10.0, SpaceDebugColor(r=44.0, g=62.0, b=80.0, a=255.0), SpaceDebugColor(r=149.0, g=165.0, b=166.0, a=255.0))

Note

Not all tranformations are supported by the debug drawing logic. Uniform scaling and translation are supported, but not rotation, linear stretching or shearing.

pymunk.pygame_util.from_pygame(p: Tuple[float, float], surface: None.Surface) Tuple[int, int][source]

Convenience method to convert pygame surface local coordinates to pymunk coordinates

pymunk.pygame_util.get_mouse_pos(surface: None.Surface) Tuple[int, int][source]

Get position of the mouse pointer in pymunk coordinates.

pymunk.pygame_util.positive_y_is_up: bool = False

Make increasing values of y point upwards.

When True:

y
^
|      . (3, 3)
|
|   . (2, 2)
|
+------ > x

When False:

+------ > x
|
|   . (2, 2)
|
|      . (3, 3)
v
y
pymunk.pygame_util.to_pygame(p: Tuple[float, float], surface: None.Surface) Tuple[int, int][source]

Convenience method to convert pymunk coordinates to pygame surface local coordinates.

Note that in case positive_y_is_up is False, this function wont actually do anything except converting the point to integers.