Collision avoidance, path finding and smooth following, 3D snippet (C#/XNA)
Posted by Roy Triesscheijn on January 13th, 2010
Today I converted my “Swarm Like collision avoidance, path finding and smooth following”- project (what a mouth full) to work with 3D coordinates, if you understood the code, you would know this wasn’t much of a problem. Anyway I did it for you today
. (original article here).
public static void Attract(GameTime gameTime, Object3D ship, Object3D[] obstacles, Object3D target)
{
float pullDistance = Vector3.Distance(target.Position, ship.Position);
//Only do something if we are not already there
if (pullDistance > ((ship.Radius + target.Radius) * 1.5f))
{
Vector3 pull = (target.Position - ship.Position) * (1 / pullDistance); //the target tries to 'pull us in'
Vector3 totalPush = Vector3.Zero;
int contenders = 0;
for (int i = 0; i < obstacles.Length; ++i)
{
//draw a vector from the obstacle to the ship, that 'pushes the ship away'
Vector3 push = ship.Position - obstacles[i].Position;
//calculate how much we are pushed away from this obstacle, the closer, the more push
float distance = (Vector3.Distance(ship.Position, obstacles[i].Position) - obstacles[i].Radius) - ship.Radius;
//only use push force if this object is close enough such that an effect is needed
if (distance < ship.Radius * 3)
{
++contenders; //count that this object is actively pushing
if (distance < 0.0001f) //prevent division by zero errors and extreme pushes
{
distance = 0.0001f;
}
float weight = 1 / distance;
totalPush += push * weight;
}
}
pull *= Math.Max(1, 4 * contenders); //4 * contenders gives the pull enough force to pull stuff trough (tweak this setting for your game!)
pull += totalPush;
//Normalize the vector so that we get a vector that points in a certain direction, which we van multiply by our desired speed
pull.Normalize();
//Set the ships new position;
ship.Position += (pull * ship.Speed) * (float)gameTime.ElapsedGameTime.TotalSeconds;
}
}

January 18th, 2010 at 7:16 PM
Hi,
I want to thank you for the wonderful peice you did on Winform and Xna integration on your old blog. I just have one question – where would I put the drawing code if I wanted to draw something inside the Xna window (which is on the winform) by clicking a button on the winform?
Any help you can provide would be much appreciated as I am new to Xna and am getting to grips with it.
Again – thnx for the best example of Xna and Winform code on the net.
I will check back on this page to see if you have responded. If you dont want to respond – please say so, so that I can stop checking.
Regards
Q
January 19th, 2010 at 1:16 PM
Hey Q,
The most simplest place to put your code is in a timer event. Let the timer fire every 15ms and you get roughly 60 updates per second
. However take a look at the XNA WinForms sample code at http://creators.xna.com , since I’ve written my old article they have improved their code, to be more easy and better at integrating with winforms than my code.
Good luck, and if you have any further questions, you can always ask
.
January 19th, 2010 at 5:03 PM
Hi Roy. Thanks for responding. I have further questions – since you dont mind me asking Ill go ahead and ask them
So what you are saying is that I should create and start a timer from within my button (which is on the form). This timer should run an override of the Draw() method in order to draw something different?
Thanks again for the help.
Regards
Q
January 21st, 2010 at 12:16 PM
Hey Q,
Indeed just create a timer that fires every 15ms. Then treat the method that you call in the timer as your Draw and Update methods (loops) or let them call your Game1.Update() and Game1.Draw() methods and work from there as normal with XNA
.
January 21st, 2010 at 8:12 PM
Thanks again Roy.
January 25th, 2010 at 10:40 AM
No problem, I’m glad you find my blog useful! When you got something to show, be sure to post me a link!