<html><head><meta http-equiv="content-type" content="text/html; charset=us-ascii"></head><body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">My video game experiment with Mercury is proving very interesting.<div><br></div><div>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.</div><div><br></div><div>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:</div><div><br></div><div><div><div><font face="Edlo">:- typeclass hittable(T) where</font></div><div><font face="Edlo">[</font></div><div><font face="Edlo">   func id(T)        = int,</font></div><div><font face="Edlo">   func as_point(T)  = pointf,</font></div><div><font face="Edlo">   func as_circle(T) = vector3f,</font></div><div><font face="Edlo">   func as_rect(T)   = rectangle,</font></div><div><font face="Edlo">   func is_hit(T)    = bool</font></div><div><font face="Edlo">%   pred set_hit(T::in, T::out) is det</font></div><div><font face="Edlo">].</font></div></div></div><div><br></div><div>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:</div><div><br></div><div><div><font face="Edlo">:- pred collisions_between(</font></div><div><font face="Edlo">    coll_type::in, list(S)::in, list(T)::in, list(int)::out, list(int)::out</font></div><div><font face="Edlo">) is det <= ( hittable(S), hittable(T) ).</font></div><div><font face="Edlo"><br></font></div><div><font face="Edlo">collisions_between(Check, Shots, Targets, Sids, Tids) :-</font></div><div><font face="Edlo">    Outer = (pred(Shot::in, !.S::in, !:S::out, !.T::in, !:T::out) is det :-</font></div><div><font face="Edlo">        Inner = (pred(Target::in, !.S::in, !:S::out, !.T::in, !:T::out) is det :-</font></div><div><font face="Edlo">            ( if did_collide(Check, Shot, Target) then</font></div><div><font face="Edlo">                set.insert(id(Shot), !S),</font></div><div><font face="Edlo">                set.insert(id(Target), !T)</font></div><div><font face="Edlo">                % set_hit(), Target is not mutable here...have another think!</font></div><div><font face="Edlo">            else</font></div><div><font face="Edlo">                true</font></div><div><font face="Edlo">            )</font></div><div><font face="Edlo">        ),</font></div><div><font face="Edlo">        list.foldl2(Inner, Targets, !S, !T)</font></div><div><font face="Edlo">    ),</font></div><div><font face="Edlo">    list.foldl2(Outer,</font></div><div><font face="Edlo">        Shots,</font></div><div><font face="Edlo">        set.init:coll_set, Sids0,</font></div><div><font face="Edlo">        set.init:coll_set, Tids0</font></div><div><font face="Edlo">    ),</font></div><div><font face="Edlo">    Sids = set.to_sorted_list(Sids0),</font></div><div><font face="Edlo">    Tids = set.to_sorted_list(Tids0).</font></div></div><div><br></div><div><br></div><div>The output is two lists, the object IDs of those things involved in collisions.</div><div><br></div><div>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.</div><div><br></div><div>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!</div><div><br></div><div><br></div><div>Thanks.</div><div>Sean</div><div><br></div></body></html>