Group-based sprite collision tools and sprite collision detection predicates.
The predicate functions in this namespace apply to sprites if they
are named <foo>?
and apply to geometric data structures (lines,
rectangles, polygons etc.) if they are names <foo>?*
.
Group-based sprite collision tools and sprite collision detection predicates. The predicate functions in this namespace apply to sprites if they are named `<foo>?` and apply to geometric data structures (lines, rectangles, polygons etc.) if they are names `<foo>?*`.
(coarse-polys-collide?* poly-a poly-b)
Predicate to determine if two polygons possibly collide.
Checks if the minimum rectangles containing the polygons overlap. If
they do we should use fine-polys-collide?
to check properly.
Predicate to determine if two polygons possibly collide. Checks if the minimum rectangles containing the polygons overlap. If they do we should use `fine-polys-collide?` to check properly.
(coarse-pos-in-poly?* [x y] poly)
Predicate to determine if a point is possibly inside a polygon.
Checks if the point is contanied by the minimum rectangle containing
the polygon. If the point is inside this rectangle we should use
fine-pos-in-poly?
to check properly.
Predicate to determine if a point is possibly inside a polygon. Checks if the point is contanied by the minimum rectangle containing the polygon. If the point is inside this rectangle we should use `fine-pos-in-poly?` to check properly.
(collide-group a group-b collider)
Check a sprite from one group for collisions with all sprites from another group, updating both as necessary.
Reducing over group-b lets us build up a new version of group-b, updating the value of a as we go.
We filter out any b that returns nil
after colliding to allow
collide functions to kill sprites.
Check a sprite from one group for collisions with all sprites from another group, updating both as necessary. Reducing over group-b lets us build up a new version of group-b, updating the value of a as we go. We filter out any b that returns `nil` after colliding to allow collide functions to kill sprites.
(collide-groups sprite-groups {:keys [group-a-key group-b-key] :as collider})
Check a group of sprites for collisions with another group of sprites, updating all sprites as necessary.
We're iterating using a reducing function over the first group, this
means that each time we check an a
against group-b
we get the
new value for a, and the new values for each sprite in group-b
.
We filter out any a that returns nil
after colliding to allow
collide functions to kill sprites.
We build our results map using the threading macro to handle the
case where group-a-key
and group-b-key
are the same.
Check a group of sprites for collisions with another group of sprites, updating all sprites as necessary. We're iterating using a reducing function over the first group, this means that each time we check an `a` against `group-b` we get the new value for a, and the new values for each sprite in `group-b`. We filter out any a that returns `nil` after colliding to allow collide functions to kill sprites. We build our results map using the threading macro to handle the case where `group-a-key` and `group-b-key` are the same.
(collide-sprites a
b
{:keys [group-a-key group-b-key collision-detection-fn
collide-fn-a collide-fn-b non-collide-fn-a
non-collide-fn-b]})
Check two sprites for collision and update them with the appropriate
collide-fn-<a|b>
provided by the collider. These functions should
return an optionally modified version of their first argument, the
second is passed in only as a reference.
In the case that we're checking a group of sprites for collisions in the same group we need to check the uuid on the sprites to ensure they're not colliding with themselves.
Check two sprites for collision and update them with the appropriate `collide-fn-<a|b>` provided by the collider. These functions should return an optionally modified version of their first argument, the second is passed in only as a reference. In the case that we're checking a group of sprites for collisions in the same group we need to check the uuid on the sprites to ensure they're not colliding with themselves.
(collider group-a-key
group-b-key
collide-fn-a
collide-fn-b
&
{:keys [collision-detection-fn non-collide-fn-a non-collide-fn-b]
:or {collision-detection-fn w-h-rects-collide?
non-collide-fn-a identity-collide-fn
non-collide-fn-b identity-collide-fn}})
Define a check for collision between to groups of sprites with functions to be invoked on the sprites when collision is detected.
Define a check for collision between to groups of sprites with functions to be invoked on the sprites when collision is detected.
(equal-pos? {pos-a :pos} {pos-b :pos})
Predicate to check if two sprites have the same position.
Predicate to check if two sprites have the same position.
(equal-pos?* pos-a pos-b)
Predicate to check if two positions are equal.
Predicate to check if two positions are equal.
(fine-polys-collide?* poly-a poly-b)
Predicate to determine if two polygons overlap.
We first check if there are any points shared by the polygons, then we check if any of the lines intersect.
If no lines intersect it is still possible that one polygon is fully containing the other. In this case one polygon will contain all the points of the other. So we can just check if the first point of poly-a is contained in poly-b or vice versa.
Predicate to determine if two polygons overlap. We first check if there are any points shared by the polygons, then we check if any of the lines intersect. If no lines intersect it is still possible that one polygon is fully containing the other. In this case one polygon will contain all the points of the other. So we can just check if the first point of poly-a is contained in poly-b or vice versa.
(fine-pos-in-poly?* pos poly)
Uses ray casting to check if a polygon encloses a pos.
We construct a line starting at our point and count how many of the polygon lines it intersects, an odd number of intersections means the point is inside the polygon.
Our line should be infinite, but in practice any large number will suffice.
Uses ray casting to check if a polygon encloses a pos. We construct a line starting at our point and count how many of the polygon lines it intersects, an odd number of intersections means the point is inside the polygon. Our line should be infinite, but in practice any large number will suffice.
(identity-collide-fn a b)
Collide functions should return an optionally modified a
sprite.
Collide functions should return an optionally modified `a` sprite.
(lines-intersect? [[x1 y1 :as p1] [x2 y2 :as p2] :as l1]
[[x3 y3 :as p3] [x4 y4 :as p4] :as l2])
Predicate to determine if two lines intersect.
We have decided that zero-length lines do not intersect as the complexity in determining their intersection is not worth the performance hit.
line a: (x1, y1) -> (x2, y2) line b: (x3, y3) -> (x4, y4)
lines intersect iff: 0.0 <= numerator-t/denominator-t <= 1.0 and 0.0 <= numerator-u/denominator-u <= 1.0
We can just assert that the fraction is bottom-heavy.
Predicate to determine if two lines intersect. We have decided that zero-length lines do not intersect as the complexity in determining their intersection is not worth the performance hit. line a: (x1, y1) -> (x2, y2) line b: (x3, y3) -> (x4, y4) lines intersect iff: 0.0 <= numerator-t/denominator-t <= 1.0 and 0.0 <= numerator-u/denominator-u <= 1.0 We can just assert that the fraction is bottom-heavy.
(poly-contains-pos? a b)
Predicate to check if the position of sprite b
is inside the
bounding polygon of sprite a
centered on its position.
Accounts for the respective :offsets
configuration of each sprite.
Predicate to check if the position of sprite `b` is inside the bounding polygon of sprite `a` centered on its position. Accounts for the respective `:offsets` configuration of each sprite.
(polys-collide? {bounds-fn-a :bounds-fn pos-a :pos :as a}
{bounds-fn-b :bounds-fn pos-b :pos :as b})
Predicate to check an intersection of the bounding polygons of
sprites a
and b
centered on their positions.
Accounts for the respective :offsets
configuration of each sprite.
Predicate to check an intersection of the bounding polygons of sprites `a` and `b` centered on their positions. Accounts for the respective `:offsets` configuration of each sprite.
(polys-collide?* poly-a poly-b)
Predicate to check if two polygons overlap.
The fine-polys-collide?
predicate is expensive so we only do it if
the cheaper coarse-polys-collide?
says this is a possible
collision.
Predicate to check if two polygons overlap. The `fine-polys-collide?` predicate is expensive so we only do it if the cheaper `coarse-polys-collide?` says this is a possible collision.
(pos->ray [x y])
Creates an arbitrarily long line starting at the specified pos.
When doing poly->point collision detection a point lying on a horizontal edge of a poly would cause a division by zero if we used a horizontal ray.
This would be handled, but would not count as a collision so we increment y to make it much less likely that the intersecting lines are parallel.
Creates an arbitrarily long line starting at the specified pos. When doing poly->point collision detection a point lying on a horizontal edge of a poly would cause a division by zero if we used a horizontal ray. This would be handled, but would not count as a collision so we increment y to make it much less likely that the intersecting lines are parallel.
(pos-in-poly? {pos-a :pos :as a} {bounds-fn :bounds-fn pos-b :pos :as b})
Predicate to check if the position of sprite a
is inside the
bounding polygon of sprite b
centered on its position.
Accounts for the respective :offsets
configuration of each sprite.
Predicate to check if the position of sprite `a` is inside the bounding polygon of sprite `b` centered on its position. Accounts for the respective `:offsets` configuration of each sprite.
(pos-in-poly?* pos poly)
Predicate to check if a pos is inside a polygon.
The fine-pos-in-poly?
predicate is expensive so we only do it if
the cheaper coarse-pos-in-poly?
says this is a possible
collision.
Predicate to check if a pos is inside a polygon. The `fine-pos-in-poly?` predicate is expensive so we only do it if the cheaper `coarse-pos-in-poly?` says this is a possible collision.
(pos-in-rect? {pos-a :pos :as a} {[bx by] :pos [bw bh] :size :as b})
Predicate to check if the position of sprite a
is inside the w
by
h
rect of sprite b
centered on its position.
Accounts for the respective :offsets
configuration of each sprite.
Predicate to check if the position of sprite `a` is inside the `w` by `h` rect of sprite `b` centered on its position. Accounts for the respective `:offsets` configuration of each sprite.
(pos-in-rect?* [ax ay] [bx1 by1 bx2 by2])
Predicate to check if a position is inside a rectangle.
Predicate to check if a position is inside a rectangle.
(pos-in-rotating-poly?
{pos-a :pos :as a}
{bounds-fn :bounds-fn pos-b :pos rotation :rotation :as b})
Predicate to check if the position of sprite a
is inside the
bounding polygon of sprite b
centered on its position, taking into
account its rotation.
Accounts for the respective :offsets
configuration of each sprite.
Predicate to check if the position of sprite `a` is inside the bounding polygon of sprite `b` centered on its position, taking into account its rotation. Accounts for the respective `:offsets` configuration of each sprite.
(rect-contains-pos? a b)
Predicate to check if the position of sprite b
is inside the w
by
h
rect of sprite a
centered on its position.
Accounts for the respective :offsets
configuration of each sprite.
Predicate to check if the position of sprite `b` is inside the `w` by `h` rect of sprite `a` centered on its position. Accounts for the respective `:offsets` configuration of each sprite.
(rects-overlap?* [ax1 ay1 ax2 ay2] [bx1 by1 bx2 by2])
Predicate to determine if two rectangles overlap.
Predicate to determine if two rectangles overlap.
(rotating-poly-contains-pos? a b)
Predicate to check if the position of sprite b
is inside the
bounding polygon of sprite a
centered on its position, taking into
account its rotation.
Accounts for the respective :offsets
configuration of each sprite.
Predicate to check if the position of sprite `b` is inside the bounding polygon of sprite `a` centered on its position, taking into account its rotation. Accounts for the respective `:offsets` configuration of each sprite.
(rotating-polys-collide?
{bounds-fn-a :bounds-fn pos-a :pos rotation-a :rotation wa :w ha :h :as a}
{bounds-fn-b :bounds-fn pos-b :pos rotation-b :rotation wb :w hb :h :as b})
Predicate to check for an intersection of the bounding polys of
sprites a
and b
centered on their positions, taking into account
the rotation of both sprites.
Accounts for the respective :offsets
configuration of each sprite.
Predicate to check for an intersection of the bounding polys of sprites `a` and `b` centered on their positions, taking into account the rotation of both sprites. Accounts for the respective `:offsets` configuration of each sprite.
(update-state {:keys [current-scene] :as state})
Update the sprites in the current scene based on the scene colliders.
Update the sprites in the current scene based on the scene colliders.
(w-h-rects-collide? {[ax ay] :pos [aw ah] :size :as a}
{[bx by] :pos [bw bh] :size :as b})
Predicate to check for overlap of the w
by h
rects of two sprites
centered on their positions.
Accounts for the respective :offsets
configuration of each sprite.
Predicate to check for overlap of the `w` by `h` rects of two sprites centered on their positions. Accounts for the respective `:offsets` configuration of each sprite.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close