Example 12: Fly Swatter

1 Kitchen Wall
2 Single Walker
3 Multiple Walkers

1 Kitchen Wall

:- ensure_loaded(library(misc/vector)).
:- ensure_loaded(library(misc/react)).
:- ensure_loaded(library(math)).
:- ensure_loaded(library(util/format)).

back(ID) :-
   tag_format('<pattern id="~a" width="50" height="40" patternUnits="userSpaceOnUse">', [ID]),
       svg_image(0,0,50,40,'tile.jpg',[]),
   tag('</pattern>'),
   format_atom('url(#~a)', [ID], F),
   svg_rect(0,0,500,400,[fill(F)]).

draw(X, Y, A, ID) :-
   format_atom('translate(~g,~g) rotate(~g)', [X,Y,A], T),
   svg_image(-16, -16, 32, 32, 'fly.png', [id(ID),transform(T)]),
   flush_output.

:- svg_begin([id(kitchen)]), back(wall),
   draw(250, 150, 0, fly),
   draw(200, 200, -90, fly1),
   draw(300, 200, 90, fly2),
   draw(250, 250, 180, fly3),
   svg_end, nl.

2 Single Walker

buzz(0, _, _, _, _) :- !.
buzz(I, X, Y, A, ID) :-
   R is A*pi/180,
   random(V), W is V*10,
   X2 is X+W*sin(R),
   Y2 is Y-W*cos(R),
   random(U), A2 is A+U*30-15,
   shield((tag_goto(ID),
           tag_remove,
           draw(X2, Y2, A2, ID))),
   I2 is I-1,
   sleep(200),
   buzz(I2, X2, Y2, A2, ID).

fly(ID, ID2) :-
   random(V), X is V*450+25,
   random(W), Y is W*350+25,
   random(U), A is U*360-180,
   shield((tag_goto(ID),
           draw(X, Y, A, ID2))),
   buzz(20, X, Y, A, ID2),
   shield((tag_goto(ID2),
           tag_remove)).

:- svg_begin([id(kitchen2)]), back(wall2),
   svg_end, nl,
   fly(kitchen2, fly4).

3 Multiple Walkers

flies(0, _) :- !.
flies(I, ID) :-
   format_atom('flies~w', [I], ID2),
   create_task(fly(ID, ID2)),
   I2 is I-1,
   sleep(1000),
   flies(I2, ID).

:- svg_begin([id(kitchen3)]), back(wall3),
   svg_end, nl,
   flies(3, kitchen3).