Physics Engines

class arcade.PhysicsEngineSimple(player_sprite: Sprite, walls: SpriteList | Iterable[SpriteList] | None = None)[source]

Bases:

A basic physics engine best for single-player top-down games.

This is the easiest engine to get started with. It’s best when:

  • You need a top-down view

  • You need to collide with non-moving terrain

  • You don’t need anything else

For side-scrolling games focused on jumping puzzles, you may want the PlatformerPhysicsEngine instead. Experienced users may want to try the PymunkPhysicsEngine.

Parameters:
  • player_sprite – A sprite which will be controlled by the player.

  • walls – A SpriteList or list of them which should stop player movement.

player_sprite: Sprite

The player-controlled Sprite.

update() list[SpriteType][source]

Move player_sprite and return any colliding sprites.

Returns:

A list of the colliding sprites. If there were zero collisions, it will be empty.

property walls: list[SpriteList]

Which SpriteList instances block player movement.

Important

Avoid moving sprites in these lists!

Doing so incurs performance costs.

See PhysicsEnginePlatformer.walls for further information. For platformer physics such as moving platforms and gravity, consider using the PhysicsEnginePlatformer.

class arcade.PhysicsEnginePlatformer(player_sprite: Sprite, platforms: SpriteList | Iterable[SpriteList] | None = None, gravity_constant: float = 0.5, ladders: SpriteList | Iterable[SpriteList] | None = None, walls: SpriteList | Iterable[SpriteList] | None = None)[source]

Bases:

A single-player engine with gravity and moving platform support.

This engine is best for simple versions of platformer games like the Super Mario Bros. (the first Mario game) and Rayman. It is more important to pay attention to the performance tips with this engine than with PhysicsEngineSimple.

Important

For best performance, you must put your sprites in the right group!

Be sure to add each Sprite and SpriteList to the right group, regardless of whether you do so via arguments or properties:

Creation argument

Purpose

list property

walls

Non-moving sprites the player can stand on.

walls

platforms

Sprites the player can stand on, but which can still move.

platforms

ladders

Ladders which allow gravity-free movement while touched by the player_sprite.

ladders

To learn about the automatic moving platform feature, please see platforms.

Not that if you use the list properties above, you can add or remove platforms in response to game events. It is also possible to add new sprites such as terrain in response to gameplay events, but there may be performance implications due to the way SpriteList handles spatial hashing. To learn more, see walls.

Parameters:
  • player_sprite – The player character’s sprite. It will be stored on the engine as player_sprite.

  • platforms – The initial list of platforms, sprites which can move freely.

  • gravity_constant – A constant to subtract from the player_sprite’s velocity (Sprite.change_y) each update() when in the air. See gravity_constant to learn more.

  • laddersSprite instances the player can climb without being affected by gravity.

  • wallsSprite instances which are static and never move. Do not put moving sprites into this! See walls to learn more.

allow_multi_jump: bool

Whether multi-jump is enabled.

For ease of use in simple games, you may want to use the following methods instead of setting this directly:

allowed_jumps: int

Total number of jumps the player should be capable of.

This includes the first jump. To enable multi-jump, see enable_multi_jump() instead.

can_jump(y_distance: float = 5) bool[source]

Update jump state and return True if the player can jump.

Warning

This runs collisions every time it is called!

If you are thinking of calling this repeatedly, first double-check whether you can store the returned value to a local variable instead.

The player can jump when at least one of the following are true: after updating state:

The player is “touching” the ground

player_sprite’s BasicSprite.center_y is within y_distance of any sprite in walls or platforms

The player can air-jump

allow_multi_jump is True and the player hasn’t jumped more than allowed_jumps times

Parameters:

y_distance – The distance to temporarily move the player_sprite downward before checking for a collision with either walls or platforms.

Returns:

True if the player can jump.

disable_multi_jump() None[source]

Disable multi-jump.

Calling this function removes the requirement for jump() to call increment_jump_counter() with each jump to prevent infinite jumping.

enable_multi_jump(allowed_jumps: int) None[source]

Enable multi-jump.

The allowed_jumps argument is the total number of jumps the player should be able to make, including the first from solid ground in walls or any platforms. It will be stored as allowed_jumps.

Important

If you override jump(), be sure to call increment_jump_counter() inside it!

Otherwise, the player may be able to jump forever.

Parameters:

allowed_jumps – Total number of jumps the player should be capable of, including the first.

gravity_constant: float

The player’s default downward acceleration.

The engine’s update() method subtracts this value from the player_sprite’s change_y when the player is not touching a sprite in ladders or walls.

You can change the value of gravity after engine creation through this attribute. In addition to responding to GUI events, you can also change gravity in response to game events such as touching power-ups.

Values for gravity_constant work as follows:

gravity_constant

Effect

Greater than zero

Gravity points downward as expected

Less than zero

Player falls upward (Consider adding a ceiling)

Zero

No gravity

To learn more, please see the following parts of the Simple Platformer:

increment_jump_counter() None[source]

Update jump tracking if multi-jump is enabled.

If allow_multi_jumps is True, calling this adds 1 to jumps_since_ground. Otherwise, it does nothing.

is_on_ladder() bool[source]

Check if the player_sprite touches any ladders.

Warning

This runs collisions every time it is called!

Returns:

True if the player_sprite touches any ladders.

jump(velocity: float) None[source]

Jump with an initial upward velocity.

This works as follows:

  1. Set the player_sprite’s change_y to the passed velocity

  2. Call increment_jump_counter()

Parameters:

velocity – A positive value to set the player’s y velocity to.

jumps_since_ground: int

How many times the player has jumped since touching a sprite in walls.

This is used throughout the engine’s logic, including the jump() and can_jump() methods.

property ladders: list[SpriteList]

Ladders turn off gravity while touched by the player.

This means that whenever the player_sprite collides with any any Sprite or BasicSprite in this list, the following are true:

property platforms: list[SpriteList]

SpriteList instances containing platforms.

Important

For best performance, put non-moving terrain in walls instead.

Platforms are intended to support automatic movement by setting the appropriate attributes.

You can enable automatic motion by setting one of the following attribute pairs on a Sprite:

Movement Axis

Sprite Attributes to Set

X (side to side)

  • change_x

  • boundary_left

  • boundary_right

Y (up and down)

  • change_y

  • boundary_bottom

  • boundary_top

For a working example, please see Moving Platforms.

player_sprite: Sprite

The sprite controlled by the player.

Important

This must be a Sprite or a subclass of it!

You can’t use BasicSprite since it lacks required change_y property.

update() list[BasicSprite][source]

Move the player and platforms, then return colliding sprites.

The returned sprites will in a list of individual sprites taken from all arcade.SpriteList instances in the following:

The ladders are not included.

Returns:

A list of all sprites the player collided with. If there were no collisions, the list will be empty.

property walls: list[SpriteList]

Exposes the SpriteList instances use as terrain.

Important

For best performance, only add non-moving sprites!

The walls lists make a tradeoff through spatial hashing:

  • Collision checking against sprites in the list becomes very fast

  • Moving sprites or adding new ones becomes very slow

This is worth the tradeoff for non-moving terrain, but it means you have to be careful. If you move too many sprites in the walls lists every frame, your game may slow down. For moving sprites the player can stand and jump on, see the platforms feature.

To learn more about spatial hashing, please see the following:

class arcade.PymunkPhysicsObject(body: Body | None = None, shape: Shape | None = None)[source]

Bases:

Object that holds pymunk body/shape for a sprite.

class arcade.PymunkException[source]

Bases: Exception

Exception raised for errors in the PymunkPhysicsEngine.

class arcade.PymunkPhysicsEngine(gravity=(0, 0), damping: float = 1.0, maximum_incline_on_ground: float = 0.708)[source]

Bases:

An Arcade-specific adapter for Pymunk.

Pymunk is itself a Python adapter for the professional-grade Chipmunk2D engine. However, Arcade’s PymunkPhysicsEngine and its doc are currently in need of improvement.

Note

Arcade would welcome assistance with improving it.

If you are interested, please see Arcade’s CONTRIBUTING.md

Parameters:
  • gravity – The direction where gravity is pointing. See pymunk.Space.gravity to learn more.

  • damping

    The default velocity loss per tick across the Space for all DYNAMIC objects.

    • Override this for objects by passing different value :add_sprite or add_spritelist()

    • See pymunk.Space.damping to learn more

  • maximum_incline_on_ground

    The maximum incline the ground can have before is_on_ground() returns False.

    • Defaults to 0.708 radians (a bit over 45 °)

    • Not a pymunk value, but an Arcade feature

DYNAMIC = 0

A body_type for moving Pymunk-controlled objects.

An indirect approach is best for controlling the velocity and positioning of dynamic objects:

Warning

Avoid setting velocity directly on dynamic objects!

If you need to set velocity directly, you may want to pass KINEMATIC as the body_type to add_sprite() instead.

If you set_velocity directly anyway, the following may occur:

  1. Setting velocity approaches infinite acceleration

  2. f = m * a approaches f = m * infinity

  3. Collisions go haywire

In some games, you may be able to find a way to harness this for comedic effect.

Note

This value is an alias of pymunk.Body.DYNAMIC.

Please see the Pymunk page linked above to learn more.

KINEMATIC = 1

A body_type for objects controlled by your code or Arcade’s.

When colliding, Kinematic objects:

  • act as if they have infinite mass

  • prevent joined and touching objects from sleeping

This makes them excellent for game elements like moving platforms or hazards which move or crush game objects. You can control kinematic objects by setting their positions and velocities directly:

Note

This value is an alias of pymunk.Body.KINEMATIC.

Please see the Pymunk page linked above to learn more.

MOMENT_INF = inf
STATIC = 2

A body_type for objects which do not move.

This is best used for terrain or non-moving platforms.

Note

This value is an alias of pymunk.Body.STATIC.

Please see the Pymunk page linked above to learn more.

add_collision_handler(first_type: str, second_type: str, begin_handler: Callable | None = None, pre_handler: Callable | None = None, post_handler: Callable | None = None, separate_handler: Callable | None = None) None[source]

Add code to handle collisions between objects.

Parameters:
  • first_type – The first type of object to check for collisions.

  • second_type – The second type of object to check for collisions.

  • begin_handler – Function to call when a collision begins.

  • pre_handler – Function to call before a collision is resolved.

  • post_handler – Function to call after a collision is resolved.

  • separate_handler – Function to call when two objects

add_sprite(sprite: Sprite, mass: float = 1.0, friction: float = 0.2, elasticity: float | None = None, moment_of_inertia: float | None = None, body_type: int = 0, damping: float | None = None, gravity: Vec2d | tuple[float, float] | Vec2 | None = None, max_velocity: int | None = None, max_horizontal_velocity: int | None = None, max_vertical_velocity: int | None = None, radius: float = 0, collision_type: str | None = 'default') None[source]

Add a sprite to the physics engine.

Parameters:
  • sprite – A Sprite to add

  • mass – The mass of the object (Defaults to 1.0).

  • friction

    How much the object resists sliding against surfaces:

    0.0

    Absolutely slippery with no resistance at all

    0.2

    Default (Waxed wood on very wet snow)

    friction > 1.0

    Very rough

    Higher values may not make a meaningful difference.

    See pymunk.Shape.friction to learn more.

  • elasticity

    How bouncy the object is.

    0.0

    No bounce

    0.99

    Very bouncy

    elasticity >= 1.0

    May behave badly (breaks conservation of energy)

    See pymunk.Shape.elasticity to learn more.

  • moment_of_inertia

    How much force is needed to change the object’s rotation ( pass MOMENT_INF or float('inf') to “lock” its angle).

    See pymunk.Shape.moment_of_inertia to learn more.

  • body_typeDYNAMIC (default), KINEMATIC, or STATIC.

  • damping – Like air resistance. See the PymunkPhysicsEngine top-level doc.

  • gravity – See the PymunkPhysicsEngine top-level doc.

  • max_velocity – The maximum velocity of this object.

  • max_horizontal_velocity – Clamp the velocity on the x axis to this.

  • max_vertical_velocity – Clamp the velocity along the y axis to this.

  • radius – The radius for the pymunk.Shape created for the sprite.

  • collision_type – Assign a collision name to this sprite. It will be used by add_collision_handler() if called.

add_sprite_list(sprite_list, mass: float = 1, friction: float = 0.2, elasticity: float | None = None, moment_of_inertia: float | None = None, body_type: int = 0, damping: float | None = None, collision_type: str | None = None) None[source]

Add all sprites in a sprite list to the physics engine.

Parameters:
  • sprite_list – A list of sprites to add

  • mass – The mass of the object (Defaults to 1.0).

  • friction

    How much the object resists sliding against surfaces:

    0.0

    Absolutely slippery with no resistance at all

    0.2

    Default (Waxed wood on very wet snow)

    friction > 1.0

    Very rough

    Higher values may not make a meaningful difference.

    See pymunk.Shape.friction to learn more.

  • elasticity

    How bouncy the object is.

    0.0

    No bounce

    0.99

    Very bouncy

    elasticity >= 1.0

    May behave badly (breaks conservation of energy)

    See pymunk.Shape.elasticity to learn more.

  • moment_of_inertia

    How much force is needed to change the object’s rotation ( pass MOMENT_INF or float('inf') to “lock” its angle).

    See pymunk.Shape.moment_of_inertia to learn more.

  • body_typeDYNAMIC (default), KINEMATIC, or STATIC.

  • damping – Like air resistance. See the PymunkPhysicsEngine top-level doc.

  • collision_type – Assign a collision name to this sprite. It will be used by add_collision_handler() if called.

apply_force(sprite: Sprite, force: tuple[float, float])[source]

Apply force to a Sprite.

Parameters:
  • sprite – The sprite to apply the force to.

  • force – The force to apply to the sprite.

apply_impulse(sprite: Sprite, impulse: tuple[float, float]) None[source]

Apply an impulse force on a sprite

apply_opposite_running_force(sprite: Sprite) None[source]

If a sprite goes left while on top of a dynamic sprite, that sprite should get pushed to the right.

check_grounding(sprite: Sprite) dict[source]

See if the player is on the ground. Used to see if we can jump.

Parameters:

sprite – The sprite to check if it is on the ground.

get_physics_object(sprite: Sprite) PymunkPhysicsObject[source]

Get the shape/body for a sprite.

Parameters:

sprite – The sprite to get the physics object for.

get_sprite_for_shape(shape: Shape | None) Sprite | None[source]

Try to get the sprite registered with this engine for shape.

This method returns None when:

  • shape is None

  • No Sprite was to this engine for shape

The second item may occur if you are using multiple instances of PymunkPhysicsEngine.

Parameters:

shape – A Pymunk shape to perform lookup for.

Returns:

A sprite for the shape; None if no sprite is known.

get_sprites_from_arbiter(arbiter: Arbiter) tuple[Sprite | None, Sprite | None][source]

Given a collision arbiter, return the sprites associated with the collision.

is_on_ground(sprite: Sprite) bool[source]

Return true of sprite is on top of something.

remove_sprite(sprite: Sprite) None[source]

Remove a sprite from the physics engine.

resync_sprites() None[source]

Set visual sprites to be the same location as physics engine sprites. Call this after stepping the pymunk physics engine

set_friction(sprite: Sprite, friction: float) None[source]

Set the friction a sprite experiences against other surfaces.

This is how “rough” a sprite is during a collision with others:

  • 0.0 is the lowest value allowed (absolute slipperiness)

  • Higher values slide less on surfaces and other objects

Pymunk allows setting friction higher than 1.0, but very high values might not have meaningful gameplay impact.

To learn more, please see:

Parameters:
  • sprite – The sprite to set the friction for.

  • friction – How much the object resists sliding against surfaces.

set_horizontal_velocity(sprite: Sprite, velocity: float) None[source]

Set a sprite’s velocity.

Parameters:
  • sprite – The sprite to set the velocity for.

  • velocity – The velocity to set the sprite to.

set_position(sprite: Sprite, position: Vec2d | tuple[float, float])[source]

Set the position of the sprite in the engine’s simulation.

To learn more, please see pymunk.Body.position.

Parameters:
  • sprite – An Arcade Sprite known to the engine.

  • position – A two-dimensional position in world space.

set_rotation(sprite: Sprite, rotation: float) None[source]
set_velocity(sprite: Sprite, velocity: tuple[float, float]) None[source]

Directly set the velocity of a sprite known to the engine.

Warning

Avoid using this on any DYNAMIC objects!

This function is meant for KINEMATIC objects. Using it on a sprite added as DYNAMIC can cause strange and very broken behavior.

To learn more, please see:

step(delta_time: float = 0.016666666666666666, resync_sprites: bool = True) None[source]

Tell the physics engine to perform calculations.

Parameters:
  • delta_time – Time to move the simulation forward. Keep this value constant, do not use varying values for each step.

  • resync_sprites – Resynchronize Arcade graphical sprites to be at the same location as their Pymunk counterparts. If running multiple steps per frame, set this to false for the first steps, and true for the last step that’s part of the update.