Main Module¶
HC = require 'HC'
The purpose of the main modules is to connect shapes with the spatial hash – a data structure to quickly look up neighboring shapes – and to provide utilities to tell which shapes intersect (collide) with each other.
Most of the time, HC will be run as a singleton; you can, however, also create several instances, that each hold their own little worlds.
Initialization¶
-
HC.
new
([cell_size = 100])¶ Arguments: - cell_size (number) – Resolution of the internal search structure (optional).
Returns: Collider instance.
Creates a new collider instance that holds a separate spatial hash. Collider instances carry the same methods as the main module. The only difference is that function calls must use the colon-syntax (see below).
Useful if you want to maintain several collision layers or several separate game worlds.
The cell_size
somewhat governs the performance of HC.neighbors()
and
HC.collisions()
. How this parameter affects the performance depends on
how many shapes there are, how big these shapes are and (somewhat) how the
shapes are distributed.
A rule of thumb would be to set cell_size
to be about four times the size
of the average object.
Or just leave it as is and worry about it only if you run into performance
problems that can be traced back to the spatial hash.
Example:
collider = HC.new(150) -- create separate world
-- method calls with colon syntax
ball = collider:circle(100,100,20)
rect = collider:rectangle(110,90,20,100)
for shape, delta in pairs(collider:collisions(ball)) do
shape:move(delta.x, delta.y)
end
-
HC.
resetHash
([cell_size = 100])¶ Arguments: - cell_size (number) – Resolution of the internal search structure (optional).
Reset the internal search structure, the spatial hash. This clears all shapes that were registered beforehand, meaning that HC will not be able to find any collisions with those shapes anymore.
Example:
function new_stage()
actors = {} -- clear the stage on our side
HC.resetHash() -- as well as on HC's side
end
Bookkeeping¶
See also the HC.shapes sub-module.
-
HC.
rectangle
(x, y, w, h)¶ Arguments: - x,y (numbers) – Upper left corner of the rectangle.
- w,h (numbers) – Width and height of the rectangle.
Returns: The rectangle
Shape()
added to the scene.
Add a rectangle shape to the scene.
Note
Shape()
transformations, e.g. Shape.moveTo()
and
Shape.rotate()
will be with respect to the center, not the upper left
corner of the rectangle!
Example:
rect = HC.rectangle(100, 120, 200, 40)
rect:rotate(23)
-
HC.
polygon
(x1, y1, ..., xn, yn)¶ Arguments: - x1,y1,...,xn,yn (numbers) – The corners of the polygon. At least three corners that do not lie on a straight line are required.
Returns: The polygon
Shape()
added to the scene.
Add a polygon to the scene. Any non-self-intersection polygon will work. The polygon will be closed; the first and the last point do not need to be the same.
Note
If three consecutive points lie on a line, the middle point will be discarded. This means you cannot construct polygon shapes that are lines.
Note
Shape()
transformations, e.g. Shape.moveTo()
and
Shape.rotate()
will be with respect to the center of the polygon.
Example:
shape = HC.polygon(10,10, 40,50, 70,10, 40,30)
shape:move(42, 5)
-
HC.
circle
(cx, cy, radius)¶ Arguments: - cx,cy (numbers) – Center of the circle.
- radius (number) – Radius of the circle.
Returns: The circle
Shape()
added to the scene.
Add a circle shape to the scene.
Example:
circle = HC.circle(400, 300, 100)
-
HC.
point
(x, y)¶ Arguments: - x, y (numbers) – Position of the point.
Returns: The point
Shape()
added to the scene.
Add a point shape to the scene.
Point shapes are most useful for bullets and such, because detecting collisions between a point and any other shape is a little faster than detecting collision between two non-point shapes. In case of a collision, the separating vector will not be valid.
Example:
bullets[#bulltes+1] = HC.point(player.pos.x, player.pos.y)
Add a shape to the bookkeeping system.
HC.neighbors()
and Hc.collisions()
works only with registered
shapes.
You don’t need to (and should not) register any shapes created with the above
functions.
Overwrites Shape.move()
, Shape.rotate()
, and Shape.scale()
with versions that update the HC.spatialhash.
This function is mostly only useful if you provide a custom shape. See Custom Shapes.
Remove a shape to the bookkeeping system.
Warning
This will also invalidate the functions Shape.move()
,
Shape.rotate()
, and Shape.scale()
.
Make sure you delete the shape from your own actor list(s).
Example:
for i = #bullets,1,-1 do
if bullets[i]:collidesWith(player)
player:takeDamage()
HC.remove(bullets[i]) -- remove bullet from HC
table.remove(bullets, i) -- remove bullet from own actor list
end
end
Collision Detection¶
-
HC.
collisions
(shape)¶ Arguments: - shape (Shape) – Query shape.
Returns: Table of colliding shapes and separating vectors.
Get shapes that are colliding with shape
and the vector to separate the shapes.
The separating vector points away from shape
.
The table is a set, meaning that the shapes are stored in keys of the table.
The values are the separating vector.
You can iterate over the shapes using pairs
(see example).
Example:
local collisions = HC.collisions(shape)
for other, separating_vector in pairs(collisions)
shape:move(-separating_vector.x/2, -separating_vector.y/2)
other:move( separating_vector.x/2, separating_vector.y/2)
end
-
HC.
neighbors
(shape)¶ Arguments: - shape (Shape) – Query shape.
Returns: Table of neighboring shapes, where the keys of the table are the shape.
Get other shapes in that are close to shape
.
The table is a set, meaning that the shapes are stored in keys of the table.
You can iterate over the shapes using pairs
(see example).
Note
The result depends on the size and position of shape
as well as the
grid size of the spatial hash: HC.neighbors()
returns the shapes that
are in the same cell(s) as shape
.
Example:
local candidates = HC.neighbors(shape)
for other in pairs(candidates)
local collides, dx, dy = shape:collidesWith(other)
if collides then
other:move(dx, dy)
end
end
-
HC.
hash
¶
Reference to the SpatialHash()
instance.