Get the Mouse!
May 18, 1998
by Pat McClellan
I'm in need of a little help. I am currently working on a project involving multiple parent/child objects moving around the screen towards varies targets, ie the mouse. I have seen some similar projects done which can be seen at http://www.mousedown.demon.co.uk/.
My problem is that the child objects tend to overlap each other when moving toward the same target. What I want them to do ultimately, is to bump off each other when they collide, or to steer away from each other to avoid collisions. Is there any way that these child objects can detect each other or know the position of other child objects, and change their behaviour occordingly, all using the same parent script?
Regards
Clint Hannaford
Atomic Media
Dear Clint,
My friend Ed Bean is currently working on just such a program, so I thought I'd let him have a crack at this question. Ed writes...
In the case of non-colliding pathfinding objects, you might approach the problem like this...
Each of your objects needs to be able to test whether it is colliding with any other object. To do this, it needs access to a list of objects it can collide with.
At each frame, each of the objects needs to see if its next calculated position will collide with any of the other objects, by iterating through the object list, and calling a test handler on each of it's peers e.g., collideTest(the prospectRect of sprite mySprite, the calcd rect of otherObj) (returns boolean) If so, it's necessary to calculate a new prospective position for the colliding sprite, and test against the target object until on collideTest returns false. The method for calculating the new position might be to calculate the slope of the line formed by the center points of the two sprites, then march the test object away from the colliding object along that line until there is no collision returned. Obviously, it's possible to have resolution of one collision actually cause another. It may be necessary to iteratively resolve the object collisions until there are none. A Manager object would be best for overseeing this sort of issue.
My approach would be to place a manager object in the actorlist. Each time it receives a stepFrame message, it should in turn cause the objects to calculate new positions. Then it should iterate through the object list, requesting each object to resolve any resulting collisions. Finally, the objects should be drawn in their new positions.
(for the manager obj)
on stepframe me updateEnemies me resolveCollisions me drawEnemies me end
on updateEnemies me repeat with whichObj in p_AttackerList updatePosition (whichObj) end repeat end
on resolveCollisions me set collisionsExist = true repeat while (collisionsExist = true) set collisionsExist = false repeat with whichObj in p_AttackerList -- call handler on each attacker, and pass -- in list of objects to test for collision -- recurse until no collisions are reported set enemycollision = resolveEnemycollisions( ¬ whichObj,p_AttackerList) if (enemycollision = true) then set ¬ collisionsExist = true end repeat end repeat end
on drawEnemies me repeat with whichObj in p_AttackerList draw (whichObj) -- tell all objects to draw themselves -- in their now collision-free positions end repeat end
The other half of the equation is detecting the collision themselves, and having the enemies respond appropriately. I've included a sample movie which demonstrates the technique, and which you can examine for more in-depth information.
Realistic bouncing (ala a billiards game) is a little more involved, and perhaps a different issue...
Hope this helps!
And soon I'll get Ed to write a more detailed article on bouncing. For now, this should get you started. Thanks for your question and special thanks to Ed for his insight.
The source code for this article (with additional code) is also available in Mac or PC format.
Copyright 1997-2024, Director Online. Article content copyright by respective authors.