[m-users.] Cartesian product of two sets of things.
Sean Charles (emacstheviking)
objitsu at gmail.com
Mon Oct 9 19:09:23 AEDT 2023
My video game experiment with Mercury is proving very interesting.
Collision detection: given the low number of objects on the screen, I have been experimenting with various ways of performing collision detection given the nature of Mercury and not using in-place destructive updates etc, which so far, to be honest, has not been a problem, I am still hitting 59FPS on a 60FPS rate limited event loop.
I have one player ship, and I have a list of attacking things, a list of falling things, the attacking things and the falling things (rocks, power ups etc) all have a common type class interface:
:- typeclass hittable(T) where
[
func id(T) = int,
func as_point(T) = pointf,
func as_circle(T) = vector3f,
func as_rect(T) = rectangle,
func is_hit(T) = bool
% pred set_hit(T::in, T::out) is det
].
Currently, I pass in two lists of things, typically the first list is the current round of missiles from the player, the second list is the list of things that I want to see have collided with anything in the first list. My current implementation is pretty simple, and probably naive:
:- pred collisions_between(
coll_type::in, list(S)::in, list(T)::in, list(int)::out, list(int)::out
) is det <= ( hittable(S), hittable(T) ).
collisions_between(Check, Shots, Targets, Sids, Tids) :-
Outer = (pred(Shot::in, !.S::in, !:S::out, !.T::in, !:T::out) is det :-
Inner = (pred(Target::in, !.S::in, !:S::out, !.T::in, !:T::out) is det :-
( if did_collide(Check, Shot, Target) then
set.insert(id(Shot), !S),
set.insert(id(Target), !T)
% set_hit(), Target is not mutable here...have another think!
else
true
)
),
list.foldl2(Inner, Targets, !S, !T)
),
list.foldl2(Outer,
Shots,
set.init:coll_set, Sids0,
set.init:coll_set, Tids0
),
Sids = set.to_sorted_list(Sids0),
Tids = set.to_sorted_list(Tids0).
The output is two lists, the object IDs of those things involved in collisions.
My question then is, given the two loops are basically generating a cartesian product, is there a module function somewhere that would do that for me, generate a single list of all pairs? Then I could list.chunk and maybe produce a cleaner bit of code. I am currently also considering on uncommenting out the set_hit() typeclass predicate so that I can modify the objects in place, so instead of returning two sets of objects ID,s I'd be returning a new set of objects with their respective hit flags set.
I am also contemplating a simple 'even system' so that the output of the collision MIGHT be a list of actions eg. explode(item), power_up(100), etc etc, like I say, it's a minefield of possibilities!
Thanks.
Sean
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20231009/b6e5f67e/attachment.html>
More information about the users
mailing list