Advanced Tiled Collider (ATC) is a collision class for Advanced Tiled Loader (ATL) Link.
Check out the demo branch for example LOVE files: Demo
Features:
- Requires ATL 0.12 (Untested for other versions)
- Customizable collision callback for all sorts of possibilities
- Supports the use of vertical/horizontal height maps for slopes
- Continuous collision detection ensures that nothing is missed
Limitations:
- Isometric orientation is not supported
- ATL offsets ( offsetX and offsetY ) aren't handled correctly
To load the class and create a new collision object:
atc = require 'atc'
object = atc.new(x,y,width,height,map,tileLayer)If a tileLayer is not specified, a layer in map.layers will be selected for you. This is useful if your map only has one layer.
The collision class creates a collision object that can interact with an ATL map. The object is a rectangle and has the following properties:
object.x (default: nil)
The top left x position of the rectangle
object.y (default: nil)
The top left y position of the rectangle
object.w (default: nil)
The width of the rectangle
object.h (default: nil)
The height of the rectangle
object.map (default: nil)
The associated ATL map for collision detection
object.tileLayer (default: nil)
The associated tile layer for collision detection
object.isActive (default: true)
If false, the object ignores all tile collision with object.move or object.moveTo
object.isBullet (default: false)
If true, use continuous collision detection with object.move or object.moveTo. false is default for best performance.
boolean = object:isResolvable(side,tile,gx,gy)
This is the user defined collision callback. It gets called whenever a sensor overlaps with a slope or tile. The side parameter marks what type of sensor it is.
Sensor types ( side ):
leftrighttopbottom
By default, the left sensor covers the left half area of the rectangle, and the right sensor covers the right half area. The top sensor covers the top half area of the rectangle, and the bottom sensor covers the bottom half area.
The tile object is passed as an argument for tile specific collision. tile properties can be set in Tiled or in tile.properties. gx and gy are the grid coordinates of the tile. The side parameter affects the direction the object is moved to resolve the collision. For example, if side is right, the object will be moved left. The callback must return true for the collision to be resolved.
Note
right is checked before left, and bottom is checked before top when moving. If your object is moving too fast, the right/bottom sensor could detect a tile when moving left / up and resolve the collision. One can avoid this problem by checking the direction of movement and only resolve collision with specific sensors.
Example:
-- direction check for fast objects
function object:isResolvable(side,tile,gx,gy)
if side == 'right' or side == 'left' then
if dx == 0 then return true end
if dx > 0 and side == 'right' then return true end
if dx < 0 and side == 'left' then return true end
end
if side == 'bottom' or side == 'top' then
if dy == 0 then return true end
if dy > 0 and side == 'bottom' then return true end
if dy < 0 and side == 'top' then return true end
end
endobject:moveTo(x,y)
Move the object to x,y and resolve all collisions. If object.isBullet is true, continuous collision detection is used to prevent tunneling through tiles. Horizontal movements are applied before vertical movements.
object:move(dx,dy)
Move the object by dx,dy amounts and resolve all collisions.
object:draw(mode)
Draw the object where mode is fill or line.
object = object:setSize(width,height)
object = object:setMap(map)
object = object:setTileLayer(tileLayer)
object = object:setActive(boolean)
object = object:setBullet(boolean)
boolean = object:isActive()
boolean = object:isBullet()
x,y,width,height = object:unpack()
object = object:rightResolve(x,y,w,h)
Resolve right sensor collision. x,y,w,h is the rectangular range of the sensor. All tiles overlapping the sensor is checked for collision.
object = object:leftResolve(x,y,w,h)
...
object = object:bottomResolve(x,y,w,h)
...
object = object:topResolve(x,y,w,h)
....
object = object:resolveX()
Resolve right and left sensor collisions.
object = object:resolveY()
Resolve top and bottom sensor collisions.
Vertical and horizontal height maps are supported for slopes. Just define an array ( verticalHeightMap or horizontalHeightMap ) of height values for each tile under tile.properties. For an object's position, vertical height maps adjust it vertically, while horizontal height maps adjust it horizontally. A tile can have both height maps at the same time. The following ASCII art shows the "shape" of a slope depending on which side touches it.
ASCII ART EXAMPLE
=================
4x4 tile example
tile.properties.verticalHeightMap = {1,2,3,4}
**Vertical Height Map**
"bottom"
4 |
3 | |
2 | | |
1 | | | |
1 2 3 4
"top"
1 | | | |
2 | | |
3 | |
4 |
1 2 3 4
**Horizontal Height Map**
tile.properties.horizontalHeightMap = {1,2,3,4}
"left"
1 =
2 = =
3 = = =
4 = = = =
1 2 3 4
"right"
1 =
2 = =
3 = = =
4 = = = =
4 3 2 1
