Michael H Lees (mhl@cs.nott.ac.uk++) writes:
> I have a sim_movable_agent which I add to a window using
> rc_add_containers. This means it's possible to move the agent with the
> mouse. The problem is I have a grid layout and I want the agent to
> 'snap' to the grid when it is moved by the mouse. I know how to do this,
> that is to check the sim_x and sim_y coordinates of the
> sim_movable_agent and round the each of them to the nearest integer.
>
> The problem is I'm not sure where to do it? I've looked through the
> libraries for the procedure which moves the sim_movable_agent (with the
> mouse) but can't find it? I assume when you move the sim_movable_agent
> with the mouse some procedure is called which sets its new sim_x and
> sim_y according to the current mouse location? Can someone tell me where
> this is done?
>
> Thanks
>
> Mike
>
You'll need to find now to alter the behaviour of a movable object
so that it is constrained.
This means going into the RCLIB package (HELP RCLIB) to understand
how movable items are implemented. E.g. try TEACH rc_linepic
Because RCLIB uses objectclass which supports multiple inheritance,
if you want to find methods associated with a class you have to look
at all the super-classes.
The mixin sim_movable_agent inherits from sim_multiwin_mobile, which
inherits from the mixin rc_linepic_movable defined in
lIB rc_linepic.
The basic method for moving is called rc_move_to, which takes a
movable object, the newx, newy, and a drawmode argument, which is
normally just true.
So you can define a new subclass of sim_movable_agent, and then
for that subclass redefine the move method. The way to do that
is to make the move method take the given coordinates, convert
to the required coordinates (on the grid) then use call_next_method
(described in HELP objectclass and REF objectclass to do the move.
E.g.
;;; first define your new class, a subclass of sim_movable_agent
define :class grid_mover;
is sim_movable_agent;
enddefine;
;;; Now redefine the method rc_move_to for this class.
;;; Restrict objects to have integer coordinates after a move.
;;; Use call_next_method to invoke the previously defined method.
define :method rc_move_to(pic:grid_mover, x, y, mode);
;;; assume an integer grid, i.e. round x and y
call_next_method(pic, round(x), round(y), mode)
enddefine;
Then all your instances of grid_mover will behave like instances of
sim_movable_agent, except that attempts to move them will always
leave them with integral coordinates (provided that you don't try
moving them by using low level slot access methods).
You can also move such a thing by using the updater of sim_coords.
e.g. if g is an instance of grid_mover you can do
(33.4, 45.9) -> sim_coords(g);
The actual coordinates it gets will be 33 and 46.
The updater of sim_coords invokes rc_move_to.
I hope that helps.
I have found the objectlcass package wonderful for designing the
sim_agent toolkit, and the rclib toolkit.
Objectclass makes it terribly easy to produce new variants of old
types of entities, without changing any of your old code.
Aaron
====
Aaron Sloman, ( http://www.cs.bham.ac.uk/~axs/ )
School of Computer Science, The University of Birmingham, B15 2TT, UK
EMAIL A.Sloman AT cs.bham.ac.uk (ReadATas@please !)
PAPERS: http://www.cs.bham.ac.uk/research/cogaff/ (And free book on Philosophy of AI)
FREE TOOLS: http://www.cs.bham.ac.uk/research/poplog/freepoplog.html
|