gale.tilemap.collision module
This file contains platformer collision helpers for TileMap: an optional, opt-in layer on top of it, not a required part of using TileMap at all. It never touches gale.physics/Box2D — this is plain AABB-against-a-grid, the same kind of hand-rolled collision most 2D platformers actually use, in or out of a physics engine.
Author: Alejandro Mujica (aledrums@gmail.com)
- class gale.tilemap.collision.CollisionType[source]
Bases:
objectThe two kinds of blocking tile move_and_collide understands, read from a tile’s custom property (see collision_type_at). Everything else — slopes, conveyor belts, ladders, hazards — is deliberately left out: define your own property (e.g. “damage”) and read it with TileMap.properties_of_gid/get_gid yourself, the same way these two are read.
- NONE: str = 'none'
- SOLID: str = 'solid'
- PLATFORM: str = 'platform'
- gale.tilemap.collision.collision_type_at(tilemap, layer_name, row, col, collision_property='collision')[source]
- Parameters:
tilemap (TileMap) – The map to check.
layer_name (str) – Which of its layers to check.
row (int) – A tile row.
col (int) – A tile column.
collision_property (str) – The custom tile property (set in Tiled’s tileset editor) collision-checking reads. The default value is “collision”.
- Returns:
One of the CollisionType constants: CollisionType.NONE for an empty cell, an out-of-bounds cell, or a tile whose collision_property isn’t “solid”/”platform”.
- Return type:
str
- gale.tilemap.collision.move_and_collide(tilemap, layer_name, x, y, width, height, dx, dy, collision_property='collision')[source]
Moves an entity’s top-left corner by (dx, dy), one axis at a time (x, then y — the usual order for a 2D platformer, so a corner case sliding along a wall still gets stopped by the wall rather than a floor first), snapping it flush against whatever it runs into instead of leaving a gap.
Works entirely in floats, and never rounds x/y to whole pixels anywhere internally — including for the tile-overlap test itself, not just for the position you get back. Rounding either one is enough to reintroduce the bug this is written to avoid: at a typical frame rate, one frame’s movement under gravity near the ground is a fraction of a pixel, so an entity resting on solid ground keeps re-falling that fraction and re-colliding every frame — which reads as the ground-check flickering on and off, since a rounded position can stay numerically unchanged call after call while the real, unrounded one keeps drifting down into the floor. Round only when you need a pygame.Rect for rendering/hit testing elsewhere (e.g. pygame.Rect(round(x), round(y), width, height)).
A “solid” tile blocks in every direction. A “platform” tile only blocks downward movement, and only if the entity was already at or above the platform’s top edge before this call — never from below (walking/jumping up through it) or from the sides (walking through it at the same height).
- Parameters:
tilemap (TileMap) – The map to collide against.
layer_name (str) – Which of its layers to collide against.
x (float) – The entity’s current x position (top-left corner), before this move.
y (float) – The entity’s current y position (top-left corner), before this move.
width (float) – The entity’s width.
height (float) – The entity’s height.
dx (float) – Horizontal movement this call, in pixels (e.g. vx * dt).
dy (float) – Vertical movement this call, in pixels (e.g. vy * dt).
collision_property (str) – Forwarded to collision_type_at.
- Returns:
(new_x, new_y, collided_x, collided_y) — the resulting position, and whether it was stopped short on each axis.
- Return type:
Tuple[float, float, bool, bool]